Skip to content

Commit

Permalink
[FEATURE] Symfony console application (#39)
Browse files Browse the repository at this point in the history
  • Loading branch information
gilbertsoft authored Aug 13, 2022
1 parent ffbc6ec commit 77f8ec8
Show file tree
Hide file tree
Showing 37 changed files with 2,543 additions and 142 deletions.
98 changes: 85 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,9 @@ working on your TYPO3 project.

## Installation

As this is a composer package, execute `composer req --dev typo3/coding-standards`
in your composer project.
Since this is a Composer package, run `composer require --dev typo3/coding-standards`
in your Composer project, which of course includes TYPO3 project or extension or
any other Composer project.

## What's in the package?

Expand All @@ -27,37 +28,47 @@ certain rules to other projects as well. TYPO3 is more than just TYPO3 Core!

### PHP-CS-Fixer rules

Making sure your PHP files apply to the same rules.
Ensures that your PHP files are subject to the same rules.

### .editorconfig

If you work on a team, and you use different IDE settings, `.editorconfig`
helps you to have the same settings across all editors. It does not matter if
it is VS-Code, vim or PhpStorm.
it is VS-Code, vim or PhpStorm, almost every editor supports the `.editorconfig`
nowadays.

### Setting up the TYPO3 rulesets as boilerplate
### Setting up the TYPO3 rule sets as boilerplate

Our coding standards file can set this up for you. Run

```bash
composer exec typo3-coding-standards project
composer exec typo3-coding-standards setup
```

or
or via the shortcut, which of course works for every command:

```bash
composer exec t3-cs s
```

The type `project` or `extension` is automatically detected. If the detection
does not work for you (please also tell us about your case at
<https://github.com/TYPO3/coding-standards/issues>), you can specify the
desired type as parameter like this:

```bash
composer exec typo3-coding-standards extension
composer exec typo3-coding-standards setup project
```

or if you want to update the rules, use the `-f` option
or

```bash
composer exec -- typo3-coding-standards extension -f
composer exec typo3-coding-standards setup extension
```

Have a look at the newly created files in your root folder:

* .php-cs-fixer.php
* .php-cs-fixer.dist.php
* .editorconfig

For projects, the folder `src` is configured by default, but you can
Expand All @@ -70,6 +81,67 @@ configurations just like with PHP-CS-Fixer.
You can decide to commit them to your Git repository, which is the recommended
way.

### Updating the TYPO3 rule sets

To update the rule sets, run `composer update typo3/coding-standards`. An updated
PHP-CS-Fixer rule set is applied immediately, but changes to the `.editorconfig`
file must be applied manually by running `composer exec typo3-coding-standards update`.

This will overwrite your changes in the `.editorconfig` and reset it to the
TYPO3 default values. Please make sure that your file has been properly
committed to your repository before proceeding with the update.

You can also reset all files to the TYPO3 defaults by providing the `--force`
option to the `setup` command:

```bash
composer exec -- typo3-coding-standards setup --force
```

Don't forget to provide the two dashes after `exec` if you use options.

### Advanced usage examples

Show a command specific help e.g. with `composer exec typo3-coding-standards help setup`.

It is possible to specify a destination folder for the files or to set up only
a part of the TYPO3 coding standards, here are some examples.

Setup `.editorconfig` only:

```bash
composer exec -- typo3-coding-standards setup --rule-set=editorconfig
```

Setup `.php-cs-fixer.dist.php` in the `Build` folder:

```bash
composer exec -- typo3-coding-standards setup --target-dir=Build --rule-set=php-cs-fixer
```

Symfony comes with a great shortcut support for all commands e.g. this is the
same like the last command above:

```bash
composer exec -- t3-cs s -d=Build -r=php-cs-fixer
```

Update the `.editorconfig`:

```bash
composer exec t3-cs u
```

Running the script directly not using Composer:

```bash
vendor/bin/typo3-coding-standards setup
```

Of course this assumes the binaries are installed by Composer at the default
location `vendor/bin`. That's why we recommend using `composer exec` in the
first place becaue Composer is aware of the correct location.

## Executing the PHP-CS-Fixer

Once you've followed the step above, running PHP CS Fixer works like this:
Expand All @@ -78,8 +150,8 @@ Once you've followed the step above, running PHP CS Fixer works like this:
composer exec php-cs-fixer
```

Leave a note on how you set it up on GitHub Actions or GitLab CI/CD so this
document can be even more helpful for everybody.
Have a look at our GitHub Actions [Continuous Integration workflow](https://github.com/TYPO3/coding-standards/blob/main/.github/workflows/continuous-integration.yml)
to get an idea on how to automate your testing workflows using this package.

## What's next?

Expand Down
14 changes: 11 additions & 3 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,15 @@
},
"require": {
"php": "^7.2 || ^8.0",
"friendsofphp/php-cs-fixer": "^3.0"
"ext-json": "*",
"friendsofphp/php-cs-fixer": "^3.0",
"symfony/console": "^4.4.30 || ^5.3.7 || ^6.0",
"symfony/filesystem": "^4.4 || ^5.0 || ^6.0"
},
"require-dev": {
"composer/package-versions-deprecated": "^1.11.99.4",
"ergebnis/composer-normalize": "*",
"keradus/cli-executor": "^1.5",
"maglnet/composer-require-checker": "*",
"nikic/php-parser": "^4.13.1",
"overtrue/phplint": "^3.0",
Expand All @@ -44,7 +48,8 @@
"phpstan/phpstan-strict-rules": "^1.0",
"phpstan/phpstan-symfony": "^1.0",
"phpunit/phpunit": "^8.5.24 || ^9.5.18",
"symfony/finder": ">=4.4.30"
"symfony/finder": ">=4.4",
"symfony/process": ">=4.4"
},
"autoload": {
"psr-4": {
Expand All @@ -56,7 +61,10 @@
"TYPO3\\CodingStandards\\Tests\\": "tests"
}
},
"bin": "typo3-coding-standards",
"bin": [
"t3-cs",
"typo3-coding-standards"
],
"config": {
"allow-plugins": {
"ergebnis/composer-normalize": true,
Expand Down
7 changes: 7 additions & 0 deletions phpstan.neon
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,10 @@ parameters:
- src
- tests
- typo3-coding-standards

excludePaths:
analyse:
- tests/Console/Style/SimpleStyle.php

stubFiles:
- stubs/Command.stub
8 changes: 8 additions & 0 deletions rector.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@
use Rector\Set\ValueObject\DowngradeLevelSetList;
use Rector\Set\ValueObject\LevelSetList;
use Rector\Set\ValueObject\SetList;
use Rector\Symfony\Set\SymfonyLevelSetList;
use Rector\Symfony\Set\SymfonySetList;

return static function (RectorConfig $rectorConfig): void {
$rectorConfig->paths([
Expand All @@ -29,6 +31,7 @@
]);

$rectorConfig->skip([
__DIR__ . '/tests/Console/Style/SimpleStyle.php',
__DIR__ . '/tests/Unit/Fixtures',

FinalizeClassesWithoutChildrenRector::class => [
Expand All @@ -50,6 +53,11 @@
SetList::TYPE_DECLARATION_STRICT,
SetList::EARLY_RETURN,

// Symfony rules
SymfonyLevelSetList::UP_TO_SYMFONY_44,
SymfonySetList::SYMFONY_STRICT,
SymfonySetList::SYMFONY_CODE_QUALITY,

// PHPUnit rules
PHPUnitLevelSetList::UP_TO_PHPUNIT_80,
PHPUnitSetList::PHPUNIT_CODE_QUALITY,
Expand Down
124 changes: 124 additions & 0 deletions src/Console/Application.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
<?php

declare(strict_types=1);

/*
* This file is part of the TYPO3 project.
*
* (c) 2019-2022 Benni Mack
* Simon Gilli
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*
* The TYPO3 project - inspiring people to share!
*/

namespace TYPO3\CodingStandards\Console;

use RuntimeException;
use Symfony\Component\Console\Application as BaseApplication;
use Symfony\Component\Console\Input\InputDefinition;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Filesystem\Filesystem;
use TYPO3\CodingStandards\Console\Command\SetupCommand;
use TYPO3\CodingStandards\Console\Command\SetupExtensionCommand;
use TYPO3\CodingStandards\Console\Command\SetupProjectCommand;
use TYPO3\CodingStandards\Console\Command\UpdateCommand;

/**
* @internal
*/
final class Application extends BaseApplication
{
/**
* @var string
*/
public const VERSION = '0.6.0-DEV';

/**
* getcwd() equivalent which always returns a string
*
* @throws RuntimeException
*/
private static function getCwd(bool $allowEmpty = false): string
{
$cwd = getcwd();

// @codeCoverageIgnoreStart
// fallback to realpath('') just in case this works but odds are it would break as well if we are in a case
// where getcwd fails
if ($cwd === false) {
$cwd = realpath('');
}

// crappy state, assume '' and hopefully relative paths allow things to continue
if ($cwd === false) {
if ($allowEmpty) {
return '';
}

throw new RuntimeException('Could not determine the current working directory');
}

// @codeCoverageIgnoreEnd

return $cwd;
}

public static function getProjectDir(): string
{
return self::getCwd(true);
}

/**
* @throws RuntimeException
*/
public static function getTargetDir(InputInterface $input): string
{
/** @var string|null $targetDir */
$targetDir = $input->getParameterOption(['--target-dir', '-d'], null, true);

if ($targetDir === null) {
$targetDir = self::getProjectDir();
}

if (!(new Filesystem())->isAbsolutePath($targetDir)) {
$targetDir = self::getProjectDir() . '/' . $targetDir;
}

if (!is_dir($targetDir)) {
throw new RuntimeException(\sprintf('Invalid target directory specified, %s does not exist.', $targetDir));
}

return $targetDir;
}

public function __construct()
{
parent::__construct('TYPO3 Coding Standards', self::VERSION);

// in alphabetical order
$this->add(new SetupCommand());
$this->add(new SetupExtensionCommand());
$this->add(new SetupProjectCommand());
$this->add(new UpdateCommand());

//$this->setDefaultCommand('setup', false);
}

protected function getDefaultInputDefinition(): InputDefinition
{
$inputDefinition = parent::getDefaultInputDefinition();
$inputDefinition->addOption(new InputOption(
'--target-dir',
'-d',
InputOption::VALUE_REQUIRED,
'If specified, use the given directory as target directory',
self::getProjectDir()
));

return $inputDefinition;
}
}
Loading

0 comments on commit 77f8ec8

Please sign in to comment.