applyChanges = !$this->option('dry-run');
$this->configName = $this->option('config');
if (!($oldConfig = config($this->configName))) {
$this->error("The specified config (config/{$this->configName}.php) doesn't exist.");
return;
}
if (array_key_exists("interactive", $oldConfig)) {
$this->error("This upgrade tool is for upgrading from Scribe v3 to v4, but it looks like you're coming from v2.");
$this->error("Please install v3 and follow its upgrade guide first.");
return;
}
$isMajorUpgrade = array_key_exists("default_group", $oldConfig) || array_key_exists("faker_seed", $oldConfig);
if ($isMajorUpgrade) $this->info("Welcome to the Scribe v3 to v4 upgrader.");
$this->line("Checking for config file changes...");
$upgrader = Upgrader::ofConfigFile("config/$this->configName.php", __DIR__ . '/../../config/scribe.php')
->dontTouch('routes', 'laravel.middleware', 'postman.overrides', 'openapi.overrides',
'example_languages', 'database_connections_to_transact', 'strategies', 'examples.models_source')
->move('default_group', 'groups.default')
->move('faker_seed', 'examples.faker_seed');
if (!$isMajorUpgrade)
$upgrader->dontTouch('groups');
$changes = $upgrader->dryRun();
if (empty($changes)) {
$this->info("✔ No config file changes needed.");
} else {
$this->info('The following changes will be made to your config file:');
$this->newLine();
foreach ($changes as $change) {
$this->line($change["description"]);
}
if ($this->applyChanges) {
$upgrader->upgrade();
$this->info("✔ Upgraded your config file. Your old config is backed up at config/$this->configName.php.bak.");
}
}
$this->newLine();
if (!$isMajorUpgrade) {
$this->info("✔ Done.");
$this->info(sprintf("See the full changelog at https://github.com/knuckleswtf/scribe/blob/%s/CHANGELOG.md", Scribe::VERSION));
return;
}
$this->finishV4Upgrade();
}
protected function finishV4Upgrade(): void
{
$this->migrateToConfigFileSort();
if ($this->applyChanges) {
if ($this->confirm("Do you have any custom strategies?")) {
$this->line('1. Add a new property public ?ExtractedEndpointData $endpointData;.');
$this->line('2. Replace the array $routeRules parameter in __invoke() with array $routeRules = [] .');
}
$this->newLine();
$this->info("✔ Done.");
}
$this->line("See the release announcement at http://scribe.knuckles.wtf/blog/laravel-v4> for the full upgrade guide!");
}
/**
* In v3, you sorted endpoints by reordering them in the group file, and groups by renaming the group files alphabetically
* (or by using `beforeGroup`/`afterGroup` for custom endpoints).
* v4 replaces them with the config item `groups.order`.
*/
protected function migrateToConfigFileSort()
{
$this->info("In v3, you sorted endpoints/groups by editing/renaming the generated YAML files (or `beforeGroup`/`afterGroup` for custom endpoints).");
$this->info("We'll automatically import your current sorting into the config item `groups.order`.");
$defaultGroup = config($this->configName.".default_group");
$pathConfig = new PathConfig($this->configName);
$extractedEndpoints = GroupedEndpointsFactory::fromCamelDir($pathConfig)->get();
$order = array_map(function (array $group) {
return array_map(function (array $endpoint) {
return $endpoint['metadata']['title'] ?: ($endpoint['httpMethods'][0] . ' /'. $endpoint['uri']);
}, $group['endpoints']);
}, $extractedEndpoints);
$groupsOrder = array_keys($order);
$keyIndices = array_flip($groupsOrder);
$userDefinedEndpoints = Camel::loadUserDefinedEndpoints(Camel::camelDir($pathConfig));
if ($userDefinedEndpoints) {
foreach ($userDefinedEndpoints as $endpoint) {
$groupName = $endpoint['metadata']['groupName'] ?? $defaultGroup;
$endpointTitle = $endpoint['metadata']['title'] ?? ($endpoint['httpMethods'][0] . ' /' . $endpoint['uri']);
if (!isset($order[$groupName])) {
// This is a new group; place it at the right spot.
if (($nextGroup = $endpoint['metadata']['beforeGroup'] ?? null)) {
$index = $keyIndices[$nextGroup];
array_splice($groupsOrder, $index, 0, [$groupName]);
} else if (($previousGroup = $endpoint['metadata']['afterGroup'] ?? null)) {
$index = $keyIndices[$previousGroup];
array_splice($groupsOrder, $index + 1, 0, [$groupName]);
} else {
$groupsOrder[] = $groupName;
}
$order[$groupName] = [$endpointTitle];
} else {
// Existing group, add endpoint
$order[$groupName] = [...$order[$groupName], $endpointTitle];
}
}
}
// Re-add them, so it's sorted in the right order
$newOrder = [];
foreach ($groupsOrder as $groupName) {
$newOrder[$groupName] = $order[$groupName];
}
$output = VarExporter::export($newOrder);
if ($this->applyChanges) {
$configFile = "config/{$this->configName}.php";
$output = str_replace("\n", "\n ", $output);
$newContents = str_replace(
"'order' => [],",
"'order' => $output,",
file_get_contents($configFile)
);
file_put_contents($configFile, $newContents);
$this->info("✔ Updated `groups.order`.");
} else {
$this->line("- `groups.order` will be set to:");
$this->info($output);
}
}
}