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

« back to all changes in this revision

Viewing changes to src/workflow/ArcanistWhichWorkflow.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
 * Show which revision or revisions are in the working copy.
 
5
 */
 
6
final class ArcanistWhichWorkflow extends ArcanistWorkflow {
 
7
 
 
8
  public function getWorkflowName() {
 
9
    return 'which';
 
10
  }
 
11
 
 
12
  public function getCommandSynopses() {
 
13
    return phutil_console_format(<<<EOTEXT
 
14
      **which** [options] (svn)
 
15
      **which** [options] [__commit__] (hg, git)
 
16
EOTEXT
 
17
      );
 
18
  }
 
19
 
 
20
  public function getCommandHelp() {
 
21
    return phutil_console_format(<<<EOTEXT
 
22
          Supports: svn, git, hg
 
23
          Shows which repository the current working copy corresponds to,
 
24
          which commits 'arc diff' will select, and which revision is in
 
25
          the working copy (or which revisions, if more than one matches).
 
26
EOTEXT
 
27
      );
 
28
  }
 
29
 
 
30
  public function requiresConduit() {
 
31
    return true;
 
32
  }
 
33
 
 
34
  public function requiresRepositoryAPI() {
 
35
    return true;
 
36
  }
 
37
 
 
38
  public function requiresAuthentication() {
 
39
    return true;
 
40
  }
 
41
 
 
42
  public function getArguments() {
 
43
    return array(
 
44
      'any-status' => array(
 
45
        'help' => 'Show committed and abandoned revisions.',
 
46
      ),
 
47
      'base' => array(
 
48
        'param' => 'rules',
 
49
        'help'  => 'Additional rules for determining base revision.',
 
50
        'nosupport' => array(
 
51
          'svn' => 'Subversion does not use base commits.',
 
52
        ),
 
53
        'supports' => array('git', 'hg'),
 
54
      ),
 
55
      'show-base' => array(
 
56
        'help'  => 'Print base commit only and exit.',
 
57
        'nosupport' => array(
 
58
          'svn' => 'Subversion does not use base commits.',
 
59
        ),
 
60
        'supports' => array('git', 'hg'),
 
61
      ),
 
62
      'head' => array(
 
63
        'param' => 'commit',
 
64
        'help' => pht('Specify the end of the commit range to select.'),
 
65
        'nosupport' => array(
 
66
          'svn' => pht('Subversion does not support commit ranges.'),
 
67
          'hg' => pht('Mercurial does not support --head yet.'),
 
68
        ),
 
69
        'supports' => array('git'),
 
70
      ),
 
71
      '*' => 'commit',
 
72
    );
 
73
  }
 
74
 
 
75
  public function run() {
 
76
    $console = PhutilConsole::getConsole();
 
77
 
 
78
    $this->printRepositorySection();
 
79
    $console->writeOut("\n");
 
80
 
 
81
    $repository_api = $this->getRepositoryAPI();
 
82
 
 
83
    $arg_commit = $this->getArgument('commit');
 
84
    if (count($arg_commit)) {
 
85
      $this->parseBaseCommitArgument($arg_commit);
 
86
    }
 
87
    $arg = $arg_commit ? ' '.head($arg_commit) : '';
 
88
 
 
89
    $repository_api->setBaseCommitArgumentRules(
 
90
      $this->getArgument('base', ''));
 
91
 
 
92
    $supports_ranges = $repository_api->supportsCommitRanges();
 
93
 
 
94
    $head_commit = $this->getArgument('head');
 
95
    if ($head_commit !== null) {
 
96
      $arg .= csprintf(' --head %R', $head_commit);
 
97
      $repository_api->setHeadCommit($head_commit);
 
98
    }
 
99
 
 
100
    if ($supports_ranges) {
 
101
      $relative = $repository_api->getBaseCommit();
 
102
 
 
103
      if ($this->getArgument('show-base')) {
 
104
        echo $relative."\n";
 
105
        return 0;
 
106
      }
 
107
 
 
108
      $info = $repository_api->getLocalCommitInformation();
 
109
      if ($info) {
 
110
        $commits = array();
 
111
        foreach ($info as $commit) {
 
112
          $hash     = substr($commit['commit'], 0, 16);
 
113
          $summary  = $commit['summary'];
 
114
 
 
115
          $commits[] = "    {$hash}  {$summary}";
 
116
        }
 
117
        $commits = implode("\n", $commits);
 
118
      } else {
 
119
        $commits = '    (No commits.)';
 
120
      }
 
121
 
 
122
      $explanation = $repository_api->getBaseCommitExplanation();
 
123
 
 
124
      $relative_summary = $repository_api->getCommitSummary($relative);
 
125
      $relative = substr($relative, 0, 16);
 
126
 
 
127
      if ($repository_api instanceof ArcanistGitAPI) {
 
128
        $head = $this->getArgument('head', 'HEAD');
 
129
        $command = csprintf('git diff %R', "{$relative}..{$head}");
 
130
      } else if ($repository_api instanceof ArcanistMercurialAPI) {
 
131
        $command = csprintf(
 
132
          'hg diff --rev %R',
 
133
          hgsprintf('%s', $relative));
 
134
      } else {
 
135
        throw new Exception('Unknown VCS!');
 
136
      }
 
137
 
 
138
      echo phutil_console_wrap(
 
139
        phutil_console_format(
 
140
          "**COMMIT RANGE**\n".
 
141
          "If you run 'arc diff{$arg}', changes between the commit:\n\n"));
 
142
 
 
143
      echo  "    {$relative}  {$relative_summary}\n\n";
 
144
 
 
145
      if ($head_commit === null) {
 
146
        $will_be_sent = pht(
 
147
          '...and the current working copy state will be sent to '.
 
148
          'Differential, because %s',
 
149
          $explanation);
 
150
      } else {
 
151
        $will_be_sent = pht(
 
152
          '...and "%s" will be sent to Differential, because %s',
 
153
          $head_commit,
 
154
          $explanation);
 
155
      }
 
156
 
 
157
      echo phutil_console_wrap(
 
158
        "{$will_be_sent}\n\n".
 
159
        "You can see the exact changes that will be sent by running ".
 
160
        "this command:\n\n".
 
161
        "    $ {$command}\n\n".
 
162
        "These commits will be included in the diff:\n\n");
 
163
 
 
164
      echo $commits."\n\n\n";
 
165
    }
 
166
 
 
167
    $any_status = $this->getArgument('any-status');
 
168
 
 
169
    $query = array(
 
170
      'status' => $any_status
 
171
        ? 'status-any'
 
172
        : 'status-open',
 
173
    );
 
174
 
 
175
    $revisions = $repository_api->loadWorkingCopyDifferentialRevisions(
 
176
      $this->getConduit(),
 
177
      $query);
 
178
 
 
179
    echo phutil_console_wrap(
 
180
      phutil_console_format(
 
181
        "**MATCHING REVISIONS**\n".
 
182
        "These Differential revisions match the changes in this working ".
 
183
        "copy:\n\n"));
 
184
 
 
185
    if (empty($revisions)) {
 
186
      echo "    (No revisions match.)\n";
 
187
      echo "\n";
 
188
      echo phutil_console_wrap(
 
189
        phutil_console_format(
 
190
          "Since there are no revisions in Differential which match this ".
 
191
          "working copy, a new revision will be **created** if you run ".
 
192
          "'arc diff{$arg}'.\n\n"));
 
193
    } else {
 
194
      $other_author_phids = array();
 
195
      foreach ($revisions as $revision) {
 
196
        if ($revision['authorPHID'] != $this->getUserPHID()) {
 
197
          $other_author_phids[] = $revision['authorPHID'];
 
198
        }
 
199
      }
 
200
 
 
201
      $other_authors = array();
 
202
      if ($other_author_phids) {
 
203
        $other_authors = $this->getConduit()->callMethodSynchronous(
 
204
          'user.query',
 
205
          array(
 
206
            'phids' => $other_author_phids,
 
207
          ));
 
208
        $other_authors = ipull($other_authors, 'userName', 'phid');
 
209
      }
 
210
 
 
211
      foreach ($revisions as $revision) {
 
212
        $title = $revision['title'];
 
213
        $monogram = 'D'.$revision['id'];
 
214
 
 
215
        if ($revision['authorPHID'] != $this->getUserPHID()) {
 
216
          $author = $other_authors[$revision['authorPHID']];
 
217
          echo pht("    %s (%s) %s\n", $monogram, $author, $title);
 
218
        } else {
 
219
          echo pht("    %s %s\n", $monogram, $title);
 
220
        }
 
221
 
 
222
        echo '        Reason: '.$revision['why']."\n";
 
223
        echo "\n";
 
224
      }
 
225
      if (count($revisions) == 1) {
 
226
        echo phutil_console_wrap(
 
227
          phutil_console_format(
 
228
            "Since exactly one revision in Differential matches this working ".
 
229
            "copy, it will be **updated** if you run 'arc diff{$arg}'."));
 
230
      } else {
 
231
        echo phutil_console_wrap(
 
232
          "Since more than one revision in Differential matches this working ".
 
233
          "copy, you will be asked which revision you want to update if ".
 
234
          "you run 'arc diff {$arg}'.");
 
235
      }
 
236
      echo "\n\n";
 
237
    }
 
238
 
 
239
    return 0;
 
240
  }
 
241
 
 
242
  private function printRepositorySection() {
 
243
    $console = PhutilConsole::getConsole();
 
244
    $console->writeOut("**%s**\n", pht('REPOSITORY'));
 
245
 
 
246
    $callsign = $this->getRepositoryCallsign();
 
247
 
 
248
    $console->writeOut(
 
249
      "%s\n\n",
 
250
      pht(
 
251
        'To identify the repository associated with this working copy, '.
 
252
        'arc followed this process:'));
 
253
 
 
254
    foreach ($this->getRepositoryReasons() as $reason) {
 
255
      $reason = phutil_console_wrap($reason, 4);
 
256
      $console->writeOut("%s\n\n", $reason);
 
257
    }
 
258
 
 
259
    if ($callsign) {
 
260
      $console->writeOut(
 
261
        "%s\n",
 
262
        pht('This working copy is associated with the %s repository.',
 
263
        phutil_console_format('**%s**', $callsign)));
 
264
    } else {
 
265
      $console->writeOut(
 
266
        "%s\n",
 
267
        pht('This working copy is not associated with any repository.'));
 
268
    }
 
269
  }
 
270
 
 
271
}