setName('update');
$this->setDescription('Update an existing BookStack instance.');
}
/**
* @throws CommandError
*/
protected function execute(InputInterface $input, OutputInterface $output): int
{
$output->writeln("Checking system requirements...");
RequirementsValidator::validate();
$output->writeln("Checking composer exists...");
$composerLocator = new ComposerLocator($this->appDir);
$composer = $composerLocator->getProgram();
if (!$composer->isFound()) {
$output->writeln("Composer does not exist, downloading a local copy...");
$composerLocator->download();
}
$output->writeln("Fetching latest code via Git...");
$this->updateCodeUsingGit();
$output->writeln("Installing PHP dependencies via composer...");
$this->installComposerDependencies($composer);
$output->writeln("Running database migrations...");
$this->runArtisanCommand(['migrate', '--force']);
$output->writeln("Clearing app caches...");
$this->runArtisanCommand(['cache:clear']);
$this->runArtisanCommand(['config:clear']);
$this->runArtisanCommand(['view:clear']);
return Command::SUCCESS;
}
/**
* @throws CommandError
*/
protected function updateCodeUsingGit(): void
{
$errors = (new ProgramRunner('git', '/usr/bin/git'))
->withTimeout(240)
->withIdleTimeout(15)
->runCapturingStdErr([
'-C', $this->appDir,
'pull', '-q', 'origin', 'release',
]);
if ($errors) {
throw new CommandError("Failed git pull with errors:\n" . $errors);
}
}
/**
* @throws CommandError
*/
protected function installComposerDependencies(ProgramRunner $composer): void
{
$errors = $composer->runCapturingStdErr([
'install',
'--no-dev', '-n', '-q', '--no-progress',
'-d', $this->appDir,
]);
if ($errors) {
throw new CommandError("Failed composer install with errors:\n" . $errors);
}
}
protected function runArtisanCommand(array $commandArgs): void
{
$errors = (new ProgramRunner('php', '/usr/bin/php'))
->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 CommandError("Failed 'php artisan {$cmdString}' with errors:\n" . $errors);
}
}
}