Changeset View
Changeset View
Standalone View
Standalone View
src/workflow/ArcanistLintWorkflow.php
| Show First 20 Lines • Show All 62 Lines • ▼ Show 20 Lines | return array( | ||||
| 'paths are specified, this is the default behavior.'), | 'paths are specified, this is the default behavior.'), | ||||
| 'conflicts' => array( | 'conflicts' => array( | ||||
| 'only-changed' => true, | 'only-changed' => true, | ||||
| ), | ), | ||||
| ), | ), | ||||
| 'only-changed' => array( | 'only-changed' => array( | ||||
| 'help' => pht( | 'help' => pht( | ||||
| 'Show lint warnings just on changed lines. When no paths are '. | 'Show lint warnings just on changed lines. When no paths are '. | ||||
| 'specified, this is the default. This differs from only-new '. | 'specified, this is the default.'), | ||||
| 'in cases where line modifications introduce lint on other '. | |||||
| 'unmodified lines.'), | |||||
| 'conflicts' => array( | 'conflicts' => array( | ||||
| 'lintall' => true, | 'lintall' => true, | ||||
| ), | ), | ||||
| ), | ), | ||||
| 'rev' => array( | 'rev' => array( | ||||
| 'param' => 'revision', | 'param' => 'revision', | ||||
| 'help' => pht('Lint changes since a specific revision.'), | 'help' => pht('Lint changes since a specific revision.'), | ||||
| 'supports' => array( | 'supports' => array( | ||||
| Show All 13 Lines | return array( | ||||
| "With 'compiler', show lint warnings in suitable for your editor. ". | "With 'compiler', show lint warnings in suitable for your editor. ". | ||||
| "With 'xml', show lint warnings in the Checkstyle XML format."), | "With 'xml', show lint warnings in the Checkstyle XML format."), | ||||
| ), | ), | ||||
| 'outfile' => array( | 'outfile' => array( | ||||
| 'param' => 'path', | 'param' => 'path', | ||||
| 'help' => pht( | 'help' => pht( | ||||
| 'Output the linter results to a file. Defaults to stdout.'), | 'Output the linter results to a file. Defaults to stdout.'), | ||||
| ), | ), | ||||
| 'only-new' => array( | |||||
| 'param' => 'bool', | |||||
| 'supports' => array('git', 'hg'), // TODO: svn | |||||
| 'help' => pht( | |||||
| 'Display only messages not present in the original code.'), | |||||
| ), | |||||
| 'engine' => array( | 'engine' => array( | ||||
| 'param' => 'classname', | 'param' => 'classname', | ||||
| 'help' => pht('Override configured lint engine for this project.'), | 'help' => pht('Override configured lint engine for this project.'), | ||||
| ), | ), | ||||
| 'apply-patches' => array( | 'apply-patches' => array( | ||||
| 'help' => pht( | 'help' => pht( | ||||
| 'Apply patches suggested by lint to the working copy without '. | 'Apply patches suggested by lint to the working copy without '. | ||||
| 'prompting.'), | 'prompting.'), | ||||
| ▲ Show 20 Lines • Show All 45 Lines • ▼ Show 20 Lines | return array( | ||||
| 'arc.lint.cache', | 'arc.lint.cache', | ||||
| 'arc.lint.cache'), | 'arc.lint.cache'), | ||||
| ), | ), | ||||
| '*' => 'paths', | '*' => 'paths', | ||||
| ); | ); | ||||
| } | } | ||||
| public function requiresAuthentication() { | public function requiresAuthentication() { | ||||
| return (bool)$this->getArgument('only-new'); | return false; | ||||
| } | } | ||||
| public function requiresWorkingCopy() { | public function requiresWorkingCopy() { | ||||
| return true; | return true; | ||||
| } | } | ||||
| public function requiresRepositoryAPI() { | public function requiresRepositoryAPI() { | ||||
| return true; | return true; | ||||
| ▲ Show 20 Lines • Show All 102 Lines • ▼ Show 20 Lines | if (!$this->shouldLintAll) { | ||||
| // Note that getChangedLines() returns null to indicate that a file | // Note that getChangedLines() returns null to indicate that a file | ||||
| // is binary or a directory (i.e., changed lines are not relevant). | // is binary or a directory (i.e., changed lines are not relevant). | ||||
| $engine->setPathChangedLines( | $engine->setPathChangedLines( | ||||
| $path, | $path, | ||||
| $this->getChangedLines($path, 'new')); | $this->getChangedLines($path, 'new')); | ||||
| } | } | ||||
| } | } | ||||
| if ($this->getArgument('only-new')) { | |||||
| $conduit = $this->getConduit(); | |||||
| $api = $this->getRepositoryAPI(); | |||||
| if ($rev) { | |||||
| $api->setBaseCommit($rev); | |||||
| } | |||||
| $svn_root = id(new PhutilURI($api->getSourceControlPath()))->getPath(); | |||||
| $all_paths = array(); | |||||
| foreach ($paths as $path) { | |||||
| $path = str_replace(DIRECTORY_SEPARATOR, '/', $path); | |||||
| $full_paths = array($path); | |||||
| $change = $this->getChange($path); | |||||
| $type = $change->getType(); | |||||
| if (ArcanistDiffChangeType::isOldLocationChangeType($type)) { | |||||
| $full_paths = $change->getAwayPaths(); | |||||
| } else if (ArcanistDiffChangeType::isNewLocationChangeType($type)) { | |||||
| continue; | |||||
| } else if (ArcanistDiffChangeType::isDeleteChangeType($type)) { | |||||
| continue; | |||||
| } | |||||
| foreach ($full_paths as $full_path) { | |||||
| $all_paths[$svn_root.'/'.$full_path] = $path; | |||||
| } | |||||
| } | |||||
| $lint_future = $conduit->callMethod('diffusion.getlintmessages', array( | |||||
| 'repositoryPHID' => idx($this->loadProjectRepository(), 'phid'), | |||||
| 'branch' => '', // TODO: Tracking branch. | |||||
| 'commit' => $api->getBaseCommit(), | |||||
| 'files' => array_keys($all_paths), | |||||
| )); | |||||
| } | |||||
| $failed = null; | $failed = null; | ||||
| try { | try { | ||||
| $engine->run(); | $engine->run(); | ||||
| } catch (Exception $ex) { | } catch (Exception $ex) { | ||||
| $failed = $ex; | $failed = $ex; | ||||
| } | } | ||||
| $results = $engine->getResults(); | $results = $engine->getResults(); | ||||
| if ($this->getArgument('only-new')) { | |||||
| $total = 0; | |||||
| foreach ($results as $result) { | |||||
| $total += count($result->getMessages()); | |||||
| } | |||||
| // Don't wait for response with default value of --only-new. | |||||
| $timeout = null; | |||||
| if ($this->getArgument('only-new') === null || !$total) { | |||||
| $timeout = 0; | |||||
| } | |||||
| $raw_messages = $this->resolveCall($lint_future, $timeout); | |||||
| if ($raw_messages && $total) { | |||||
| $old_messages = array(); | |||||
| $line_maps = array(); | |||||
| foreach ($raw_messages as $message) { | |||||
| $path = $all_paths[$message['path']]; | |||||
| $line = $message['line']; | |||||
| $code = $message['code']; | |||||
| if (!isset($line_maps[$path])) { | |||||
| $line_maps[$path] = $this->getChange($path)->buildLineMap(); | |||||
| } | |||||
| $new_lines = idx($line_maps[$path], $line); | |||||
| if (!$new_lines) { // Unmodified lines after last hunk. | |||||
| $last_old = ($line_maps[$path] ? last_key($line_maps[$path]) : 0); | |||||
| $news = array_filter($line_maps[$path]); | |||||
| $last_new = ($news ? last(end($news)) : 0); | |||||
| $new_lines = array($line + $last_new - $last_old); | |||||
| } | |||||
| $error = array($code => array(true)); | |||||
| foreach ($new_lines as $new) { | |||||
| if (isset($old_messages[$path][$new])) { | |||||
| $old_messages[$path][$new][$code][] = true; | |||||
| break; | |||||
| } | |||||
| $old_messages[$path][$new] = &$error; | |||||
| } | |||||
| unset($error); | |||||
| } | |||||
| foreach ($results as $result) { | |||||
| foreach ($result->getMessages() as $message) { | |||||
| $path = str_replace(DIRECTORY_SEPARATOR, '/', $message->getPath()); | |||||
| $line = $message->getLine(); | |||||
| $code = $message->getCode(); | |||||
| if (!empty($old_messages[$path][$line][$code])) { | |||||
| $message->setObsolete(true); | |||||
| array_pop($old_messages[$path][$line][$code]); | |||||
| } | |||||
| } | |||||
| $result->sortAndFilterMessages(); | |||||
| } | |||||
| } | |||||
| } | |||||
| if ($this->getArgument('never-apply-patches')) { | if ($this->getArgument('never-apply-patches')) { | ||||
| $apply_patches = false; | $apply_patches = false; | ||||
| } else { | } else { | ||||
| $apply_patches = true; | $apply_patches = true; | ||||
| } | } | ||||
| if ($this->getArgument('apply-patches')) { | if ($this->getArgument('apply-patches')) { | ||||
| $prompt_patches = false; | $prompt_patches = false; | ||||
| ▲ Show 20 Lines • Show All 255 Lines • Show Last 20 Lines | |||||