diff --git a/foo.bar b/foo.bar new file mode 100644 index 00000000..e69de29b diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php index ba14bbba..0f12d494 100644 --- a/src/__phutil_library_map__.php +++ b/src/__phutil_library_map__.php @@ -34,6 +34,7 @@ phutil_register_library_map(array( 'ArcanistGitAPI' => 'repository/api/git', 'ArcanistGitHookPreReceiveWorkflow' => 'workflow/git-hook-pre-receive', 'ArcanistHelpWorkflow' => 'workflow/help', + 'ArcanistLicenseLinter' => 'lint/linter/license', 'ArcanistLintEngine' => 'lint/engine/base', 'ArcanistLintMessage' => 'lint/message', 'ArcanistLintPatcher' => 'lint/patcher', @@ -75,7 +76,7 @@ phutil_register_library_map(array( 'requires_class' => array( 'ArcanistAmendWorkflow' => 'ArcanistBaseWorkflow', - 'ArcanistApacheLicenseLinter' => 'ArcanistLinter', + 'ArcanistApacheLicenseLinter' => 'ArcanistLicenseLinter', 'ArcanistCommitWorkflow' => 'ArcanistBaseWorkflow', 'ArcanistCoverWorkflow' => 'ArcanistBaseWorkflow', 'ArcanistDiffParserTestCase' => 'ArcanistPhutilTestCase', @@ -86,6 +87,7 @@ phutil_register_library_map(array( 'ArcanistGitAPI' => 'ArcanistRepositoryAPI', 'ArcanistGitHookPreReceiveWorkflow' => 'ArcanistBaseWorkflow', 'ArcanistHelpWorkflow' => 'ArcanistBaseWorkflow', + 'ArcanistLicenseLinter' => 'ArcanistLinter', 'ArcanistLintWorkflow' => 'ArcanistBaseWorkflow', 'ArcanistListWorkflow' => 'ArcanistBaseWorkflow', 'ArcanistMarkCommittedWorkflow' => 'ArcanistBaseWorkflow', diff --git a/src/lint/linter/apachelicense/ArcanistApacheLicenseLinter.php b/src/lint/linter/apachelicense/ArcanistApacheLicenseLinter.php index c3264cca..a57cd40f 100644 --- a/src/lint/linter/apachelicense/ArcanistApacheLicenseLinter.php +++ b/src/lint/linter/apachelicense/ArcanistApacheLicenseLinter.php @@ -16,46 +16,15 @@ * limitations under the License. */ -class ArcanistApacheLicenseLinter extends ArcanistLinter { - - const LINT_NO_LICENSE_HEADER = 1; - - public function willLintPaths(array $paths) { - return; - } - +class ArcanistApacheLicenseLinter extends ArcanistLicenseLinter { public function getLinterName() { return 'APACHELICENSE'; } - public function getLintSeverityMap() { - return array(); - } - - public function getLintNameMap() { - return array( - self::LINT_NO_LICENSE_HEADER => 'No License Header', - ); - } - - public function lintPath($path) { - $working_copy = $this->getEngine()->getWorkingCopy(); - $copyright_holder = $working_copy->getConfig('copyright_holder'); - - if (!$copyright_holder) { - return; - } - + protected function getLicenseText($copyright_holder) { $year = date('Y'); - $maybe_php_or_script = '(#![^\n]+?[\n])?(<[?]php\s+?)?'; - $patterns = array( - "@^{$maybe_php_or_script}//[^\n]*Copyright[^\n]*[\n]\s*@i", - "@^{$maybe_php_or_script}/[*].*?Copyright.*?[*]/\s*@is", - "@^{$maybe_php_or_script}\s*@", - ); - - $license = <<getData($path); - $matches = 0; - if (preg_match($pattern, $data, $matches)) { - $expect = rtrim(implode('', array_slice($matches, 1)))."\n\n".$license; - $expect = ltrim($expect); - if (rtrim($matches[0]) != rtrim($expect)) { - $this->raiseLintAtOffset( - 0, - self::LINT_NO_LICENSE_HEADER, - 'This file has a missing or out of date license header.', - $matches[0], - $expect); - } - break; - } - } } + protected function getLicensePatterns() { + $maybe_php_or_script = '(#![^\n]+?[\n])?(<[?]php\s+?)?'; + return array( + "@^{$maybe_php_or_script}//[^\n]*Copyright[^\n]*[\n]\s*@i", + "@^{$maybe_php_or_script}/[*].*?Copyright.*?[*]/\s*@is", + "@^{$maybe_php_or_script}\s*@", + ); + } } diff --git a/src/lint/linter/apachelicense/__init__.php b/src/lint/linter/apachelicense/__init__.php index 08dd7e0e..e5067bc0 100644 --- a/src/lint/linter/apachelicense/__init__.php +++ b/src/lint/linter/apachelicense/__init__.php @@ -5,8 +5,6 @@ */ - -phutil_require_module('arcanist', 'lint/linter/base'); - +phutil_require_module('arcanist', 'lint/linter/license'); phutil_require_source('ArcanistApacheLicenseLinter.php'); diff --git a/src/lint/linter/license/ArcanistLicenseLinter.php b/src/lint/linter/license/ArcanistLicenseLinter.php new file mode 100644 index 00000000..d725dad2 --- /dev/null +++ b/src/lint/linter/license/ArcanistLicenseLinter.php @@ -0,0 +1,79 @@ + 'No License Header', + ); + } + + /** + * Given the name of the copyright holder, return appropriate license header + * text. + */ + abstract protected function getLicenseText($copyright_holder); + /** + * Return an array of regular expressions that, if matched, indicate + * that a copyright header is required. The appropriate match will be + * stripped from the input when comparing against the expected license. + */ + abstract protected function getLicensePatterns(); + + public function lintPath($path) { + $working_copy = $this->getEngine()->getWorkingCopy(); + $copyright_holder = $working_copy->getConfig('copyright_holder'); + + if (!$copyright_holder) { + return; + } + + $patterns = $this->getLicensePatterns(); + $license = $this->getLicenseText($copyright_holder); + + foreach ($patterns as $pattern) { + $data = $this->getData($path); + $matches = 0; + if (preg_match($pattern, $data, $matches)) { + $expect = rtrim(implode('', array_slice($matches, 1)))."\n\n".$license; + $expect = ltrim($expect); + if (rtrim($matches[0]) != rtrim($expect)) { + $this->raiseLintAtOffset( + 0, + self::LINT_NO_LICENSE_HEADER, + 'This file has a missing or out of date license header.', + $matches[0], + $expect); + } + break; + } + } + } +} + + diff --git a/src/lint/linter/license/__init__.php b/src/lint/linter/license/__init__.php new file mode 100644 index 00000000..4ef6a342 --- /dev/null +++ b/src/lint/linter/license/__init__.php @@ -0,0 +1,12 @@ +