Added script for checking formatting and ordering. #238 https://github.com/ziadoz/awesome-php/issues/238

This commit is contained in:
Julius Beckmann 2014-09-30 01:00:12 +02:00
parent 2510ee2f4f
commit c97b9a7e60
5 changed files with 213 additions and 3 deletions

12
.travis.yml Normal file
View File

@ -0,0 +1,12 @@
language: php
php:
- 5.6
before_script:
- cd test
- composer self-update || true
- composer install --no-interaction --no-progress
script:
- php check.php

View File

@ -509,7 +509,7 @@ A curated list of amazingly awesome PHP libraries, resources and shiny things.
* [Ruler](https://github.com/bobthecow/Ruler) - A simple stateless production rules engine.
* [LiteCQRS](https://github.com/beberlei/litecqrs-php) - A CQRS (Command Query Responsibility Separation) library.
* [Sslurp](https://github.com/EvanDotPro/Sslurp) - A library that makes dealing with SSL suck less.
* [PHP Option](https://github.com/schmittjoh/php-option) An option type library.
* [PHP Option](https://github.com/schmittjoh/php-option) - An option type library.
* [Metrics](https://github.com/beberlei/metrics) - A simple metrics API library.
* [Sabre VObject](https://github.com/evert/sabre-vobject) - A library for parsing VCard and iCalendar objects.
* [Annotations](https://github.com/doctrine/annotations) - An annotations library (part of Doctrine).
@ -559,7 +559,7 @@ A curated list of amazingly awesome PHP libraries, resources and shiny things.
* [Ansible](http://www.ansibleworks.com/) - A radically simple orchestration framework.
* [Puppet](http://puppetlabs.com/) - A server automation framework and application.
* [Chef](https://github.com/opscode/chef) - A systems integration framework.
* [SaltStack](http://saltstack.com/community.html) - An infrastructure management tool.
* [SaltStack](http://www.saltstack.com/) - An infrastructure management tool.
* [PHP Brew](https://github.com/c9s/phpbrew) - A PHP version manager and installer.
* [PHP Env](https://github.com/CHH/phpenv) - Another PHP version manager.
* [PHP Switch](https://github.com/jubianchi/phpswitch) - Another version manager.
@ -630,7 +630,6 @@ Various resources, such as books, websites and articles, for improving your PHP
* [Preventing CSRF Attacks](http://blog.ircmaxell.com/2013/02/preventing-csrf-attacks.html) - An article on preventing CSRF attacks.
* [Don't Worry About BREACH](http://blog.ircmaxell.com/2013/08/dont-worry-about-breach.html) - An article about the BREACH hack and CSRF tokens.
* [On PHP 5.3, Lamda Functions and Closures](http://fabien.potencier.org/article/17/on-php-5-3-lambda-functions-and-closures) - An article about lambda functions and closures.
* [Use Env](http://seancoates.com/blogs/use-env) - An article about using the unix environment helper.
* [Composer Primer](http://daylerees.com/composer-primer) - A Composer primer.
* [Composer Versioning](https://igor.io/2013/01/07/composer-versioning.html) - An article about Composer versioning.
* [Composer Stability Flags](https://igor.io/2013/02/07/composer-stability-flags.html) - An article about Composer stability flags.

2
test/.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
vendor/
composer.lock

188
test/check.php Normal file
View File

@ -0,0 +1,188 @@
<?php
require_once(__DIR__ . '/vendor/autoload.php');
// Overwriting the Markdown parser so we get the Blocks instead of HTML.
class MyMarkdown extends \cebe\markdown\GithubMarkdown
{
protected function parseBlocks($lines)
{
$blocks = [];
// convert lines to blocks
for ($i = 0, $count = count($lines); $i < $count; $i++) {
if (!empty($lines[$i]) && rtrim($lines[$i]) !== '') { // skip empty lines
// identify a blocks beginning
$blockType = $this->identifyLine($lines, $i);
// call consume method for the detected block type to consume further lines
list($block, $i) = $this->{'consume' . $blockType}($lines, $i);
if ($block !== false) {
$blocks[] = $block;
}
}
}
return $blocks;
}
}
// Loading Markdown and parsing blocks from it.
$text = file_get_contents(__DIR__ . '/../README.md');
$markdown = new MyMarkdown();
$blocks = $markdown->parse($text);
// Run checks.
checkBlocks($blocks);
checkLinks($text);
// Some List items have a special formatting.
// List items that are stripos'ing one of these strings will be ignored.
function getIgnoredListItems()
{
return array(
'blog.ircmaxell.com/2013/09/beyond-design-patterns',
'blog.ircmaxell.com/2012/03/phps-source-code-for-php-developers',
'php.net/manual/en/features.gc.refcounting-basics',
);
}
//--- Functions
function checkLinks($text)
{
// Regex from: https://mathiasbynens.be/demo/url-regex
preg_match_all('_\((?:(?:https?|ftp)://)(?:\S+(?::\S*)?@)?(?:(?!10(?:\.\d{1,3}){3})(?!127(?:\.\d{1,3}){3})(?!169\.254(?:\.\d{1,3}){2})(?!192\.168(?:\.\d{1,3}){2})(?!172\.(?:1[6-9]|2\d|3[0-1])(?:\.\d{1,3}){2})(?:[1-9]\d?|1\d\d|2[01]\d|22[0-3])(?:\.(?:1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.(?:[1-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(?:(?:[a-z\x{00a1}-\x{ffff}0-9]+-?)*[a-z\x{00a1}-\x{ffff}0-9]+)(?:\.(?:[a-z\x{00a1}-\x{ffff}0-9]+-?)*[a-z\x{00a1}-\x{ffff}0-9]+)*(?:\.(?:[a-z\x{00a1}-\x{ffff}]{2,})))(?::\d{2,5})?(?:/[^\s\)]*)?\)_iuS', $text, $links);
$links = array_map(function ($link) {
return trim($link, '()');
}, array_unique($links[0]));
$client = new GuzzleHttp\Client();
// Ignoring some domains.
$links = array_filter($links, function($link) {
$ignoredDomains = array(
'www.owasp.org', // Their server somehow fails responding to curl.
);
foreach($ignoredDomains as $ignoredDomain) {
if(false !== stripos($link, $ignoredDomain)) {
return false;
}
}
return true;
});
// Creating guzzle requests.
$requests = array_map(function ($link) use ($client) {
return $client->createRequest('GET', $link, array('verify' => false, 'timeout' => 99999));
}, $links);
// Start all these requests partially parallel.
$responses = GuzzleHttp\batch(
$client,
$requests,
array(
'parallel' => 5,
'complete' => function (\GuzzleHttp\Event\CompleteEvent $event) {
echo 'Completed request to ' . $event->getRequest()->getUrl() . "\n";
},
'error' => function (\GuzzleHttp\Event\ErrorEvent $event) {
echo 'Request failed: ' . $event->getRequest()->getUrl() . "\n";
$event->throwImmediately(true);
}
)
);
// Check for exceptions.
foreach($responses as $response) {
if($response instanceof \Exception) {
throw $response;
}
}
}
function checkBlocks(array $blocks)
{
// Check List formatting
$lists = onlyLists($blocks);
$tableOfContent = array_shift($lists);
checkLists($lists);
// Check table of content ordering.
$tableOfContent = $tableOfContent['items'];
$indentedHeadlines = indentHeadlines(onlyHeadlines($blocks));
// Checking array to be euqal.
if (var_export($tableOfContent, true) != var_export($indentedHeadlines, true)) {
throw new \Exception("Table of contents and headlines in document are _not_ in the same order.");
}
}
function indentHeadlines(array $headlines)
{
$indented = array();
$index = 0;
foreach ($headlines as $headline) {
$content = $headline['content'];
$contentFormatted = '[' . $content . '](#' . str_ireplace(' ', '-', strtolower($content)) . ')';
if (1 == $headline['level']) {
$index++;
$indented[$index][] = $contentFormatted;
} else {
$indented[$index][] = '- ' . $contentFormatted;
}
}
return $indented;
}
function checkLists(array $lists)
{
array_map(function ($list) {
if ('list' == $list['type']) {
checkListItems($list['items']);
}
}, $lists);
}
function checkListItems(array $list)
{
array_map(function ($items) {
foreach ($items as $item) {
validateListItem($item);
}
}, $list);
}
function validateListItem($item)
{
$item = trim($item);
foreach (getIgnoredListItems() as $ignoredString) {
if (false !== stripos($item, $ignoredString)) {
// ignore this list item because it contains a special formatting or such.
return;
}
}
if (!preg_match('@^\[(.+)\]\((.+)\) - (.+).$@i', $item, $matches)) {
throw new \Exception("Invalid ListItem: " . $item);
}
//$name = $matches[1];
//$url = $matches[2];
//$description = $matches[3];
}
function onlyHeadlines(array $blocks)
{
return array_values(array_filter($blocks, function ($block) {
return 'headline' == $block['type'];
}));
}
function onlyLists(array $blocks)
{
return array_values(array_filter($blocks, function ($block) {
return 'list' == $block['type'];
}));
}

9
test/composer.json Normal file
View File

@ -0,0 +1,9 @@
{
"name": "ziadoz/awesome-php",
"description": "Just a test script for formatting and links.",
"require": {
"cebe/markdown": "~0.9",
"guzzlehttp/guzzle": "~4.0"
},
"license": "MIT"
}