Changeset View
Changeset View
Standalone View
Standalone View
arcanist/workflow/ArcanistBuildWorkflow.php
- This file was added.
<?php | |||||
/** | |||||
* Build the project | |||||
*/ | |||||
final class ArcanistBuildWorkflow extends ArcanistWorkflow { | |||||
const RESULT_OKAY = 0; | |||||
const RESULT_WARNINGS = 1; | |||||
const RESULT_ERRORS = 2; | |||||
const RESULT_SKIP = 3; | |||||
public function getWorkflowName() { | |||||
return 'build'; | |||||
} | |||||
public function getCommandSynopses() { | |||||
return phutil_console_format(<<<EOTEXT | |||||
**build** [__options__] [__targets__] | |||||
EOTEXT | |||||
); | |||||
} | |||||
public function getCommandHelp() { | |||||
return phutil_console_format(<<<EOTEXT | |||||
Build the bitcoin-abc project using CMake and Ninja. | |||||
You can specify the Ninja targets by passing them to __targets__. | |||||
Requires: cmake, ninja | |||||
EOTEXT | |||||
); | |||||
} | |||||
public function getArguments() { | |||||
return array( | |||||
'clear-cache' => array( | |||||
'help' => pht('Clear the CMake cache before running the build.'), | |||||
), | |||||
'dir' => array( | |||||
'param' => 'build directory', | |||||
'help' => pht('Set the build directory. It will be created if it does '. | |||||
'not exist. It defaults to the build directory configured using the '. | |||||
'`build_directory` option in your configuration file.'), | |||||
), | |||||
'post-clean' => array( | |||||
'help' => pht('Delete all files and the build directory if the build '. | |||||
'is successful.'), | |||||
), | |||||
'*' => 'targets', | |||||
); | |||||
} | |||||
public function requiresWorkingCopy() { | |||||
return true; | |||||
} | |||||
private function setSuccess($duration) { | |||||
$out = phutil_console_format( | |||||
"**<bg:green> %s </bg>** %s (%.3f s)\n", | |||||
pht('OKAY'), | |||||
pht('Build is successful'), | |||||
$duration); | |||||
PhutilConsole::getConsole()->writeOut($out); | |||||
return self::RESULT_OKAY; | |||||
} | |||||
private function setFailure($failureReason) { | |||||
$out = phutil_console_format( | |||||
"**<bg:red> %s </bg>** %s\n", | |||||
pht('FAILED'), | |||||
pht($failureReason)); | |||||
PhutilConsole::getConsole()->writeOut($out); | |||||
return self::RESULT_ERRORS; | |||||
} | |||||
public function run() { | |||||
$root = $this->getWorkingCopy()->getProjectRoot(); | |||||
/* | |||||
* Create the build directory if it doesn't exist. | |||||
* The build directory can be specified on the command line using the --dir | |||||
* option. If not specified, the build directory is read from the | |||||
* configuration option `build_directory`. | |||||
*/ | |||||
$buildDir = $this->getArgument('dir', | |||||
$this->getConfigurationManager()->getConfigFromAnySource( | |||||
'build_directory')); | |||||
if (!$buildDir) { | |||||
return $this->setFailure( | |||||
'No build directory is configured. Set the `build_directory` option '. | |||||
'in you configuration file and run `arc build` again, or select the '. | |||||
'build directory by using the `--dir` argument on the command line.'); | |||||
} | |||||
$buildDir = Filesystem::resolvePath($buildDir, $root); | |||||
try { | |||||
$buildDir = Filesystem::createDirectory($buildDir, 0755, | |||||
$recursive = true); | |||||
} catch (FilesystemException $e) { | |||||
var_dump($e); | |||||
return $this->setFailure( | |||||
'Unable to create the build directory: '.$buildDir.'. '. | |||||
'Check the permissions and run `arc build` again.'); | |||||
} | |||||
/* Clear the CMake cache if requested */ | |||||
if ($this->getArgument('clear-cache')) { | |||||
/* Delete the CMakeCache.txt file */ | |||||
$cacheFile = Filesystem::resolvePath('CMakeCache.txt', $buildDir); | |||||
if (file_exists($cacheFile)) { | |||||
try { | |||||
Filesystem::remove($cacheFile); | |||||
} catch (FilesystemException $e) { | |||||
return $this->setFailure( | |||||
'Unable to remove the '.$buildDir.'/CMakeCache.txt file. '. | |||||
'Check the permissions and run `arc build --clear-cache` again.'); | |||||
} | |||||
} | |||||
} | |||||
$timeStart = microtime(true); | |||||
/* Run CMake from the build repository */ | |||||
$future = new ExecFuture('cmake -GNinja '.$root); | |||||
$future->setCWD($buildDir); | |||||
list($ret) = $future->resolve(); | |||||
if ($ret != 0) { | |||||
return $this->setFailure( | |||||
'CMake failed with error '.strval($ret)); | |||||
deadalnix: At no point the user called cmake, so this error is 100% completely irrelevant. | |||||
} | |||||
/* | |||||
* Run Ninja from the build directory. | |||||
* If "targets" arguments are specified, pass them to Ninja, otherwise do | |||||
* not speficy any target and let Ninja build the default. | |||||
*/ | |||||
$targets = $this->getArgument('targets'); | |||||
$cmd = 'ninja'; | |||||
foreach ($targets as $_) { | |||||
$cmd .= ' %s'; | |||||
deadalnixUnsubmitted Not Done Inline ActionsThis is not how you build command lines. deadalnix: This is not how you build command lines. | |||||
FabienAuthorUnsubmitted Done Inline ActionsThis printf-like syntax is what the Phutil ExecFuture expects. Fabien: This printf-like syntax is what the Phutil `ExecFuture` expects. | |||||
} | |||||
$future = new ExecFuture($cmd, ...$targets); | |||||
$future->setCWD($buildDir); | |||||
list($ret) = $future->resolve(); | |||||
$timeEnd = microtime(true); | |||||
if ($ret != 0) { | |||||
return $this->setFailure( | |||||
'Ninja failed with error '.strval($ret)); | |||||
deadalnixUnsubmitted Not Done Inline Actionsdito deadalnix: dito | |||||
} | |||||
/* Remove the build directory if requested. */ | |||||
if ($this->getArgument('post-clean')) { | |||||
try { | |||||
Filesystem::remove($buildDir); | |||||
} catch (FilesystemException $e) { | |||||
return $this->setFailure( | |||||
'Unable to delete the build directory: '.$buildDir.'. '. | |||||
'Check the permissions and run `arc build --post-clean` again.'); | |||||
} | |||||
} | |||||
return $this->setSuccess($timeEnd - $timeStart); | |||||
} | |||||
} |
At no point the user called cmake, so this error is 100% completely irrelevant.