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

« back to all changes in this revision

Viewing changes to src/workflow/ArcanistLintersWorkflow.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
 * List available linters.
 
5
 */
 
6
final class ArcanistLintersWorkflow extends ArcanistWorkflow {
 
7
 
 
8
  public function getWorkflowName() {
 
9
    return 'linters';
 
10
  }
 
11
 
 
12
  public function getCommandSynopses() {
 
13
    return phutil_console_format(<<<EOTEXT
 
14
      **linters** [__options__]
 
15
EOTEXT
 
16
      );
 
17
  }
 
18
 
 
19
  public function getCommandHelp() {
 
20
    return phutil_console_format(pht(<<<EOTEXT
 
21
          Supports: cli
 
22
          List the available and configured linters, with information about
 
23
          what they do and which versions are installed.
 
24
EOTEXT
 
25
      ));
 
26
  }
 
27
 
 
28
  public function getArguments() {
 
29
    return array(
 
30
      'verbose' => array(
 
31
        'help' => pht('Show detailed information, including options.'),
 
32
      ),
 
33
    );
 
34
  }
 
35
 
 
36
  public function run() {
 
37
    $console = PhutilConsole::getConsole();
 
38
 
 
39
    $linters = id(new PhutilSymbolLoader())
 
40
      ->setAncestorClass('ArcanistLinter')
 
41
      ->loadObjects();
 
42
 
 
43
    try {
 
44
      $built = $this->newLintEngine()->buildLinters();
 
45
    } catch (ArcanistNoEngineException $ex) {
 
46
      $built = array();
 
47
    }
 
48
 
 
49
    // Note that an engine can emit multiple linters of the same class to run
 
50
    // different rulesets on different groups of files, so these linters do not
 
51
    // necessarily have unique classes or types.
 
52
    $groups = array();
 
53
    foreach ($built as $linter) {
 
54
      $groups[get_class($linter)][] = $linter;
 
55
    }
 
56
 
 
57
    $linter_info = array();
 
58
    foreach ($linters as $key => $linter) {
 
59
      $installed = idx($groups, $key, array());
 
60
      $exception = null;
 
61
 
 
62
      if ($installed) {
 
63
        $status = 'configured';
 
64
        try {
 
65
          $version = head($installed)->getVersion();
 
66
        } catch (Exception $ex) {
 
67
          $status = 'error';
 
68
          $exception = $ex;
 
69
        }
 
70
      } else {
 
71
        $status = 'available';
 
72
        $version = null;
 
73
      }
 
74
 
 
75
      $linter_info[$key] = array(
 
76
        'short' => $linter->getLinterConfigurationName(),
 
77
        'class' => get_class($linter),
 
78
        'status' => $status,
 
79
        'version' => $version,
 
80
        'name' => $linter->getInfoName(),
 
81
        'uri' => $linter->getInfoURI(),
 
82
        'description' => $linter->getInfoDescription(),
 
83
        'exception' => $exception,
 
84
        'options' => $linter->getLinterConfigurationOptions(),
 
85
      );
 
86
    }
 
87
 
 
88
    $linter_info = isort($linter_info, 'short');
 
89
 
 
90
    $status_map = $this->getStatusMap();
 
91
    $pad = '    ';
 
92
 
 
93
    $color_map = array(
 
94
      'configured' => 'green',
 
95
      'available' => 'yellow',
 
96
      'error' => 'red',
 
97
    );
 
98
 
 
99
    foreach ($linter_info as $key => $linter) {
 
100
      $status = $linter['status'];
 
101
      $color = $color_map[$status];
 
102
      $text = $status_map[$status];
 
103
      $print_tail = false;
 
104
 
 
105
      $console->writeOut(
 
106
        "<bg:".$color.">** %s **</bg> **%s** (%s)\n",
 
107
        $text,
 
108
        nonempty($linter['short'], '-'),
 
109
        $linter['name']);
 
110
 
 
111
      if ($linter['exception']) {
 
112
        $console->writeOut(
 
113
          "\n%s**%s**\n%s\n",
 
114
          $pad,
 
115
          get_class($linter['exception']),
 
116
          phutil_console_wrap(
 
117
            $linter['exception']->getMessage(),
 
118
            strlen($pad)));
 
119
        $print_tail = true;
 
120
      }
 
121
 
 
122
      $version = $linter['version'];
 
123
      $uri = $linter['uri'];
 
124
      if ($version || $uri) {
 
125
        $console->writeOut("\n");
 
126
        $print_tail = true;
 
127
      }
 
128
 
 
129
      if ($version) {
 
130
        $console->writeOut("%s%s **%s**\n", $pad, pht('Version'), $version);
 
131
      }
 
132
 
 
133
      if ($uri) {
 
134
        $console->writeOut("%s__%s__\n", $pad, $linter['uri']);
 
135
      }
 
136
 
 
137
      $description = $linter['description'];
 
138
      if ($description) {
 
139
        $console->writeOut(
 
140
          "\n%s\n",
 
141
          phutil_console_wrap($linter['description'], strlen($pad)));
 
142
        $print_tail = true;
 
143
      }
 
144
 
 
145
      $options = $linter['options'];
 
146
      if ($options && $this->getArgument('verbose')) {
 
147
        $console->writeOut(
 
148
          "\n%s**%s**\n\n",
 
149
          $pad,
 
150
          pht('Configuration Options'));
 
151
 
 
152
        $last_option = last_key($options);
 
153
        foreach ($options as $option => $option_spec) {
 
154
          $console->writeOut(
 
155
            "%s__%s__ (%s)\n",
 
156
            $pad,
 
157
            $option,
 
158
            $option_spec['type']);
 
159
 
 
160
          $console->writeOut(
 
161
            "%s\n",
 
162
            phutil_console_wrap(
 
163
              $option_spec['help'],
 
164
              strlen($pad) + 2));
 
165
 
 
166
          if ($option != $last_option) {
 
167
            $console->writeOut("\n");
 
168
          }
 
169
        }
 
170
        $print_tail = true;
 
171
      }
 
172
 
 
173
      if ($print_tail) {
 
174
        $console->writeOut("\n");
 
175
      }
 
176
    }
 
177
 
 
178
    if (!$this->getArgument('verbose')) {
 
179
      $console->writeOut(
 
180
        "%s\n",
 
181
        pht('(Run `arc linters --verbose` for more details.)'));
 
182
    }
 
183
  }
 
184
 
 
185
 
 
186
  /**
 
187
   * Get human-readable linter statuses, padded to fixed width.
 
188
   *
 
189
   * @return map<string, string> Human-readable linter status names.
 
190
   */
 
191
  private function getStatusMap() {
 
192
    $text_map = array(
 
193
      'configured' => pht('CONFIGURED'),
 
194
      'available' => pht('AVAILABLE'),
 
195
      'error' => pht('ERROR'),
 
196
    );
 
197
 
 
198
    $sizes = array();
 
199
    foreach ($text_map as $key => $string) {
 
200
      $sizes[$key] = phutil_utf8_console_strlen($string);
 
201
    }
 
202
 
 
203
    $longest = max($sizes);
 
204
    foreach ($text_map as $key => $string) {
 
205
      if ($sizes[$key] < $longest) {
 
206
        $text_map[$key] .= str_repeat(' ', $longest - $sizes[$key]);
 
207
      }
 
208
    }
 
209
 
 
210
    $text_map['padding'] = str_repeat(' ', $longest);
 
211
 
 
212
    return $text_map;
 
213
  }
 
214
 
 
215
}