From: Dan Brown Date: Mon, 6 Mar 2023 21:39:22 +0000 (+0000) Subject: Started restore command, extracted artisan command X-Git-Url: http://source.bookstackapp.com/system-cli/commitdiff_plain/0632ad4355078352b430a395e69b10cd790d739a Started restore command, extracted artisan command --- diff --git a/scripts/Commands/RestoreCommand.php b/scripts/Commands/RestoreCommand.php new file mode 100644 index 0000000..1f83045 --- /dev/null +++ b/scripts/Commands/RestoreCommand.php @@ -0,0 +1,63 @@ +setName('restore'); + $this->addArgument('backup-zip', InputArgument::REQUIRED, 'Path to the ZIP file containing your backup.'); + $this->setDescription('Restore data and files from a backup ZIP file.'); + $this->addOption('app-directory', null, InputOption::VALUE_OPTIONAL, 'BookStack install directory to restore into', ''); + } + + /** + * @throws CommandError + */ + protected function execute(InputInterface $input, OutputInterface $output): int + { + $appDir = AppLocator::require($input->getOption('app-directory')); + $output->writeln("Checking system requirements..."); + RequirementsValidator::validate(); + + // TODO - Warn that potentially dangerous, + // warn for same/forward versions only, + // warn this won't handle server-level stuff + + // TODO - Validate provided backup zip contents + // - Display and prompt to user + + // TODO - Environment handling + // - Restore of old .env + // - Prompt for correct DB details (Test before serving?) + // - Prompt for correct URL (Allow entry of new?) + + // TODO - Restore folders from backup + + // TODO - Restore database from backup + + $output->writeln("Running database migrations..."); + $artisan = (new ArtisanRunner($appDir)); + $artisan->run(['migrate', '--force']); + + // TODO - Update system URL (via BookStack artisan command) if + // there's been a change from old backup env + + $output->writeln("Clearing app caches..."); + $artisan->run(['cache:clear']); + $artisan->run(['config:clear']); + $artisan->run(['view:clear']); + + return Command::SUCCESS; + } +} diff --git a/scripts/Commands/UpdateCommand.php b/scripts/Commands/UpdateCommand.php index e9dfa60..1ca3ec0 100644 --- a/scripts/Commands/UpdateCommand.php +++ b/scripts/Commands/UpdateCommand.php @@ -3,8 +3,8 @@ namespace Cli\Commands; use Cli\Services\AppLocator; +use Cli\Services\ArtisanRunner; use Cli\Services\ComposerLocator; -use Cli\Services\EnvironmentLoader; use Cli\Services\ProgramRunner; use Cli\Services\RequirementsValidator; use Symfony\Component\Console\Command\Command; @@ -45,12 +45,13 @@ class UpdateCommand extends Command $this->installComposerDependencies($composer, $appDir); $output->writeln("Running database migrations..."); - $this->runArtisanCommand(['migrate', '--force'], $appDir); + $artisan = (new ArtisanRunner($appDir)); + $artisan->run(['migrate', '--force']); $output->writeln("Clearing app caches..."); - $this->runArtisanCommand(['cache:clear'], $appDir); - $this->runArtisanCommand(['config:clear'], $appDir); - $this->runArtisanCommand(['view:clear'], $appDir); + $artisan->run(['cache:clear']); + $artisan->run(['config:clear']); + $artisan->run(['view:clear']); return Command::SUCCESS; } @@ -88,22 +89,4 @@ class UpdateCommand extends Command throw new CommandError("Failed composer install with errors:\n" . $errors); } } - - protected function runArtisanCommand(array $commandArgs, string $appDir): void - { - $errors = (new ProgramRunner('php', '/usr/bin/php')) - ->withTimeout(60) - ->withIdleTimeout(5) - ->withEnvironment(EnvironmentLoader::load($appDir)) - ->runCapturingAllOutput([ - $appDir . DIRECTORY_SEPARATOR . 'artisan', - '-n', '-q', - ...$commandArgs - ]); - - if ($errors) { - $cmdString = implode(' ', $commandArgs); - throw new CommandError("Failed 'php artisan {$cmdString}' with errors:\n" . $errors); - } - } } diff --git a/scripts/Services/ArtisanRunner.php b/scripts/Services/ArtisanRunner.php new file mode 100644 index 0000000..c2bafc7 --- /dev/null +++ b/scripts/Services/ArtisanRunner.php @@ -0,0 +1,31 @@ +withTimeout(60) + ->withIdleTimeout(5) + ->withEnvironment(EnvironmentLoader::load($this->appDir)) + ->runCapturingAllOutput([ + $this->appDir . DIRECTORY_SEPARATOR . 'artisan', + '-n', '-q', + ...$commandArgs + ]); + + if ($errors) { + $cmdString = implode(' ', $commandArgs); + throw new Exception("Failed 'php artisan {$cmdString}' with errors:\n" . $errors); + } + } +} \ No newline at end of file diff --git a/scripts/run b/scripts/run index aee6902..8711169 100644 --- a/scripts/run +++ b/scripts/run @@ -7,10 +7,11 @@ if (php_sapi_name() !== 'cli') { require __DIR__ . '/vendor/autoload.php'; -use Symfony\Component\Console\Application; use Cli\Commands\BackupCommand; use Cli\Commands\InitCommand; +use Cli\Commands\RestoreCommand; use Cli\Commands\UpdateCommand; +use Symfony\Component\Console\Application; use Symfony\Component\Console\Formatter\OutputFormatterStyle; use Symfony\Component\Console\Output\ConsoleOutput; @@ -21,6 +22,7 @@ $app->setCatchExceptions(false); $app->add(new BackupCommand()); $app->add(new UpdateCommand()); $app->add(new InitCommand()); +$app->add(new RestoreCommand()); try { $app->run();