public static function getAliases(ArcanistConfigurationManager $configuration_manager) { $sources = $configuration_manager->getConfigFromAllSources('aliases'); $aliases = array(); foreach ($sources as $source) { $aliases += $source; } return $aliases; }
public static function getAliases(ArcanistConfigurationManager $configuration_manager) { $working_copy_config_aliases = $configuration_manager->getProjectConfig('aliases'); if (!$working_copy_config_aliases) { $working_copy_config_aliases = array(); } $user_config_aliases = idx($configuration_manager->readUserConfigurationFile(), 'aliases', array()); return $user_config_aliases + $working_copy_config_aliases; }
private function buildParser() { // TODO: This is a little hacky because we're using the Arcanist repository // itself to execute tests with, but it should be OK until we get proper // isolation for repository-oriented test cases. $root = dirname(phutil_get_library_root('arcanist')); $working_copy = ArcanistWorkingCopyIdentity::newFromPath($root); $configuration_manager = new ArcanistConfigurationManager(); $configuration_manager->setWorkingCopyIdentity($working_copy); $repo = ArcanistRepositoryAPI::newAPIFromConfigurationManager($configuration_manager); return new ArcanistBaseCommitParser($repo); }
private function parseState($test) { $dir = dirname(__FILE__) . '/state/'; $fixture = PhutilDirectoryFixture::newFromArchive($dir . '/' . $test); $fixture_path = $fixture->getPath(); $working_copy = ArcanistWorkingCopyIdentity::newFromPath($fixture_path); $configuration_manager = new ArcanistConfigurationManager(); $configuration_manager->setWorkingCopyIdentity($working_copy); $api = ArcanistRepositoryAPI::newAPIFromConfigurationManager($configuration_manager); $api->setBaseCommitArgumentRules('arc:this'); if ($api instanceof ArcanistSubversionAPI) { // Upgrade the repository so that the test will still pass if the local // `svn` is newer than the `svn` which created the repository. // NOTE: Some versions of Subversion (1.7.x?) exit with an error code on // a no-op upgrade, although newer versions do not. We just ignore the // error here; if it's because of an actual problem we'll hit an error // shortly anyway. $api->execManualLocal('upgrade'); } $this->assertCorrectState($test, $api); }
public static function newAPIFromConfigurationManager(ArcanistConfigurationManager $configuration_manager) { $working_copy = $configuration_manager->getWorkingCopyIdentity(); if (!$working_copy) { throw new Exception(pht('Trying to create a %s without a working copy!', __CLASS__)); } $root = $working_copy->getProjectRoot(); switch ($working_copy->getVCSType()) { case 'svn': $api = new ArcanistSubversionAPI($root); break; case 'hg': $api = new ArcanistMercurialAPI($root); break; case 'git': $api = new ArcanistGitAPI($root); break; default: throw new Exception(pht('The current working directory is not part of a working copy for ' . 'a supported version control system (Git, Subversion or ' . 'Mercurial).')); } $api->configurationManager = $configuration_manager; return $api; }
public function run($dir) { $working_copy = ArcanistWorkingCopyIdentity::newFromPath($dir); $configuration_manager = new ArcanistConfigurationManager(); $configuration_manager->setWorkingCopyIdentity($working_copy); $api = ArcanistRepositoryAPI::newAPIFromConfigurationManager($configuration_manager); $this->svnRoot = id(new PhutilURI($api->getSourceControlPath()))->getPath(); if ($api instanceof ArcanistGitAPI) { $svn_fetch = $api->getGitConfig('svn-remote.svn.fetch'); list($this->svnRoot) = explode(':', $svn_fetch); if ($this->svnRoot != '') { $this->svnRoot = '/' . $this->svnRoot; } } $callsign = $configuration_manager->getConfigFromAnySource('repository.callsign'); $uuid = $api->getRepositoryUUID(); $remote_uri = $api->getRemoteURI(); $repository_query = id(new PhabricatorRepositoryQuery())->setViewer(PhabricatorUser::getOmnipotentUser()); if ($callsign) { $repository_query->withCallsigns(array($callsign)); } else { if ($uuid) { $repository_query->withUUIDs(array($uuid)); } else { if ($remote_uri) { $repository_query->withRemoteURIs(array($remote_uri)); } } } $repository = $repository_query->executeOne(); $branch_name = $api->getBranchName(); if (!$repository) { throw new Exception(pht('No repository was found.')); } $this->branch = PhabricatorRepositoryBranch::loadOrCreateBranch($repository->getID(), $branch_name); $this->conn = $this->branch->establishConnection('w'); $this->lintCommit = null; if (!$this->all) { $this->lintCommit = $this->branch->getLintCommit(); } if ($this->lintCommit) { try { $commit = $this->lintCommit; if ($this->svnRoot) { $commit = $api->getCanonicalRevisionName('@' . $commit); } $all_files = $api->getChangedFiles($commit); } catch (ArcanistCapabilityNotSupportedException $ex) { $this->lintCommit = null; } } if (!$this->lintCommit) { $where = $this->svnRoot ? qsprintf($this->conn, 'AND path LIKE %>', $this->svnRoot . '/') : ''; queryfx($this->conn, 'DELETE FROM %T WHERE branchID = %d %Q', PhabricatorRepository::TABLE_LINTMESSAGE, $this->branch->getID(), $where); $all_files = $api->getAllFiles(); } $count = 0; $files = array(); foreach ($all_files as $file => $val) { $count++; if (!$this->lintCommit) { $file = $val; } else { $this->deletes[] = $this->svnRoot . '/' . $file; if ($val & ArcanistRepositoryAPI::FLAG_DELETED) { continue; } } $files[$file] = $file; if (count($files) >= $this->chunkSize) { $this->runArcLint($files); $files = array(); } } $this->runArcLint($files); $this->saveLintMessages(); $this->lintCommit = $api->getUnderlyingWorkingCopyRevision(); $this->branch->setLintCommit($this->lintCommit); $this->branch->save(); if ($this->blame) { $this->blameAuthors(); $this->blame = array(); } return $count; }
$workflow = null; try { $console->writeLog("libphutil loaded from '%s'.\n", phutil_get_library_root('phutil')); $console->writeLog("arcanist loaded from '%s'.\n", phutil_get_library_root('arcanist')); if (!$args) { if ($help) { $args = array('help'); } else { throw new ArcanistUsageException("No command provided. Try 'arc help'."); } } else { if ($help) { array_unshift($args, 'help'); } } $configuration_manager = new ArcanistConfigurationManager(); if ($custom_arcrc) { $configuration_manager->setUserConfigurationFileLocation($custom_arcrc); } $global_config = $configuration_manager->readUserArcConfig(); $system_config = $configuration_manager->readSystemArcConfig(); $runtime_config = $configuration_manager->applyRuntimeArcConfig($base_args); if ($skip_arcconfig) { $working_copy = ArcanistWorkingCopyIdentity::newDummyWorkingCopy(); } else { $working_copy = ArcanistWorkingCopyIdentity::newFromPath($working_directory); } $configuration_manager->setWorkingCopyIdentity($working_copy); reenter_if_this_is_arcanist_or_libphutil($console, $working_copy, $original_argv); // Load additional libraries, which can provide new classes like configuration // overrides, linters and lint engines, unit test engines, etc.
private function lintFile($file, ArcanistLinter $linter) { $linter = clone $linter; $contents = Filesystem::readFile($file); $contents = preg_split('/^~{4,}\\n/m', $contents); if (count($contents) < 2) { throw new Exception(pht("Expected '%s' separating test case and results.", '~~~~~~~~~~')); } list($data, $expect, $xform, $config) = array_merge($contents, array(null, null)); $basename = basename($file); if ($config) { $config = phutil_json_decode($config); } else { $config = array(); } PhutilTypeSpec::checkMap($config, array('config' => 'optional map<string, wild>', 'path' => 'optional string', 'mode' => 'optional string', 'stopped' => 'optional bool')); $exception = null; $after_lint = null; $messages = null; $exception_message = false; $caught_exception = false; try { $tmp = new TempFile($basename); Filesystem::writeFile($tmp, $data); $full_path = (string) $tmp; $mode = idx($config, 'mode'); if ($mode) { Filesystem::changePermissions($tmp, octdec($mode)); } $dir = dirname($full_path); $path = basename($full_path); $working_copy = ArcanistWorkingCopyIdentity::newFromRootAndConfigFile($dir, null, pht('Unit Test')); $configuration_manager = new ArcanistConfigurationManager(); $configuration_manager->setWorkingCopyIdentity($working_copy); $engine = new ArcanistUnitTestableLintEngine(); $engine->setWorkingCopy($working_copy); $engine->setConfigurationManager($configuration_manager); $path_name = idx($config, 'path', $path); $engine->setPaths(array($path_name)); $linter->addPath($path_name); $linter->addData($path_name, $data); foreach (idx($config, 'config', array()) as $key => $value) { $linter->setLinterConfigurationValue($key, $value); } $engine->addLinter($linter); $engine->addFileData($path_name, $data); $results = $engine->run(); $this->assertEqual(1, count($results), pht('Expect one result returned by linter.')); $assert_stopped = idx($config, 'stopped'); if ($assert_stopped !== null) { $this->assertEqual($assert_stopped, $linter->didStopAllLinters(), $assert_stopped ? pht('Expect linter to be stopped.') : pht('Expect linter to not be stopped.')); } $result = reset($results); $patcher = ArcanistLintPatcher::newFromArcanistLintResult($result); $after_lint = $patcher->getModifiedFileContent(); } catch (PhutilTestTerminatedException $ex) { throw $ex; } catch (Exception $exception) { $caught_exception = true; if ($exception instanceof PhutilAggregateException) { $caught_exception = false; foreach ($exception->getExceptions() as $ex) { if ($ex instanceof ArcanistUsageException || $ex instanceof ArcanistMissingLinterException) { $this->assertSkipped($ex->getMessage()); } else { $caught_exception = true; } } } else { if ($exception instanceof ArcanistUsageException || $exception instanceof ArcanistMissingLinterException) { $this->assertSkipped($exception->getMessage()); } } $exception_message = $exception->getMessage() . "\n\n" . $exception->getTraceAsString(); } $this->assertEqual(false, $caught_exception, $exception_message); $this->compareLint($basename, $expect, $result); $this->compareTransform($xform, $after_lint); }
public function run($dir) { $working_copy = ArcanistWorkingCopyIdentity::newFromPath($dir); $configuration_manager = new ArcanistConfigurationManager(); $configuration_manager->setWorkingCopyIdentity($working_copy); $api = ArcanistRepositoryAPI::newAPIFromConfigurationManager($configuration_manager); $this->svnRoot = id(new PhutilURI($api->getSourceControlPath()))->getPath(); if ($api instanceof ArcanistGitAPI) { $svn_fetch = $api->getGitConfig('svn-remote.svn.fetch'); list($this->svnRoot) = explode(':', $svn_fetch); if ($this->svnRoot != '') { $this->svnRoot = '/' . $this->svnRoot; } } $project_id = $working_copy->getProjectID(); $project = id(new PhabricatorRepositoryArcanistProject())->loadOneWhere('name = %s', $project_id); if (!$project || !$project->getRepositoryID()) { throw new Exception("Couldn't find repository for {$project_id}."); } $branch_name = $api->getBranchName(); $this->branch = PhabricatorRepositoryBranch::loadOrCreateBranch($project->getRepositoryID(), $branch_name); $this->conn = $this->branch->establishConnection('w'); $this->lintCommit = null; if (!$this->all) { $this->lintCommit = $this->branch->getLintCommit(); } if ($this->lintCommit) { try { $commit = $this->lintCommit; if ($this->svnRoot) { $commit = $api->getCanonicalRevisionName('@' . $commit); } $all_files = $api->getChangedFiles($commit); } catch (ArcanistCapabilityNotSupportedException $ex) { $this->lintCommit = null; } } if (!$this->lintCommit) { $where = $this->svnRoot ? qsprintf($this->conn, 'AND path LIKE %>', $this->svnRoot . '/') : ''; queryfx($this->conn, 'DELETE FROM %T WHERE branchID = %d %Q', PhabricatorRepository::TABLE_LINTMESSAGE, $this->branch->getID(), $where); $all_files = $api->getAllFiles(); } $count = 0; $files = array(); foreach ($all_files as $file => $val) { $count++; if (!$this->lintCommit) { $file = $val; } else { $this->deletes[] = $this->svnRoot . '/' . $file; if ($val & ArcanistRepositoryAPI::FLAG_DELETED) { continue; } } $files[$file] = $file; if (count($files) >= $this->chunkSize) { $this->runArcLint($files); $files = array(); } } $this->runArcLint($files); $this->saveLintMessages(); $this->lintCommit = $api->getUnderlyingWorkingCopyRevision(); $this->branch->setLintCommit($this->lintCommit); $this->branch->save(); if ($this->blame) { $this->blameAuthors(); $this->blame = array(); } return $count; }