protected function execute(InputInterface $input, OutputInterface $output)
{
if (!file_exists(CLI_ROOT . '/vendor')) {
$this->stdErr->writeln('Directory not found: <error>' . CLI_ROOT . '/vendor</error>');
$this->stdErr->writeln('Cannot build from a global install');
return 1;
}
$outputFilename = $input->getOption('output');
if ($outputFilename && !is_writable(dirname($outputFilename))) {
$this->stdErr->writeln("Not writable: <error>{$outputFilename}</error>");
return 1;
}
/** @var \Platformsh\Cli\Helper\ShellHelper $shellHelper */
$shellHelper = $this->getHelper('shell');
if (!$shellHelper->commandExists('box')) {
$this->stdErr->writeln('Command not found: <error>box</error>');
$this->stdErr->writeln('The Box utility is required to build new CLI packages. Try:');
$this->stdErr->writeln(' composer global require kherge/box:~2.5');
return 1;
}
$keyFilename = $input->getOption('key');
if ($keyFilename && !file_exists($keyFilename)) {
$this->stdErr->writeln("File not found: <error>{$keyFilename}</error>");
return 1;
}
$boxConfig = [];
if ($outputFilename) {
/** @var \Platformsh\Cli\Helper\FilesystemHelper $fsHelper */
$fsHelper = $this->getHelper('fs');
$boxConfig['output'] = $fsHelper->makePathAbsolute($outputFilename);
} else {
// Default output: CLI_PHAR in the current directory.
$cwd = getcwd();
if ($cwd && $cwd !== CLI_ROOT) {
$boxConfig['output'] = getcwd() . '/' . self::$config->get('application.phar');
}
}
if ($keyFilename) {
$boxConfig['key'] = realpath($keyFilename);
}
$phar = isset($boxConfig['output']) ? $boxConfig['output'] : CLI_ROOT . '/' . self::$config->get('application.phar');
if (file_exists($phar)) {
/** @var \Platformsh\Cli\Helper\QuestionHelper $questionHelper */
$questionHelper = $this->getHelper('question');
if (!$questionHelper->confirm("File exists: <comment>{$phar}</comment>. Overwrite?")) {
return 1;
}
}
if (!$input->getOption('no-composer-rebuild')) {
$this->stdErr->writeln('Ensuring correct composer dependencies');
// Remove the 'vendor' directory, in case the developer has incorporated
// their own version of dependencies locally.
$shellHelper->execute(['rm', '-r', 'vendor'], CLI_ROOT, true, false);
$shellHelper->execute([$shellHelper->resolveCommand('composer'), 'install', '--no-dev', '--classmap-authoritative', '--no-interaction', '--no-progress'], CLI_ROOT, true, false);
}
$boxArgs = [$shellHelper->resolveCommand('box'), 'build', '--no-interaction'];
// Create a temporary box.json file for this build.
if (!empty($boxConfig)) {
$originalConfig = json_decode(file_get_contents(CLI_ROOT . '/box.json'), true);
$boxConfig = array_merge($originalConfig, $boxConfig);
$boxConfig['base-path'] = CLI_ROOT;
$tmpJson = tempnam('/tmp', 'box_json');
file_put_contents($tmpJson, json_encode($boxConfig));
$boxArgs[] = '--configuration=' . $tmpJson;
}
$this->stdErr->writeln("Building Phar package using Box");
$result = $shellHelper->execute($boxArgs, CLI_ROOT, false, true);
// Clean up the temporary file, regardless of errors.
if (!empty($tmpJson)) {
unlink($tmpJson);
}
if ($result === false) {
return 1;
}
if (!file_exists($phar)) {
$this->stdErr->writeln("File not found: <error>{$phar}</error>");
return 1;
}
$sha1 = sha1_file($phar);
$version = self::$config->get('application.version');
$size = filesize($phar);
$output->writeln("Package built: <info>{$phar}</info>");
$this->stdErr->writeln(" Size: " . number_format($size) . " B");
$this->stdErr->writeln(" SHA1: {$sha1}");
$this->stdErr->writeln(" Version: {$version}");
return 0;
}