diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php index e0c89d1f..efa18576 100644 --- a/src/__phutil_library_map__.php +++ b/src/__phutil_library_map__.php @@ -13,6 +13,7 @@ phutil_register_library_map(array( 'ArcanistAliasWorkflow' => 'workflow/ArcanistAliasWorkflow.php', 'ArcanistAmendWorkflow' => 'workflow/ArcanistAmendWorkflow.php', 'ArcanistAnoidWorkflow' => 'workflow/ArcanistAnoidWorkflow.php', + 'ArcanistApacheLicenseLinter' => 'lint/linter/ArcanistApacheLicenseLinter.php', 'ArcanistArcanistLinterTestCase' => 'lint/linter/__tests__/ArcanistArcanistLinterTestCase.php', 'ArcanistBaseCommitParser' => 'parser/ArcanistBaseCommitParser.php', 'ArcanistBaseCommitParserTestCase' => 'parser/__tests__/ArcanistBaseCommitParserTestCase.php', @@ -73,6 +74,7 @@ phutil_register_library_map(array( 'ArcanistJSHintLinter' => 'lint/linter/ArcanistJSHintLinter.php', 'ArcanistLandWorkflow' => 'workflow/ArcanistLandWorkflow.php', 'ArcanistLiberateWorkflow' => 'workflow/ArcanistLiberateWorkflow.php', + 'ArcanistLicenseLinter' => 'lint/linter/ArcanistLicenseLinter.php', 'ArcanistLintConsoleRenderer' => 'lint/renderer/ArcanistLintConsoleRenderer.php', 'ArcanistLintEngine' => 'lint/engine/ArcanistLintEngine.php', 'ArcanistLintJSONRenderer' => 'lint/renderer/ArcanistLintJSONRenderer.php', @@ -168,6 +170,7 @@ phutil_register_library_map(array( 'ArcanistAliasWorkflow' => 'ArcanistBaseWorkflow', 'ArcanistAmendWorkflow' => 'ArcanistBaseWorkflow', 'ArcanistAnoidWorkflow' => 'ArcanistBaseWorkflow', + 'ArcanistApacheLicenseLinter' => 'ArcanistLicenseLinter', 'ArcanistArcanistLinterTestCase' => 'ArcanistLinterTestCase', 'ArcanistBaseCommitParserTestCase' => 'ArcanistTestCase', 'ArcanistBaseWorkflow' => 'Phobject', @@ -211,6 +214,7 @@ phutil_register_library_map(array( 'ArcanistJSHintLinter' => 'ArcanistLinter', 'ArcanistLandWorkflow' => 'ArcanistBaseWorkflow', 'ArcanistLiberateWorkflow' => 'ArcanistBaseWorkflow', + 'ArcanistLicenseLinter' => 'ArcanistLinter', 'ArcanistLintConsoleRenderer' => 'ArcanistLintRenderer', 'ArcanistLintJSONRenderer' => 'ArcanistLintRenderer', 'ArcanistLintLikeCompilerRenderer' => 'ArcanistLintRenderer', diff --git a/src/lint/linter/ArcanistApacheLicenseLinter.php b/src/lint/linter/ArcanistApacheLicenseLinter.php new file mode 100644 index 00000000..fbed31cc --- /dev/null +++ b/src/lint/linter/ArcanistApacheLicenseLinter.php @@ -0,0 +1,51 @@ + 'No License Header', + ); + } + + abstract protected function getLicenseText($copyright_holder); + abstract protected function getLicensePatterns(); + + public function lintPath($path) { + $copyright_holder = $this->getConfig('copyright_holder'); + if ($copyright_holder === null) { + $working_copy = $this->getEngine()->getWorkingCopy(); + $copyright_holder = $working_copy->getConfig('copyright_holder'); + } + + if (!$copyright_holder) { + return; + } + + $patterns = $this->getLicensePatterns(); + $license = $this->getLicenseText($copyright_holder); + + $data = $this->getData($path); + $matches = 0; + + foreach ($patterns as $pattern) { + if (preg_match($pattern, $data, $matches)) { + $expect = rtrim(implode('', array_slice($matches, 1)))."\n".$license; + if (trim($matches[0]) != trim($expect)) { + $this->raiseLintAtOffset( + 0, + self::LINT_NO_LICENSE_HEADER, + 'This file has a missing or out of date license header.', + $matches[0], + ltrim($expect)); + } + break; + } + } + } +} + +