From ec3de41684c987c048da9f42c8dba35c8467c859 Mon Sep 17 00:00:00 2001 From: Joshua Spence Date: Tue, 13 May 2014 13:20:29 -0700 Subject: [PATCH] Support Checkstyle as an output format for lint results. Summary: Fixes T4948. Add a lint renderer which supports outputting the lint results in the Checkstyle XML format. Test Plan: Ran `arc lint --xml` and inspected the output. Reviewers: #blessed_reviewers, epriestley Reviewed By: #blessed_reviewers, epriestley Subscribers: epriestley, Korvin Maniphest Tasks: T4948 Differential Revision: https://secure.phabricator.com/D9083 --- src/__phutil_library_map__.php | 2 + .../ArcanistLintCheckstyleXMLRenderer.php | 53 +++++++++++++++++++ src/lint/renderer/ArcanistLintRenderer.php | 4 ++ src/workflow/ArcanistLintWorkflow.php | 8 ++- 4 files changed, 66 insertions(+), 1 deletion(-) create mode 100644 src/lint/renderer/ArcanistLintCheckstyleXMLRenderer.php diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php index b5613651..6131a1aa 100644 --- a/src/__phutil_library_map__.php +++ b/src/__phutil_library_map__.php @@ -91,6 +91,7 @@ phutil_register_library_map(array( 'ArcanistLesscLinter' => 'lint/linter/ArcanistLesscLinter.php', 'ArcanistLesscLinterTestCase' => 'lint/linter/__tests__/ArcanistLesscLinterTestCase.php', 'ArcanistLiberateWorkflow' => 'workflow/ArcanistLiberateWorkflow.php', + 'ArcanistLintCheckstyleXMLRenderer' => 'lint/renderer/ArcanistLintCheckstyleXMLRenderer.php', 'ArcanistLintConsoleRenderer' => 'lint/renderer/ArcanistLintConsoleRenderer.php', 'ArcanistLintEngine' => 'lint/engine/ArcanistLintEngine.php', 'ArcanistLintJSONRenderer' => 'lint/renderer/ArcanistLintJSONRenderer.php', @@ -262,6 +263,7 @@ phutil_register_library_map(array( 'ArcanistLesscLinter' => 'ArcanistExternalLinter', 'ArcanistLesscLinterTestCase' => 'ArcanistArcanistLinterTestCase', 'ArcanistLiberateWorkflow' => 'ArcanistBaseWorkflow', + 'ArcanistLintCheckstyleXMLRenderer' => 'ArcanistLintRenderer', 'ArcanistLintConsoleRenderer' => 'ArcanistLintRenderer', 'ArcanistLintJSONRenderer' => 'ArcanistLintRenderer', 'ArcanistLintLikeCompilerRenderer' => 'ArcanistLintRenderer', diff --git a/src/lint/renderer/ArcanistLintCheckstyleXMLRenderer.php b/src/lint/renderer/ArcanistLintCheckstyleXMLRenderer.php new file mode 100644 index 00000000..081ead90 --- /dev/null +++ b/src/lint/renderer/ArcanistLintCheckstyleXMLRenderer.php @@ -0,0 +1,53 @@ +writer = new XMLWriter(); + $this->writer->openMemory(); + $this->writer->setIndent(true); + $this->writer->setIndentString(' '); + + $this->writer->startDocument('1.0', 'UTF-8'); + $this->writer->startElement('checkstyle'); + $this->writer->writeAttribute('version', '4.3'); + } + + public function renderLintResult(ArcanistLintResult $result) { + $this->writer->startElement('file'); + $this->writer->writeAttribute('name', $result->getPath()); + + foreach ($result->getMessages() as $message) { + $this->writer->startElement('error'); + + $this->writer->writeAttribute('line', $message->getLine()); + $this->writer->writeAttribute('column', $message->getChar()); + $this->writer->writeAttribute('severity', + ArcanistLintSeverity::getStringForSeverity($message->getSeverity())); + $this->writer->writeAttribute('message', $message->getDescription()); + $this->writer->writeAttribute('source', $message->getCode()); + + $this->writer->endElement(); + } + + $this->writer->endElement(); + return $this->writer->flush(); + } + + public function renderOkayResult() { + return ''; + } + + public function renderPostamble() { + $this->writer->endElement(); + $this->writer->endDocument(); + return $this->writer->flush(); + } +} diff --git a/src/lint/renderer/ArcanistLintRenderer.php b/src/lint/renderer/ArcanistLintRenderer.php index 1b1c19fd..bc82a32f 100644 --- a/src/lint/renderer/ArcanistLintRenderer.php +++ b/src/lint/renderer/ArcanistLintRenderer.php @@ -10,4 +10,8 @@ abstract class ArcanistLintRenderer { abstract public function renderLintResult(ArcanistLintResult $result); abstract public function renderOkayResult(); + public function renderPostamble() { + return ''; + } + } diff --git a/src/workflow/ArcanistLintWorkflow.php b/src/workflow/ArcanistLintWorkflow.php index df515585..3845118d 100644 --- a/src/workflow/ArcanistLintWorkflow.php +++ b/src/workflow/ArcanistLintWorkflow.php @@ -96,7 +96,8 @@ EOTEXT "With 'summary', show lint warnings in a more compact format. ". "With 'json', show lint warnings in machine-readable JSON format. ". "With 'none', show no lint warnings. ". - "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." ), 'only-new' => array( 'param' => 'bool', @@ -456,6 +457,9 @@ EOTEXT $prompt_patches = false; $apply_patches = $this->getArgument('apply-patches'); break; + case 'xml': + $renderer = new ArcanistLintCheckstyleXMLRenderer(); + break; default: $renderer = new ArcanistLintConsoleRenderer(); $renderer->setShowAutofixPatches($prompt_autofix_patches); @@ -514,6 +518,8 @@ EOTEXT } } + $console->writeOut('%s', $renderer->renderPostamble()); + if ($wrote_to_disk && $this->shouldAmendChanges) { if ($this->shouldAmendWithoutPrompt || ($this->shouldAmendAutofixesWithoutPrompt && $all_autofix)) {