~ubuntu-branches/ubuntu/wily/phabricator/wily

« back to all changes in this revision

Viewing changes to src/workflow/ArcanistBrowseWorkflow.php

  • Committer: Package Import Robot
  • Author(s): Richard Sellam
  • Date: 2014-11-01 23:20:06 UTC
  • mto: This revision was merged to the branch mainline in revision 4.
  • Revision ID: package-import@ubuntu.com-20141101232006-mvlnp0cil67tsboe
Tags: upstream-0~git20141101/arcanist
Import upstream version 0~git20141101, component arcanist

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
<?php
 
2
 
 
3
/**
 
4
 * Browse files or objects in the Phabricator web interface.
 
5
 */
 
6
final class ArcanistBrowseWorkflow extends ArcanistWorkflow {
 
7
 
 
8
  public function getWorkflowName() {
 
9
    return 'browse';
 
10
  }
 
11
 
 
12
  public function getCommandSynopses() {
 
13
    return phutil_console_format(<<<EOTEXT
 
14
      **browse** [__options__] __path__ ...
 
15
      **browse** [__options__] __object__ ...
 
16
EOTEXT
 
17
      );
 
18
  }
 
19
 
 
20
  public function getCommandHelp() {
 
21
    return phutil_console_format(<<<EOTEXT
 
22
          Supports: git, hg, svn
 
23
          Open a file or object (like a task or revision) in your web browser.
 
24
 
 
25
            $ arc browse README   # Open a file in Diffusion.
 
26
            $ arc browse T123     # View a task.
 
27
            $ arc browse HEAD     # View a symbolic commit.
 
28
 
 
29
          Set the 'browser' value using 'arc set-config' to select a browser. If
 
30
          no browser is set, the command will try to guess which browser to use.
 
31
EOTEXT
 
32
      );
 
33
  }
 
34
 
 
35
  public function getArguments() {
 
36
    return array(
 
37
      'branch' => array(
 
38
        'param' => 'branch_name',
 
39
        'help' => pht(
 
40
          'Default branch name to view on server. Defaults to "master".'),
 
41
      ),
 
42
      'force' => array(
 
43
        'help' => pht(
 
44
          'Open arguments as paths, even if they do not exist in the '.
 
45
          'working copy.'),
 
46
      ),
 
47
      '*' => 'paths',
 
48
    );
 
49
  }
 
50
 
 
51
  public function desiresWorkingCopy() {
 
52
    return true;
 
53
  }
 
54
 
 
55
  public function requiresConduit() {
 
56
    return true;
 
57
  }
 
58
 
 
59
  public function requiresAuthentication() {
 
60
    return true;
 
61
  }
 
62
 
 
63
  public function desiresRepositoryAPI() {
 
64
    return true;
 
65
  }
 
66
 
 
67
  public function run() {
 
68
    $console = PhutilConsole::getConsole();
 
69
 
 
70
    $is_force = $this->getArgument('force');
 
71
 
 
72
    $things = $this->getArgument('paths');
 
73
    if (!$things) {
 
74
      throw new ArcanistUsageException(
 
75
        pht(
 
76
          'Specify one or more paths or objects to browse. Use the command '.
 
77
          '"arc browse ." if you want to browse this directory.'));
 
78
    }
 
79
    $things = array_fuse($things);
 
80
 
 
81
    $objects = $this->getConduit()->callMethodSynchronous(
 
82
      'phid.lookup',
 
83
      array(
 
84
        'names' => array_keys($things),
 
85
      ));
 
86
 
 
87
    $uris = array();
 
88
    foreach ($objects as $name => $object) {
 
89
      $uris[] = $object['uri'];
 
90
 
 
91
      $console->writeOut(
 
92
        pht(
 
93
          'Opening **%s** as an object.',
 
94
          $name)."\n");
 
95
 
 
96
      unset($things[$name]);
 
97
    }
 
98
 
 
99
    if ($this->hasRepositoryAPI()) {
 
100
      $repository_api = $this->getRepositoryAPI();
 
101
      $project_root = $this->getWorkingCopy()->getProjectRoot();
 
102
 
 
103
      // First, try to resolve arguments as symbolic commits.
 
104
 
 
105
      $commits = array();
 
106
      foreach ($things as $key => $thing) {
 
107
        if ($thing == '.') {
 
108
          // Git resolves '.' like HEAD, but it should be interpreted to mean
 
109
          // "the current directory". Just skip resolution and fall through.
 
110
          continue;
 
111
        }
 
112
 
 
113
        try {
 
114
          $commit = $repository_api->getCanonicalRevisionName($thing);
 
115
          if ($commit) {
 
116
            $commits[$commit] = $key;
 
117
          }
 
118
        } catch (Exception $ex) {
 
119
          // Ignore.
 
120
        }
 
121
      }
 
122
 
 
123
      if ($commits) {
 
124
        $commit_info = $this->getConduit()->callMethodSynchronous(
 
125
          'diffusion.querycommits',
 
126
          array(
 
127
            'repositoryPHID' => $this->getRepositoryPHID(),
 
128
            'names' => array_keys($commits),
 
129
          ));
 
130
 
 
131
        foreach ($commit_info['identifierMap'] as $ckey => $cphid) {
 
132
          $thing = $commits[$ckey];
 
133
          unset($things[$thing]);
 
134
 
 
135
          $uris[] = $commit_info['data'][$cphid]['uri'];
 
136
 
 
137
          $console->writeOut(
 
138
            pht(
 
139
              'Opening **%s** as a commit.',
 
140
              $thing)."\n");
 
141
        }
 
142
      }
 
143
 
 
144
      // If we fail, try to resolve them as paths.
 
145
 
 
146
      foreach ($things as $key => $path) {
 
147
        $lines = null;
 
148
        $parts = explode(':', $path);
 
149
        if (count($parts) > 1) {
 
150
          $lines = array_pop($parts);
 
151
        }
 
152
        $path = implode(':', $parts);
 
153
 
 
154
        $full_path = Filesystem::resolvePath($path);
 
155
 
 
156
        if (!$is_force && !Filesystem::pathExists($full_path)) {
 
157
          continue;
 
158
        }
 
159
 
 
160
        $console->writeOut(
 
161
          pht(
 
162
            'Opening **%s** as a repository path.',
 
163
            $key)."\n");
 
164
 
 
165
        unset($things[$key]);
 
166
 
 
167
        if ($full_path == $project_root) {
 
168
          $path = '';
 
169
        } else {
 
170
          $path = Filesystem::readablePath($full_path, $project_root);
 
171
        }
 
172
 
 
173
        $base_uri = $this->getBaseURI();
 
174
        $uri = $base_uri.$path;
 
175
 
 
176
        if ($lines) {
 
177
          $uri = $uri.'$'.$lines;
 
178
        }
 
179
 
 
180
        $uris[] = $uri;
 
181
      }
 
182
    } else {
 
183
      if ($things) {
 
184
        $console->writeOut(
 
185
          pht(
 
186
            "The current working directory is not a repository working ".
 
187
            "copy, so remaining arguments can not be resolved as paths or ".
 
188
            "commits. To browse paths or symbolic commits in Diffusion, run ".
 
189
            "'arc browse' from inside a working copy.")."\n");
 
190
      }
 
191
    }
 
192
 
 
193
    foreach ($things as $thing) {
 
194
      $console->writeOut(
 
195
        pht(
 
196
          'Unable to find an object named **%s**, no such commit exists in '.
 
197
          'the remote, and no such path exists in the working copy. Use '.
 
198
          '__--force__ to treat this as a path anyway.',
 
199
          $thing)."\n");
 
200
    }
 
201
 
 
202
    if ($uris) {
 
203
      $this->openURIsInBrowser($uris);
 
204
    }
 
205
 
 
206
    return 0;
 
207
  }
 
208
 
 
209
  private function getBaseURI() {
 
210
    $repo_uri = $this->getRepositoryURI();
 
211
    if ($repo_uri === null) {
 
212
      throw new ArcanistUsageException(
 
213
        pht(
 
214
          'arc is unable to determine which repository in Diffusion '.
 
215
          'this working copy belongs to. Use "arc which" to understand how '.
 
216
          'arc looks for a repository.'));
 
217
    }
 
218
 
 
219
    $branch = $this->getArgument('branch', 'master');
 
220
 
 
221
    return $repo_uri.'browse/'.$branch.'/';
 
222
  }
 
223
 
 
224
}