mirror of
https://we.phorge.it/source/arcanist.git
synced 2024-11-29 10:12:41 +01:00
Add a puppet-lint
linter.
Summary: This linter is a wrapper around [[http://puppet-lint.com/ | puppet-lint[]]. Test Plan: Wrote an executed unit tests. Reviewers: #blessed_reviewers, epriestley Reviewed By: #blessed_reviewers, epriestley Subscribers: epriestley, Korvin Differential Revision: https://secure.phabricator.com/D8990
This commit is contained in:
parent
48d52c30b0
commit
8523b98f39
17 changed files with 195 additions and 0 deletions
|
@ -125,6 +125,8 @@ phutil_register_library_map(array(
|
||||||
'ArcanistPhutilTestTerminatedException' => 'unit/engine/phutil/testcase/ArcanistPhutilTestTerminatedException.php',
|
'ArcanistPhutilTestTerminatedException' => 'unit/engine/phutil/testcase/ArcanistPhutilTestTerminatedException.php',
|
||||||
'ArcanistPhutilXHPASTLinter' => 'lint/linter/ArcanistPhutilXHPASTLinter.php',
|
'ArcanistPhutilXHPASTLinter' => 'lint/linter/ArcanistPhutilXHPASTLinter.php',
|
||||||
'ArcanistPhutilXHPASTLinterTestCase' => 'lint/linter/__tests__/ArcanistPhutilXHPASTLinterTestCase.php',
|
'ArcanistPhutilXHPASTLinterTestCase' => 'lint/linter/__tests__/ArcanistPhutilXHPASTLinterTestCase.php',
|
||||||
|
'ArcanistPuppetLintLinter' => 'lint/linter/ArcanistPuppetLintLinter.php',
|
||||||
|
'ArcanistPuppetLintLinterTestCase' => 'lint/linter/__tests__/ArcanistPuppetLintLinterTestCase.php',
|
||||||
'ArcanistPyFlakesLinter' => 'lint/linter/ArcanistPyFlakesLinter.php',
|
'ArcanistPyFlakesLinter' => 'lint/linter/ArcanistPyFlakesLinter.php',
|
||||||
'ArcanistPyFlakesLinterTestCase' => 'lint/linter/__tests__/ArcanistPyFlakesLinterTestCase.php',
|
'ArcanistPyFlakesLinterTestCase' => 'lint/linter/__tests__/ArcanistPyFlakesLinterTestCase.php',
|
||||||
'ArcanistPyLintLinter' => 'lint/linter/ArcanistPyLintLinter.php',
|
'ArcanistPyLintLinter' => 'lint/linter/ArcanistPyLintLinter.php',
|
||||||
|
@ -281,6 +283,8 @@ phutil_register_library_map(array(
|
||||||
'ArcanistPhutilTestTerminatedException' => 'Exception',
|
'ArcanistPhutilTestTerminatedException' => 'Exception',
|
||||||
'ArcanistPhutilXHPASTLinter' => 'ArcanistBaseXHPASTLinter',
|
'ArcanistPhutilXHPASTLinter' => 'ArcanistBaseXHPASTLinter',
|
||||||
'ArcanistPhutilXHPASTLinterTestCase' => 'ArcanistArcanistLinterTestCase',
|
'ArcanistPhutilXHPASTLinterTestCase' => 'ArcanistArcanistLinterTestCase',
|
||||||
|
'ArcanistPuppetLintLinter' => 'ArcanistExternalLinter',
|
||||||
|
'ArcanistPuppetLintLinterTestCase' => 'ArcanistArcanistLinterTestCase',
|
||||||
'ArcanistPyFlakesLinter' => 'ArcanistExternalLinter',
|
'ArcanistPyFlakesLinter' => 'ArcanistExternalLinter',
|
||||||
'ArcanistPyFlakesLinterTestCase' => 'ArcanistArcanistLinterTestCase',
|
'ArcanistPyFlakesLinterTestCase' => 'ArcanistArcanistLinterTestCase',
|
||||||
'ArcanistPyLintLinter' => 'ArcanistLinter',
|
'ArcanistPyLintLinter' => 'ArcanistLinter',
|
||||||
|
|
92
src/lint/linter/ArcanistPuppetLintLinter.php
Normal file
92
src/lint/linter/ArcanistPuppetLintLinter.php
Normal file
|
@ -0,0 +1,92 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A linter for Puppet files.
|
||||||
|
*/
|
||||||
|
final class ArcanistPuppetLintLinter extends ArcanistExternalLinter {
|
||||||
|
|
||||||
|
public function getLinterName() {
|
||||||
|
return 'PUPPETLINT';
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getLinterConfigurationName() {
|
||||||
|
return 'puppet-lint';
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getDefaultBinary() {
|
||||||
|
return 'puppet-lint';
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getVersion() {
|
||||||
|
list($stdout) = execx('%C --version', $this->getExecutableCommand());
|
||||||
|
|
||||||
|
$matches = array();
|
||||||
|
$regex = '/^Puppet-lint (?P<version>\d+\.\d+\.\d+)$/';
|
||||||
|
if (preg_match($regex, $stdout, $matches)) {
|
||||||
|
return $matches['version'];
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getInstallInstructions() {
|
||||||
|
return pht('Install puppet-lint using `gem install puppet-lint`.');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function shouldExpectCommandErrors() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function supportsReadDataFromStdin() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function getMandatoryFlags() {
|
||||||
|
return array(sprintf('--log-format=%s', implode('|', array(
|
||||||
|
'%{linenumber}',
|
||||||
|
'%{column}',
|
||||||
|
'%{kind}',
|
||||||
|
'%{check}',
|
||||||
|
'%{message}'))));
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function parseLinterOutput($path, $err, $stdout, $stderr) {
|
||||||
|
$lines = phutil_split_lines($stdout, false);
|
||||||
|
|
||||||
|
$messages = array();
|
||||||
|
foreach ($lines as $line) {
|
||||||
|
$matches = explode('|', $line, 5);
|
||||||
|
|
||||||
|
if (count($matches) === 5) {
|
||||||
|
$message = new ArcanistLintMessage();
|
||||||
|
$message->setPath($path);
|
||||||
|
$message->setLine($matches[0]);
|
||||||
|
$message->setChar($matches[1]);
|
||||||
|
$message->setName(ucwords(str_replace('_', ' ', $matches[3])));
|
||||||
|
$message->setDescription(ucfirst($matches[4]));
|
||||||
|
|
||||||
|
switch ($matches[2]) {
|
||||||
|
case 'warning':
|
||||||
|
$message->setSeverity(ArcanistLintSeverity::SEVERITY_WARNING);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'error':
|
||||||
|
$message->setSeverity(ArcanistLintSeverity::SEVERITY_ERROR);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
$message->setSeverity(ArcanistLintSeverity::SEVERITY_ADVICE);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
$messages[] = $message;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($err && !$messages) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $messages;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,12 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
final class ArcanistPuppetLintLinterTestCase
|
||||||
|
extends ArcanistArcanistLinterTestCase {
|
||||||
|
|
||||||
|
public function testPuppetLintLinter() {
|
||||||
|
return $this->executeTestsInDirectory(
|
||||||
|
dirname(__FILE__).'/puppet-lint/',
|
||||||
|
new ArcanistPuppetLintLinter());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,7 @@
|
||||||
|
exec { 'test':
|
||||||
|
subscribe => File['/etc/test'],
|
||||||
|
refreshonly => true,
|
||||||
|
}
|
||||||
|
~~~~~~~~~~
|
||||||
|
error:2:1
|
||||||
|
error:3:1
|
|
@ -0,0 +1,6 @@
|
||||||
|
exec { 'test':
|
||||||
|
subscribe => File['/etc/test'],
|
||||||
|
refreshonly => true,
|
||||||
|
}
|
||||||
|
~~~~~~~~~~
|
||||||
|
warning:3:15
|
|
@ -0,0 +1,7 @@
|
||||||
|
user { 'dave':
|
||||||
|
ensure => present,
|
||||||
|
home => '/home/dave',
|
||||||
|
comment => "This is a double quoted string",
|
||||||
|
}
|
||||||
|
~~~~~~~~~~
|
||||||
|
warning:4:14
|
|
@ -0,0 +1,6 @@
|
||||||
|
service { 'anacron':
|
||||||
|
ensure => 'absent',
|
||||||
|
ensure => 'stopped',
|
||||||
|
}
|
||||||
|
~~~~~~~~~~
|
||||||
|
error:3:3
|
|
@ -0,0 +1,5 @@
|
||||||
|
file { '/var/log/syslog':
|
||||||
|
ensure => '/var/log/messages',
|
||||||
|
}
|
||||||
|
~~~~~~~~~~
|
||||||
|
warning:2:13
|
|
@ -0,0 +1,6 @@
|
||||||
|
file { '/var/log/syslog':
|
||||||
|
ensure => present,
|
||||||
|
mode => '644',
|
||||||
|
}
|
||||||
|
~~~~~~~~~~
|
||||||
|
warning:3:13
|
|
@ -0,0 +1,7 @@
|
||||||
|
exec { 'test':
|
||||||
|
subscribe => File['/etc/test'],
|
||||||
|
refreshonly => true,
|
||||||
|
}
|
||||||
|
~~~~~~~~~~
|
||||||
|
error:2:1
|
||||||
|
error:3:1
|
|
@ -0,0 +1,3 @@
|
||||||
|
$foo-bar123
|
||||||
|
~~~~~~~~~~
|
||||||
|
warning:1:1
|
|
@ -0,0 +1,6 @@
|
||||||
|
service { 'anacron':
|
||||||
|
ensure => 'stopped',
|
||||||
|
enable => 'true',
|
||||||
|
}
|
||||||
|
~~~~~~~~~~
|
||||||
|
warning:3:13
|
|
@ -0,0 +1,3 @@
|
||||||
|
Service['httpd'] <- Package['httpd']
|
||||||
|
~~~~~~~~~~
|
||||||
|
warning:1:18
|
19
src/lint/linter/__tests__/puppet-lint/site.lint-test
Normal file
19
src/lint/linter/__tests__/puppet-lint/site.lint-test
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
import 'classes/*'
|
||||||
|
import 'nodes.pp'
|
||||||
|
|
||||||
|
Exec['apt-get-update'] -> Package <| |>
|
||||||
|
|
||||||
|
Exec {
|
||||||
|
path => '/usr/bin:/usr/sbin:/bin',
|
||||||
|
}
|
||||||
|
|
||||||
|
exec { 'apt-get-update':
|
||||||
|
command => '/usr/bin/apt-get update',
|
||||||
|
require => File['/etc/apt/apt.conf.d/01proxy'],
|
||||||
|
}
|
||||||
|
|
||||||
|
file { '/etc/apt/apt.conf.d/01proxy':
|
||||||
|
ensure => 'file',
|
||||||
|
source => '/tmp/vagrant-puppet/manifests/files/apt-conf',
|
||||||
|
}
|
||||||
|
~~~~~~~~~~
|
|
@ -0,0 +1,3 @@
|
||||||
|
// This is a comment
|
||||||
|
~~~~~~~~~~
|
||||||
|
warning:1:1
|
|
@ -0,0 +1,3 @@
|
||||||
|
/* This is a comment */
|
||||||
|
~~~~~~~~~~
|
||||||
|
warning:1:1
|
|
@ -0,0 +1,6 @@
|
||||||
|
file { '/var/log/syslog':
|
||||||
|
ensure => present,
|
||||||
|
mode => 0644,
|
||||||
|
}
|
||||||
|
~~~~~~~~~~
|
||||||
|
warning:3:13
|
Loading…
Reference in a new issue