public function run()

in src/workflow/ArcanistBrowseWorkflow.php [68:213]


  public function run() {
    $console = PhutilConsole::getConsole();

    $is_force = $this->getArgument('force');

    $things = $this->getArgument('paths');
    if (!$things) {
      throw new ArcanistUsageException(
        pht(
          'Specify one or more paths or objects to browse. Use the command '.
          '"%s" if you want to browse this directory.',
          'arc browse .'));
    }
    $things = array_fuse($things);

    $objects = $this->getConduit()->callMethodSynchronous(
      'phid.lookup',
      array(
        'names' => array_keys($things),
      ));

    $uris = array();
    foreach ($objects as $name => $object) {
      $uris[] = $object['uri'];

      $console->writeOut(
        pht(
          'Opening **%s** as an object.',
          $name)."\n");

      unset($things[$name]);
    }

    if ($this->hasRepositoryAPI()) {
      $repository_api = $this->getRepositoryAPI();
      $project_root = $this->getWorkingCopy()->getProjectRoot();

      // First, try to resolve arguments as symbolic commits.

      $commits = array();
      foreach ($things as $key => $thing) {
        if ($thing == '.') {
          // Git resolves '.' like HEAD, but it should be interpreted to mean
          // "the current directory". Just skip resolution and fall through.
          continue;
        }

        try {
          $commit = $repository_api->getCanonicalRevisionName($thing);
          if ($commit) {
            $commits[$commit] = $key;
          }
        } catch (Exception $ex) {
          // Ignore.
        }
      }

      if ($commits) {
        $commit_info = $this->getConduit()->callMethodSynchronous(
          'diffusion.querycommits',
          array(
            'repositoryPHID' => $this->getRepositoryPHID(),
            'names' => array_keys($commits),
          ));

        foreach ($commit_info['identifierMap'] as $ckey => $cphid) {
          $thing = $commits[$ckey];
          unset($things[$thing]);

          $uris[] = $commit_info['data'][$cphid]['uri'];

          $console->writeOut(
            pht(
              'Opening **%s** as a commit.',
              $thing)."\n");
        }
      }

      // If we fail, try to resolve them as paths.

      foreach ($things as $key => $path) {
        $lines = null;
        $parts = explode(':', $path);
        if (count($parts) > 1) {
          $lines = array_pop($parts);
        }
        $path = implode(':', $parts);

        $full_path = Filesystem::resolvePath($path);

        if (!$is_force && !Filesystem::pathExists($full_path)) {
          continue;
        }

        $console->writeOut(
          pht(
            'Opening **%s** as a repository path.',
            $key)."\n");

        unset($things[$key]);

        if ($full_path == $project_root) {
          $path = '';
        } else {
          $path = Filesystem::readablePath($full_path, $project_root);
        }

        $base_uri = $this->getBaseURI();
        $uri = $base_uri.$path;

        if ($lines) {
          $uri = $uri.'$'.$lines;
        }

        $uris[] = $uri;
      }
    } else {
      if ($things) {
        $console->writeOut(
          "%s\n",
          pht(
            "The current working directory is not a repository working ".
            "copy, so remaining arguments can not be resolved as paths or ".
            "commits. To browse paths or symbolic commits in Diffusion, run ".
            "'%s' from inside a working copy.",
            'arc browse'));
      }
    }

    foreach ($things as $thing) {
      $console->writeOut(
        "%s\n",
        pht(
          'Unable to find an object named **%s**, no such commit exists in '.
          'the remote, and no such path exists in the working copy. Use '.
          '__%s__ to treat this as a path anyway.',
          $thing,
          '--force'));
    }

    if ($uris) {
      $this->openURIsInBrowser($uris);
    }

    return 0;
  }