forked from php-pds/skeleton
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
2 changed files
with
360 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,291 @@ | ||
#!/usr/bin/env php | ||
|
||
<?php | ||
|
||
if (!defined('ENV') || ENV != 'test') { | ||
$lines = scandir(__DIR__ . "/../../../../"); | ||
foreach ($lines as $i => $line) { | ||
if (is_dir($line)) { | ||
$lines[$i] .= "/"; | ||
} | ||
} | ||
$validator = new ComplianceValidator(); | ||
$results = $validator->validate($lines); | ||
$validator->outputResults($results); | ||
} | ||
|
||
class ComplianceValidator | ||
{ | ||
const STATE_OPTIONAL_NOT_PRESENT = 1; | ||
const STATE_CORRECT_PRESENT = 2; | ||
const STATE_REQUIRED_NOT_PRESENT = 3; | ||
const STATE_INCORRECT_PRESENT = 4; | ||
|
||
public function validate($lines) | ||
{ | ||
$complianceTests = [ | ||
"Command-line executables" => $this->checkBin($lines), | ||
"Configuration files" => $this->checkConfig($lines), | ||
"Documentation files" => $this->checkDocs($lines), | ||
"Web server files" => $this->checkPublic($lines), | ||
"Other resource files" => $this->checkResources($lines), | ||
"PHP source code" => $this->checkSrc($lines), | ||
"Test code" => $this->checkTests($lines), | ||
"Package managers" => $this->checkVendor($lines), | ||
"Log of changes between releases" => $this->checkChangelog($lines), | ||
"Guidelines for contributors" => $this->checkContributing($lines), | ||
"Licensing information" => $this->checkLicense($lines), | ||
"Information about the package itself" => $this->checkReadme($lines), | ||
]; | ||
|
||
$results = []; | ||
foreach ($complianceTests as $label => $complianceResult) { | ||
$state = $complianceResult[0]; | ||
$expected = $complianceResult[1]; | ||
$actual = $complianceResult[2]; | ||
$results[$expected] = [ | ||
'label' => $label, | ||
'state' => $state, | ||
'expected' => $expected, | ||
'actual' => $actual, | ||
]; | ||
} | ||
return $results; | ||
} | ||
|
||
public function outputResults($results) | ||
{ | ||
foreach ($results as $result) { | ||
$this->outputResultLine($result['label'], $result['state'], $result['expected'], $result['actual']); | ||
} | ||
} | ||
|
||
protected function outputResultLine($label, $complianceState, $expected, $actual) | ||
{ | ||
$messages = [ | ||
self::STATE_OPTIONAL_NOT_PRESENT => "Optional {$expected} not present", | ||
self::STATE_CORRECT_PRESENT => "Correct {$actual} present", | ||
self::STATE_INCORRECT_PRESENT => "Incorrect {$actual} present", | ||
self::STATE_REQUIRED_NOT_PRESENT => "Required {$expected} not present", | ||
]; | ||
echo $this->colorConsoleText("- " . $label . ": " . $messages[$complianceState], $complianceState) . PHP_EOL; | ||
} | ||
|
||
protected function colorConsoleText($text, $complianceState) | ||
{ | ||
$colors = [ | ||
self::STATE_OPTIONAL_NOT_PRESENT => "\033[43;30m", | ||
self::STATE_CORRECT_PRESENT => "\033[42;30m", | ||
self::STATE_INCORRECT_PRESENT => "\033[41m", | ||
self::STATE_REQUIRED_NOT_PRESENT => "\033[41m", | ||
]; | ||
if (!array_key_exists($complianceState, $colors)) { | ||
return $text; | ||
} | ||
return $colors[$complianceState] . " " . $text . " \033[0m"; | ||
} | ||
|
||
protected function checkDir($lines, $pass, array $fail) | ||
{ | ||
foreach ($lines as $line) { | ||
$line = trim($line); | ||
if ($line == $pass) { | ||
return [self::STATE_CORRECT_PRESENT, $pass, $line]; | ||
} | ||
if (in_array($line, $fail)) { | ||
return [self::STATE_INCORRECT_PRESENT, $pass, $line]; | ||
} | ||
} | ||
return [self::STATE_OPTIONAL_NOT_PRESENT, $pass, null]; | ||
} | ||
|
||
protected function checkFile($lines, $pass, array $fail) | ||
{ | ||
foreach ($lines as $line) { | ||
$line = trim($line); | ||
if (preg_match("/^{$pass}(\.[a-z]+)?$/", $line)) { | ||
return [self::STATE_CORRECT_PRESENT, $pass, $line]; | ||
} | ||
foreach ($fail as $regex) { | ||
if (preg_match($regex, $line)) { | ||
return [self::STATE_INCORRECT_PRESENT, $pass, $line]; | ||
} | ||
} | ||
} | ||
return [self::STATE_OPTIONAL_NOT_PRESENT, $pass, null]; | ||
} | ||
|
||
protected function checkVendor($lines, $pass = 'vendor/') | ||
{ | ||
foreach ($lines as $line) { | ||
$line = trim($line); | ||
if ($line == $pass) { | ||
return [self::STATE_CORRECT_PRESENT, $pass, $line]; | ||
} | ||
} | ||
return [self::STATE_REQUIRED_NOT_PRESENT, $pass, null]; | ||
} | ||
|
||
protected function checkChangelog($lines) | ||
{ | ||
return $this->checkFile($lines, 'CHANGELOG', [ | ||
'/^.*CHANGLOG.*$/i', | ||
'/^.*CAHNGELOG.*$/i', | ||
'/^WHATSNEW(\.[a-z]+)?$/i', | ||
'/^RELEASE((_|-)?NOTES)?(\.[a-z]+)?$/i', | ||
'/^RELEASES(\.[a-z]+)?$/i', | ||
'/^CHANGES(\.[a-z]+)?$/i', | ||
'/^CHANGE(\.[a-z]+)?$/i', | ||
'/^HISTORY(\.[a-z]+)?$/i', | ||
]); | ||
} | ||
|
||
protected function checkContributing($lines) | ||
{ | ||
return $this->checkFile($lines, 'CONTRIBUTING', [ | ||
'/^DEVELOPMENT(\.[a-z]+)?$/i', | ||
'/^README\.CONTRIBUTING(\.[a-z]+)?$/i', | ||
'/^DEVELOPMENT_README(\.[a-z]+)?$/i', | ||
'/^CONTRIBUTE(\.[a-z]+)?$/i', | ||
'/^HACKING(\.[a-z]+)?$/i', | ||
]); | ||
} | ||
|
||
protected function checkLicense($lines) | ||
{ | ||
return $this->checkFile($lines, 'LICENSE', [ | ||
'/^.*EULA.*$/i', | ||
'/^.*(GPL|BSD).*$/i', | ||
'/^([A-Z-]+)?LI(N)?(S|C)(E|A)N(S|C)(E|A)(_[A-Z_]+)?(\.[a-z]+)?$/i', | ||
'/^COPY(I)?NG(\.[a-z]+)?$/i', | ||
'/^COPYRIGHT(\.[a-z]+)?$/i', | ||
]); | ||
} | ||
|
||
protected function checkReadme($lines) | ||
{ | ||
return $this->checkFile($lines, 'README', [ | ||
'/^USAGE(\.[a-z]+)?$/i', | ||
'/^SUMMARY(\.[a-z]+)?$/i', | ||
'/^DESCRIPTION(\.[a-z]+)?$/i', | ||
'/^IMPORTANT(\.[a-z]+)?$/i', | ||
'/^NOTICE(\.[a-z]+)?$/i', | ||
'/^GETTING(_|-)STARTED(\.[a-z]+)?$/i', | ||
]); | ||
} | ||
|
||
protected function checkBin($lines) | ||
{ | ||
return $this->checkDir($lines, 'bin/', [ | ||
'cli/', | ||
'scripts/', | ||
'console/', | ||
'shell/', | ||
'script/', | ||
]); | ||
} | ||
|
||
protected function checkConfig($lines) | ||
{ | ||
return $this->checkDir($lines, 'config/', [ | ||
'etc/', | ||
'settings/', | ||
'configuration/', | ||
'configs/', | ||
'_config/', | ||
'conf/', | ||
]); | ||
} | ||
|
||
protected function checkDocs($lines) | ||
{ | ||
return $this->checkDir($lines, 'docs/', [ | ||
'manual/', | ||
'documentation/', | ||
'usage/', | ||
'doc/', | ||
'guide/', | ||
'phpdoc/', | ||
]); | ||
} | ||
|
||
protected function checkPublic($lines) | ||
{ | ||
return $this->checkDir($lines, 'public/', [ | ||
'assets/', | ||
'static/', | ||
'html/', | ||
'httpdocs/', | ||
'media/', | ||
'docroot/', | ||
'css/', | ||
'fonts/', | ||
'styles/', | ||
'style/', | ||
'js/', | ||
'javascript/', | ||
'images/', | ||
'site/', | ||
'mysite/', | ||
'img/', | ||
'web/', | ||
'pub/', | ||
'webroot/', | ||
'www/', | ||
'htdocs/', | ||
'asset/', | ||
'public_html/', | ||
'publish/', | ||
'pages/', | ||
]); | ||
} | ||
|
||
protected function checkSrc($lines) | ||
{ | ||
return $this->checkDir($lines, 'src/', [ | ||
'exception/', | ||
'exceptions/', | ||
'src-files/', | ||
'traits/', | ||
'interfaces/', | ||
'common/', | ||
'sources/', | ||
'php/', | ||
'inc/', | ||
'libraries/', | ||
'autoloads/', | ||
'autoload/', | ||
'source/', | ||
'includes/', | ||
'include/', | ||
'lib/', | ||
'libs/', | ||
'library/', | ||
'code/', | ||
'classes/', | ||
'func/', | ||
]); | ||
} | ||
|
||
protected function checkTests($lines) | ||
{ | ||
return $this->checkDir($lines, 'tests/', [ | ||
'test/', | ||
'unit-tests/', | ||
'phpunit/', | ||
'testing/', | ||
]); | ||
} | ||
|
||
protected function checkResources($lines) | ||
{ | ||
return $this->checkDir($lines, 'resources/', [ | ||
'Resources/', | ||
'res/', | ||
'resource/', | ||
'Resource/', | ||
'ressources/', | ||
'Ressources/', | ||
]); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
<?php | ||
|
||
define('ENV', 'test'); | ||
require __DIR__ . "/../bin/validate"; | ||
|
||
$tester = new ComplianceValidatorTest(); | ||
// Test all 4 possible states. | ||
$tester->testValidate_WithIncorrectBin_ReturnsIncorrectBin(); | ||
$tester->testValidate_WithoutVendor_ReturnsMissingVendor(); | ||
|
||
echo "Errors: {$tester->numErrors}" . PHP_EOL; | ||
|
||
class ComplianceValidatorTest | ||
{ | ||
public $numErrors = 0; | ||
|
||
public function testValidate_WithIncorrectBin_ReturnsIncorrectBin() | ||
{ | ||
$paths = [ | ||
'cli/', | ||
'vendor/', | ||
]; | ||
|
||
$validator = new ComplianceValidator(); | ||
$results = $validator->validate($paths); | ||
|
||
foreach ($results as $expected => $result) { | ||
if ($expected == "bin/") { | ||
if ($result['state'] != ComplianceValidator::STATE_INCORRECT_PRESENT) { | ||
$this->numErrors++; | ||
echo __FUNCTION__ . ": Expected state of {$result['expected']} to be STATE_INCORRECT_PRESENT" . PHP_EOL; | ||
} | ||
continue; | ||
} | ||
if ($expected == "vendor/") { | ||
if ($result['state'] != ComplianceValidator::STATE_CORRECT_PRESENT) { | ||
$this->numErrors++; | ||
echo __FUNCTION__ . ": Expected state of {$result['expected']} to be STATE_CORRECT_PRESENT" . PHP_EOL; | ||
} | ||
continue; | ||
} | ||
if ($result['state'] != ComplianceValidator::STATE_OPTIONAL_NOT_PRESENT) { | ||
$this->numErrors++; | ||
echo __FUNCTION__ . ": Expected state of {$result['expected']} to be STATE_OPTIONAL_NOT_PRESENT" . PHP_EOL; | ||
continue; | ||
} | ||
} | ||
} | ||
|
||
public function testValidate_WithoutVendor_ReturnsMissingVendor() | ||
{ | ||
$paths = [ | ||
'bin/', | ||
]; | ||
|
||
$validator = new ComplianceValidator(); | ||
$results = $validator->validate($paths); | ||
|
||
foreach ($results as $expected => $result) { | ||
if ($expected == "vendor/") { | ||
if ($result['state'] != ComplianceValidator::STATE_REQUIRED_NOT_PRESENT) { | ||
$this->numErrors++; | ||
echo __FUNCTION__ . ": Expected state of {$result['expected']} to be STATE_REQUIRED_NOT_PRESENT" . PHP_EOL; | ||
} | ||
continue; | ||
} | ||
} | ||
} | ||
} |