Esempio n. 1
0
 private function loadCommitInfo(array $branches, ArcanistRepositoryAPI $repository_api)
 {
     $futures = array();
     foreach ($branches as $branch) {
         // NOTE: "-s" is an option deep in git's diff argument parser that doesn't
         // seem to have much documentation and has no long form. It suppresses any
         // diff output.
         $futures[$branch['name']] = $repository_api->execFutureLocal('show -s --format=%C %s', '%H%x01%ct%x01%T%x01%s%x01%b', $branch['name']);
     }
     $branches = ipull($branches, null, 'name');
     $commit_map = array();
     foreach (Futures($futures) as $name => $future) {
         list($info) = $future->resolvex();
         list($hash, $epoch, $tree, $desc, $text) = explode("", trim($info), 5);
         $branch = $branches[$name];
         $branch['hash'] = $hash;
         $branch['desc'] = $desc;
         try {
             $text = $desc . "\n" . $text;
             $message = ArcanistDifferentialCommitMessage::newFromRawCorpus($text);
             $id = $message->getRevisionID();
             $branch += array('epoch' => (int) $epoch, 'tree' => $tree, 'revisionID' => $id);
         } catch (ArcanistUsageException $ex) {
             // In case of invalid commit message which fails the parsing,
             // do nothing.
         }
         $commit_map[$hash] = $branch;
     }
     return $commit_map;
 }
 public function pushWorkspaceRepository(PhabricatorRepository $repository, ArcanistRepositoryAPI $workspace)
 {
     $token = $this->getAccessToken();
     $github_repo = $this->findGitHubRepo($repository);
     $remote = urisprintf('https://%s:x-oauth-basic@%s/%s.git', $token, $this->provider->getProviderDomain(), $github_repo);
     $workspace->execxLocal('push %P HEAD:master', new PhutilOpaqueEnvelope($remote));
 }
 public function run()
 {
     $roots = array('libphutil' => dirname(phutil_get_library_root('phutil')), 'arcanist' => dirname(phutil_get_library_root('arcanist')));
     foreach ($roots as $lib => $root) {
         echo phutil_console_format("%s\n", pht('Upgrading %s...', $lib));
         $working_copy = ArcanistWorkingCopyIdentity::newFromPath($root);
         $configuration_manager = clone $this->getConfigurationManager();
         $configuration_manager->setWorkingCopyIdentity($working_copy);
         $repository = ArcanistRepositoryAPI::newAPIFromConfigurationManager($configuration_manager);
         if (!Filesystem::pathExists($repository->getMetadataPath())) {
             throw new ArcanistUsageException(pht("%s must be in its git working copy to be automatically upgraded. " . "This copy of %s (in '%s') is not in a git working copy.", $lib, $lib, $root));
         }
         $this->setRepositoryAPI($repository);
         // Require no local changes.
         $this->requireCleanWorkingCopy();
         // Require the library be on master.
         $branch_name = $repository->getBranchName();
         if ($branch_name != 'master') {
             throw new ArcanistUsageException(pht("%s must be on branch '%s' to be automatically upgraded. " . "This copy of %s (in '%s') is on branch '%s'.", $lib, 'master', $lib, $root, $branch_name));
         }
         chdir($root);
         try {
             phutil_passthru('git pull --rebase');
         } catch (Exception $ex) {
             phutil_passthru('git rebase --abort');
             throw $ex;
         }
     }
     echo phutil_console_format("**%s** %s\n", pht('Updated!'), pht('Your copy of arc is now up to date.'));
     return 0;
 }
 public function run()
 {
     $roots = array();
     $roots['libphutil'] = dirname(phutil_get_library_root('phutil'));
     $roots['arcanist'] = dirname(phutil_get_library_root('arcanist'));
     foreach ($roots as $lib => $root) {
         echo "Upgrading {$lib}...\n";
         if (!Filesystem::pathExists($root . '/.git')) {
             throw new ArcanistUsageException("{$lib} must be in its git working copy to be automatically " . "upgraded. This copy of {$lib} (in '{$root}') is not in a git " . "working copy.");
         }
         $working_copy = ArcanistWorkingCopyIdentity::newFromPath($root);
         $configuration_manager = clone $this->getConfigurationManager();
         $configuration_manager->setWorkingCopyIdentity($working_copy);
         $repository_api = ArcanistRepositoryAPI::newAPIFromConfigurationManager($configuration_manager);
         $this->setRepositoryAPI($repository_api);
         // Require no local changes.
         $this->requireCleanWorkingCopy();
         // Require the library be on master.
         $branch_name = $repository_api->getBranchName();
         if ($branch_name != 'master') {
             throw new ArcanistUsageException("{$lib} must be on branch 'master' to be automatically upgraded. " . "This copy of {$lib} (in '{$root}') is on branch '{$branch_name}'.");
         }
         chdir($root);
         try {
             phutil_passthru('git pull --rebase');
         } catch (Exception $ex) {
             phutil_passthru('git rebase --abort');
             throw $ex;
         }
     }
     echo phutil_console_wrap(phutil_console_format("**Updated!** Your copy of arc is now up to date.\n"));
     return 0;
 }
 public function run()
 {
     $roots = array();
     $roots['libphutil'] = dirname(phutil_get_library_root('phutil'));
     $roots['arcanist'] = dirname(phutil_get_library_root('arcanist'));
     foreach ($roots as $lib => $root) {
         echo "Upgrading {$lib}...\n";
         if (!Filesystem::pathExists($root . '/.git')) {
             throw new ArcanistUsageException("{$lib} must be in its git working copy to be automatically " . "upgraded. This copy of {$lib} (in '{$root}') is not in a git " . "working copy.");
         }
         $working_copy = ArcanistWorkingCopyIdentity::newFromPath($root);
         $repository_api = ArcanistRepositoryAPI::newAPIFromWorkingCopyIdentity($working_copy);
         // Force the range to HEAD^..HEAD, which is meaningless but keeps us
         // from triggering "base" rules or other commit range resolution rules
         // that might prompt the user when we pull the working copy status.
         $repository_api->setRelativeCommit('HEAD^');
         $this->setRepositoryAPI($repository_api);
         // Require no local changes.
         $this->requireCleanWorkingCopy();
         // Require the library be on master.
         $branch_name = $repository_api->getBranchName();
         if ($branch_name != 'master') {
             throw new ArcanistUsageException("{$lib} must be on branch 'master' to be automatically upgraded. " . "This copy of {$lib} (in '{$root}') is on branch '{$branch_name}'.");
         }
         chdir($root);
         try {
             phutil_passthru('git pull --rebase');
         } catch (Exception $ex) {
             phutil_passthru('git rebase --abort');
             throw $ex;
         }
     }
     echo phutil_console_wrap(phutil_console_format("**Updated!** Your copy of arc is now up to date.\n"));
     return 0;
 }
 private function assertCorrectState($test, ArcanistRepositoryAPI $api)
 {
     $f_mod = ArcanistRepositoryAPI::FLAG_MODIFIED;
     $f_add = ArcanistRepositoryAPI::FLAG_ADDED;
     $f_del = ArcanistRepositoryAPI::FLAG_DELETED;
     $f_unt = ArcanistRepositoryAPI::FLAG_UNTRACKED;
     $f_con = ArcanistRepositoryAPI::FLAG_CONFLICT;
     $f_mis = ArcanistRepositoryAPI::FLAG_MISSING;
     $f_uns = ArcanistRepositoryAPI::FLAG_UNSTAGED;
     $f_unc = ArcanistRepositoryAPI::FLAG_UNCOMMITTED;
     $f_ext = ArcanistRepositoryAPI::FLAG_EXTERNALS;
     $f_obs = ArcanistRepositoryAPI::FLAG_OBSTRUCTED;
     $f_inc = ArcanistRepositoryAPI::FLAG_INCOMPLETE;
     switch ($test) {
         case 'svn_basic.svn.tgz':
             $expect = array('ADDED' => $f_add, 'COPIED_TO' => $f_add, 'DELETED' => $f_del, 'MODIFIED' => $f_mod, 'MOVED' => $f_del, 'MOVED_TO' => $f_add, 'PROPCHANGE' => $f_mod, 'UNTRACKED' => $f_unt);
             $this->assertEqual($expect, $api->getUncommittedStatus());
             $this->assertEqual($expect, $api->getCommitRangeStatus());
             break;
         case 'git_basic.git.tgz':
             $expect_uncommitted = array('UNCOMMITTED' => $f_add | $f_unc, 'UNSTAGED' => $f_mod | $f_uns | $f_unc, 'UNTRACKED' => $f_unt);
             $this->assertEqual($expect_uncommitted, $api->getUncommittedStatus());
             $expect_range = array('ADDED' => $f_add, 'DELETED' => $f_del, 'MODIFIED' => $f_mod, 'UNCOMMITTED' => $f_add, 'UNSTAGED' => $f_add);
             $this->assertEqual($expect_range, $api->getCommitRangeStatus());
             break;
         case 'hg_basic.hg.tgz':
             $expect_uncommitted = array('UNCOMMITTED' => $f_mod | $f_unc, 'UNTRACKED' => $f_unt);
             $this->assertEqual($expect_uncommitted, $api->getUncommittedStatus());
             $expect_range = array('ADDED' => $f_add, 'DELETED' => $f_del, 'MODIFIED' => $f_mod, 'UNCOMMITTED' => $f_add);
             $this->assertEqual($expect_range, $api->getCommitRangeStatus());
             break;
         default:
             throw new Exception("No test cases for working copy '{$test}'!");
     }
 }
 private function buildParser()
 {
     // TODO: This is a little hacky beacuse 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'));
     $copy = ArcanistWorkingCopyIdentity::newFromPath($root);
     $repo = ArcanistRepositoryAPI::newAPIFromWorkingCopyIdentity($copy);
     return new ArcanistBaseCommitParser($repo);
 }
 public function run()
 {
     $console = PhutilConsole::getConsole();
     if (!Filesystem::binaryExists('git')) {
         throw new ArcanistUsageException(pht('Cannot display current version without having `%s` installed.', 'git'));
     }
     $roots = array('arcanist' => dirname(phutil_get_library_root('arcanist')), 'libphutil' => dirname(phutil_get_library_root('phutil')));
     foreach ($roots as $lib => $root) {
         $working_copy = ArcanistWorkingCopyIdentity::newFromPath($root);
         $configuration_manager = clone $this->getConfigurationManager();
         $configuration_manager->setWorkingCopyIdentity($working_copy);
         $repository = ArcanistRepositoryAPI::newAPIFromConfigurationManager($configuration_manager);
         if (!Filesystem::pathExists($repository->getMetadataPath())) {
             throw new ArcanistUsageException(pht('%s is not a git working copy.', $lib));
         }
         list($stdout) = $repository->execxLocal('log -1 --format=%s', '%H %ct');
         list($commit, $timestamp) = explode(' ', $stdout);
         $console->writeOut("%s %s (%s)\n", $lib, $commit, date('j M Y', (int) $timestamp));
     }
 }
 public function run()
 {
     $roots = array('libphutil' => dirname(phutil_get_library_root('phutil')), 'arcanist' => dirname(phutil_get_library_root('arcanist')));
     foreach ($roots as $lib => $root) {
         echo phutil_console_format("%s\n", pht('Upgrading %s...', $lib));
         $working_copy = ArcanistWorkingCopyIdentity::newFromPath($root);
         $configuration_manager = clone $this->getConfigurationManager();
         $configuration_manager->setWorkingCopyIdentity($working_copy);
         $repository = ArcanistRepositoryAPI::newAPIFromConfigurationManager($configuration_manager);
         if (!Filesystem::pathExists($repository->getMetadataPath())) {
             throw new ArcanistUsageException(pht("%s must be in its git working copy to be automatically upgraded. " . "This copy of %s (in '%s') is not in a git working copy.", $lib, $lib, $root));
         }
         $this->setRepositoryAPI($repository);
         // NOTE: Don't use requireCleanWorkingCopy() here because it tries to
         // amend changes and generally move the workflow forward. We just want to
         // abort if there are local changes and make the user sort things out.
         $uncommitted = $repository->getUncommittedStatus();
         if ($uncommitted) {
             $message = pht('You have uncommitted changes in the working copy for this ' . 'library:');
             $list = id(new PhutilConsoleList())->setWrap(false)->addItems(array_keys($uncommitted));
             id(new PhutilConsoleBlock())->addParagraph($message)->addList($list)->draw();
             throw new ArcanistUsageException(pht('`arc upgrade` can only upgrade clean working copies.'));
         }
         $branch_name = $repository->getBranchName();
         if ($branch_name != 'master' && $branch_name != 'stable') {
             throw new ArcanistUsageException(pht("%s must be on either branch '%s' or '%s' to be automatically " . "upgraded. " . "This copy of %s (in '%s') is on branch '%s'.", $lib, 'master', 'stable', $lib, $root, $branch_name));
         }
         chdir($root);
         try {
             execx('git pull --rebase');
         } catch (Exception $ex) {
             // If we failed, try to go back to the old state, then throw the
             // original exception.
             exec_manual('git rebase --abort');
             throw $ex;
         }
     }
     echo phutil_console_format("**%s** %s\n", pht('Updated!'), pht('Your copy of arc is now up to date.'));
     return 0;
 }
Esempio n. 10
0
 function generateCoverageResults()
 {
     // Find all executables, not just the test executables.
     // We need to do this because the test executables may not
     // include all of the possible code (linker decides to omit
     // it from the image) so we see a skewed representation of
     // the source lines.
     $fp = popen("find {$this->repo_root} -type f -name watchman -o " . "-name \\*.a -o -name \\*.so -o -name \\*.dylib", "r");
     while (true) {
         $line = fgets($fp);
         if ($line === false) {
             break;
         }
         $obj_files[] = trim($line);
     }
     // Parse line information from the objects
     foreach ($obj_files as $object) {
         DwarfLineInfo::loadObject($object);
     }
     $CG = new CallgrindFile((string) $this->cg_file);
     $CG->parse();
     $source_files = array();
     foreach ($CG->getSourceFiles() as $filename) {
         if (Filesystem::isDescendant($filename, $this->repo_root) && !preg_match("/(thirdparty|tests)/", $filename)) {
             $source_files[$filename] = $filename;
         }
     }
     $cov = array();
     foreach ($source_files as $filename) {
         $relsrc = substr($filename, strlen($this->repo_root) + 1);
         $cov[$relsrc] = CallgrindFile::mergeSourceLineData($filename, array($CG));
     }
     $res = new ArcanistUnitTestResult();
     $res->setName('coverage');
     $res->setUserData("Collected");
     $res->setResult(ArcanistUnitTestResult::RESULT_PASS);
     $res->setCoverage($cov);
     // Stash it for review with our `arc cov` command
     $wc = ArcanistWorkingCopyIdentity::newFromPath($this->repo_root);
     $api = ArcanistRepositoryAPI::newAPIFromWorkingCopyIdentity($wc);
     $api->writeScratchFile('wman-cov.json', json_encode($cov));
     return array($res);
 }
Esempio n. 11
0
 $certificate = idx($host_config, 'cert');
 $description = implode(' ', $original_argv);
 $credentials = array('user' => $user_name, 'certificate' => $certificate, 'description' => $description);
 $workflow->setConduitCredentials($credentials);
 if ($need_auth) {
     if (!$user_name || !$certificate) {
         $arc = 'arc';
         if ($force_conduit) {
             $arc .= csprintf(' --conduit-uri=%s', $conduit_uri);
         }
         throw new ArcanistUsageException(phutil_console_format("YOU NEED TO __INSTALL A CERTIFICATE__ TO LOGIN TO PHABRICATOR\n\n" . "You are trying to connect to '{$conduit_uri}' but do not have " . "a certificate installed for this host. Run:\n\n" . "      \$ **{$arc} install-certificate**\n\n" . "...to install one."));
     }
     $workflow->authenticateConduit();
 }
 if ($need_repository_api || $want_repository_api && $working_copy->getVCSType()) {
     $repository_api = ArcanistRepositoryAPI::newAPIFromConfigurationManager($configuration_manager);
     $workflow->setRepositoryAPI($repository_api);
 }
 $listeners = $configuration_manager->getConfigFromAnySource('events.listeners');
 if ($listeners) {
     foreach ($listeners as $listener) {
         $console->writeLog("Registering event listener '%s'.\n", $listener);
         try {
             id(new $listener())->register();
         } catch (PhutilMissingSymbolException $ex) {
             // Continue anyway, since you may otherwise be unable to run commands
             // like `arc set-config events.listeners` in order to repair the damage
             // you've caused. We're writing out the entire exception here because
             // it might not have been triggered by the listener itself (for example,
             // the listener might use a bad class in its register() method).
             $console->writeErr("ERROR: Failed to load event listener '%s': %s\n", $listener, $ex->getMessage());
 public function run()
 {
     $pos = $this->getArgument('current');
     $argv = $this->getArgument('argv', array());
     $argc = count($argv);
     if ($pos === null) {
         $pos = $argc - 1;
     }
     if ($pos > $argc) {
         throw new ArcanistUsageException(pht('Specified position is greater than the number of ' . 'arguments provided.'));
     }
     // Determine which revision control system the working copy uses, so we
     // can filter out commands and flags which aren't supported. If we can't
     // figure it out, just return all flags/commands.
     $vcs = null;
     // We have to build our own because if we requiresWorkingCopy() we'll throw
     // if we aren't in a .arcconfig directory. We probably still can't do much,
     // but commands can raise more detailed errors.
     $configuration_manager = $this->getConfigurationManager();
     $working_copy = ArcanistWorkingCopyIdentity::newFromPath(getcwd());
     if ($working_copy->getVCSType()) {
         $configuration_manager->setWorkingCopyIdentity($working_copy);
         $repository_api = ArcanistRepositoryAPI::newAPIFromConfigurationManager($configuration_manager);
         $vcs = $repository_api->getSourceControlSystemName();
     }
     $arc_config = $this->getArcanistConfiguration();
     if ($pos <= 1) {
         $workflows = $arc_config->buildAllWorkflows();
         $complete = array();
         foreach ($workflows as $name => $workflow) {
             if (!$workflow->shouldShellComplete()) {
                 continue;
             }
             $workflow->setArcanistConfiguration($this->getArcanistConfiguration());
             $workflow->setConfigurationManager($this->getConfigurationManager());
             if ($vcs || $workflow->requiresWorkingCopy()) {
                 $supported_vcs = $workflow->getSupportedRevisionControlSystems();
                 if (!in_array($vcs, $supported_vcs)) {
                     continue;
                 }
             }
             $complete[] = $name;
         }
         // Also permit autocompletion of "arc alias" commands.
         $aliases = ArcanistAliasWorkflow::getAliases($configuration_manager);
         foreach ($aliases as $key => $value) {
             $complete[] = $key;
         }
         echo implode(' ', $complete) . "\n";
         return 0;
     } else {
         $workflow = $arc_config->buildWorkflow($argv[1]);
         if (!$workflow) {
             list($new_command, $new_args) = ArcanistAliasWorkflow::resolveAliases($argv[1], $arc_config, array_slice($argv, 2), $configuration_manager);
             if ($new_command) {
                 $workflow = $arc_config->buildWorkflow($new_command);
             }
             if (!$workflow) {
                 return 1;
             } else {
                 $argv = array_merge(array($argv[0]), array($new_command), $new_args);
             }
         }
         $arguments = $workflow->getArguments();
         $prev = idx($argv, $pos - 1, null);
         if (!strncmp($prev, '--', 2)) {
             $prev = substr($prev, 2);
         } else {
             $prev = null;
         }
         if ($prev !== null && isset($arguments[$prev]) && isset($arguments[$prev]['param'])) {
             $type = idx($arguments[$prev], 'paramtype');
             switch ($type) {
                 case 'file':
                     echo "FILE\n";
                     break;
                 case 'complete':
                     echo implode(' ', $workflow->getShellCompletions($argv)) . "\n";
                     break;
                 default:
                     echo "ARGUMENT\n";
                     break;
             }
             return 0;
         } else {
             $output = array();
             foreach ($arguments as $argument => $spec) {
                 if ($argument == '*') {
                     continue;
                 }
                 if ($vcs && isset($spec['supports']) && !in_array($vcs, $spec['supports'])) {
                     continue;
                 }
                 $output[] = '--' . $argument;
             }
             $cur = idx($argv, $pos, '');
             $any_match = false;
             if (strlen($cur)) {
                 foreach ($output as $possible) {
                     if (!strncmp($possible, $cur, strlen($cur))) {
                         $any_match = true;
                     }
                 }
             }
             if (!$any_match && isset($arguments['*'])) {
                 // TODO: This is mega hacktown but something else probably breaks
                 // if we use a rich argument specification; fix it when we move to
                 // PhutilArgumentParser since everything will need to be tested then
                 // anyway.
                 if ($arguments['*'] == 'branch' && isset($repository_api)) {
                     $branches = $repository_api->getAllBranches();
                     $branches = ipull($branches, 'name');
                     $output = $branches;
                 } else {
                     $output = array('FILE');
                 }
             }
             echo implode(' ', $output) . "\n";
             return 0;
         }
     }
 }
 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;
 }
Esempio n. 14
0
    }
    $hosts_config = idx($user_config, 'hosts', array());
    $host_config = idx($hosts_config, $conduit_uri, array());
    $user_name = idx($host_config, 'user');
    $certificate = idx($host_config, 'cert');
    $description = implode(' ', $original_argv);
    $credentials = array('user' => $user_name, 'certificate' => $certificate, 'description' => $description);
    $workflow->setConduitCredentials($credentials);
    if ($need_auth) {
        if (!$user_name || !$certificate) {
            throw new ArcanistUsageException(phutil_console_format("YOU NEED TO __INSTALL A CERTIFICATE__ TO LOGIN TO PHABRICATOR\n\n" . "You are trying to connect to '{$conduit_uri}' but do not have " . "a certificate installed for this host. Run:\n\n" . "      \$ **arc install-certificate**\n\n" . "...to install one."));
        }
        $workflow->authenticateConduit();
    }
    if ($need_repository_api || $want_repository_api && $working_copy) {
        $repository_api = ArcanistRepositoryAPI::newAPIFromWorkingCopyIdentity($working_copy);
        $workflow->setRepositoryAPI($repository_api);
    }
    $listeners = $working_copy->getConfig('events.listeners');
    if ($listeners) {
        foreach ($listeners as $listener) {
            id(new $listener())->register();
        }
    }
    $config->willRunWorkflow($command, $workflow);
    $workflow->willRunWorkflow();
    $err = $workflow->run();
    $config->didRunWorkflow($command, $workflow, $err);
    exit((int) $err);
} catch (ArcanistUsageException $ex) {
    echo phutil_console_format("**Usage Exception:** %s\n", $ex->getMessage());
 public function convertToBinaryChange(ArcanistRepositoryAPI $api)
 {
     // Fill in the binary data from the working copy.
     $this->setOriginalFileData($api->getOriginalFileData($this->getOldPath()));
     $this->setCurrentFileData($api->getCurrentFileData($this->getCurrentPath()));
     $this->hunks = array();
     $this->setFileType(ArcanistDiffChangeType::FILE_BINARY);
     return $this;
 }
 public function pushWorkspaceRepository(PhabricatorRepository $repository, ArcanistRepositoryAPI $workspace, PhabricatorUser $user)
 {
     $workspace->execxLocal('push origin HEAD:master');
 }
 public function pushWorkspaceRepository(PhabricatorRepository $repository, ArcanistRepositoryAPI $workspace, PhabricatorUser $user)
 {
     $workspace->execxLocal('push -b default');
 }
 public function __construct(ArcanistRepositoryAPI $api)
 {
     $name = $api->getSourceControlSystemName();
     parent::__construct(pht("This repository API ('%s') does not support the requested capability.", $name));
 }
 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;
 }
 public function run()
 {
     $pos = $this->getArgument('current');
     $argv = $this->getArgument('argv', array());
     $argc = count($argv);
     if ($pos === null) {
         $pos = $argc - 1;
     }
     // Determine which revision control system the working copy uses, so we
     // can filter out commands and flags which aren't supported. If we can't
     // figure it out, just return all flags/commands.
     $vcs = null;
     // We have to build our own because if we requiresWorkingCopy() we'll throw
     // if we aren't in a .arcconfig directory. We probably still can't do much,
     // but commands can raise more detailed errors.
     $working_copy = ArcanistWorkingCopyIdentity::newFromPath(getcwd());
     if ($working_copy->getProjectRoot()) {
         $repository_api = ArcanistRepositoryAPI::newAPIFromWorkingCopyIdentity($working_copy);
         $vcs = $repository_api->getSourceControlSystemName();
     }
     $arc_config = $this->getArcanistConfiguration();
     if ($pos == 1) {
         $workflows = $arc_config->buildAllWorkflows();
         $complete = array();
         foreach ($workflows as $name => $workflow) {
             if (!$workflow->shouldShellComplete()) {
                 continue;
             }
             $supported = $workflow->getSupportedRevisionControlSystems();
             $ok = in_array('any', $supported) || in_array($vcs, $supported);
             if (!$ok) {
                 continue;
             }
             $complete[] = $name;
         }
         // Also permit autocompletion of "arc alias" commands.
         foreach (ArcanistAliasWorkflow::getAliases($working_copy) as $key => $value) {
             $complete[] = $key;
         }
         echo implode(' ', $complete) . "\n";
         return 0;
     } else {
         $workflow = $arc_config->buildWorkflow($argv[1]);
         if (!$workflow) {
             list($new_command, $new_args) = ArcanistAliasWorkflow::resolveAliases($argv[1], $arc_config, array_slice($argv, 2), $working_copy);
             if ($new_command) {
                 $workflow = $arc_config->buildWorkflow($new_command);
             }
             if (!$workflow) {
                 return 1;
             } else {
                 $argv = array_merge(array($argv[0]), array($new_command), $new_args);
             }
         }
         $arguments = $workflow->getArguments();
         $prev = idx($argv, $pos - 1, null);
         if (!strncmp($prev, '--', 2)) {
             $prev = substr($prev, 2);
         } else {
             $prev = null;
         }
         if ($prev !== null && isset($arguments[$prev]) && isset($arguments[$prev]['param'])) {
             $type = idx($arguments[$prev], 'paramtype');
             switch ($type) {
                 case 'file':
                     echo "FILE\n";
                     break;
                 case 'complete':
                     echo implode(' ', $workflow->getShellCompletions($argv)) . "\n";
                     break;
                 default:
                     echo "ARGUMENT\n";
                     break;
             }
             return 0;
         } else {
             $output = array();
             foreach ($arguments as $argument => $spec) {
                 if ($argument == '*') {
                     continue;
                 }
                 if ($vcs && isset($spec['supports']) && !in_array($vcs, $spec['supports'])) {
                     continue;
                 }
                 $output[] = '--' . $argument;
             }
             $cur = idx($argv, $pos, '');
             $any_match = false;
             foreach ($output as $possible) {
                 if (!strncmp($possible, $cur, strlen($cur))) {
                     $any_match = true;
                 }
             }
             if (!$any_match && isset($arguments['*'])) {
                 // TODO: the '*' specifier should probably have more details about
                 // whether or not it is a list of files. Since it almost always is in
                 // practice, assume FILE for now.
                 echo "FILE\n";
             } else {
                 echo implode(' ', $output) . "\n";
             }
             return 0;
         }
     }
 }