use Cli\Services\AppLocator;
use Cli\Services\ArtisanRunner;
use Cli\Services\ComposerLocator;
+use Cli\Services\Paths;
use Cli\Services\ProgramRunner;
use Cli\Services\RequirementsValidator;
+use Phar;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
$output->writeln("<info>Checking system requirements...</info>");
RequirementsValidator::validate();
+ $output->writeln("<info>Checking local Git repository is active...</info>");
+ $this->ensureGitRepoExists($appDir);
+
$output->writeln("<info>Checking composer exists...</info>");
$composerLocator = new ComposerLocator($appDir);
$composer = $composerLocator->getProgram();
$composerLocator->download();
}
+ $cliPath = Phar::running(false);
+ $cliPreUpdateHash = $cliPath ? hash_file('sha256', $cliPath) : '';
+
$output->writeln("<info>Fetching latest code via Git...</info>");
$this->updateCodeUsingGit($appDir);
+ $cliPostUpdateHash = $cliPath ? hash_file('sha256', $cliPath) : '';
+ if ($cliPostUpdateHash !== $cliPreUpdateHash) {
+ $output->writeln("<error>System CLI file changed during update!\nRe-run the update command to complete the update process.</error>");
+ return Command::FAILURE;
+ }
+
$output->writeln("<info>Installing PHP dependencies via composer...</info>");
$this->installComposerDependencies($composer, $appDir);
$artisan->run(['config:clear']);
$artisan->run(['view:clear']);
+ $output->writeln("<success>Your BookStack instance at [{$appDir}] has been updated!</success>");
+
return Command::SUCCESS;
}
throw new CommandError("Failed composer install with errors:\n" . $errors);
}
}
+
+ protected function ensureGitRepoExists(string $appDir): void
+ {
+ $expectedPath = Paths::join($appDir, '.git');
+ if (!is_dir($expectedPath)) {
+ $message = "Could not find a local git repository, it does not look like this instance is managed via common means.\n";
+ $message .= "If you are running BookStack via a docker container, you should update following the advised process for the docker container image in use.\n";
+ $message .= "This typically involves pulling and using an updated docker container image.";
+
+ throw new CommandError($message);
+ }
+ }
}