Skip to content

Commit

Permalink
Merge pull request #98 from mnapoli/code-quality-tools
Browse files Browse the repository at this point in the history
Setup stricter code quality tools
  • Loading branch information
mnapoli authored Nov 25, 2018
2 parents 1843e13 + 3e1fb78 commit 8558255
Show file tree
Hide file tree
Showing 37 changed files with 437 additions and 307 deletions.
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,5 @@
/tests/Bridge/Symfony/cache
/tests/Bridge/Symfony/logs
/.bref/
/.php_cs.cache
/.phpcs-cache
/composer.lock
17 changes: 0 additions & 17 deletions .php_cs

This file was deleted.

146 changes: 146 additions & 0 deletions .phpcs.xml.dist
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
<?xml version="1.0"?>
<ruleset>
<arg name="basepath" value="."/>
<arg name="extensions" value="php"/>
<arg name="parallel" value="80"/>
<arg name="cache" value=".phpcs-cache"/>
<arg name="colors"/>
<!-- Show sniff names -->
<arg value="s"/>

<file>src</file>
<file>tests</file>
<exclude-pattern>tests/Bridge/Symfony/cache</exclude-pattern>
<exclude-pattern>tests/Bridge/Symfony/logs</exclude-pattern>
<exclude-pattern>tests/Bridge/Laravel/bootstrap/cache</exclude-pattern>

<!-- Import the Doctrine coding standard -->
<rule ref="Doctrine"/>

<!-- Allow long lines -->
<rule ref="Generic.Files.LineLength.TooLong">
<severity>0</severity>
</rule>

<!-- Do not align assignments -->
<rule ref="Generic.Formatting.MultipleStatementAlignment">
<severity>0</severity>
</rule>

<!-- Require specific order of phpDoc annotations with empty newline between specific groups -->
<rule ref="SlevomatCodingStandard.Commenting.DocCommentSpacing">
<properties>
<property name="linesCountBeforeFirstContent" value="0"/>
<property name="linesCountAfterLastContent" value="0"/>
<property name="linesCountBetweenDescriptionAndAnnotations" value="1"/>
<property name="linesCountBetweenAnnotationsGroups" value="1"/>
<property name="annotationsGroups" type="array">
<element value="
@ORM\,
@ODM\,
"/>
<element value="
@param,
@return,
@throws,
"/>
<element value="
@internal,
@deprecated,
@link,
@see,
@uses,
"/>
</property>
</properties>
</rule>

<!-- Do not enforce usage of early exit -->
<rule ref="SlevomatCodingStandard.ControlStructures.EarlyExit">
<severity>0</severity>
</rule>

<!-- Require new instances without parentheses when not passing parameters -->
<rule ref="SlevomatCodingStandard.ControlStructures.NewWithParentheses">
<severity>0</severity>
</rule>
<rule ref="SlevomatCodingStandard.ControlStructures.NewWithoutParentheses"/>

<!-- Do not require closures not referencing $this be static -->
<rule ref="SlevomatCodingStandard.Functions.StaticClosure">
<severity>0</severity>
</rule>

<!-- Allow using some absolute class name references (except global ones) -->
<rule ref="SlevomatCodingStandard.Namespaces.ReferenceUsedNamesOnly">
<properties>
<property name="allowFallbackGlobalConstants" value="true"/>
<property name="allowFallbackGlobalFunctions" value="true"/>
<property name="allowFullyQualifiedGlobalClasses" value="true"/>
<property name="allowFullyQualifiedGlobalConstants" value="true"/>
<property name="allowFullyQualifiedGlobalFunctions" value="true"/>
<property name="allowFullyQualifiedNameForCollidingClasses" value="true"/>
<property name="allowFullyQualifiedNameForCollidingConstants" value="true"/>
<property name="allowFullyQualifiedNameForCollidingFunctions" value="true"/>
<property name="searchAnnotations" value="true"/>
</properties>
</rule>

<!-- Require presence of declare(strict_types=1) -->
<rule ref="SlevomatCodingStandard.TypeHints.DeclareStrictTypes">
<properties>
<!-- Inline with the `<?php` opening tag -->
<property name="newlinesCountBetweenOpenTagAndDeclare" value="0"/>
<property name="spacesCountAroundEqualsSign" value="0"/>
<property name="newlinesCountAfterDeclare" value="2"/>
</properties>
</rule>

<!-- Require no space before colon in return types -->
<rule ref="SlevomatCodingStandard.TypeHints.ReturnTypeHintSpacing">
<properties>
<property name="spacesCountBeforeColon" value="0"/>
</properties>
</rule>

<!-- Do not force arrays with 1 item to be inline -->
<rule ref="Squiz.Arrays.ArrayDeclaration.MultiLineNotAllowed">
<severity>0</severity>
</rule>

<!-- Do not forbid declaring functions -->
<rule ref="Squiz.Functions.GlobalFunction">
<severity>0</severity>
</rule>

<!-- Allow using variables in double quoted strings -->
<rule ref="Squiz.Strings.DoubleQuoteUsage.ContainsVar">
<severity>0</severity>
</rule>

<!-- More lax rules about `array` type-hints (no need to always detail what's in the array) -->
<rule ref="SlevomatCodingStandard.TypeHints.TypeHintDeclaration.MissingTraversablePropertyTypeHintSpecification">
<severity>0</severity>
</rule>
<rule ref="SlevomatCodingStandard.TypeHints.TypeHintDeclaration.MissingTraversableParameterTypeHintSpecification">
<severity>0</severity>
</rule>
<rule ref="SlevomatCodingStandard.TypeHints.TypeHintDeclaration.MissingTraversableReturnTypeHintSpecification">
<severity>0</severity>
</rule>

<!-- ########################-->
<!-- TESTS -->
<!-- ########################-->

<!-- Allow underscores and non-breakable spaces to be used in tests for readability -->
<rule ref="PSR1.Methods.CamelCapsMethodName.NotCamelCaps">
<exclude-pattern type="relative">tests/*</exclude-pattern>
</rule>

<!-- Do not enforce return types in tests else it crowds the test methods with `: void` -->
<rule ref="SlevomatCodingStandard.TypeHints.TypeHintDeclaration.MissingReturnTypeHint">
<exclude-pattern type="relative">tests/*</exclude-pattern>
</rule>

</ruleset>
5 changes: 5 additions & 0 deletions .prettyci.composer.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"require": {
"doctrine/coding-standard": "^5.0"
}
}
4 changes: 2 additions & 2 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ notifications:
on_success: never

php:
- 7.1
- 7.2
- nightly

Expand All @@ -14,7 +13,7 @@ matrix:
allow_failures:
- php: nightly
include:
- php: 7.1
- php: 7.2
env: dependencies=lowest

cache:
Expand All @@ -27,3 +26,4 @@ before_script:

script:
- vendor/bin/phpunit
- vendor/bin/phpstan analyse
2 changes: 0 additions & 2 deletions bref
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,6 @@ use Symfony\Component\Console\Style\SymfonyStyle;
use Symfony\Component\Filesystem\Filesystem;
use Symfony\Component\Process\Process;

const DEFAULT_PHP_TARGET_VERSION = '7.2.5';

if (file_exists(__DIR__ . '/vendor/autoload.php')) {
require_once __DIR__ . '/vendor/autoload.php';
} elseif (file_exists(__DIR__ . '/../autoload.php')) {
Expand Down
15 changes: 11 additions & 4 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,16 @@
"src/functions.php"
]
},
"autoload-dev": {
"psr-4": {
"Bref\\Test\\": "tests"
}
},
"bin": [
"bref"
],
"require": {
"php": "^7.1.0",
"php": "^7.2.0",
"ext-json": "*",
"mnapoli/silly": "^1.7",
"symfony/filesystem": "^3.1|^4.0",
Expand All @@ -28,16 +33,18 @@
"zendframework/zend-diactoros": "^1.6",
"jolicode/jolinotif": "^2.0",
"matomo/ini": "^2.0",
"riverline/multipart-parser": "^1.2"
"riverline/multipart-parser": "^1.2",
"innmind/json": "^1.0"
},
"require-dev": {
"phpunit/phpunit": "^6.5",
"symfony/symfony": "^3.4|^4.0",
"symfony/debug": "^3.1|^4.0",
"slim/slim": "^3.9",
"friendsofphp/php-cs-fixer": "^2.4",
"illuminate/contracts": "^5.0",
"illuminate/http": "^5.0",
"laravel/framework": "^5.6"
"laravel/framework": "^5.6",
"doctrine/coding-standard": "^5.0",
"phpstan/phpstan": "^0.10.5"
}
}
10 changes: 10 additions & 0 deletions phpstan.neon.dist
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
parameters:
level: 5
paths:
- src
- tests
excludes_analyse:
- %rootDir%/../../../tests/Bridge/Laravel/bootstrap/cache/*
- %rootDir%/../../../tests/Bridge/Laravel/storage/*
- %rootDir%/../../../tests/Bridge/Symfony/cache/*
- %rootDir%/../../../tests/Bridge/Symfony/logs/*
47 changes: 19 additions & 28 deletions src/Application.php
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
<?php
declare(strict_types=1);
<?php declare(strict_types=1);

namespace Bref;

Expand All @@ -8,16 +7,14 @@
use Bref\Cli\WelcomeApplication;
use Bref\Http\LambdaResponse;
use Bref\Http\WelcomeHandler;
use Innmind\Json\Json;
use Psr\Http\Server\RequestHandlerInterface;
use Symfony\Component\Console\Input\StringInput;
use Symfony\Component\Console\Output\BufferedOutput;
use Symfony\Component\Filesystem\Filesystem;
use Zend\Diactoros\Response\SapiEmitter;
use Zend\Diactoros\ServerRequestFactory;

/**
* @author Matthieu Napoli <[email protected]>
*/
class Application
{
/**
Expand All @@ -27,19 +24,13 @@ class Application
private const BREF_DIRECTORY = '/tmp/.bref';
private const OUTPUT_FILE_NAME = self::BREF_DIRECTORY . '/output.json';

/**
* @var callable
*/
/** @var callable */
private $simpleHandler;

/**
* @var RequestHandlerInterface
*/
/** @var RequestHandlerInterface */
private $httpHandler;

/**
* @var \Symfony\Component\Console\Application
*/
/** @var \Symfony\Component\Console\Application */
private $cliHandler;

public function __construct()
Expand All @@ -58,7 +49,7 @@ public function __construct()
*
* @param callable $handler This callable takes a $event parameter (array) and must return anything serializable to JSON.
*/
public function simpleHandler(callable $handler) : void
public function simpleHandler(callable $handler): void
{
$this->simpleHandler = $handler;
}
Expand All @@ -69,7 +60,7 @@ public function simpleHandler(callable $handler) : void
* The handler must be a PSR-15 request handler, it can be any
* framework that is compatible with PSR-15 for example.
*/
public function httpHandler(RequestHandlerInterface $handler) : void
public function httpHandler(RequestHandlerInterface $handler): void
{
$this->httpHandler = $handler;
}
Expand All @@ -84,7 +75,7 @@ public function httpHandler(RequestHandlerInterface $handler) : void
* That can also be a Silly (https://github.com/mnapoli/silly) application
* since Silly is based on the Symfony Console.
*/
public function cliHandler(\Symfony\Component\Console\Application $console) : void
public function cliHandler(\Symfony\Component\Console\Application $console): void
{
// Necessary to avoid any `exit()` call :)
$console->setAutoExit(false);
Expand All @@ -103,10 +94,10 @@ public function cliHandler(\Symfony\Component\Console\Application $console) : vo
* The application will detect how the lambda is being invoked (HTTP,
* CLI, direct invocation, etc.) and execute the proper handler.
*/
public function run() : void
public function run(): void
{
if (!$this->isRunningInAwsLambda()) {
if (php_sapi_name() == "cli") {
if (! $this->isRunningInAwsLambda()) {
if (PHP_SAPI === 'cli') {
$this->cliHandler->setAutoExit(true);
$this->cliHandler->run();
} else {
Expand All @@ -132,40 +123,40 @@ public function run() : void
$cliInput = new StringInput($event['cli']);
$cliOutput = new BufferedOutput;
$exitCode = $this->cliHandler->run($cliInput, $cliOutput);
$output = json_encode([
$output = Json::encode([
'exitCode' => $exitCode,
'output' => $cliOutput->fetch(),
]);
} else {
// Simple invocation
$output = ($this->simpleHandler)($event);
$output = json_encode($output);
$output = Json::encode($output);
}

$this->writeLambdaOutput($output);
}

private function ensureTempDirectoryExists() : void
private function ensureTempDirectoryExists(): void
{
$filesystem = new Filesystem;
if (! $filesystem->exists(self::BREF_DIRECTORY)) {
$filesystem->mkdir(self::BREF_DIRECTORY);
}
}

private function readLambdaEvent() : array
private function readLambdaEvent(): array
{
// The lambda event is passed as JSON by `handler.js` as a CLI argument
global $argv;
return json_decode($argv[1], true) ?: [];
$argv = $_SERVER['argv'];
return Json::decode($argv[1]) ?: [];
}

private function writeLambdaOutput(string $json) : void
private function writeLambdaOutput(string $json): void
{
file_put_contents(self::OUTPUT_FILE_NAME, $json);
}

private function isRunningInAwsLambda() : bool
private function isRunningInAwsLambda(): bool
{
// LAMBDA_TASK_ROOT is a constant defined by AWS
// TODO: use a solution that would work with other hosts?
Expand Down
Loading

0 comments on commit 8558255

Please sign in to comment.