diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php --- a/src/__phutil_library_map__.php +++ b/src/__phutil_library_map__.php @@ -32,6 +32,7 @@ 'ArcanistCSharpLinter' => 'lint/linter/ArcanistCSharpLinter.php', 'ArcanistCallConduitWorkflow' => 'workflow/ArcanistCallConduitWorkflow.php', 'ArcanistCapabilityNotSupportedException' => 'workflow/exception/ArcanistCapabilityNotSupportedException.php', + 'ArcanistChmodLinter' => 'lint/linter/ArcanistChmodLinter.php', 'ArcanistChooseInvalidRevisionException' => 'exception/ArcanistChooseInvalidRevisionException.php', 'ArcanistChooseNoRevisionsException' => 'exception/ArcanistChooseNoRevisionsException.php', 'ArcanistCloseRevisionWorkflow' => 'workflow/ArcanistCloseRevisionWorkflow.php', @@ -222,6 +223,7 @@ 'ArcanistCSharpLinter' => 'ArcanistLinter', 'ArcanistCallConduitWorkflow' => 'ArcanistBaseWorkflow', 'ArcanistCapabilityNotSupportedException' => 'Exception', + 'ArcanistChmodLinter' => 'ArcanistLinter', 'ArcanistChooseInvalidRevisionException' => 'Exception', 'ArcanistChooseNoRevisionsException' => 'Exception', 'ArcanistCloseRevisionWorkflow' => 'ArcanistBaseWorkflow', diff --git a/src/lint/linter/ArcanistChmodLinter.php b/src/lint/linter/ArcanistChmodLinter.php new file mode 100644 --- /dev/null +++ b/src/lint/linter/ArcanistChmodLinter.php @@ -0,0 +1,80 @@ + pht('Invalid Executable'), + ); + } + + public function getLintSeverityMap() { + return array( + self::LINT_INVALID_EXECUTABLE => ArcanistLintSeverity::SEVERITY_WARNING, + ); + } + + public function lintPath($path) { + if (is_executable($path)) { + if ($this->getEngine()->isBinaryFile($path)) { + // Path is a binary file, which makes it a valid executable. + return; + } else if ($this->getShebang($path)) { + // Path contains a shebang, which makes it a valid executable. + return; + } else { + $this->raiseLintAtPath( + self::LINT_INVALID_EXECUTABLE, + pht( + 'Executable files should either be binary or contain a shebang.')); + } + } + } + + /** + * Returns the path's shebang. + * + * @param string + * @return string|null + */ + private function getShebang($path) { + $line = head(phutil_split_lines($this->getEngine()->loadData($path), true)); + + $matches = array(); + if (preg_match('/^#!(.*)$/', $line, $matches)) { + return $matches[1]; + } else { + return null; + } + } + +}