Changeset View
Changeset View
Standalone View
Standalone View
src/workflow/ArcanistLiberateWorkflow.php
| <?php | <?php | ||||
| /** | |||||
| * Create and update libphutil libraries. | |||||
| * | |||||
| * This workflow is unusual and involves re-executing 'arc liberate' as a | |||||
| * subprocess with `--remap` and `--verify`. This is because there is no way | |||||
| * to unload or reload a library, so every process is stuck with the library | |||||
| * definition it had when it first loaded. This is normally fine, but | |||||
| * problematic in this case because `arc liberate` modifies library definitions. | |||||
| */ | |||||
| final class ArcanistLiberateWorkflow extends ArcanistWorkflow { | final class ArcanistLiberateWorkflow extends ArcanistWorkflow { | ||||
| public function getWorkflowName() { | public function getWorkflowName() { | ||||
| return 'liberate'; | return 'liberate'; | ||||
| } | } | ||||
| public function getCommandSynopses() { | public function getWorkflowInformation() { | ||||
| return phutil_console_format(<<<EOTEXT | // TOOLSETS: Expand this help. | ||||
| **liberate** [__path__] | |||||
| EOTEXT | |||||
| ); | |||||
| } | |||||
| public function getCommandHelp() { | $help = pht(<<<EOTEXT | ||||
| return phutil_console_format(<<<EOTEXT | Create or update an Arcanist library. | ||||
| Supports: libphutil | |||||
| Create or update a libphutil library, generating required metadata | |||||
| files like \__init__.php. | |||||
| EOTEXT | EOTEXT | ||||
| ); | ); | ||||
| return $this->newWorkflowInformation() | |||||
| ->addExample(pht('**liberate**')) | |||||
| ->addExample(pht('**liberate** [__path__]')) | |||||
| ->setHelp($help); | |||||
| } | } | ||||
| public function getArguments() { | public function getWorkflowArguments() { | ||||
| return array( | return array( | ||||
| 'all' => array( | $this->newWorkflowArgument('clean') | ||||
| 'help' => pht( | ->setHelp( | ||||
| 'Drop the module cache before liberating. This will completely '. | pht('Perform a clean rebuild, ignoring caches. Thorough, but slow.')), | ||||
| 'reanalyze the entire library. Thorough, but slow!'), | $this->newWorkflowArgument('argv') | ||||
| ), | ->setWildcard(true), | ||||
| 'force-update' => array( | |||||
| 'help' => pht( | |||||
| 'Force the library map to be updated, even in the presence of '. | |||||
| 'lint errors.'), | |||||
| ), | |||||
| 'library-name' => array( | |||||
| 'param' => 'name', | |||||
| 'help' => | |||||
| pht('Use a flag for library name rather than awaiting user input.'), | |||||
| ), | |||||
| 'remap' => array( | |||||
| 'hide' => true, | |||||
| 'help' => pht( | |||||
| 'Internal. Run the remap step of liberation. You do not need to '. | |||||
| 'run this unless you are debugging the workflow.'), | |||||
| ), | |||||
| 'verify' => array( | |||||
| 'hide' => true, | |||||
| 'help' => pht( | |||||
| 'Internal. Run the verify step of liberation. You do not need to '. | |||||
| 'run this unless you are debugging the workflow.'), | |||||
| ), | |||||
| 'upgrade' => array( | |||||
| 'hide' => true, | |||||
| 'help' => pht('Experimental. Upgrade library to v2.'), | |||||
| ), | |||||
| '*' => 'argv', | |||||
| ); | ); | ||||
| } | } | ||||
| public function runWorkflow() { | public function runWorkflow() { | ||||
| $argv = $this->getArgument('argv'); | $argv = $this->getArgument('argv'); | ||||
| if (count($argv) > 1) { | if (count($argv) > 1) { | ||||
| throw new ArcanistUsageException( | throw new ArcanistUsageException( | ||||
| pht( | pht( | ||||
| Show All 16 Lines | if (count($argv) > 1) { | ||||
| $paths[] = Filesystem::resolvePath(dirname($init)); | $paths[] = Filesystem::resolvePath(dirname($init)); | ||||
| } | } | ||||
| } else { | } else { | ||||
| $paths = array( | $paths = array( | ||||
| Filesystem::resolvePath(head($argv)), | Filesystem::resolvePath(head($argv)), | ||||
| ); | ); | ||||
| } | } | ||||
| $is_remap = $this->getArgument('remap'); | |||||
| $is_verify = $this->getArgument('verify'); | |||||
| foreach ($paths as $path) { | foreach ($paths as $path) { | ||||
| $this->liberatePath($path); | $this->liberatePath($path); | ||||
| } | } | ||||
| return 0; | return 0; | ||||
| } | } | ||||
| private function liberatePath($path) { | private function liberatePath($path) { | ||||
| if (!Filesystem::pathExists($path.'/__phutil_library_init__.php')) { | if (!Filesystem::pathExists($path.'/__phutil_library_init__.php')) { | ||||
| echo tsprintf( | echo tsprintf( | ||||
| "%s\n", | "%s\n", | ||||
| pht( | pht( | ||||
| 'No library currently exists at the path "%s"...', | 'No library currently exists at the path "%s"...', | ||||
| $path)); | $path)); | ||||
| $this->liberateCreateDirectory($path); | $this->liberateCreateDirectory($path); | ||||
| $this->liberateCreateLibrary($path); | $this->liberateCreateLibrary($path); | ||||
| return; | return; | ||||
| } | } | ||||
| $version = $this->getLibraryFormatVersion($path); | $version = $this->getLibraryFormatVersion($path); | ||||
| switch ($version) { | switch ($version) { | ||||
| case 1: | case 1: | ||||
| if ($this->getArgument('upgrade')) { | |||||
| return $this->upgradeLibrary($path); | |||||
| } | |||||
| throw new ArcanistUsageException( | throw new ArcanistUsageException( | ||||
| pht( | pht( | ||||
| "This library is using libphutil v1, which is no ". | 'This very old library is no longer supported.')); | ||||
| "longer supported. Run '%s' to upgrade to v2.", | |||||
| 'arc liberate --upgrade')); | |||||
| case 2: | case 2: | ||||
| if ($this->getArgument('upgrade')) { | |||||
| throw new ArcanistUsageException( | |||||
| pht("Can't upgrade a v2 library!")); | |||||
| } | |||||
| return $this->liberateVersion2($path); | return $this->liberateVersion2($path); | ||||
| default: | default: | ||||
| throw new ArcanistUsageException( | throw new ArcanistUsageException( | ||||
| pht("Unknown library version '%s'!", $version)); | pht("Unknown library version '%s'!", $version)); | ||||
| } | } | ||||
| } | } | ||||
| private function getLibraryFormatVersion($path) { | private function getLibraryFormatVersion($path) { | ||||
| Show All 14 Lines | ); | ||||
| } | } | ||||
| private function liberateVersion2($path) { | private function liberateVersion2($path) { | ||||
| $bin = $this->getScriptPath('scripts/library/library-map.php'); | $bin = $this->getScriptPath('scripts/library/library-map.php'); | ||||
| return phutil_passthru( | return phutil_passthru( | ||||
| 'php %s %C %s', | 'php %s %C %s', | ||||
| $bin, | $bin, | ||||
| $this->getArgument('all') ? '--drop-cache' : '', | $this->getArgument('clean') ? '--drop-cache' : '', | ||||
| $path); | $path); | ||||
| } | } | ||||
| private function upgradeLibrary($path) { | |||||
| $inits = id(new FileFinder($path)) | |||||
| ->withPath('*/__init__.php') | |||||
| ->withType('f') | |||||
| ->find(); | |||||
| echo pht('Removing %s files...', '__init__.php')."\n"; | |||||
| foreach ($inits as $init) { | |||||
| Filesystem::remove($path.'/'.$init); | |||||
| } | |||||
| echo pht('Upgrading library to v2...')."\n"; | |||||
| $this->liberateVersion2($path); | |||||
| } | |||||
| private function liberateCreateDirectory($path) { | private function liberateCreateDirectory($path) { | ||||
| if (Filesystem::pathExists($path)) { | if (Filesystem::pathExists($path)) { | ||||
| if (!is_dir($path)) { | if (!is_dir($path)) { | ||||
| throw new ArcanistUsageException( | throw new ArcanistUsageException( | ||||
| pht( | pht( | ||||
| 'Provide a directory to create or update a libphutil library in.')); | 'Provide a directory to create or update a libphutil library in.')); | ||||
| } | } | ||||
| return; | return; | ||||
| ▲ Show 20 Lines • Show All 56 Lines • Show Last 20 Lines | |||||