From d102813ddbcdab1c3a4a95b522269c7e32e4f6e4 Mon Sep 17 00:00:00 2001 From: Raphael Stolt Date: Mon, 16 Dec 2019 16:47:13 +0100 Subject: [PATCH 001/152] Drop support for eoled PHP 7.1 --- .appveyor.yml | 2 +- .travis.yml | 10 +++------- CHANGELOG.md | 4 ++++ README.md | 2 +- 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/.appveyor.yml b/.appveyor.yml index 75df31e..372aa1f 100644 --- a/.appveyor.yml +++ b/.appveyor.yml @@ -4,8 +4,8 @@ platform: x86 environment: matrix: + - php_ver_target: 7.4 - php_ver_target: 7.2 - - php_ver_target: 7.1 cache: - C:\php -> .appveyor.yml diff --git a/.travis.yml b/.travis.yml index 05cb6a7..0b6cd0c 100755 --- a/.travis.yml +++ b/.travis.yml @@ -10,20 +10,16 @@ git: matrix: include: - - php: nightly + - php: 7.4 - php: 7.3 + env: + - LINT=true - php: 7.2 env: - STATIC_ANALYSE=true - EXECUTE_DEPLOYMENT=true - - php: 7.1 - env: - - LINT=true fast_finish: true - allow_failures: - - php: nightly - - php: 7.1 cache: directories: diff --git a/CHANGELOG.md b/CHANGELOG.md index 99e9b4c..a9a7f6b 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,10 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/) and this p ## [Unreleased] +## [v2.1.0] - 2019-12-16 +### Removed +- Removed support for PHP `7.1`. + ## [v2.0.2] - 2019-09-04 - Added zend-stdlib glob fallback for alpine based systems. diff --git a/README.md b/README.md index 703620d..1225a9c 100755 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ [![Build Status](https://secure.travis-ci.org/raphaelstolt/lean-package-validator.png)](http://travis-ci.org/raphaelstolt/lean-package-validator) [![Build Status](https://ci.appveyor.com/api/projects/status/github/raphaelstolt/lean-package-validator?svg=true)](https://ci.appveyor.com/project/raphaelstolt/lean-package-validator) [![Version](http://img.shields.io/packagist/v/stolt/lean-package-validator.svg?style=flat)](https://packagist.org/packages/stolt/lean-package-validator) -![PHP Version](https://img.shields.io/badge/php-7.1+-ff69b4.svg) +![PHP Version](https://img.shields.io/badge/php-7.2+-ff69b4.svg) [![composer.lock available](https://poser.pugx.org/stolt/lean-package-validator/composerlock)](https://packagist.org/packages/stolt/lean-package-validator) [![PDS Skeleton](https://img.shields.io/badge/pds-skeleton-blue.svg?style=flat)](https://github.com/php-pds/skeleton) From ad8233484c4a28f107ae02b269159ec42a43e400 Mon Sep 17 00:00:00 2001 From: Raphael Stolt Date: Mon, 16 Dec 2019 16:50:00 +0100 Subject: [PATCH 002/152] Fix PHPStan errors --- phpstan.neon.dist | 2 +- src/Archive.php | 2 +- src/Commands/ValidateCommand.php | 2 ++ 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/phpstan.neon.dist b/phpstan.neon.dist index b9c8616..21e5432 100644 --- a/phpstan.neon.dist +++ b/phpstan.neon.dist @@ -2,8 +2,8 @@ parameters: level: max paths: - src - - tests reportUnmatchedIgnoredErrors: false + checkMissingIterableValueType: false ignoreErrors: - '#Constant WORKING_DIRECTORY not found.#' - '#Mockery\\MockInterface#' diff --git a/src/Archive.php b/src/Archive.php index f170ecd..d5ce923 100755 --- a/src/Archive.php +++ b/src/Archive.php @@ -114,7 +114,7 @@ public function hasHead() /** * Is the Git command available? * - * @paramk string $command The command to check availabilty of. Defaults to git. + * @param string $command The command to check availabilty of. Defaults to git. * * @return boolean */ diff --git a/src/Commands/ValidateCommand.php b/src/Commands/ValidateCommand.php index 91e9542..f795443 100755 --- a/src/Commands/ValidateCommand.php +++ b/src/Commands/ValidateCommand.php @@ -355,6 +355,7 @@ protected function execute(InputInterface $input, OutputInterface $output) /** * Check if a glob pattern file is setable. * + * @param string $file The glob pattern file to check. * @return boolean */ protected function isGlobPatternFileSetable($file) @@ -369,6 +370,7 @@ protected function isGlobPatternFileSetable($file) /** * Check if a glob pattern file was provided. * + * @param string $file The glob pattern file provided. * @return boolean */ protected function isGlobPatternFileProvided($file) From a63f2f2a31fd24fbeb1dafd8ed2e9941670e6805 Mon Sep 17 00:00:00 2001 From: Raphael Stolt Date: Tue, 25 Feb 2020 10:36:29 +0100 Subject: [PATCH 003/152] Bump copyright --- LICENSE.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LICENSE.md b/LICENSE.md index ee8db24..82faeb9 100755 --- a/LICENSE.md +++ b/LICENSE.md @@ -1,6 +1,6 @@ The MIT License (MIT) -Copyright (c) 2016 - 2018 Raphael Stolt +Copyright (c) 2016 - ∞ Raphael Stolt Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal From dda7c408e503277a983afdef678995348f7be3d7 Mon Sep 17 00:00:00 2001 From: Raphael Stolt Date: Thu, 28 Apr 2022 12:29:14 +0200 Subject: [PATCH 004/152] Upgrades PHP, dependencies and introduces GitHub Actions --- .gitattributes | 3 +- .github/CONTRIBUTING.md | 2 - .github/workflows/distribute.yml | 56 +++++++++++++++ .github/workflows/lint.yml | 31 ++++++++ .github/workflows/static-analyse.yml | 31 ++++++++ .github/workflows/test.yml | 30 ++++++++ .gitignore | 1 + .php-cs-fixer.php | 22 ++++++ .php_cs | 19 ----- .travis.yml | 72 ------------------- README.md | 10 +-- bin/lean-package-validator | 2 +- bin/release-version | 1 - ...fail-non-feature-topic-branch-pull-request | 6 -- composer.json | 15 ++-- phpstan.neon.dist | 1 + src/Analyser.php | 2 +- tests/CommandTester.php | 4 +- 18 files changed, 186 insertions(+), 122 deletions(-) create mode 100644 .github/workflows/distribute.yml create mode 100644 .github/workflows/lint.yml create mode 100644 .github/workflows/static-analyse.yml create mode 100644 .github/workflows/test.yml create mode 100755 .php-cs-fixer.php delete mode 100755 .php_cs delete mode 100755 .travis.yml delete mode 100755 bin/travis/fail-non-feature-topic-branch-pull-request diff --git a/.gitattributes b/.gitattributes index c59559b..e5bce46 100755 --- a/.gitattributes +++ b/.gitattributes @@ -8,8 +8,9 @@ .gitignore export-ignore .gitmessage export-ignore .gub export-ignore -.php_cs export-ignore +.php-cs-fixer.php export-ignore .travis.yml export-ignore +.phpunit.result.cache export-ignore bin/application-version export-ignore bin/lean-package-validator.phar export-ignore bin/release-version export-ignore diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md index d685bd0..ec28efe 100755 --- a/.github/CONTRIBUTING.md +++ b/.github/CONTRIBUTING.md @@ -8,6 +8,4 @@ Thanks for considering to contribute to the `LeanPackageValidator`. Please follo - Commits __MUST__ use the provided [commit message template](../.gitmessage), which follows the [rules](http://chris.beams.io/posts/git-commit/) described by Chris Beams. It can be configured via `composer lpv:configure-commit-template` prior to committing. -- All changes on the `.travis.yml` file __MUST__ be linted before committing or opening pull requests by running `composer lpv:travis-lint` in the root directory of this repository. - - All upstreamed contributions __MUST__ use [feature / topic branches](https://git-scm.com/book/en/v2/Git-Branching-Branching-Workflows) to ease merging. diff --git a/.github/workflows/distribute.yml b/.github/workflows/distribute.yml new file mode 100644 index 0000000..dac3f50 --- /dev/null +++ b/.github/workflows/distribute.yml @@ -0,0 +1,56 @@ +name: distribute-cli + +on: + push: + tags: + - 'v*' + +jobs: + tests: + name: distribute-cli + runs-on: ubuntu-latest + + strategy: + fail-fast: true + matrix: + php: + - "8.1" + + steps: + - name: Checkout + uses: actions/checkout@v2 + + - name: Install PHP + uses: shivammathur/setup-php@v2 + with: + php-version: "${{ matrix.php }}" + + - name: Install Composer dependencies + run: composer install --no-progress --no-suggest --prefer-dist --optimize-autoloader && composer require --dev --with-all-dependencies humbug/box + + - name: Build PHAR + run: vendor/humbug/box/bin/box compile + + - name: Check generated PHAR + run: bin/lean-package-validator.phar + + - name: Create Release + id: create_release + uses: actions/create-release@v1 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + tag_name: ${{ github.ref }} + release_name: Release ${{ github.ref }} + draft: false + prerelease: false + + - name: Upload generated PHAR + uses: actions/upload-release-asset@v1 + env: + GITHUB_TOKEN: ${{ github.token }} + with: + upload_url: ${{ steps.create_release.outputs.upload_url }} + asset_path: bin/lean-package-validator.phar + asset_name: lean-package-validator.phar + asset_content_type: application/gzip diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml new file mode 100644 index 0000000..d3cb1d5 --- /dev/null +++ b/.github/workflows/lint.yml @@ -0,0 +1,31 @@ +name: lint-cli + +on: push + +jobs: + tests: + name: lint-cli + runs-on: ubuntu-latest + + strategy: + fail-fast: true + matrix: + php: + - "7.4" + - "8.0" + - "8.1" + + steps: + - name: Checkout + uses: actions/checkout@v2 + + - name: Install PHP + uses: shivammathur/setup-php@v2 + with: + php-version: "${{ matrix.php }}" + + - name: Install Composer dependencies + run: composer install --no-progress --no-suggest --prefer-dist --optimize-autoloader + + - name: Check coding styles + run: composer run-script lpv:cs-lint diff --git a/.github/workflows/static-analyse.yml b/.github/workflows/static-analyse.yml new file mode 100644 index 0000000..eda8fcf --- /dev/null +++ b/.github/workflows/static-analyse.yml @@ -0,0 +1,31 @@ +name: static-analyse-cli + +on: push + +jobs: + tests: + name: static-analyse-cli + runs-on: ubuntu-latest + + strategy: + fail-fast: true + matrix: + php: + - "7.4" + - "8.0" + - "8.1" + + steps: + - name: Checkout + uses: actions/checkout@v2 + + - name: Install PHP + uses: shivammathur/setup-php@v2 + with: + php-version: "${{ matrix.php }}" + + - name: Install Composer dependencies + run: composer install --no-progress --no-suggest --prefer-dist --optimize-autoloader + + - name: Run static analyse + run: composer run-script lpv:static-analyse diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml new file mode 100644 index 0000000..9fce887 --- /dev/null +++ b/.github/workflows/test.yml @@ -0,0 +1,30 @@ +name: test-cli + +on: push + +jobs: + test: + name: "PHPUnit (PHP ${{ matrix.php }})" + runs-on: "ubuntu-20.04" + + strategy: + matrix: + php: + - "7.4" + - "8.0" + - "8.1" + + steps: + - name: Checkout + uses: actions/checkout@v2 + + - name: Install PHP + uses: shivammathur/setup-php@v2 + with: + php-version: "${{ matrix.php }}" + + - name: Install Composer dependencies + run: composer update --no-progress --no-suggest --prefer-dist --optimize-autoloader + + - name: Run tests + run: composer run-script lpv:test diff --git a/.gitignore b/.gitignore index 3d19894..f9ab5a9 100755 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,4 @@ vendor/ coverage-reports/ composer.lock .php_cs.cache +.phpunit.result.cache diff --git a/.php-cs-fixer.php b/.php-cs-fixer.php new file mode 100755 index 0000000..c762fae --- /dev/null +++ b/.php-cs-fixer.php @@ -0,0 +1,22 @@ +in(__DIR__); + +$rules = [ + 'psr_autoloading' => false, + '@PSR2' => true, + 'phpdoc_order' => true, + 'ordered_imports' => true, +]; + +$cacheDir = getenv('HOME') ? getenv('HOME') : __DIR__; + +$config = new Config(); + +return $config->setRules($rules) + ->setFinder($finder) + ->setCacheFile($cacheDir . '/.php-cs-fixer.cache'); diff --git a/.php_cs b/.php_cs deleted file mode 100755 index fa11883..0000000 --- a/.php_cs +++ /dev/null @@ -1,19 +0,0 @@ -in(__DIR__); - -$rules = [ - 'psr0' => false, - '@PSR2' => true, - 'array_syntax' => ['syntax' => 'short'], - 'phpdoc_order' => true, - 'ordered_imports' => true, -]; - -$cacheDir = getenv('TRAVIS') ? getenv('HOME') . '/.php-cs-fixer' : __DIR__; - -return PhpCsFixer\Config::create() - ->setRules($rules) - ->setFinder($finder) - ->setCacheFile($cacheDir . '/.php_cs.cache'); diff --git a/.travis.yml b/.travis.yml deleted file mode 100755 index 0b6cd0c..0000000 --- a/.travis.yml +++ /dev/null @@ -1,72 +0,0 @@ -language: php - -env: - global: - - EXCLUDEGROUP=travis-ci-exclude - - DISABLE_XDEBUG=true - -git: - depth: 1 - -matrix: - include: - - php: 7.4 - - php: 7.3 - env: - - LINT=true - - php: 7.2 - env: - - STATIC_ANALYSE=true - - EXECUTE_DEPLOYMENT=true - - fast_finish: true - -cache: - directories: - - $HOME/.composer/cache - - $HOME/.php-cs-fixer - -notifications: - email: false - -before_script: - - phpenv config-rm xdebug.ini || true - - travis_retry composer self-update - - travis_retry composer install --no-interaction - - travis_retry composer dump-autoload --optimize - -script: - # Use custom script to avoid the risk of terminating the build process - - ./bin/travis/fail-non-feature-topic-branch-pull-request - # Verify application version and Git tag match on tagged builds - - if [[ ! -z "$TRAVIS_TAG" ]]; then - composer lpv:application-version-guard; - fi - # Verify coding standard compliance only once - - if [[ $LINT = true ]]; then - composer lpv:cs-lint; - fi - # Do static code analyse only once - - if [[ $STATIC_ANALYSE = true ]]; then - composer require --dev phpstan/phpstan; - composer lpv:static-analyse; - fi - - if [[ $EXCLUDEGROUP = travis-ci-exclude ]]; then - composer lpv:test -- --exclude-group travis-ci-exclude; - fi - -before_deploy: - - curl -LSs https://box-project.github.io/box2/installer.php | php - - php -d phar.readonly=0 box.phar build - - composer lpv:application-phar-version-guard - -deploy: - provider: releases - api_key: - secure: rol9z0gDIkyfs9Gad2L2p7saWFzC+CECx7nF81Cgqmu3c6qBsYllO9Fz/2H0Jggcwq1boy78PJeAZ2WNXnFk7zmsStMEYk5qMffYsrZI4xz90i9P/+377bx1n8XqaKza/7Cbnuu4Idda5DXn9Jx0EmSE+SFS2/4Ank5lTSCjKo+p0wJK5PWP3d4SVwdtvqJQT9uEDjIELvQW6ari3jErGGuXfXOfHbbxHb3Bc/a+9Xe50r+U/49JvI75XT/GW1eFzUv/o3CvJIX0s5YxUKCTFbCtxlDke3NMA+wYEU+nNWwmEMaXC/5eE32fwQI4daJoOCgqYD9eB7Mfw/mCDudi4NwzetPp2+KEjThUPxhzPNmqF3H/SyA1WvZd9MJZNDuG86rQVdqNryg+xNDzb5DTEqwI44NdUZzpmssrbGL85MBh5ZSX31XOzE2FIihoh611ui58OrWrb7AZYbcjZUqS2wkKt+ROHXMAwwXzUZoOMo3JdGq8+Keo3hXM6PYYcseBli7WgIZ+uv8eaS9lKz49A3hr/JzjK53SpiF3mEa0y9PizjaZ6agKnMcc+s2D4rmRBFb0ag1QveUk1kA5TEXEAB4HsH599Iv33zyt4v1MFPIIRC2w4yo6NGSJhE+w5fsohlfCRhf8C7bqWZJiPBg0TpBGq6qflv++rymQltfMohs= - file: bin/lean-package-validator.phar - skip_cleanup: true - on: - tags: true - repo: raphaelstolt/lean-package-validator - condition: "$EXECUTE_DEPLOYMENT" diff --git a/README.md b/README.md index 1225a9c..34370ba 100755 --- a/README.md +++ b/README.md @@ -1,8 +1,8 @@ # LeanPackageValidator -[![Build Status](https://secure.travis-ci.org/raphaelstolt/lean-package-validator.png)](http://travis-ci.org/raphaelstolt/lean-package-validator) +![Test Status](https://github.com/raphaelstolt/lean-package-validator/workflows/test/badge.svg) [![Build Status](https://ci.appveyor.com/api/projects/status/github/raphaelstolt/lean-package-validator?svg=true)](https://ci.appveyor.com/project/raphaelstolt/lean-package-validator) [![Version](http://img.shields.io/packagist/v/stolt/lean-package-validator.svg?style=flat)](https://packagist.org/packages/stolt/lean-package-validator) -![PHP Version](https://img.shields.io/badge/php-7.2+-ff69b4.svg) +![PHP Version](https://img.shields.io/badge/php-7.4+-ff69b4.svg) [![composer.lock available](https://poser.pugx.org/stolt/lean-package-validator/composerlock)](https://packagist.org/packages/stolt/lean-package-validator) [![PDS Skeleton](https://img.shields.io/badge/pds-skeleton-blue.svg?style=flat)](https://github.com/php-pds/skeleton) @@ -113,12 +113,6 @@ By adding the following to the project/micro-package its `composer.json` the ` . }, } ``` -Further this Composer script could also be utilised in Travis CI [builds](.travis.yml) like shown next. - -``` yml -script: - - composer validate-gitattributes -``` #### Running tests ``` bash diff --git a/bin/lean-package-validator b/bin/lean-package-validator index 7b0a6d6..6ae672e 100755 --- a/bin/lean-package-validator +++ b/bin/lean-package-validator @@ -24,7 +24,7 @@ if (false === $autoloaded) { } define('WORKING_DIRECTORY', getcwd()); -define('VERSION', '2.0.1'); +define('VERSION', '2.1.0'); use Stolt\LeanPackage\Commands\InitCommand; use Stolt\LeanPackage\Commands\ValidateCommand; diff --git a/bin/release-version b/bin/release-version index 7565b53..ff8e689 100755 --- a/bin/release-version +++ b/bin/release-version @@ -72,7 +72,6 @@ function fulfillsPreconditions() echo 'Checking release preconditions' . PHP_EOL; $precondictionCommands = [ - "composer lpv:travis-lint", "composer lpv:cs-lint", ]; diff --git a/bin/travis/fail-non-feature-topic-branch-pull-request b/bin/travis/fail-non-feature-topic-branch-pull-request deleted file mode 100755 index 2ea58b5..0000000 --- a/bin/travis/fail-non-feature-topic-branch-pull-request +++ /dev/null @@ -1,6 +0,0 @@ -#!/bin/bash -set -e -if [[ $TRAVIS_PULL_REQUEST_BRANCH = master ]]; then - echo "Please open pull request from a feature / topic branch."; - exit 1; -fi diff --git a/composer.json b/composer.json index 74e8bcc..5564954 100755 --- a/composer.json +++ b/composer.json @@ -10,9 +10,9 @@ } ], "require": { - "php": ">=7.1", - "symfony/console": "^3.1", - "zendframework/zend-stdlib": "^3.2" + "php": ">=7.4", + "symfony/console": "^v6.0.8||^v5.4.8", + "laminas/laminas-stdlib": "^3.7" }, "autoload": { "psr-4": { @@ -28,7 +28,6 @@ "minimum-stability": "stable", "bin": ["bin/lean-package-validator"], "scripts-descriptions": { - "lpv:travis-lint": "Lints the local Travis CI configuration file.", "lpv:test": "Runs all tests.", "lpv:test-with-coverage": "Runs all tests and measures code coverage.", "lpv:cs-fix": "Fixes coding standard violations.", @@ -39,7 +38,6 @@ "lpv:static-analyse": "Runs a static code analysis via PHPStan." }, "scripts": { - "lpv:travis-lint": "Stolt\\Composer\\Travis::lint", "lpv:test": "phpunit", "lpv:test-with-coverage": "phpunit --coverage-html coverage-reports", "lpv:cs-fix": "php-cs-fixer fix . -vv || true", @@ -53,12 +51,11 @@ "sort-packages": true }, "require-dev": { - "friendsofphp/php-cs-fixer": "^2.0", + "friendsofphp/php-cs-fixer": "^3.0", "mockery/mockery": "^1.0", "php-mock/php-mock-phpunit": "^2.4||^1.1", - "phpstan/phpstan": "^0.11.15", - "phpunit/phpunit": "^8.3||^7.5", - "stolt/composer-travis-lint": "^1.0", + "phpstan/phpstan": "^1.6.2", + "phpunit/phpunit": "8.*", "vierbergenlars/php-semver": "^3.0" } } diff --git a/phpstan.neon.dist b/phpstan.neon.dist index 21e5432..ee086b7 100644 --- a/phpstan.neon.dist +++ b/phpstan.neon.dist @@ -12,3 +12,4 @@ parameters: - '#array_filter#' - '#cannot be cast to string#' - '#Cannot cast#' + - '#is never read#' diff --git a/src/Analyser.php b/src/Analyser.php index 6f73c92..984bef2 100755 --- a/src/Analyser.php +++ b/src/Analyser.php @@ -2,10 +2,10 @@ namespace Stolt\LeanPackage; +use Laminas\Stdlib\Glob; use Stolt\LeanPackage\Exceptions\InvalidGlobPattern; use Stolt\LeanPackage\Exceptions\InvalidGlobPatternFile; use Stolt\LeanPackage\Exceptions\NonExistentGlobPatternFile; -use Zend\Stdlib\Glob; class Analyser { diff --git a/tests/CommandTester.php b/tests/CommandTester.php index c843c14..cc8022a 100644 --- a/tests/CommandTester.php +++ b/tests/CommandTester.php @@ -13,7 +13,7 @@ class CommandTester extends ConsoleCommandTester * * @return string The display */ - public function getDisplay($normalize = true) + public function getDisplay($normalize = true):string { return parent::getDisplay($normalize); } @@ -32,7 +32,7 @@ public function getDisplay($normalize = true) * * @return int The command exit code */ - public function execute(array $input, array $options = ['decorated' => false]) + public function execute(array $input, array $options = ['decorated' => false]):int { return parent::execute($input, $options); } From 0f5a5afe96b9aab982edd858aa1fe6aa9764857b Mon Sep 17 00:00:00 2001 From: Raphael Stolt Date: Thu, 28 Apr 2022 16:30:25 +0200 Subject: [PATCH 005/152] Release version 3.0.0 --- bin/lean-package-validator | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bin/lean-package-validator b/bin/lean-package-validator index 6ae672e..6c09299 100755 --- a/bin/lean-package-validator +++ b/bin/lean-package-validator @@ -24,7 +24,7 @@ if (false === $autoloaded) { } define('WORKING_DIRECTORY', getcwd()); -define('VERSION', '2.1.0'); +define('VERSION', '3.0.0'); use Stolt\LeanPackage\Commands\InitCommand; use Stolt\LeanPackage\Commands\ValidateCommand; From a23f426bd7e4e53345b8c162c1db7f79bca4e754 Mon Sep 17 00:00:00 2001 From: Raphael Stolt Date: Thu, 28 Apr 2022 17:02:28 +0200 Subject: [PATCH 006/152] Documents changes and limits lint and static analysis runs --- .github/workflows/lint.yml | 2 -- .github/workflows/static-analyse.yml | 2 -- CHANGELOG.md | 12 +++++++++++- 3 files changed, 11 insertions(+), 5 deletions(-) diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index d3cb1d5..3dd7604 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -11,8 +11,6 @@ jobs: fail-fast: true matrix: php: - - "7.4" - - "8.0" - "8.1" steps: diff --git a/.github/workflows/static-analyse.yml b/.github/workflows/static-analyse.yml index eda8fcf..bef7f9c 100644 --- a/.github/workflows/static-analyse.yml +++ b/.github/workflows/static-analyse.yml @@ -11,8 +11,6 @@ jobs: fail-fast: true matrix: php: - - "7.4" - - "8.0" - "8.1" steps: diff --git a/CHANGELOG.md b/CHANGELOG.md index a9a7f6b..4168bf7 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,12 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/) and this p ## [Unreleased] +## [v3.0.0] - 2022-04-28 +### Removed +- Removed support for PHP `7.3` and `7.2`. +### Added +- Introduced GitHub Actions. + ## [v2.1.0] - 2019-12-16 ### Removed - Removed support for PHP `7.1`. @@ -124,7 +130,11 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/) and this p ## v1.0.0 - 2016-09-04 - Initial release. -[Unreleased]: https://github.com/raphaelstolt/lean-package-validator/compare/v2.0.0...HEAD +[Unreleased]: https://github.com/raphaelstolt/lean-package-validator/compare/v3.0.0...HEAD +[v3.0.0]: https://github.com/raphaelstolt/lean-package-validator/compare/v2.1.0...v3.0.0 +[v2.1.0]: https://github.com/raphaelstolt/lean-package-validator/compare/v2.0.2...v2.1.0 +[v2.0.2]: https://github.com/raphaelstolt/lean-package-validator/compare/v2.0.1...v2.0.2 +[v2.0.1]: https://github.com/raphaelstolt/lean-package-validator/compare/v2.0.0...v2.0.1 [v2.0.0]: https://github.com/raphaelstolt/lean-package-validator/compare/v1.9.0...v2.0.0 [v1.9.0]: https://github.com/raphaelstolt/lean-package-validator/compare/v1.8.1...v1.9.0 [v1.8.1]: https://github.com/raphaelstolt/lean-package-validator/compare/v1.8.0...v1.8.1 From ebf2bbaf76a0d2481ca21d1769198b8767f85761 Mon Sep 17 00:00:00 2001 From: Raphael Stolt Date: Wed, 21 Dec 2022 17:46:10 +0100 Subject: [PATCH 007/152] Updates build matrix --- .github/workflows/test.yml | 2 +- README.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 9fce887..c304d2c 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -10,9 +10,9 @@ jobs: strategy: matrix: php: - - "7.4" - "8.0" - "8.1" + - "8.2" steps: - name: Checkout diff --git a/README.md b/README.md index 34370ba..91bd990 100755 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ ![Test Status](https://github.com/raphaelstolt/lean-package-validator/workflows/test/badge.svg) [![Build Status](https://ci.appveyor.com/api/projects/status/github/raphaelstolt/lean-package-validator?svg=true)](https://ci.appveyor.com/project/raphaelstolt/lean-package-validator) [![Version](http://img.shields.io/packagist/v/stolt/lean-package-validator.svg?style=flat)](https://packagist.org/packages/stolt/lean-package-validator) -![PHP Version](https://img.shields.io/badge/php-7.4+-ff69b4.svg) +![PHP Version](https://img.shields.io/badge/php-8.0+-ff69b4.svg) [![composer.lock available](https://poser.pugx.org/stolt/lean-package-validator/composerlock)](https://packagist.org/packages/stolt/lean-package-validator) [![PDS Skeleton](https://img.shields.io/badge/pds-skeleton-blue.svg?style=flat)](https://github.com/php-pds/skeleton) From b39bd6e1bd31810a6ced31446331f94bf2f6817c Mon Sep 17 00:00:00 2001 From: Raphael Stolt Date: Wed, 13 Sep 2023 06:10:49 +0200 Subject: [PATCH 008/152] Drop support for eoled PHP 7.4 --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 5564954..9f29aaf 100755 --- a/composer.json +++ b/composer.json @@ -10,7 +10,7 @@ } ], "require": { - "php": ">=7.4", + "php": ">=8.0", "symfony/console": "^v6.0.8||^v5.4.8", "laminas/laminas-stdlib": "^3.7" }, From aac1ba21bc0e07977dff559c27321694a21182b3 Mon Sep 17 00:00:00 2001 From: Raphael Stolt Date: Wed, 13 Sep 2023 06:11:44 +0200 Subject: [PATCH 009/152] Improves documentation --- README.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/README.md b/README.md index 91bd990..e484fd4 100755 --- a/README.md +++ b/README.md @@ -31,6 +31,12 @@ composer require --dev stolt/lean-package-validator ``` As of release `v1.9.0` it's also possible to install and use the LeanPackageValidator via a PHAR [file](https://github.com/raphaelstolt/lean-package-validator/releases/tag/v1.9.0). +Therefor download a released version i.e. v1.9.0 and move it to `/usr/local/bin` as shown next. + +``` bash +wget https://github.com/raphaelstolt/lean-package-validator/releases/download/v1.9.0/lean-package-validator.phar +mv lean-package-validator.phar /usr/local/bin/lean-package-validator +``` ## Usage Run the LeanPackageValidator CLI within or against a project/micro-package directory and it will validate the [export-ignore](https://git-scm.com/book/en/v2/Customizing-Git-Git-Attributes#Exporting-Your-Repository) entries present in a `.gitattributes` file against a set of common repository artifacts. If no `.gitattributes` file is present it will suggest to create one. From ef14f96960f0546695cbf4dfa239ef1ea354694a Mon Sep 17 00:00:00 2001 From: Raphael Stolt Date: Wed, 13 Sep 2023 06:22:58 +0200 Subject: [PATCH 010/152] Fixes appveyor environment matrix --- .appveyor.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.appveyor.yml b/.appveyor.yml index 372aa1f..9217862 100644 --- a/.appveyor.yml +++ b/.appveyor.yml @@ -4,8 +4,7 @@ platform: x86 environment: matrix: - - php_ver_target: 7.4 - - php_ver_target: 7.2 + - php_ver_target: 8.0 cache: - C:\php -> .appveyor.yml From 80e8d7fabc855f0aa4477e01c6d0e3a40f1222d5 Mon Sep 17 00:00:00 2001 From: Raphael Stolt Date: Wed, 13 Sep 2023 10:49:00 +0200 Subject: [PATCH 011/152] Adds header to generated files --- bin/release-version | 17 ++++++-- composer.json | 4 +- phpunit.xml.dist | 31 ++++++-------- src/Commands/ValidateCommand.php | 18 ++++++++ tests/Commands/ValidateCommandTest.php | 57 ++++++++++++++++++++++++-- 5 files changed, 99 insertions(+), 28 deletions(-) diff --git a/bin/release-version b/bin/release-version index ff8e689..0df8efa 100755 --- a/bin/release-version +++ b/bin/release-version @@ -14,8 +14,9 @@ foreach ($autoloads as $autoload) { } } +use Composer\Semver\Comparator; use Stolt\LeanPackage\Helpers\Str as OsHelper; -use vierbergenlars\SemVer\version as SemVer; +use PHLAK\SemVer\Version; $binApplicationName = 'lean-package-validator'; $binFile = __DIR__ . DIRECTORY_SEPARATOR . $binApplicationName; @@ -130,7 +131,7 @@ if ($version === null) { } if ($version) { - if (SemVer::lte($version, $currentVersion)) { + if (Comparator::lessThanOrEqualTo($version, $currentVersion)) { echo "Earlier version '{$version}' provided." . PHP_EOL; exit(1); } @@ -156,7 +157,17 @@ if ($increment) { exit(1); } - $version = (new SemVer($currentVersion))->inc($increment)->getVersion(); + switch ($increment) { + case 'major': + $version = (new Version($currentVersion))->incrementMajor()->__toString(); + break; + case 'minor': + $version = (new Version($currentVersion))->incrementMinor()->__toString(); + break; + case 'patch': + $version = (new Version($currentVersion))->incrementPatch()->__toString(); + break; + } } if (!isset($version)) { diff --git a/composer.json b/composer.json index 9f29aaf..cafe563 100755 --- a/composer.json +++ b/composer.json @@ -53,9 +53,9 @@ "require-dev": { "friendsofphp/php-cs-fixer": "^3.0", "mockery/mockery": "^1.0", + "phlak/semver": "^4.1", "php-mock/php-mock-phpunit": "^2.4||^1.1", "phpstan/phpstan": "^1.6.2", - "phpunit/phpunit": "8.*", - "vierbergenlars/php-semver": "^3.0" + "phpunit/phpunit": "^10.3" } } diff --git a/phpunit.xml.dist b/phpunit.xml.dist index dd51ad5..ece54d7 100755 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -1,21 +1,14 @@ - - - - tests/ - - - - - src/ - - + + + + + tests/ + + + + + src/ + + diff --git a/src/Commands/ValidateCommand.php b/src/Commands/ValidateCommand.php index f795443..4b66d92 100755 --- a/src/Commands/ValidateCommand.php +++ b/src/Commands/ValidateCommand.php @@ -81,6 +81,7 @@ protected function configure() $overwriteDescription = 'Overwrite existing .gitattributes file ' . 'with missing export-ignores'; $validateArchiveDescription = 'Validate Git archive against current HEAD'; + $omitHeaderDescription = 'Omit adding a header to created or modified .gitattributes file'; $exampleGlobPattern = '{.*,*.md}'; $globPatternDescription = 'Use this glob pattern e.g. ' @@ -139,6 +140,12 @@ protected function configure() InputOption::VALUE_NONE, $alignExportIgnoresDescription ); + $this->addOption( + 'omit-header', + null, + InputOption::VALUE_NONE, + $omitHeaderDescription + ); } /** @@ -171,6 +178,7 @@ protected function execute(InputInterface $input, OutputInterface $output) $validateArchive = $input->getOption('validate-git-archive'); $globPattern = $input->getOption('glob-pattern'); $globPatternFile = (string) $input->getOption('glob-pattern-file'); + $omitHeader = $input->getOption('omit-header'); $enforceStrictOrderComparison = $input->getOption('enforce-strict-order'); @@ -238,6 +246,16 @@ protected function execute(InputInterface $input, OutputInterface $output) if ($expectedGitattributesFileContent !== '') { if ($createGitattributesFile || $overwriteGitattributesFile) { try { + if ($omitHeader === false) { + $headerContent = 'This file was partly modified by the lean package validator (http://git.io/lean-package-validator).' . PHP_EOL; + + if ($createGitattributesFile) { + $headerContent = 'This file was generated by the lean package validator (http://git.io/lean-package-validator).' . PHP_EOL; + } + $expectedGitattributesFileContent = $headerContent . PHP_EOL . $expectedGitattributesFileContent; + } + + $expectedGitattributesFileContent = $expectedGitattributesFileContent; $outputContent .= $this->createGitattributesFile( $expectedGitattributesFileContent ); diff --git a/tests/Commands/ValidateCommandTest.php b/tests/Commands/ValidateCommandTest.php index 2a7a341..918b701 100644 --- a/tests/Commands/ValidateCommandTest.php +++ b/tests/Commands/ValidateCommandTest.php @@ -577,6 +577,47 @@ function () { $mock->disable(); } + /** + * @test + */ + public function validateOnNonExistentGitattributesFilesWithCreationOptionCreatesOneWithoutHeader() + { + $artifactFilenames = ['CONDUCT.md']; + + $this->createTemporaryFiles( + $artifactFilenames, + ['specs'] + ); + + $command = $this->application->find('validate'); + $commandTester = new CommandTester($command); + $commandTester->execute([ + 'command' => $command->getName(), + 'directory' => WORKING_DIRECTORY, + '--create' => true, + '--omit-header' => true + ]); + + $expectedDisplay = <<assertEquals($expectedDisplay, $commandTester->getDisplay()); + $this->assertTrue($commandTester->getStatusCode() == 0); + $this->assertFileExists( + WORKING_DIRECTORY . DIRECTORY_SEPARATOR . '.gitattributes' + ); + } + /** * @test */ @@ -598,9 +639,11 @@ public function validateOnNonExistentGitattributesFilesWithCreationOptionCreates ]); $expectedDisplay = <<temporaryDirectory}. +Warning: There is no .gitattributes file present in /tmp/lpv. Created a .gitattributes file with the shown content: +This file was generated by the lean package validator (http://git.io/lean-package-validator). + * text=auto eol=lf .gitattributes export-ignore @@ -610,7 +653,7 @@ public function validateOnNonExistentGitattributesFilesWithCreationOptionCreates CONTENT; - $this->assertSame($expectedDisplay, $commandTester->getDisplay()); + $this->assertEquals($expectedDisplay, $commandTester->getDisplay()); $this->assertTrue($commandTester->getStatusCode() == 0); $this->assertFileExists( WORKING_DIRECTORY . DIRECTORY_SEPARATOR . '.gitattributes' @@ -642,6 +685,8 @@ public function validateOnNonExistentGitattributesFilesWithCreationOptionCreates Warning: There is no .gitattributes file present in {$this->temporaryDirectory}. Created a .gitattributes file with the shown content: +This file was generated by the lean package validator (http://git.io/lean-package-validator). + * text=auto eol=lf .gitattributes export-ignore @@ -652,6 +697,8 @@ public function validateOnNonExistentGitattributesFilesWithCreationOptionCreates CONTENT; $expectedGitattributesContent = <<assertSame($expectedDisplay, $commandTester->getDisplay()); + $this->assertEquals($expectedDisplay, $commandTester->getDisplay()); $this->assertTrue($commandTester->getStatusCode() == 0); $this->assertStringEqualsFile( WORKING_DIRECTORY . DIRECTORY_SEPARATOR . '.gitattributes', @@ -854,6 +901,8 @@ public function overwriteOptionOnNonExistentGitattributesFileImplicatesCreate() Warning: There is no .gitattributes file present in {$this->temporaryDirectory}. Created a .gitattributes file with the shown content: +This file was partly modified by the lean package validator (http://git.io/lean-package-validator). + * text=auto eol=lf .gitattributes export-ignore @@ -1819,7 +1868,7 @@ public function gitignoredFilesAreExcludedFromValidation() /** * @return array */ - public function optionProvider() + public static function optionProvider() { return [ ['--overwrite'], From 60747307f5f1a3a5f4c808bf021ec6b708c318cc Mon Sep 17 00:00:00 2001 From: Raphael Stolt Date: Tue, 26 Sep 2023 13:02:48 +0200 Subject: [PATCH 012/152] Release version 3.0.1 --- CHANGELOG.md | 9 ++++++++- bin/lean-package-validator | 2 +- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4168bf7..3f7cbbb 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,12 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/) and this p ## [Unreleased] +## [v3.0.1] - 2023-09-26 +### Removed +- Removed support for PHP `7.4`. +### Added +- Header in generated or modified `.gitattributes` file. + ## [v3.0.0] - 2022-04-28 ### Removed - Removed support for PHP `7.3` and `7.2`. @@ -130,7 +136,8 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/) and this p ## v1.0.0 - 2016-09-04 - Initial release. -[Unreleased]: https://github.com/raphaelstolt/lean-package-validator/compare/v3.0.0...HEAD +[Unreleased]: https://github.com/raphaelstolt/lean-package-validator/compare/v3.0.1...HEAD +[v3.0.1]: https://github.com/raphaelstolt/lean-package-validator/compare/v3.0.0...v3.0.1 [v3.0.0]: https://github.com/raphaelstolt/lean-package-validator/compare/v2.1.0...v3.0.0 [v2.1.0]: https://github.com/raphaelstolt/lean-package-validator/compare/v2.0.2...v2.1.0 [v2.0.2]: https://github.com/raphaelstolt/lean-package-validator/compare/v2.0.1...v2.0.2 diff --git a/bin/lean-package-validator b/bin/lean-package-validator index 6c09299..f5aa443 100755 --- a/bin/lean-package-validator +++ b/bin/lean-package-validator @@ -24,7 +24,7 @@ if (false === $autoloaded) { } define('WORKING_DIRECTORY', getcwd()); -define('VERSION', '3.0.0'); +define('VERSION', '3.0.1'); use Stolt\LeanPackage\Commands\InitCommand; use Stolt\LeanPackage\Commands\ValidateCommand; From cced5ddb6e7fec3675f314eae5d5654f59255315 Mon Sep 17 00:00:00 2001 From: Raphael Stolt Date: Thu, 28 Sep 2023 12:25:45 +0200 Subject: [PATCH 013/152] Adds \ prefix to internal PHP function calls --- composer.json | 2 +- src/Analyser.php | 188 ++++++++++++------------- src/Archive.php | 24 ++-- src/Commands/InitCommand.php | 4 +- src/Commands/ValidateCommand.php | 10 +- src/Helpers/Str.php | 2 +- tests/AnalyserTest.php | 10 +- tests/ApplicationTest.php | 2 +- tests/Archive/ValidatorTest.php | 2 +- tests/ArchiveTest.php | 2 +- tests/Commands/InitCommandTest.php | 12 +- tests/Commands/ValidateCommandTest.php | 10 +- tests/TestCase.php | 26 ++-- 13 files changed, 147 insertions(+), 147 deletions(-) diff --git a/composer.json b/composer.json index cafe563..dd36043 100755 --- a/composer.json +++ b/composer.json @@ -54,7 +54,7 @@ "friendsofphp/php-cs-fixer": "^3.0", "mockery/mockery": "^1.0", "phlak/semver": "^4.1", - "php-mock/php-mock-phpunit": "^2.4||^1.1", + "php-mock/php-mock-phpunit": "^2.7||^1.1", "phpstan/phpstan": "^1.6.2", "phpunit/phpunit": "^10.3" } diff --git a/src/Analyser.php b/src/Analyser.php index 984bef2..e36f4e3 100755 --- a/src/Analyser.php +++ b/src/Analyser.php @@ -130,7 +130,7 @@ public function __construct() 'RMT' ]; - $this->globPattern = '{' . implode(',', $this->defaultGlobPatterns) . '}*'; + $this->globPattern = '{' . \implode(',', $this->defaultGlobPatterns) . '}*'; } /** @@ -173,26 +173,26 @@ public function hasTextAutoConfiguration() */ public function setGlobPatternFromFile($file) { - if (!is_file($file)) { + if (!\is_file($file)) { $message = "Glob pattern file {$file} doesn't exist."; throw new NonExistentGlobPatternFile($message); } - $globPatternContent = (string) file_get_contents($file); + $globPatternContent = (string) \file_get_contents($file); - $globPatternLines = preg_split( + $globPatternLines = \preg_split( '/\\r\\n|\\r|\\n/', $globPatternContent ); $globPatterns = []; - array_filter($globPatternLines, function ($line) use (&$globPatterns) { - if (trim($line) !== '') { - $globPatterns[] = trim($line); + \array_filter($globPatternLines, function ($line) use (&$globPatterns) { + if (\trim($line) !== '') { + $globPatterns[] = \trim($line); } }); - $globPattern = '{' . implode(',', $globPatterns) . '}*'; + $globPattern = '{' . \implode(',', $globPatterns) . '}*'; try { $this->setGlobPattern($globPattern); @@ -214,20 +214,20 @@ private function guardGlobPattern() { $invalidGlobPattern = false; - if (substr($this->globPattern, 0) !== '{' - && (substr($this->globPattern, -1) !== '}' && substr($this->globPattern, -2) !== '}*')) { + if (\substr($this->globPattern, 0) !== '{' + && (\substr($this->globPattern, -1) !== '}' && \substr($this->globPattern, -2) !== '}*')) { $invalidGlobPattern = true; } - $bracesContent = trim(substr($this->globPattern, 1, -1)); + $bracesContent = \trim(\substr($this->globPattern, 1, -1)); if (empty($bracesContent)) { $invalidGlobPattern = true; } - $globPatterns = explode(',', $bracesContent); + $globPatterns = \explode(',', $bracesContent); - if (count($globPatterns) == 1) { + if (\count($globPatterns) == 1) { $invalidGlobPattern = true; } @@ -248,7 +248,7 @@ private function guardGlobPattern() */ public function setGlobPattern($pattern) { - $this->globPattern = trim($pattern); + $this->globPattern = \trim($pattern); $this->guardGlobPattern(); return $this; @@ -264,7 +264,7 @@ public function setGlobPattern($pattern) */ public function setDirectory($directory = __DIR__) { - if (!is_dir($directory)) { + if (!\is_dir($directory)) { $message = "Directory {$directory} doesn't exist."; throw new \RuntimeException($message); } @@ -391,8 +391,8 @@ public function getGitattributesFilePath() */ public function hasGitattributesFile() { - return file_exists($this->gitattributesFile) && - is_readable($this->gitattributesFile); + return \file_exists($this->gitattributesFile) && + \is_readable($this->gitattributesFile); } /** @@ -404,28 +404,28 @@ public function getGitignoredPatterns() { $gitignoreFile = $this->getDirectory() . DIRECTORY_SEPARATOR . '.gitignore'; - if (!file_exists($gitignoreFile)) { + if (!\file_exists($gitignoreFile)) { return []; } - $gitignoreContent = (string) file_get_contents($gitignoreFile); + $gitignoreContent = (string) \file_get_contents($gitignoreFile); $eol = $this->detectEol($gitignoreContent); - $gitignoreLines = preg_split( + $gitignoreLines = \preg_split( '/\\r\\n|\\r|\\n/', $gitignoreContent ); $gitignoredPatterns = []; - array_filter($gitignoreLines, function ($line) use (&$gitignoredPatterns) { - $line = trim($line); - if ($line !== '' && strpos($line, '#') === false) { - if (substr($line, 0, 1) === "/") { - $gitignoredPatterns[] = substr($line, 1); + \array_filter($gitignoreLines, function ($line) use (&$gitignoredPatterns) { + $line = \trim($line); + if ($line !== '' && \strpos($line, '#') === false) { + if (\substr($line, 0, 1) === "/") { + $gitignoredPatterns[] = \substr($line, 1); } - if (substr($line, -1, 1) === "/") { - $gitignoredPatterns[] = substr($line, 0, -1); + if (\substr($line, -1, 1) === "/") { + $gitignoredPatterns[] = \substr($line, 0, -1); } $gitignoredPatterns[] = $line; } @@ -448,40 +448,40 @@ public function getExpectedGitattributesContent(array $postfixlessExportIgnores $postfixlessExportIgnores = $this->collectExpectedExportIgnores(); } - if (!$this->hasGitattributesFile() && count($postfixlessExportIgnores) > 0) { + if (!$this->hasGitattributesFile() && \count($postfixlessExportIgnores) > 0) { $postfixlessExportIgnores[] = '.gitattributes'; } - sort($postfixlessExportIgnores, SORT_STRING | SORT_FLAG_CASE); + \sort($postfixlessExportIgnores, SORT_STRING | SORT_FLAG_CASE); - if (count($postfixlessExportIgnores) > 0) { + if (\count($postfixlessExportIgnores) > 0) { if ($this->isAlignExportIgnoresEnabled() || $this->isStrictAlignmentCamparisonEnabled()) { $postfixlessExportIgnores = $this->getAlignedExportIgnoreArtifacts( $postfixlessExportIgnores ); } - $content = implode(" export-ignore" . $this->preferredEol, $postfixlessExportIgnores) + $content = \implode(" export-ignore" . $this->preferredEol, $postfixlessExportIgnores) . " export-ignore" . $this->preferredEol; if ($this->hasGitattributesFile()) { - $exportIgnoreContent = rtrim($content); + $exportIgnoreContent = \rtrim($content); $content = $this->getPresentNonExportIgnoresContent(); - if (strstr($content, self::EXPORT_IGNORES_PLACEMENT_PLACEHOLDER)) { - $content = str_replace( + if (\strstr($content, self::EXPORT_IGNORES_PLACEMENT_PLACEHOLDER)) { + $content = \str_replace( self::EXPORT_IGNORES_PLACEMENT_PLACEHOLDER, $exportIgnoreContent, $content ); } else { $content = $content - . str_repeat($this->preferredEol, 2) + . \str_repeat($this->preferredEol, 2) . $exportIgnoreContent; } } else { $content = "* text=auto eol=lf" - . str_repeat($this->preferredEol, 2) + . \str_repeat($this->preferredEol, 2) . $content; } @@ -500,45 +500,45 @@ public function getExpectedGitattributesContent(array $postfixlessExportIgnores */ public function getPresentExportIgnoresToPreserve(array $globPatternMatchingExportIgnores) { - $gitattributesContent = (string) file_get_contents($this->gitattributesFile); + $gitattributesContent = (string) \file_get_contents($this->gitattributesFile); - if (preg_match("/(\*\h*)(text\h*)(=\h*auto)/", $gitattributesContent)) { + if (\preg_match("/(\*\h*)(text\h*)(=\h*auto)/", $gitattributesContent)) { $this->hasTextAutoConfiguration = true; } $eol = $this->detectEol($gitattributesContent); - $gitattributesLines = preg_split( + $gitattributesLines = \preg_split( '/\\r\\n|\\r|\\n/', $gitattributesContent ); - $basenamedGlobPatternMatchingExportIgnores = array_map( + $basenamedGlobPatternMatchingExportIgnores = \array_map( 'basename', $globPatternMatchingExportIgnores ); $exportIgnoresToPreserve = []; - array_filter($gitattributesLines, function ($line) use ( + \array_filter($gitattributesLines, function ($line) use ( &$exportIgnoresToPreserve, &$globPatternMatchingExportIgnores, &$basenamedGlobPatternMatchingExportIgnores ) { - if (strstr($line, 'export-ignore') && strpos($line, '#') === false) { - list($pattern, $void) = explode('export-ignore', $line); - if (substr($pattern, 0, 1) === '/') { - $pattern = substr($pattern, 1); + if (\strstr($line, 'export-ignore') && \strpos($line, '#') === false) { + list($pattern, $void) = \explode('export-ignore', $line); + if (\substr($pattern, 0, 1) === '/') { + $pattern = \substr($pattern, 1); $this->hasPrecedingSlashesInExportIgnorePattern = true; } $patternMatches = $this->patternHasMatch($pattern); - $pattern = trim($pattern); + $pattern = \trim($pattern); if ($patternMatches - && !in_array($pattern, $globPatternMatchingExportIgnores) - && !in_array($pattern, $basenamedGlobPatternMatchingExportIgnores) + && !\in_array($pattern, $globPatternMatchingExportIgnores) + && !\in_array($pattern, $basenamedGlobPatternMatchingExportIgnores) ) { - return $exportIgnoresToPreserve[] = trim($pattern); + return $exportIgnoresToPreserve[] = \trim($pattern); } } }); @@ -555,24 +555,24 @@ public function collectExpectedExportIgnores() { $expectedExportIgnores = []; - $initialWorkingDirectory = (string) getcwd(); + $initialWorkingDirectory = (string) \getcwd(); - chdir($this->directory); + \chdir($this->directory); - $ignoredGlobMatches = array_merge( + $ignoredGlobMatches = \array_merge( $this->ignoredGlobMatches, $this->getGitignoredPatterns() ); $globMatches = Glob::glob($this->globPattern, Glob::GLOB_BRACE); - if (!is_array($globMatches)) { + if (!\is_array($globMatches)) { return $expectedExportIgnores; } foreach ($globMatches as $filename) { - if (!in_array($filename, $ignoredGlobMatches)) { - if (is_dir($filename)) { + if (!\in_array($filename, $ignoredGlobMatches)) { + if (\is_dir($filename)) { $expectedExportIgnores[] = $filename . '/'; continue; } @@ -580,23 +580,23 @@ public function collectExpectedExportIgnores() } } - chdir($initialWorkingDirectory); + \chdir($initialWorkingDirectory); if ($this->hasGitattributesFile()) { - $expectedExportIgnores = array_merge( + $expectedExportIgnores = \array_merge( $expectedExportIgnores, $this->getPresentExportIgnoresToPreserve($expectedExportIgnores) ); } - sort($expectedExportIgnores, SORT_STRING | SORT_FLAG_CASE); + \sort($expectedExportIgnores, SORT_STRING | SORT_FLAG_CASE); if ($this->isKeepLicenseEnabled()) { $licenseLessExpectedExportIgnores = []; - array_filter($expectedExportIgnores, function ($exportIgnore) use ( + \array_filter($expectedExportIgnores, function ($exportIgnore) use ( &$licenseLessExpectedExportIgnores ) { - if (!preg_match('/(License.*)/i', $exportIgnore)) { + if (!\preg_match('/(License.*)/i', $exportIgnore)) { $licenseLessExpectedExportIgnores[] = $exportIgnore; } }); @@ -604,7 +604,7 @@ public function collectExpectedExportIgnores() $expectedExportIgnores = $licenseLessExpectedExportIgnores; } - return array_unique($expectedExportIgnores); + return \array_unique($expectedExportIgnores); } /** @@ -621,7 +621,7 @@ private function detectEol($content) $eols = ["\n", "\r", "\n\r", "\r\n"]; foreach ($eols as $eol) { - if (($count = substr_count($content, $eol)) >= $maxCount) { + if (($count = \substr_count($content, $eol)) >= $maxCount) { $maxCount = $count; $preferredEol = $eol; } @@ -641,22 +641,22 @@ private function detectEol($content) */ private function patternHasMatch($globPattern) { - if (substr(trim($globPattern), 0, 1) === '/') { - $globPattern = trim(substr($globPattern, 1)); - } elseif (substr(trim($globPattern), -1) === '/') { - $globPattern = trim(substr($globPattern, 0, -1)); + if (\substr(\trim($globPattern), 0, 1) === '/') { + $globPattern = \trim(\substr($globPattern, 1)); + } elseif (\substr(\trim($globPattern), -1) === '/') { + $globPattern = \trim(\substr($globPattern, 0, -1)); } else { - $globPattern = '{' . trim($globPattern) . '}*'; + $globPattern = '{' . \trim($globPattern) . '}*'; } - $initialWorkingDirectory = (string) getcwd(); - chdir($this->directory); + $initialWorkingDirectory = (string) \getcwd(); + \chdir($this->directory); $matches = Glob::glob($globPattern, Glob::GLOB_BRACE); - chdir($initialWorkingDirectory); + \chdir($initialWorkingDirectory); - return is_array($matches) && count($matches) > 0; + return \is_array($matches) && \count($matches) > 0; } /** @@ -671,10 +671,10 @@ public function getPresentNonExportIgnoresContent() return ''; } - $gitattributesContent = (string) file_get_contents($this->gitattributesFile); + $gitattributesContent = (string) \file_get_contents($this->gitattributesFile); $eol = $this->detectEol($gitattributesContent); - $gitattributesLines = preg_split( + $gitattributesLines = \preg_split( '/\\r\\n|\\r|\\n/', $gitattributesContent ); @@ -683,13 +683,13 @@ public function getPresentNonExportIgnoresContent() $exportIgnoresPlacementPlaceholderSet = false; $exportIgnoresPlacementPlaceholder = self::EXPORT_IGNORES_PLACEMENT_PLACEHOLDER; - array_filter($gitattributesLines, function ($line) use ( + \array_filter($gitattributesLines, function ($line) use ( &$nonExportIgnoreLines, &$exportIgnoresPlacementPlaceholderSet, &$exportIgnoresPlacementPlaceholder ) { - if (strstr($line, 'export-ignore') === false || strstr($line, '#')) { - return $nonExportIgnoreLines[] = trim($line); + if (\strstr($line, 'export-ignore') === false || \strstr($line, '#')) { + return $nonExportIgnoreLines[] = \trim($line); } else { if ($exportIgnoresPlacementPlaceholderSet === false) { $exportIgnoresPlacementPlaceholderSet = true; @@ -698,7 +698,7 @@ public function getPresentNonExportIgnoresContent() } }); - return implode($eol, $nonExportIgnoreLines); + return \implode($eol, $nonExportIgnoreLines); } /** @@ -713,32 +713,32 @@ public function getPresentExportIgnores() return []; } - $gitattributesContent = (string) file_get_contents($this->gitattributesFile); + $gitattributesContent = (string) \file_get_contents($this->gitattributesFile); - $gitattributesLines = preg_split( + $gitattributesLines = \preg_split( '/\\r\\n|\\r|\\n/', $gitattributesContent ); $exportIgnores = []; - array_filter($gitattributesLines, function ($line) use (&$exportIgnores) { - if (strstr($line, 'export-ignore', true)) { - list($line, $void) = explode('export-ignore', $line); - if ($this->patternHasMatch(trim($line))) { - if (substr($line, 0, 1) === '/') { - $line = substr($line, 1); + \array_filter($gitattributesLines, function ($line) use (&$exportIgnores) { + if (\strstr($line, 'export-ignore', true)) { + list($line, $void) = \explode('export-ignore', $line); + if ($this->patternHasMatch(\trim($line))) { + if (\substr($line, 0, 1) === '/') { + $line = \substr($line, 1); } - return $exportIgnores[] = trim($line); + return $exportIgnores[] = \trim($line); } } }); if ($this->isStrictOrderCamparisonEnabled() === false) { - sort($exportIgnores, SORT_STRING | SORT_FLAG_CASE); + \sort($exportIgnores, SORT_STRING | SORT_FLAG_CASE); } - return array_unique($exportIgnores); + return \array_unique($exportIgnores); } /** @@ -747,13 +747,13 @@ public function getPresentExportIgnores() */ private function getAlignedExportIgnoreArtifacts(array $artifacts) { - $longestArtifact = max(array_map('strlen', $artifacts)); + $longestArtifact = \max(\array_map('strlen', $artifacts)); - return array_map(function ($artifact) use (&$longestArtifact) { - if (strlen($artifact) < $longestArtifact) { - return $artifact . str_repeat( + return \array_map(function ($artifact) use (&$longestArtifact) { + if (\strlen($artifact) < $longestArtifact) { + return $artifact . \str_repeat( ' ', - $longestArtifact - strlen($artifact) + $longestArtifact - \strlen($artifact) ); } return $artifact; @@ -781,6 +781,6 @@ public function hasCompleteExportIgnores() ); } - return array_values($expectedExportIgnores) === array_values($actualExportIgnores); + return \array_values($expectedExportIgnores) === \array_values($actualExportIgnores); } } diff --git a/src/Archive.php b/src/Archive.php index d5ce923..111790b 100755 --- a/src/Archive.php +++ b/src/Archive.php @@ -104,7 +104,7 @@ public function getFoundUnexpectedArtifacts() public function hasHead() { if ($this->isGitCommandAvailable()) { - exec('git show-ref --head 2>&1', $output, $returnValue); + \exec('git show-ref --head 2>&1', $output, $returnValue); return $returnValue === 0; } @@ -120,9 +120,9 @@ public function hasHead() */ public function isGitCommandAvailable($command = 'git') { - exec('where ' . $command . ' 2>&1', $output, $returnValue); + \exec('where ' . $command . ' 2>&1', $output, $returnValue); if ((new OsHelper())->isWindows() === false) { - exec('which ' . $command . ' 2>&1', $output, $returnValue); + \exec('which ' . $command . ' 2>&1', $output, $returnValue); } return $returnValue === 0; @@ -139,7 +139,7 @@ public function createArchive() { if ($this->hasHead()) { $command = 'git archive -o ' . $this->getFilename() . ' HEAD 2>&1'; - exec($command, $output, $returnValue); + \exec($command, $output, $returnValue); return $returnValue === 0; } @@ -163,21 +163,21 @@ public function compareArchive(array $unexpectedArtifacts) foreach ($archive as $archiveFile) { if ($archiveFile instanceof \SplFileInfo) { if ($archiveFile->isDir()) { - $file = basename($archiveFile) . '/'; - if (in_array($file, $unexpectedArtifacts)) { + $file = \basename($archiveFile) . '/'; + if (\in_array($file, $unexpectedArtifacts)) { $foundUnexpectedArtifacts[] = $file; } continue; } - $file = basename($archiveFile); + $file = \basename($archiveFile); if ($this->validateLicenseFilePresence()) { - if (preg_match('/(License.*)/i', $file)) { + if (\preg_match('/(License.*)/i', $file)) { $hasLicenseFile = true; } } - if (in_array($file, $unexpectedArtifacts)) { + if (\in_array($file, $unexpectedArtifacts)) { $foundUnexpectedArtifacts[] = $file; } } @@ -187,7 +187,7 @@ public function compareArchive(array $unexpectedArtifacts) throw new NoLicenseFilePresent('No license file present in archive.'); } - sort($foundUnexpectedArtifacts, SORT_STRING | SORT_FLAG_CASE); + \sort($foundUnexpectedArtifacts, SORT_STRING | SORT_FLAG_CASE); return $foundUnexpectedArtifacts; } @@ -199,8 +199,8 @@ public function compareArchive(array $unexpectedArtifacts) */ public function removeArchive() { - if (file_exists($this->getFilename())) { - return unlink($this->getFilename()); + if (\file_exists($this->getFilename())) { + return \unlink($this->getFilename()); } return false; diff --git a/src/Commands/InitCommand.php b/src/Commands/InitCommand.php index fa80b17..0b7f94c 100644 --- a/src/Commands/InitCommand.php +++ b/src/Commands/InitCommand.php @@ -81,7 +81,7 @@ protected function execute(InputInterface $input, OutputInterface $output) $defaultLpvFile = WORKING_DIRECTORY . DIRECTORY_SEPARATOR . '.lpv'; - if (file_exists($defaultLpvFile) && $overwriteDefaultLpvFile === false) { + if (\file_exists($defaultLpvFile) && $overwriteDefaultLpvFile === false) { $warning = 'Warning: A default .lpv file already exists.'; $outputContent = '' . $warning . ''; $output->writeln($outputContent); @@ -90,7 +90,7 @@ protected function execute(InputInterface $input, OutputInterface $output) } $defaultGlobPatterns = $this->analyser->getDefaultGlobPatterns(); - $lpvFileContent = implode("\n", $defaultGlobPatterns); + $lpvFileContent = \implode("\n", $defaultGlobPatterns); $bytesWritten = file_put_contents( $defaultLpvFile, diff --git a/src/Commands/ValidateCommand.php b/src/Commands/ValidateCommand.php index 4b66d92..e673d25 100755 --- a/src/Commands/ValidateCommand.php +++ b/src/Commands/ValidateCommand.php @@ -297,12 +297,12 @@ protected function execute(InputInterface $input, OutputInterface $output) $info = 'The archive file of the current HEAD is not considered lean.' . PHP_EOL . PHP_EOL . 'Seems like the following artifacts slipped in:' . PHP_EOL - . implode(PHP_EOL, $foundUnexpectedArchiveArtifacts) . '' . PHP_EOL; + . \implode(PHP_EOL, $foundUnexpectedArchiveArtifacts) . '' . PHP_EOL; - if (count($this->archiveValidator->getFoundUnexpectedArchiveArtifacts()) === 1) { + if (\count($this->archiveValidator->getFoundUnexpectedArchiveArtifacts()) === 1) { $info = 'The archive file of the current HEAD is not considered lean.' . PHP_EOL . PHP_EOL . 'Seems like the following artifact slipped in:' . PHP_EOL - . implode(PHP_EOL, $foundUnexpectedArchiveArtifacts) . '' . PHP_EOL; + . \implode(PHP_EOL, $foundUnexpectedArchiveArtifacts) . '' . PHP_EOL; } } catch (NoLicenseFilePresent $e) { $errorMessage = 'The archive file of the current HEAD ' @@ -403,7 +403,7 @@ protected function isGlobPatternFileProvided($file) */ protected function isDefaultGlobPatternFilePresent() { - return file_exists($this->defaultLpvFile); + return \file_exists($this->defaultLpvFile); } /** @@ -439,7 +439,7 @@ protected function getExpectedGitattributesFileContentOutput( $content = 'Would expect the following .gitattributes file content:' . PHP_EOL . '' . $expectedGitattributesFileContent . ''; - return str_repeat(PHP_EOL, 2) . $content; + return \str_repeat(PHP_EOL, 2) . $content; } /** diff --git a/src/Helpers/Str.php b/src/Helpers/Str.php index 26ba7ab..fe388cf 100644 --- a/src/Helpers/Str.php +++ b/src/Helpers/Str.php @@ -13,7 +13,7 @@ class Str */ public function isWindows($os = PHP_OS) { - if (strtoupper(substr($os, 0, 3)) !== 'WIN') { + if (\strtoupper(\substr($os, 0, 3)) !== 'WIN') { return false; } diff --git a/tests/AnalyserTest.php b/tests/AnalyserTest.php index 381fec0..59dab85 100755 --- a/tests/AnalyserTest.php +++ b/tests/AnalyserTest.php @@ -26,7 +26,7 @@ protected function setUp(): void */ protected function tearDown(): void { - if (is_dir($this->temporaryDirectory)) { + if (\is_dir($this->temporaryDirectory)) { $this->removeDirectory($this->temporaryDirectory); } } @@ -413,7 +413,7 @@ public function hasGitattributesFileOnExistingGitattributesFile() . DIRECTORY_SEPARATOR . '.gitattributes'; - touch($temporaryGitattributesFile); + \touch($temporaryGitattributesFile); $analyser = (new Analyser())->setDirectory($this->temporaryDirectory); @@ -431,7 +431,7 @@ public function hasGitattributesFileFailsOnNonExistingGitattributesFile() . DIRECTORY_SEPARATOR . '.nope'; - touch($temporaryGitattributesFile); + \touch($temporaryGitattributesFile); $analyser = (new Analyser())->setDirectory($this->temporaryDirectory); @@ -971,7 +971,7 @@ public function defaultExportIgnoresGlobPatternIsOverwritableFromFile() $actualExportIgnores = $analyser->collectExpectedExportIgnores(); - sort($artifactFilenamesMatchingGlob, SORT_STRING | SORT_FLAG_CASE); + \sort($artifactFilenamesMatchingGlob, SORT_STRING | SORT_FLAG_CASE); $this->assertEquals( $artifactFilenamesMatchingGlob, @@ -1001,7 +1001,7 @@ public function defaultExportIgnoresGlobPatternIsOverwritable() $actualExportIgnores = $analyser->collectExpectedExportIgnores(); - sort($artifactFilenamesMatchingGlob); + \sort($artifactFilenamesMatchingGlob); $this->assertEquals( $artifactFilenamesMatchingGlob, diff --git a/tests/ApplicationTest.php b/tests/ApplicationTest.php index 6805baa..2c81fb3 100644 --- a/tests/ApplicationTest.php +++ b/tests/ApplicationTest.php @@ -14,7 +14,7 @@ public function executableIsAvailable() { $binaryCommand = 'php bin/lean-package-validator'; - exec($binaryCommand, $output, $returnValue); + \exec($binaryCommand, $output, $returnValue); $this->assertStringStartsWith( 'Lean package validator', diff --git a/tests/Archive/ValidatorTest.php b/tests/Archive/ValidatorTest.php index 14b4ac1..ee2fc92 100755 --- a/tests/Archive/ValidatorTest.php +++ b/tests/Archive/ValidatorTest.php @@ -25,7 +25,7 @@ protected function setUp(): void */ protected function tearDown(): void { - if (is_dir($this->temporaryDirectory)) { + if (\is_dir($this->temporaryDirectory)) { $this->removeDirectory($this->temporaryDirectory); } } diff --git a/tests/ArchiveTest.php b/tests/ArchiveTest.php index 97ffbbf..ac46d1a 100755 --- a/tests/ArchiveTest.php +++ b/tests/ArchiveTest.php @@ -23,7 +23,7 @@ public function setUp():void */ protected function tearDown():void { - if (is_dir($this->temporaryDirectory)) { + if (\is_dir($this->temporaryDirectory)) { $this->removeDirectory($this->temporaryDirectory); } } diff --git a/tests/Commands/InitCommandTest.php b/tests/Commands/InitCommandTest.php index 14ecc79..d6f5a09 100644 --- a/tests/Commands/InitCommandTest.php +++ b/tests/Commands/InitCommandTest.php @@ -27,8 +27,8 @@ class InitCommandTest extends TestCase protected function setUp(): void { $this->setUpTemporaryDirectory(); - if (!defined('WORKING_DIRECTORY')) { - define('WORKING_DIRECTORY', $this->temporaryDirectory); + if (!\defined('WORKING_DIRECTORY')) { + \define('WORKING_DIRECTORY', $this->temporaryDirectory); } $this->application = $this->getApplication(); } @@ -40,7 +40,7 @@ protected function setUp(): void */ protected function tearDown(): void { - if (is_dir($this->temporaryDirectory)) { + if (\is_dir($this->temporaryDirectory)) { $this->removeDirectory($this->temporaryDirectory); } } @@ -92,7 +92,7 @@ public function createsExpectedDefaultLpvFile() $this->assertSame($expectedDisplay, $commandTester->getDisplay()); $this->assertTrue($commandTester->getStatusCode() == 0); $this->assertFileExists($expectedDefaultLpvFile); - $this->assertEquals($expectedDefaultLpvFileContent, file_get_contents($expectedDefaultLpvFile)); + $this->assertEquals($expectedDefaultLpvFileContent, \file_get_contents($expectedDefaultLpvFile)); } /** @@ -135,7 +135,7 @@ public function existingDefaultLpvFileIsNotOverwritten() $expectedDefaultLpvFile = $this->temporaryDirectory . DIRECTORY_SEPARATOR . '.lpv'; - touch($expectedDefaultLpvFile); + \touch($expectedDefaultLpvFile); $command = $this->application->find('init'); $commandTester = new CommandTester($command); @@ -161,7 +161,7 @@ public function existingDefaultLpvFileIsOverwrittenWhenDesired() $expectedDefaultLpvFile = $this->temporaryDirectory . DIRECTORY_SEPARATOR . '.lpv'; - touch($expectedDefaultLpvFile); + \touch($expectedDefaultLpvFile); $command = $this->application->find('init'); $commandTester = new CommandTester($command); diff --git a/tests/Commands/ValidateCommandTest.php b/tests/Commands/ValidateCommandTest.php index 918b701..b830d5e 100644 --- a/tests/Commands/ValidateCommandTest.php +++ b/tests/Commands/ValidateCommandTest.php @@ -28,8 +28,8 @@ class ValidateCommandTest extends TestCase protected function setUp(): void { $this->setUpTemporaryDirectory(); - if (!defined('WORKING_DIRECTORY')) { - define('WORKING_DIRECTORY', $this->temporaryDirectory); + if (!\defined('WORKING_DIRECTORY')) { + \define('WORKING_DIRECTORY', $this->temporaryDirectory); } $this->application = $this->getApplication(); } @@ -41,7 +41,7 @@ protected function setUp(): void */ protected function tearDown(): void { - if (is_dir($this->temporaryDirectory)) { + if (\is_dir($this->temporaryDirectory)) { $this->removeDirectory($this->temporaryDirectory); } } @@ -1885,7 +1885,7 @@ protected function getApplicationWithMockedAnalyser(MockInterface $mockedAnalyse $archive = new Archive( $this->temporaryDirectory, - basename($this->temporaryDirectory) + \basename($this->temporaryDirectory) ); $analyserCommand = new ValidateCommand( @@ -1923,7 +1923,7 @@ protected function getApplication() $application = new Application(); $archive = new Archive( $this->temporaryDirectory, - basename($this->temporaryDirectory) + \basename($this->temporaryDirectory) ); $analyserCommand = new ValidateCommand( diff --git a/tests/TestCase.php b/tests/TestCase.php index cc336f3..a71cf53 100755 --- a/tests/TestCase.php +++ b/tests/TestCase.php @@ -17,16 +17,16 @@ class TestCase extends PHPUnit protected function setUpTemporaryDirectory() { if ((new OsHelper())->isWindows() === false) { - ini_set('sys_temp_dir', '/tmp/lpv'); + \ini_set('sys_temp_dir', '/tmp/lpv'); $this->temporaryDirectory = '/tmp/lpv'; } else { - $this->temporaryDirectory = sys_get_temp_dir() + $this->temporaryDirectory = \sys_get_temp_dir() . DIRECTORY_SEPARATOR . 'lpv'; } - if (!file_exists($this->temporaryDirectory)) { - mkdir($this->temporaryDirectory); + if (!\file_exists($this->temporaryDirectory)) { + \mkdir($this->temporaryDirectory); } } @@ -44,13 +44,13 @@ protected function removeDirectory($directory) foreach ($files as $fileinfo) { if ($fileinfo->isDir()) { - @rmdir($fileinfo->getRealPath()); + @\rmdir($fileinfo->getRealPath()); continue; } - @unlink($fileinfo->getRealPath()); + @\unlink($fileinfo->getRealPath()); } - @rmdir($directory); + @\rmdir($directory); } /** @@ -68,15 +68,15 @@ protected function createTemporaryFiles(array $files, array $directories = []) $artifactFile = $this->temporaryDirectory . DIRECTORY_SEPARATOR . $file; - touch($artifactFile); + \touch($artifactFile); } - if (is_array($directories) && count($directories) > 0) { + if (\is_array($directories) && \count($directories) > 0) { foreach ($directories as $directory) { $artifactDirectory = $this->temporaryDirectory . DIRECTORY_SEPARATOR . $directory; - mkdir($artifactDirectory); + \mkdir($artifactDirectory); } } } @@ -94,7 +94,7 @@ protected function createTemporaryGitattributesFile($content) . DIRECTORY_SEPARATOR . '.gitattributes'; - return file_put_contents($temporaryGitattributesFile, $content) >= 0; + return \file_put_contents($temporaryGitattributesFile, $content) >= 0; } /** @@ -110,7 +110,7 @@ protected function createTemporaryGitignoreFile($content) . DIRECTORY_SEPARATOR . '.gitignore'; - return file_put_contents($temporaryGitignoreFile, $content) >= 0; + return \file_put_contents($temporaryGitignoreFile, $content) >= 0; } /** @@ -126,6 +126,6 @@ protected function createTemporaryGlobPatternFile($content) . DIRECTORY_SEPARATOR . '.lpv'; - return file_put_contents($temporaryLpvFile, $content) >= 0; + return \file_put_contents($temporaryLpvFile, $content) >= 0; } } From ebcc7177bbdee7ba7069c19f601d1d3f2c051238 Mon Sep 17 00:00:00 2001 From: Raphael Stolt Date: Thu, 28 Sep 2023 13:22:38 +0200 Subject: [PATCH 014/152] Fixes broken build --- .github/workflows/distribute.yml | 4 ++-- .github/workflows/lint.yml | 4 ++-- .github/workflows/static-analyse.yml | 4 ++-- .github/workflows/test.yml | 4 ++-- composer.json | 2 +- 5 files changed, 9 insertions(+), 9 deletions(-) diff --git a/.github/workflows/distribute.yml b/.github/workflows/distribute.yml index dac3f50..0d02337 100644 --- a/.github/workflows/distribute.yml +++ b/.github/workflows/distribute.yml @@ -18,7 +18,7 @@ jobs: steps: - name: Checkout - uses: actions/checkout@v2 + uses: actions/checkout@v3 - name: Install PHP uses: shivammathur/setup-php@v2 @@ -26,7 +26,7 @@ jobs: php-version: "${{ matrix.php }}" - name: Install Composer dependencies - run: composer install --no-progress --no-suggest --prefer-dist --optimize-autoloader && composer require --dev --with-all-dependencies humbug/box + run: composer install --no-progress --prefer-dist --optimize-autoloader && composer require --dev --with-all-dependencies humbug/box - name: Build PHAR run: vendor/humbug/box/bin/box compile diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 3dd7604..23029c4 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -15,7 +15,7 @@ jobs: steps: - name: Checkout - uses: actions/checkout@v2 + uses: actions/checkout@v3 - name: Install PHP uses: shivammathur/setup-php@v2 @@ -23,7 +23,7 @@ jobs: php-version: "${{ matrix.php }}" - name: Install Composer dependencies - run: composer install --no-progress --no-suggest --prefer-dist --optimize-autoloader + run: composer install --no-progress --prefer-dist --optimize-autoloader - name: Check coding styles run: composer run-script lpv:cs-lint diff --git a/.github/workflows/static-analyse.yml b/.github/workflows/static-analyse.yml index bef7f9c..a0f0abb 100644 --- a/.github/workflows/static-analyse.yml +++ b/.github/workflows/static-analyse.yml @@ -15,7 +15,7 @@ jobs: steps: - name: Checkout - uses: actions/checkout@v2 + uses: actions/checkout@v3 - name: Install PHP uses: shivammathur/setup-php@v2 @@ -23,7 +23,7 @@ jobs: php-version: "${{ matrix.php }}" - name: Install Composer dependencies - run: composer install --no-progress --no-suggest --prefer-dist --optimize-autoloader + run: composer install --no-progress --prefer-dist --optimize-autoloader - name: Run static analyse run: composer run-script lpv:static-analyse diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index c304d2c..1d2c87f 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -16,7 +16,7 @@ jobs: steps: - name: Checkout - uses: actions/checkout@v2 + uses: actions/checkout@v3 - name: Install PHP uses: shivammathur/setup-php@v2 @@ -24,7 +24,7 @@ jobs: php-version: "${{ matrix.php }}" - name: Install Composer dependencies - run: composer update --no-progress --no-suggest --prefer-dist --optimize-autoloader + run: composer update --no-progress --prefer-dist --optimize-autoloader - name: Run tests run: composer run-script lpv:test diff --git a/composer.json b/composer.json index dd36043..3842cdb 100755 --- a/composer.json +++ b/composer.json @@ -56,6 +56,6 @@ "phlak/semver": "^4.1", "php-mock/php-mock-phpunit": "^2.7||^1.1", "phpstan/phpstan": "^1.6.2", - "phpunit/phpunit": "^10.3" + "phpunit/phpunit": "^10.3||^9.6.13" } } From 017965580159b012348721adec870ebf52df1d65 Mon Sep 17 00:00:00 2001 From: Raphael Stolt Date: Mon, 2 Oct 2023 11:17:10 +0200 Subject: [PATCH 015/152] Aligns CI jobs --- .github/workflows/distribute.yml | 4 ++-- .github/workflows/lint.yml | 4 ++-- .github/workflows/static-analyse.yml | 4 ++-- .github/workflows/test.yml | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/.github/workflows/distribute.yml b/.github/workflows/distribute.yml index 0d02337..8e6b5ca 100644 --- a/.github/workflows/distribute.yml +++ b/.github/workflows/distribute.yml @@ -1,4 +1,4 @@ -name: distribute-cli +name: distribute on: push: @@ -7,7 +7,7 @@ on: jobs: tests: - name: distribute-cli + name: distribute runs-on: ubuntu-latest strategy: diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 23029c4..6f4b788 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -1,10 +1,10 @@ -name: lint-cli +name: lint on: push jobs: tests: - name: lint-cli + name: lint runs-on: ubuntu-latest strategy: diff --git a/.github/workflows/static-analyse.yml b/.github/workflows/static-analyse.yml index a0f0abb..8b03569 100644 --- a/.github/workflows/static-analyse.yml +++ b/.github/workflows/static-analyse.yml @@ -1,10 +1,10 @@ -name: static-analyse-cli +name: static-analyse on: push jobs: tests: - name: static-analyse-cli + name: static-analyse runs-on: ubuntu-latest strategy: diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 1d2c87f..80e59aa 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -1,4 +1,4 @@ -name: test-cli +name: test on: push From 24b76422cca17b231cba1587018f024d3d713a3e Mon Sep 17 00:00:00 2001 From: Raphael Stolt Date: Mon, 2 Oct 2023 15:18:10 +0200 Subject: [PATCH 016/152] Enforces native_function_invocation PHP-CS-Fixer rule --- .php-cs-fixer.php | 4 ++++ composer.json | 4 ++-- tests/TestCase.php | 6 +++--- 3 files changed, 9 insertions(+), 5 deletions(-) diff --git a/.php-cs-fixer.php b/.php-cs-fixer.php index c762fae..18d929c 100755 --- a/.php-cs-fixer.php +++ b/.php-cs-fixer.php @@ -11,6 +11,10 @@ '@PSR2' => true, 'phpdoc_order' => true, 'ordered_imports' => true, + 'native_function_invocation' => [ + 'include' => ['@internal'], + 'exclude' => ['file_put_contents'] + ] ]; $cacheDir = getenv('HOME') ? getenv('HOME') : __DIR__; diff --git a/composer.json b/composer.json index 3842cdb..b4f445a 100755 --- a/composer.json +++ b/composer.json @@ -40,8 +40,8 @@ "scripts": { "lpv:test": "phpunit", "lpv:test-with-coverage": "phpunit --coverage-html coverage-reports", - "lpv:cs-fix": "php-cs-fixer fix . -vv || true", - "lpv:cs-lint": "php-cs-fixer fix --diff --stop-on-violation --verbose --dry-run", + "lpv:cs-fix": "php-cs-fixer --allow-risky=yes fix . -vv || true", + "lpv:cs-lint": "php-cs-fixer fix --diff --stop-on-violation --verbose --dry-run --allow-risky=yes", "lpv:configure-commit-template": "git config --add commit.template .gitmessage", "lpv:application-version-guard": "php bin/application-version --verify-tag-match=bin", "lpv:application-phar-version-guard": "php bin/application-version --verify-tag-match=phar", diff --git a/tests/TestCase.php b/tests/TestCase.php index a71cf53..7f72158 100755 --- a/tests/TestCase.php +++ b/tests/TestCase.php @@ -94,7 +94,7 @@ protected function createTemporaryGitattributesFile($content) . DIRECTORY_SEPARATOR . '.gitattributes'; - return \file_put_contents($temporaryGitattributesFile, $content) >= 0; + return file_put_contents($temporaryGitattributesFile, $content) >= 0; } /** @@ -110,7 +110,7 @@ protected function createTemporaryGitignoreFile($content) . DIRECTORY_SEPARATOR . '.gitignore'; - return \file_put_contents($temporaryGitignoreFile, $content) >= 0; + return file_put_contents($temporaryGitignoreFile, $content) >= 0; } /** @@ -126,6 +126,6 @@ protected function createTemporaryGlobPatternFile($content) . DIRECTORY_SEPARATOR . '.lpv'; - return \file_put_contents($temporaryLpvFile, $content) >= 0; + return file_put_contents($temporaryLpvFile, $content) >= 0; } } From ae08d65f172ef5ffcfb5e27868077ccbd28bf240 Mon Sep 17 00:00:00 2001 From: Raphael Stolt Date: Mon, 2 Oct 2023 16:42:48 +0200 Subject: [PATCH 017/152] Improves documentation --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index e484fd4..bc35914 100755 --- a/README.md +++ b/README.md @@ -64,14 +64,14 @@ The `--overwrite|-o` option overwrites an existing `.gitattributes` file when th lean-package-validator validate [] --overwrite ``` -The `--glob-pattern` option allows you to overwrite the default pattern\* used to match common repository artifacts. The amount of pattern in the grouping braces is expected to be `>1`. As shown next this utility could thereby also be used for projects (i.e. Python) outside of the PHP ecosystem. +The `--glob-pattern` option allows you to overwrite the default pattern used to match common repository artifacts. The amount of pattern in the grouping braces is expected to be `>1`. As shown next this utility could thereby also be used for projects (i.e. Python) outside of the PHP ecosystem. ``` bash lean-package-validator validate [] --glob-pattern '{.*,*.rst,*.py[cod],dist/}' ``` -\* The default pattern is `{.*,*.lock,*.txt,*.rst,*.{md,MD},*.xml,*.yml,appveyor.yml,box.json,captainhook.json,*.dist.*,*.dist,{B,b}uild*,{D,d}oc*,{T,t}ool*,{T,t}est*,{S,s}pec*,{E,e}xample*,LICENSE,{{M,m}ake,{B,b}ox,{V,v}agrant,{P,p}hulp}file,RMT}*`. +The default pattern is `{.*,*.lock,*.txt,*.rst,*.{md,MD},*.xml,*.yml,appveyor.yml,box.json,captainhook.json,*.dist.*,*.dist,{B,b}uild*,{D,d}oc*,{T,t}ool*,{T,t}est*,{S,s}pec*,{E,e}xample*,LICENSE,{{M,m}ake,{B,b}ox,{V,v}agrant,{P,p}hulp}file,RMT}*`. -The `--glob-pattern-file` option allows you to load patterns, which should be used to match the common repository artifacts, from a given file. You can put a `.lpv` file in the repository which will be used per default and overwrite the default pattern\*. The structure of such a glob pattern file can be taken from the [example](example/.lpv) directory or be created via `lean-package-validator init`. +The `--glob-pattern-file` option allows you to load patterns, which should be used to match the common repository artifacts, from a given file. You can put a `.lpv` file in the repository which will be used per default and overwrite the default pattern. The structure of such a glob pattern file can be taken from the [example](example/.lpv) directory or be created via `lean-package-validator init`. ``` bash lean-package-validator validate [] --glob-pattern-file /path/to/glob-pattern-file From df47b6da609b97d533152ec98c9c36756db32344 Mon Sep 17 00:00:00 2001 From: Raphael Stolt Date: Mon, 2 Oct 2023 17:08:12 +0200 Subject: [PATCH 018/152] Uses .lpv glob pattern file if present --- composer.json | 2 +- src/Commands/ValidateCommand.php | 9 +++- tests/Commands/ValidateCommandTest.php | 58 +++++++++++++++++++++++++- 3 files changed, 65 insertions(+), 4 deletions(-) diff --git a/composer.json b/composer.json index b4f445a..5956770 100755 --- a/composer.json +++ b/composer.json @@ -39,7 +39,7 @@ }, "scripts": { "lpv:test": "phpunit", - "lpv:test-with-coverage": "phpunit --coverage-html coverage-reports", + "lpv:test-with-coverage": "export XDEBUG_MODE=coverage && phpunit --coverage-html coverage-reports", "lpv:cs-fix": "php-cs-fixer --allow-risky=yes fix . -vv || true", "lpv:cs-lint": "php-cs-fixer fix --diff --stop-on-violation --verbose --dry-run --allow-risky=yes", "lpv:configure-commit-template": "git config --add commit.template .gitmessage", diff --git a/src/Commands/ValidateCommand.php b/src/Commands/ValidateCommand.php index e673d25..1980010 100755 --- a/src/Commands/ValidateCommand.php +++ b/src/Commands/ValidateCommand.php @@ -215,9 +215,14 @@ protected function execute(InputInterface $input, OutputInterface $output) return 1; } - } elseif ($this->isGlobPatternFileSetable($globPatternFile)) { + } elseif($this->isGlobPatternFileSetable($globPatternFile)) { try { - $this->analyser->setGlobPatternFromFile($globPatternFile); + if ($this->isDefaultGlobPatternFilePresent()) { + $this->analyser->setGlobPatternFromFile($this->defaultLpvFile); + } + if ($globPatternFile) { + $this->analyser->setGlobPatternFromFile($globPatternFile); + } } catch (NonExistentGlobPatternFile $e) { $warning = "Warning: The provided glob pattern file " . "'$globPatternFile' doesn't exist."; diff --git a/tests/Commands/ValidateCommandTest.php b/tests/Commands/ValidateCommandTest.php index b830d5e..b705b5b 100644 --- a/tests/Commands/ValidateCommandTest.php +++ b/tests/Commands/ValidateCommandTest.php @@ -1531,7 +1531,8 @@ public function givenGlobPatternTakesPrecedenceOverDefaultGlobPatternFile() $artifactFilenames = [ '.buildignore', 'phpspec.yml.dist', - 'Phulpfile' + 'Phulpfile', + '.lpv' ]; $this->createTemporaryFiles( @@ -1632,6 +1633,61 @@ public function presentGlobPatternFileTakesPrecedenceOverDefaultGlobPattern() $expectedDisplay = <<assertSame($expectedDisplay, $commandTester->getDisplay()); + $this->assertTrue($commandTester->getStatusCode() === 0); + } + + /** + * @test + * @group glob + * @ticket 35 https://github.com/raphaelstolt/lean-package-validator/issues/35 + */ + public function presentLpvPatternFileIsUsed() + { + $artifactFilenames = [ + 'a.txt', + 'b.rst', + 'Vagrantfile' + ]; + + $this->createTemporaryFiles( + $artifactFilenames, + ['example'] + ); + + $gitattributesContent = <<createTemporaryGitattributesFile($gitattributesContent); + + $lpvContent = <<createTemporaryGlobPatternFile($lpvContent); + + $command = $this->application->find('validate'); + $commandTester = new CommandTester($command); + $commandTester->execute([ + 'command' => $command->getName(), + 'directory' => WORKING_DIRECTORY, + ]); + + $expectedDisplay = <<assertSame($expectedDisplay, $commandTester->getDisplay()); From 8fc79d4b187595bccc8fc17d2e5a8a35b13d7789 Mon Sep 17 00:00:00 2001 From: Raphael Stolt Date: Tue, 3 Oct 2023 05:23:16 +0200 Subject: [PATCH 019/152] Uses lean-package-validator GitHub Action --- .github/workflows/lint.yml | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 6f4b788..0cfe2f7 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -15,7 +15,7 @@ jobs: steps: - name: Checkout - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Install PHP uses: shivammathur/setup-php@v2 @@ -27,3 +27,9 @@ jobs: - name: Check coding styles run: composer run-script lpv:cs-lint + + - name: Check leanness of package + uses: raphaelstolt/lean-package-validator-action@v0.1.0 + with: + php-version: "${{ matrix.php }}" + lpv-version: "3.0.0" From 9f5e0d24515de0520fcb09438a5e0cd48db4e142 Mon Sep 17 00:00:00 2001 From: Raphael Stolt Date: Tue, 3 Oct 2023 11:21:40 +0200 Subject: [PATCH 020/152] Links GitHub Action --- README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index bc35914..401ea8d 100755 --- a/README.md +++ b/README.md @@ -107,7 +107,7 @@ lean-package-validator init [] The `--overwrite|-o` option overwrites an existing `.lpv` file. -## Utilisation via Composer scripts +## Utilisation via Composer scripts or it's dedicated GitHub Action To avoid that changes coming from contributions or own modifications slip into release/dist archives it might be helpful to use a guarding [Composer script](https://getcomposer.org/doc/articles/scripts.md), which will be available at everyone's fingertips. By adding the following to the project/micro-package its `composer.json` the ` .gitattributes` file can now be easily validated via `composer validate-gitattributes`. @@ -120,6 +120,8 @@ By adding the following to the project/micro-package its `composer.json` the ` . } ``` +For utilising a dedicated GitHub Action have a look at the documentation over [here](https://github.com/raphaelstolt/lean-package-validator-action). + #### Running tests ``` bash composer lpv:test From 6cf3f03014be906996b307cff4a210ddc8b5c94e Mon Sep 17 00:00:00 2001 From: Raphael Stolt Date: Tue, 3 Oct 2023 11:46:58 +0200 Subject: [PATCH 021/152] Repository maintenance --- .gitattributes | 2 -- .gitignore | 1 + 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/.gitattributes b/.gitattributes index e5bce46..02be349 100755 --- a/.gitattributes +++ b/.gitattributes @@ -9,13 +9,11 @@ .gitmessage export-ignore .gub export-ignore .php-cs-fixer.php export-ignore -.travis.yml export-ignore .phpunit.result.cache export-ignore bin/application-version export-ignore bin/lean-package-validator.phar export-ignore bin/release-version export-ignore bin/start-watchman export-ignore -bin/travis/ export-ignore box.json.dist export-ignore CHANGELOG.md export-ignore example/ export-ignore diff --git a/.gitignore b/.gitignore index f9ab5a9..5e23c48 100755 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,4 @@ coverage-reports/ composer.lock .php_cs.cache .phpunit.result.cache +.phpunit.cache From c26278ea753d3c69bb997a275b1558c0cc2ca618 Mon Sep 17 00:00:00 2001 From: Raphael Stolt Date: Fri, 6 Oct 2023 00:51:29 +0200 Subject: [PATCH 022/152] Catches empty glob pattern --- CHANGELOG.md | 2 ++ src/Commands/ValidateCommand.php | 3 +-- tests/Commands/ValidateCommandTest.php | 25 +++++++++++++++++++++++++ 3 files changed, 28 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3f7cbbb..0571ed7 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,8 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](http://keepachangelog.com/) and this project adheres to [Semantic Versioning](http://semver.org/). ## [Unreleased] +### Fixed +- Empty glob pattern is catched as invalid. Closes [#38](https://github.com/raphaelstolt/lean-package-validator/issues/38). ## [v3.0.1] - 2023-09-26 ### Removed diff --git a/src/Commands/ValidateCommand.php b/src/Commands/ValidateCommand.php index 1980010..86b4123 100755 --- a/src/Commands/ValidateCommand.php +++ b/src/Commands/ValidateCommand.php @@ -203,8 +203,7 @@ protected function execute(InputInterface $input, OutputInterface $output) if ($alignExportIgnores) { $this->analyser->alignExportIgnores(); } - - if ($globPattern) { + if ($globPattern || $globPattern === '') { try { $this->analyser->setGlobPattern((string) $globPattern); } catch (InvalidGlobPattern $e) { diff --git a/tests/Commands/ValidateCommandTest.php b/tests/Commands/ValidateCommandTest.php index b705b5b..9fdd54c 100644 --- a/tests/Commands/ValidateCommandTest.php +++ b/tests/Commands/ValidateCommandTest.php @@ -871,6 +871,31 @@ public function usageOfInvalidGlobFailsValidation() $expectedDisplay = <<assertSame($expectedDisplay, $commandTester->getDisplay()); + $this->assertTrue($commandTester->getStatusCode() > 0); + } + + /** + * @test + * @group glob + * @ticket 38 (https://github.com/raphaelstolt/lean-package-validator/issues/38) + */ + public function missingGlobPatternProducesUserFriendlyErrorMessage() + { + $missingGlobPattern = ''; + $command = $this->application->find('validate'); + $commandTester = new CommandTester($command); + $commandTester->execute([ + 'command' => $command->getName(), + 'directory' => WORKING_DIRECTORY, + '--glob-pattern' => $missingGlobPattern, + ]); + + $expectedDisplay = <<assertSame($expectedDisplay, $commandTester->getDisplay()); From 3dd05d7136d5bef47bd12f37d8093add714bb2d5 Mon Sep 17 00:00:00 2001 From: Raphael Stolt Date: Fri, 6 Oct 2023 01:25:08 +0200 Subject: [PATCH 023/152] Updates dependency --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 5956770..4982be5 100755 --- a/composer.json +++ b/composer.json @@ -11,7 +11,7 @@ ], "require": { "php": ">=8.0", - "symfony/console": "^v6.0.8||^v5.4.8", + "symfony/console": "^v6.3||^v5.4.8", "laminas/laminas-stdlib": "^3.7" }, "autoload": { From 33373b09867245ad1d6d722674a4f1ddd59f1177 Mon Sep 17 00:00:00 2001 From: Raphael Stolt Date: Fri, 6 Oct 2023 01:25:47 +0200 Subject: [PATCH 024/152] Adds verbose output --- .gitignore | 1 + CHANGELOG.md | 3 + src/Commands/InitCommand.php | 10 +++ src/Commands/ValidateCommand.php | 113 +++++++++++++++++++++++------ tests/Commands/InitCommandTest.php | 34 ++++++++- 5 files changed, 135 insertions(+), 26 deletions(-) diff --git a/.gitignore b/.gitignore index 5e23c48..065f112 100755 --- a/.gitignore +++ b/.gitignore @@ -5,3 +5,4 @@ composer.lock .php_cs.cache .phpunit.result.cache .phpunit.cache +.idea/ diff --git a/CHANGELOG.md b/CHANGELOG.md index 0571ed7..dbad1ff 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,9 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](http://keepachangelog.com/) and this project adheres to [Semantic Versioning](http://semver.org/). ## [Unreleased] +### Added +- Added verbose output. Closes [#37](https://github.com/raphaelstolt/lean-package-validator/issues/37). + ### Fixed - Empty glob pattern is catched as invalid. Closes [#38](https://github.com/raphaelstolt/lean-package-validator/issues/38). diff --git a/src/Commands/InitCommand.php b/src/Commands/InitCommand.php index 0b7f94c..f025f3b 100644 --- a/src/Commands/InitCommand.php +++ b/src/Commands/InitCommand.php @@ -1,5 +1,7 @@ ' . $warning . ''; $output->writeln($outputContent); + $output->writeln($e->getMessage(), OutputInterface::VERBOSITY_DEBUG); + return 1; } } $defaultLpvFile = WORKING_DIRECTORY . DIRECTORY_SEPARATOR . '.lpv'; + $verboseOutput = "+ Checking .lpv file existence in " . WORKING_DIRECTORY . "."; + $output->writeln($verboseOutput, OutputInterface::VERBOSITY_VERBOSE); + if (\file_exists($defaultLpvFile) && $overwriteDefaultLpvFile === false) { $warning = 'Warning: A default .lpv file already exists.'; $outputContent = '' . $warning . ''; @@ -97,6 +104,9 @@ protected function execute(InputInterface $input, OutputInterface $output) $lpvFileContent ); + $verboseOutput = '+ Writing default glob pattern to .lpv file in ' . WORKING_DIRECTORY . '.'; + $output->writeln($verboseOutput, OutputInterface::VERBOSITY_VERBOSE); + if ($bytesWritten === false) { $warning = 'Warning: The creation of the default .lpv file failed.'; $outputContent = '' . $warning . ''; diff --git a/src/Commands/ValidateCommand.php b/src/Commands/ValidateCommand.php index 86b4123..a551542 100755 --- a/src/Commands/ValidateCommand.php +++ b/src/Commands/ValidateCommand.php @@ -1,7 +1,10 @@ ' . $warning . ''; $output->writeln($outputContent); + $output->writeln($e->getMessage(), OutputInterface::VERBOSITY_DEBUG); + return 1; } } + $verboseOutput = '+ Scanning directory ' . $directory . '.'; + $output->writeln($verboseOutput, OutputInterface::VERBOSITY_VERBOSE); + $createGitattributesFile = $input->getOption('create'); $overwriteGitattributesFile = $input->getOption('overwrite'); $validateArchive = $input->getOption('validate-git-archive'); @@ -183,28 +191,44 @@ protected function execute(InputInterface $input, OutputInterface $output) $enforceStrictOrderComparison = $input->getOption('enforce-strict-order'); if ($enforceStrictOrderComparison) { + $verboseOutput = '+ Enforcing strict order comparison.'; + $output->writeln($verboseOutput, OutputInterface::VERBOSITY_VERBOSE); + $this->analyser->enableStrictOrderCamparison(); } $enforceExportIgnoresAlignment = $input->getOption('enforce-alignment'); if ($enforceExportIgnoresAlignment) { + $verboseOutput = '+ Enforcing alignment comparison.'; + $output->writeln($verboseOutput, OutputInterface::VERBOSITY_VERBOSE); + $this->analyser->enableStrictAlignmentCamparison(); } $keepLicense = (boolean) $input->getOption('keep-license'); if ($keepLicense) { + $verboseOutput = '+ Keeping the license file.'; + $output->writeln($verboseOutput, OutputInterface::VERBOSITY_VERBOSE); + $this->analyser->keepLicense(); } $alignExportIgnores = $input->getOption('align-export-ignores'); if ($alignExportIgnores) { + $verboseOutput = '+ Aligning the export-ignores.'; + $output->writeln($verboseOutput, OutputInterface::VERBOSITY_VERBOSE); + $this->analyser->alignExportIgnores(); } + if ($globPattern || $globPattern === '') { try { + $verboseOutput = "+ Using glob pattern $globPattern."; + $output->writeln($verboseOutput, OutputInterface::VERBOSITY_VERBOSE); + $this->analyser->setGlobPattern((string) $globPattern); } catch (InvalidGlobPattern $e) { $warning = "Warning: The provided glob pattern " @@ -212,14 +236,20 @@ protected function execute(InputInterface $input, OutputInterface $output) $outputContent = '' . $warning . ''; $output->writeln($outputContent); + $output->writeln($e->getMessage(), OutputInterface::VERBOSITY_DEBUG); + return 1; } } elseif($this->isGlobPatternFileSetable($globPatternFile)) { try { if ($this->isDefaultGlobPatternFilePresent()) { - $this->analyser->setGlobPatternFromFile($this->defaultLpvFile); + $this->analyser->setGlobPatternFromFile($globPatternFile); } if ($globPatternFile) { + $globPatternFileInfo = new SplFileInfo($globPatternFile); + $verboseOutput = '+ Using ' . $globPatternFileInfo->getBasename() . ' file as glob pattern input.'; + $output->writeln($verboseOutput, OutputInterface::VERBOSITY_VERBOSE); + $this->analyser->setGlobPatternFromFile($globPatternFile); } } catch (NonExistentGlobPatternFile $e) { @@ -228,6 +258,8 @@ protected function execute(InputInterface $input, OutputInterface $output) $outputContent = '' . $warning . ''; $output->writeln($outputContent); + $output->writeln($e->getMessage(), OutputInterface::VERBOSITY_DEBUG); + return 1; } catch (InvalidGlobPatternFile $e) { $warning = "Warning: The provided glob pattern file " @@ -235,10 +267,15 @@ protected function execute(InputInterface $input, OutputInterface $output) $outputContent = '' . $warning . ''; $output->writeln($outputContent); + $output->writeln($e->getMessage(), OutputInterface::VERBOSITY_DEBUG); + return 1; } } + $verboseOutput = '+ Checking .gitattribute file existence in ' . WORKING_DIRECTORY . '.'; + $output->writeln($verboseOutput, OutputInterface::VERBOSITY_VERBOSE); + if (!$this->analyser->hasGitattributesFile()) { $warning = 'Warning: There is no .gitattributes file present in ' . $this->analyser->getDirectory() . '.'; @@ -247,6 +284,9 @@ protected function execute(InputInterface $input, OutputInterface $output) $expectedGitattributesFileContent = $this->analyser ->getExpectedGitattributesContent(); + $verboseOutput = '+ Getting expected .gitattribute file content.'; + $output->writeln($verboseOutput, OutputInterface::VERBOSITY_VERBOSE); + if ($expectedGitattributesFileContent !== '') { if ($createGitattributesFile || $overwriteGitattributesFile) { try { @@ -270,9 +310,15 @@ protected function execute(InputInterface $input, OutputInterface $output) } catch (GitattributesCreationFailed $e) { $outputContent .= PHP_EOL . PHP_EOL . $e->getMessage(); $output->writeln($outputContent); + + $output->writeln($e->getMessage(), OutputInterface::VERBOSITY_DEBUG); + return 1; } } else { + $verboseOutput = '+ Suggesting .gitattribute file content.'; + $output->writeln($verboseOutput, OutputInterface::VERBOSITY_VERBOSE); + $outputContent .= $this->getSuggestGitattributesFileCreationOptionOutput( $expectedGitattributesFileContent ); @@ -290,6 +336,9 @@ protected function execute(InputInterface $input, OutputInterface $output) return 1; } elseif ($validateArchive) { try { + $verboseOutput = '+ Validating Git archive.'; + $output->writeln($verboseOutput, OutputInterface::VERBOSITY_VERBOSE); + if ($this->isValidArchive($keepLicense)) { $info = 'The archive file of the current HEAD is considered lean.'; $output->writeln($info); @@ -312,6 +361,9 @@ protected function execute(InputInterface $input, OutputInterface $output) $errorMessage = 'The archive file of the current HEAD ' . 'is considered invalid due to a missing license file.'; $info = '' . $errorMessage . '' . PHP_EOL; + + $output->writeln($e->getMessage(), OutputInterface::VERBOSITY_DEBUG); + $this->archiveValidator->getArchive()->removeArchive(); } @@ -319,44 +371,59 @@ protected function execute(InputInterface $input, OutputInterface $output) return 1; } else { + $verboseOutput = '+ Analysing the .gitattribute content.'; + $output->writeln($verboseOutput, OutputInterface::VERBOSITY_VERBOSE); + if ($this->analyser->hasCompleteExportIgnores() === false) { $outputContent = 'The present .gitattributes file is considered invalid.'; - if ($this->analyser->hasCompleteExportIgnores() === false) { - $expectedGitattributesFileContent = $this->analyser - ->getExpectedGitattributesContent(); + $verboseOutput = "+ Gathering expected .gitattribute content."; + $output->writeln($verboseOutput, OutputInterface::VERBOSITY_VERBOSE); + + $expectedGitattributesFileContent = $this->analyser + ->getExpectedGitattributesContent(); - if ($createGitattributesFile || $overwriteGitattributesFile) { - try { - $outputContent .= $this->overwriteGitattributesFile( - $expectedGitattributesFileContent - ); + if ($createGitattributesFile || $overwriteGitattributesFile) { + try { + $verboseOutput = "+ Trying to create expected .gitattribute file."; + if ($overwriteGitattributesFile) { + $verboseOutput = "+ Trying to overwrite existing .gitattribute file with expected content."; + } + $output->writeln($verboseOutput, OutputInterface::VERBOSITY_VERBOSE); + + $outputContent .= $this->overwriteGitattributesFile( + $expectedGitattributesFileContent + ); - $output->writeln($outputContent); + $output->writeln($outputContent); - return 0; - } catch (GitattributesCreationFailed $e) { - $outputContent .= PHP_EOL . PHP_EOL . $e->getMessage(); - $output->writeln($outputContent); + return 0; + } catch (GitattributesCreationFailed $e) { + $outputContent .= PHP_EOL . PHP_EOL . $e->getMessage(); + $output->writeln($outputContent); - return 1; - } + $output->writeln($e->getMessage(), OutputInterface::VERBOSITY_DEBUG); + + return 1; } + } - $outputContent .= $this->getExpectedGitattributesFileContentOutput( - $expectedGitattributesFileContent - ); + $outputContent .= $this->getExpectedGitattributesFileContentOutput( + $expectedGitattributesFileContent + ); - $output->writeln($outputContent); + $output->writeln($outputContent); - return 1; - } + return 1; } $info = 'The present .gitattributes file is considered valid.'; $output->writeln($info); if ($this->analyser->hasPrecedingSlashesInExportIgnorePattern()) { + $verboseOutput = '+ Checking for preceding slashes in export-ignore statements.'; + $output->writeln($verboseOutput, OutputInterface::VERBOSITY_VERBOSE); + $warning = "Warning: At least one export-ignore pattern has a leading '/', " . $warning = 'which is considered as a smell.'; $outputContent = '' . $warning . ''; @@ -364,6 +431,8 @@ protected function execute(InputInterface $input, OutputInterface $output) } if ($this->analyser->hasTextAutoConfiguration() === false) { + $verboseOutput = '+ Checking for text auto configuration.'; + $warning = 'Warning: Missing a text auto configuration. ' . 'Consider adding one.'; $outputContent = '' . $warning . ''; diff --git a/tests/Commands/InitCommandTest.php b/tests/Commands/InitCommandTest.php index d6f5a09..8b3d89e 100644 --- a/tests/Commands/InitCommandTest.php +++ b/tests/Commands/InitCommandTest.php @@ -1,18 +1,17 @@ assertTrue($commandTester->getStatusCode() > 0); } + /** + * @test + */ + public function verboseOutputIsAvailableWhenDesired() + { + $expectedDefaultLpvFile = $this->temporaryDirectory + . DIRECTORY_SEPARATOR + . '.lpv'; + \touch($expectedDefaultLpvFile); + + $command = $this->application->find('init'); + $commandTester = new CommandTester($command); + $commandTester->execute( + ['command' => $command->getName(), + 'directory' => WORKING_DIRECTORY], + ['verbosity' => OutputInterface::VERBOSITY_VERBOSE] + ); + + $expectedDisplay = <<assertSame($expectedDisplay, $commandTester->getDisplay()); + } + /** * @test */ From 38064ad3f49765c424a175766cbfcf61a90a744b Mon Sep 17 00:00:00 2001 From: Raphael Stolt Date: Tue, 10 Oct 2023 14:27:45 +0200 Subject: [PATCH 025/152] Adds diff option --- CHANGELOG.md | 1 + composer.json | 5 ++-- src/Analyser.php | 22 ++++++++++---- src/Commands/ValidateCommand.php | 19 ++++++++++++ tests/Commands/ValidateCommandTest.php | 41 ++++++++++++++++++++++++++ 5 files changed, 80 insertions(+), 8 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index dbad1ff..ad12e6c 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/) and this p ## [Unreleased] ### Added +- Added `--diff` option to show differences between expected and actual .gitattributes content. Closes [#39](https://github.com/raphaelstolt/lean-package-validator/issues/39). - Added verbose output. Closes [#37](https://github.com/raphaelstolt/lean-package-validator/issues/37). ### Fixed diff --git a/composer.json b/composer.json index 4982be5..567dc36 100755 --- a/composer.json +++ b/composer.json @@ -11,8 +11,9 @@ ], "require": { "php": ">=8.0", - "symfony/console": "^v6.3||^v5.4.8", - "laminas/laminas-stdlib": "^3.7" + "laminas/laminas-stdlib": "^3.7", + "sebastian/diff": "^5.0||^4.0.3", + "symfony/console": "^v6.3||^v5.4.8" }, "autoload": { "psr-4": { diff --git a/src/Analyser.php b/src/Analyser.php index e36f4e3..e78c984 100755 --- a/src/Analyser.php +++ b/src/Analyser.php @@ -437,12 +437,10 @@ public function getGitignoredPatterns() /** * Return the expected .gitattributes content. * - * @param array $postfixlessExportIgnores Expected patterns without - * an export-ignore postfix. - * + * @param array $postfixlessExportIgnores Expected patterns without an export-ignore postfix. * @return string */ - public function getExpectedGitattributesContent(array $postfixlessExportIgnores = []) + public function getExpectedGitattributesContent(array $postfixlessExportIgnores = []): string { if ($postfixlessExportIgnores === []) { $postfixlessExportIgnores = $this->collectExpectedExportIgnores(); @@ -659,13 +657,25 @@ private function patternHasMatch($globPattern) return \is_array($matches) && \count($matches) > 0; } + /** + * @return string + */ + public function getPresentGitAttributesContent(): string + { + if ($this->hasGitattributesFile() === false) { + return ''; + } + + return (string) \file_get_contents($this->gitattributesFile); + } + /** * Get the present non export-ignore entries of * the .gitattributes file. * * @return string */ - public function getPresentNonExportIgnoresContent() + public function getPresentNonExportIgnoresContent(): string { if ($this->hasGitattributesFile() === false) { return ''; @@ -707,7 +717,7 @@ public function getPresentNonExportIgnoresContent() * * @return array */ - public function getPresentExportIgnores() + public function getPresentExportIgnores(): array { if ($this->hasGitattributesFile() === false) { return []; diff --git a/src/Commands/ValidateCommand.php b/src/Commands/ValidateCommand.php index a551542..afe290f 100755 --- a/src/Commands/ValidateCommand.php +++ b/src/Commands/ValidateCommand.php @@ -4,6 +4,8 @@ namespace Stolt\LeanPackage\Commands; +use SebastianBergmann\Diff\Differ; +use SebastianBergmann\Diff\Output\UnifiedDiffOutputBuilder; use SplFileInfo; use Stolt\LeanPackage\Analyser; use Stolt\LeanPackage\Archive\Validator; @@ -85,6 +87,7 @@ protected function configure() . 'with missing export-ignores'; $validateArchiveDescription = 'Validate Git archive against current HEAD'; $omitHeaderDescription = 'Omit adding a header to created or modified .gitattributes file'; + $diffDescription = 'Show difference between expected and actual .gitattributes content'; $exampleGlobPattern = '{.*,*.md}'; $globPatternDescription = 'Use this glob pattern e.g. ' @@ -149,6 +152,12 @@ protected function configure() InputOption::VALUE_NONE, $omitHeaderDescription ); + $this->addOption( + 'diff', + null, + InputOption::VALUE_NONE, + $diffDescription + ); } /** @@ -187,6 +196,7 @@ protected function execute(InputInterface $input, OutputInterface $output) $globPattern = $input->getOption('glob-pattern'); $globPatternFile = (string) $input->getOption('glob-pattern-file'); $omitHeader = $input->getOption('omit-header'); + $showDifference = $input->getOption('diff'); $enforceStrictOrderComparison = $input->getOption('enforce-strict-order'); @@ -408,6 +418,15 @@ protected function execute(InputInterface $input, OutputInterface $output) } } + if ($showDifference) { + $actual = $this->analyser->getPresentGitAttributesContent(); + $builder = new UnifiedDiffOutputBuilder( + "--- Original" . PHP_EOL . "+++ Expected" . PHP_EOL, + true + ); + $differ = new Differ($builder); + $expectedGitattributesFileContent = $differ->diff($actual, $expectedGitattributesFileContent); + } $outputContent .= $this->getExpectedGitattributesFileContentOutput( $expectedGitattributesFileContent ); diff --git a/tests/Commands/ValidateCommandTest.php b/tests/Commands/ValidateCommandTest.php index 9fdd54c..3679c45 100644 --- a/tests/Commands/ValidateCommandTest.php +++ b/tests/Commands/ValidateCommandTest.php @@ -137,6 +137,47 @@ public function validateOnNonExistentGitattributesFilesSuggestsCreationWithAlign $this->assertTrue($commandTester->getStatusCode() > 0); } + /** + * @test + * @ticket 39 (https://github.com/raphaelstolt/lean-package-validator/issues/19) + */ + public function showsDifferenceBetweenActualAndExpectedGitattributesContent() + { + $artifactFilenames = [ + '.gitattributes', + ]; + + $this->createTemporaryFiles( + $artifactFilenames, + ['.github'] + ); + + $gitattributesContent = <<createTemporaryGitattributesFile($gitattributesContent); + + $command = $this->application->find('validate'); + $commandTester = new CommandTester($command); + $commandTester->execute([ + 'command' => $command->getName(), + 'directory' => WORKING_DIRECTORY, + '--diff' => true, + ]); + + $actualDisplayRows = array_values(explode(PHP_EOL, $commandTester->getDisplay())); + + $expectedDiffRows = ['--- Original', '+++ Expected', '@@ -1 +1,2 @@']; + + foreach ($expectedDiffRows as $expectedDiffRow) { + $this->assertContains($expectedDiffRow, $actualDisplayRows); + } + + $this->assertTrue($commandTester->getStatusCode() > 0); + } + + /** * @test * @ticket 16 (https://github.com/raphaelstolt/lean-package-validator/issues/16) From 3ff45cccaaaa5b9879921fe9c1043e90fd3ecd42 Mon Sep 17 00:00:00 2001 From: Raphael Stolt Date: Tue, 10 Oct 2023 15:58:21 +0200 Subject: [PATCH 026/152] Excludes global gitignored files when validating --- .github/workflows/lint.yml | 10 +++---- CHANGELOG.md | 6 +++- bin/lean-package-validator | 2 +- src/Analyser.php | 39 ++++++++++++++++++++++---- tests/Commands/ValidateCommandTest.php | 14 +++++++-- 5 files changed, 57 insertions(+), 14 deletions(-) diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 0cfe2f7..df4959c 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -28,8 +28,8 @@ jobs: - name: Check coding styles run: composer run-script lpv:cs-lint - - name: Check leanness of package - uses: raphaelstolt/lean-package-validator-action@v0.1.0 - with: - php-version: "${{ matrix.php }}" - lpv-version: "3.0.0" +# - name: Check leanness of package +# uses: raphaelstolt/lean-package-validator-action@v0.1.0 +# with: +# php-version: "${{ matrix.php }}" +# lpv-version: "3.0.0" diff --git a/CHANGELOG.md b/CHANGELOG.md index ad12e6c..0053741 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,7 +4,10 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](http://keepachangelog.com/) and this project adheres to [Semantic Versioning](http://semver.org/). ## [Unreleased] + +## [v3.1.0] - 2023-10-10 ### Added +- Global .gitignore'd files are excluded from validation. Closes [#36](https://github.com/raphaelstolt/lean-package-validator/issues/36). - Added `--diff` option to show differences between expected and actual .gitattributes content. Closes [#39](https://github.com/raphaelstolt/lean-package-validator/issues/39). - Added verbose output. Closes [#37](https://github.com/raphaelstolt/lean-package-validator/issues/37). @@ -142,7 +145,8 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/) and this p ## v1.0.0 - 2016-09-04 - Initial release. -[Unreleased]: https://github.com/raphaelstolt/lean-package-validator/compare/v3.0.1...HEAD +[Unreleased]: https://github.com/raphaelstolt/lean-package-validator/compare/v3.1.0...HEAD +[v3.1.0]: https://github.com/raphaelstolt/lean-package-validator/compare/v3.0.1...v3.1.0 [v3.0.1]: https://github.com/raphaelstolt/lean-package-validator/compare/v3.0.0...v3.0.1 [v3.0.0]: https://github.com/raphaelstolt/lean-package-validator/compare/v2.1.0...v3.0.0 [v2.1.0]: https://github.com/raphaelstolt/lean-package-validator/compare/v2.0.2...v2.1.0 diff --git a/bin/lean-package-validator b/bin/lean-package-validator index f5aa443..ca43da1 100755 --- a/bin/lean-package-validator +++ b/bin/lean-package-validator @@ -24,7 +24,7 @@ if (false === $autoloaded) { } define('WORKING_DIRECTORY', getcwd()); -define('VERSION', '3.0.1'); +define('VERSION', '3.10.0'); use Stolt\LeanPackage\Commands\InitCommand; use Stolt\LeanPackage\Commands\ValidateCommand; diff --git a/src/Analyser.php b/src/Analyser.php index e78c984..c8bba2f 100755 --- a/src/Analyser.php +++ b/src/Analyser.php @@ -396,14 +396,30 @@ public function hasGitattributesFile() } /** - * Return patterns in .gitignore file. - * * @return array */ - public function getGitignoredPatterns() + public function getGlobalGitignorePatterns(): array { - $gitignoreFile = $this->getDirectory() . DIRECTORY_SEPARATOR . '.gitignore'; + $gitConfigGetCommand = 'git config --get core.excludesfile'; + + \exec($gitConfigGetCommand, $output, $statusCode); + + if ($statusCode !== 0) { + return []; + } + + $homeDirectory = \getenv('HOME') ? \getenv('HOME') : __DIR__; + $excludesFile = \str_replace('~', $homeDirectory, \trim($output[0])); + + return $this->getGitignorePatterns($excludesFile); + } + /** + * @param string $gitignoreFile + * @return array + */ + private function getGitignorePatterns(string $gitignoreFile): array + { if (!\file_exists($gitignoreFile)) { return []; } @@ -434,6 +450,18 @@ public function getGitignoredPatterns() return $gitignoredPatterns; } + /** + * Return patterns in .gitignore file. + * + * @return array + */ + public function getGitignoredPatterns(): array + { + $gitignoreFile = $this->getDirectory() . DIRECTORY_SEPARATOR . '.gitignore'; + + return $this->getGitignorePatterns($gitignoreFile); + } + /** * Return the expected .gitattributes content. * @@ -559,7 +587,8 @@ public function collectExpectedExportIgnores() $ignoredGlobMatches = \array_merge( $this->ignoredGlobMatches, - $this->getGitignoredPatterns() + $this->getGitignoredPatterns(), + $this->getGlobalGitignorePatterns() ); $globMatches = Glob::glob($this->globPattern, Glob::GLOB_BRACE); diff --git a/tests/Commands/ValidateCommandTest.php b/tests/Commands/ValidateCommandTest.php index 3679c45..64abb96 100644 --- a/tests/Commands/ValidateCommandTest.php +++ b/tests/Commands/ValidateCommandTest.php @@ -166,7 +166,7 @@ public function showsDifferenceBetweenActualAndExpectedGitattributesContent() '--diff' => true, ]); - $actualDisplayRows = array_values(explode(PHP_EOL, $commandTester->getDisplay())); + $actualDisplayRows = \array_values(\explode(PHP_EOL, $commandTester->getDisplay())); $expectedDiffRows = ['--- Original', '+++ Expected', '@@ -1 +1,2 @@']; @@ -184,6 +184,16 @@ public function showsDifferenceBetweenActualAndExpectedGitattributesContent() */ public function gitattributesFileWithNonExportIgnoreContentShowsExpectedContent() { + $mock = Mockery::mock( + 'Stolt\LeanPackage\Analyser[getGlobalGitignorePatterns]' + ); + $mock->shouldReceive('getGlobalGitignorePatterns') + ->once() + ->withAnyArgs() + ->andReturn([]); + + $application = $this->getApplicationWithMockedAnalyser($mock); + $artifactFilenames = [ '.gitattributes', '.gitignore', @@ -213,7 +223,7 @@ public function gitattributesFileWithNonExportIgnoreContentShowsExpectedContent( $this->createTemporaryGitattributesFile($gitattributesContent); - $command = $this->application->find('validate'); + $command = $application->find('validate'); $commandTester = new CommandTester($command); $commandTester->execute([ 'command' => $command->getName(), From 913eec067336ad85c90628fbd063a6d01178cc0c Mon Sep 17 00:00:00 2001 From: Raphael Stolt Date: Wed, 11 Oct 2023 08:01:18 +0200 Subject: [PATCH 027/152] Fixes broken distribute GitHub Action --- .github/workflows/distribute.yml | 31 ++++++++++--------------------- box.json.dist | 10 ++-------- 2 files changed, 12 insertions(+), 29 deletions(-) diff --git a/.github/workflows/distribute.yml b/.github/workflows/distribute.yml index 8e6b5ca..b7aaea4 100644 --- a/.github/workflows/distribute.yml +++ b/.github/workflows/distribute.yml @@ -26,31 +26,20 @@ jobs: php-version: "${{ matrix.php }}" - name: Install Composer dependencies - run: composer install --no-progress --prefer-dist --optimize-autoloader && composer require --dev --with-all-dependencies humbug/box + run: composer install --no-progress --prefer-dist --optimize-autoloader + + - name: Install Box Phar bundler + run: wget --quiet https://github.com/box-project/box/releases/download/4.3.8/box.phar && sudo mv box.phar /usr/bin/box && sudo chmod u+x /usr/bin/box + shell: bash - name: Build PHAR - run: vendor/humbug/box/bin/box compile + run: /usr/bin/box compile - name: Check generated PHAR - run: bin/lean-package-validator.phar + run: bin/lean-package-validator.phar --version - name: Create Release - id: create_release - uses: actions/create-release@v1 - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - with: - tag_name: ${{ github.ref }} - release_name: Release ${{ github.ref }} - draft: false - prerelease: false - - - name: Upload generated PHAR - uses: actions/upload-release-asset@v1 - env: - GITHUB_TOKEN: ${{ github.token }} + uses: softprops/action-gh-release@v1 + if: startsWith(github.ref, 'refs/tags/') with: - upload_url: ${{ steps.create_release.outputs.upload_url }} - asset_path: bin/lean-package-validator.phar - asset_name: lean-package-validator.phar - asset_content_type: application/gzip + files: bin/lean-package-validator.phar diff --git a/box.json.dist b/box.json.dist index b948726..d33327a 100644 --- a/box.json.dist +++ b/box.json.dist @@ -1,16 +1,10 @@ { - "chmod": "0755", - "main": "bin/lean-package-validator", - "output": "bin/lean-package-validator.phar", - "directories": ["src"], "finder": [ { "name": "*.php", - "exclude": ["tests"], + "exclude": ["tests", ".github", "example", ".*"], "in": "vendor" } - ], - - "stub": true + ] } From 049d59c04bc659e6fcce26a6e04a2b48d455df8a Mon Sep 17 00:00:00 2001 From: Raphael Stolt Date: Wed, 11 Oct 2023 10:03:09 +0200 Subject: [PATCH 028/152] Makes archive name optional --- bin/lean-package-validator | 5 +---- src/Archive.php | 5 ++++- tests/Commands/ValidateCommandTest.php | 6 ++---- 3 files changed, 7 insertions(+), 9 deletions(-) diff --git a/bin/lean-package-validator b/bin/lean-package-validator index ca43da1..2da44b7 100755 --- a/bin/lean-package-validator +++ b/bin/lean-package-validator @@ -33,10 +33,7 @@ use Stolt\LeanPackage\Archive; use Stolt\LeanPackage\Archive\Validator; use Symfony\Component\Console\Application; -$archive = new Archive( - WORKING_DIRECTORY, - basename(WORKING_DIRECTORY) -); +$archive = new Archive(WORKING_DIRECTORY); $analyser = new Analyser; $initCommand = new InitCommand( diff --git a/src/Archive.php b/src/Archive.php index 111790b..85967b4 100755 --- a/src/Archive.php +++ b/src/Archive.php @@ -43,10 +43,13 @@ class Archive * @param string $directory The directory of the repository to archive. * @param string $name The extensionless name of the repository archive. */ - public function __construct($directory, $name) + public function __construct(string $directory, string $name = '') { $this->directory = $directory; $this->name = $name; + if ('' === $name) { + $this->name = \basename($directory); + } $this->filename = $directory . DIRECTORY_SEPARATOR . $name . '.tar.gz'; diff --git a/tests/Commands/ValidateCommandTest.php b/tests/Commands/ValidateCommandTest.php index 64abb96..2000420 100644 --- a/tests/Commands/ValidateCommandTest.php +++ b/tests/Commands/ValidateCommandTest.php @@ -2016,8 +2016,7 @@ protected function getApplicationWithMockedAnalyser(MockInterface $mockedAnalyse $application = new Application(); $archive = new Archive( - $this->temporaryDirectory, - \basename($this->temporaryDirectory) + $this->temporaryDirectory ); $analyserCommand = new ValidateCommand( @@ -2054,8 +2053,7 @@ protected function getApplication() { $application = new Application(); $archive = new Archive( - $this->temporaryDirectory, - \basename($this->temporaryDirectory) + $this->temporaryDirectory ); $analyserCommand = new ValidateCommand( From 95a2ab569b21eedb729c5e7a576bdc47cd1100a3 Mon Sep 17 00:00:00 2001 From: Raphael Stolt Date: Wed, 11 Oct 2023 11:32:07 +0200 Subject: [PATCH 029/152] Adds \ prefix to internal PHP function calls --- .php-cs-fixer.php | 2 +- bin/lean-package-validator | 14 ++++++-------- 2 files changed, 7 insertions(+), 9 deletions(-) diff --git a/.php-cs-fixer.php b/.php-cs-fixer.php index 18d929c..db2b0a4 100755 --- a/.php-cs-fixer.php +++ b/.php-cs-fixer.php @@ -17,7 +17,7 @@ ] ]; -$cacheDir = getenv('HOME') ? getenv('HOME') : __DIR__; +$cacheDir = \getenv('HOME') ? \getenv('HOME') : __DIR__; $config = new Config(); diff --git a/bin/lean-package-validator b/bin/lean-package-validator index 2da44b7..4939977 100755 --- a/bin/lean-package-validator +++ b/bin/lean-package-validator @@ -9,12 +9,10 @@ $autoloads = [ __DIR__ . '/vendor/autoload.php', ]; -foreach ($autoloads as $autoload) { - if (file_exists($autoload)) { - require $autoload; - $autoloaded = true; - break; - } +foreach (\array_filter($autoloads, 'file_exists') as $autoload) { + require $autoload; + $autoloaded = true; + break; } if (false === $autoloaded) { @@ -23,8 +21,8 @@ if (false === $autoloaded) { exit(1); } -define('WORKING_DIRECTORY', getcwd()); -define('VERSION', '3.10.0'); +\define('WORKING_DIRECTORY', \getcwd()); +\define('VERSION', '3.10.0'); use Stolt\LeanPackage\Commands\InitCommand; use Stolt\LeanPackage\Commands\ValidateCommand; From afe45527748559fd1c5f1ad45531b41808324a4e Mon Sep 17 00:00:00 2001 From: Raphael Stolt Date: Wed, 11 Oct 2023 11:49:19 +0200 Subject: [PATCH 030/152] Fixes broken PHAR compilation --- box.json.dist | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/box.json.dist b/box.json.dist index d33327a..8aa0078 100644 --- a/box.json.dist +++ b/box.json.dist @@ -1,5 +1,7 @@ { - "directories": ["src"], + "$schema": "res/schema.json", + "directories": ["src", "vendor/symfony/console/Resources"], + "force-autodiscovery": true, "finder": [ { "name": "*.php", From 5466bde3301b0ff00cae421371862921760ce357 Mon Sep 17 00:00:00 2001 From: Raphael Stolt Date: Wed, 11 Oct 2023 12:06:31 +0200 Subject: [PATCH 031/152] Documents diff option --- README.md | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/README.md b/README.md index 401ea8d..c0fce86 100755 --- a/README.md +++ b/README.md @@ -97,6 +97,29 @@ The `--validate-git-archive` option will validate that no common repository arti lean-package-validator validate [] --validate-git-archive ``` +The `--diff` option will show a visual diff betweeen the actual and expected .gitattributes content. + +``` bash +lean-package-validator validate --diff + +The present .gitattributes file is considered invalid. + +Would expect the following .gitattributes file content: +--- Original ++++ Expected +@@ -7,9 +7,8 @@ + .github/ export-ignore + .gitignore export-ignore + .gitmessage export-ignore + .php-cs-fixer.php export-ignore +-.phpunit.result.cache export-ignore ++.idea/ export-ignore + bin/application-version export-ignore + bin/lean-package-validator.phar export-ignore + bin/release-version export-ignore +``` + + #### Additional commands The `init` command will create an initial `.lpv` file with the default patterns used to match common repository artifacts. From a0cc725d16a4552dd1c6c738d814550e46ef9aa8 Mon Sep 17 00:00:00 2001 From: Raphael Stolt Date: Wed, 11 Oct 2023 12:14:55 +0200 Subject: [PATCH 032/152] Runs tests against PHP 8.3 --- .github/workflows/test.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 80e59aa..1587ae6 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -13,6 +13,7 @@ jobs: - "8.0" - "8.1" - "8.2" + - "8.3" steps: - name: Checkout From c31e1ecefb2fb53724e1943fd1a46883ff7825d5 Mon Sep 17 00:00:00 2001 From: Raphael Stolt Date: Wed, 11 Oct 2023 14:43:56 +0200 Subject: [PATCH 033/152] Expands coding standard and static analysis --- .php-cs-fixer.php | 2 +- phpstan.neon.dist | 2 + tests/AnalyserTest.php | 103 +++++++++++++------------ tests/ApplicationTest.php | 4 +- tests/Archive/ValidatorTest.php | 8 +- tests/ArchiveTest.php | 31 ++++---- tests/Commands/InitCommandTest.php | 12 +-- tests/Commands/ValidateCommandTest.php | 94 +++++++++++----------- tests/Helpers/StrTest.php | 4 +- tests/TestCase.php | 14 +++- 10 files changed, 146 insertions(+), 128 deletions(-) diff --git a/.php-cs-fixer.php b/.php-cs-fixer.php index db2b0a4..5a71278 100755 --- a/.php-cs-fixer.php +++ b/.php-cs-fixer.php @@ -4,7 +4,7 @@ use PhpCsFixer\Finder; $finder = Finder::create() - ->in(__DIR__); + ->in([__DIR__, __DIR__ . DIRECTORY_SEPARATOR . 'tests']); $rules = [ 'psr_autoloading' => false, diff --git a/phpstan.neon.dist b/phpstan.neon.dist index ee086b7..83c2878 100644 --- a/phpstan.neon.dist +++ b/phpstan.neon.dist @@ -2,6 +2,7 @@ parameters: level: max paths: - src + - tests reportUnmatchedIgnoredErrors: false checkMissingIterableValueType: false ignoreErrors: @@ -13,3 +14,4 @@ parameters: - '#cannot be cast to string#' - '#Cannot cast#' - '#is never read#' + - '#Comparison operation ">="#' diff --git a/tests/AnalyserTest.php b/tests/AnalyserTest.php index 59dab85..8f68902 100755 --- a/tests/AnalyserTest.php +++ b/tests/AnalyserTest.php @@ -1,5 +1,7 @@ setDirectory($this->temporaryDirectory); $this->assertFalse( @@ -45,7 +46,7 @@ public function hasCompleteExportIgnoresFailsOnEmptyExportIgnores() /** * @test */ - public function hasCompleteExportIgnoresFailsOnNonExistingGitattributesFile() + public function hasCompleteExportIgnoresFailsOnNonExistingGitattributesFile(): void { $mock = Mockery::mock( 'Stolt\LeanPackage\Analyser[hasGitattributesFile]' @@ -66,7 +67,7 @@ public function hasCompleteExportIgnoresFailsOnNonExistingGitattributesFile() /** * @test */ - public function returnsTrueWhenDirectoryHasCompleteExportIgnores() + public function returnsTrueWhenDirectoryHasCompleteExportIgnores(): void { $gitattributesContent = <<expectException(\RuntimeException::class); @@ -115,7 +116,7 @@ public function analyseOnNonExistingDirectoryThrowsExpectedException() /** * @test */ - public function gitattributesFileHasAnAccessor() + public function gitattributesFileHasAnAccessor(): void { $analyser = (new Analyser())->setDirectory($this->temporaryDirectory); $expectedGitattributesFilePath = $this->temporaryDirectory @@ -131,7 +132,7 @@ public function gitattributesFileHasAnAccessor() /** * @test */ - public function directoryHasAnAccessor() + public function directoryHasAnAccessor(): void { $analyser = (new Analyser())->setDirectory($this->temporaryDirectory); $this->assertEquals($this->temporaryDirectory, $analyser->getDirectory()); @@ -140,7 +141,7 @@ public function directoryHasAnAccessor() /** * @test */ - public function returnsExpectedGitattributesContent() + public function returnsExpectedGitattributesContent(): void { $artifactsWithoutExportIgnore = [ 'README.md', @@ -177,7 +178,7 @@ public function returnsExpectedGitattributesContent() /** * @test */ - public function expectedFileMatchesAreInExpectedGitattributesContent() + public function expectedFileMatchesAreInExpectedGitattributesContent(): void { $artifactFilenames = [ 'Vagrantfile', @@ -212,7 +213,7 @@ public function expectedFileMatchesAreInExpectedGitattributesContent() /** * @test */ - public function nonExportIgnoresContentIsEmptyForNonexistentGitattributesFile() + public function nonExportIgnoresContentIsEmptyForNonexistentGitattributesFile(): void { $analyser = (new Analyser())->setDirectory($this->temporaryDirectory); @@ -222,7 +223,7 @@ public function nonExportIgnoresContentIsEmptyForNonexistentGitattributesFile() /** * @test */ - public function nonExportIgnoresContentOfGitattributesFileIsReturned() + public function nonExportIgnoresContentOfGitattributesFileIsReturned(): void { $gitattributesContent = <<temporaryDirectory . DIRECTORY_SEPARATOR @@ -425,7 +426,7 @@ public function hasGitattributesFileOnExistingGitattributesFile() /** * @test */ - public function hasGitattributesFileFailsOnNonExistingGitattributesFile() + public function hasGitattributesFileFailsOnNonExistingGitattributesFile(): void { $temporaryGitattributesFile = $this->temporaryDirectory . DIRECTORY_SEPARATOR @@ -443,7 +444,7 @@ public function hasGitattributesFileFailsOnNonExistingGitattributesFile() /** * @test */ - public function collectExpectedExportIgnoresReturnsExpectedEntries() + public function collectExpectedExportIgnoresReturnsExpectedEntries(): void { $temporaryGitattributesFile = $this->temporaryDirectory . DIRECTORY_SEPARATOR @@ -482,7 +483,7 @@ public function collectExpectedExportIgnoresReturnsExpectedEntries() /** * @test */ - public function returnsAnEmptyArrayOnNonExistingGitattributesFile() + public function returnsAnEmptyArrayOnNonExistingGitattributesFile(): void { $analyser = (new Analyser())->setDirectory($this->temporaryDirectory); @@ -497,7 +498,7 @@ public function returnsAnEmptyArrayOnNonExistingGitattributesFile() /** * @test */ - public function returnsExpectedPresentExportIgnores() + public function returnsExpectedPresentExportIgnores(): void { $gitattributesContent = <<temporaryDirectory . DIRECTORY_SEPARATOR @@ -941,7 +942,7 @@ public function emptyGlobPatternFileThrowsExpectedException() * @group glob * @ticket 9 (https://github.com/raphaelstolt/lean-package-validator/issues/9) */ - public function defaultExportIgnoresGlobPatternIsOverwritableFromFile() + public function defaultExportIgnoresGlobPatternIsOverwritableFromFile(): void { $temporaryLpvFile = $this->temporaryDirectory . DIRECTORY_SEPARATOR @@ -983,7 +984,7 @@ public function defaultExportIgnoresGlobPatternIsOverwritableFromFile() * @test * @group glob */ - public function defaultExportIgnoresGlobPatternIsOverwritable() + public function defaultExportIgnoresGlobPatternIsOverwritable(): void { $analyser = (new Analyser()) ->setDirectory($this->temporaryDirectory) @@ -1013,10 +1014,10 @@ public function defaultExportIgnoresGlobPatternIsOverwritable() * @test * @group glob */ - public function emptyGlobPatternThrowsExpectedException() + public function emptyGlobPatternThrowsExpectedException(): void { $this->expectException(InvalidGlobPattern::class); - $analyser = (new Analyser()) + (new Analyser()) ->setDirectory($this->temporaryDirectory) ->setGlobPattern(''); } @@ -1025,7 +1026,7 @@ public function emptyGlobPatternThrowsExpectedException() * @test * @group glob */ - public function invalidGlobPatternBracesThrowsExpectedException() + public function invalidGlobPatternBracesThrowsExpectedException(): void { $this->expectException(InvalidGlobPattern::class); $analyser = (new Analyser()) @@ -1039,7 +1040,7 @@ public function invalidGlobPatternBracesThrowsExpectedException() * @test * @group glob */ - public function wildcardAfterBracesIsNotRaisingAnException() + public function wildcardAfterBracesIsNotRaisingAnException(): void { $analyser = (new Analyser()) ->setDirectory($this->temporaryDirectory) @@ -1052,7 +1053,7 @@ public function wildcardAfterBracesIsNotRaisingAnException() * @test * @group glob */ - public function emptyGlobPatternBracesContentThrowsExpectedException() + public function emptyGlobPatternBracesContentThrowsExpectedException(): void { $this->expectException(InvalidGlobPattern::class); $analyser = (new Analyser()) @@ -1064,7 +1065,7 @@ public function emptyGlobPatternBracesContentThrowsExpectedException() * @test * @group glob */ - public function singleGlobPatternThrowsExpectedException() + public function singleGlobPatternThrowsExpectedException(): void { $this->expectException(InvalidGlobPattern::class); $analyser = (new Analyser()) @@ -1076,7 +1077,7 @@ public function singleGlobPatternThrowsExpectedException() * @test * @group glob */ - public function globPatternWithEnclosedBracesAreConsideredValid() + public function globPatternWithEnclosedBracesAreConsideredValid(): void { $analyser = (new Analyser()) ->setDirectory($this->temporaryDirectory) @@ -1088,7 +1089,7 @@ public function globPatternWithEnclosedBracesAreConsideredValid() /** * @test */ - public function withDistEndingFilesAreNotExportIgnored() + public function withDistEndingFilesAreNotExportIgnored(): void { $artifactFilenames = [ 'SUPPORT.md', @@ -1123,7 +1124,7 @@ public function withDistEndingFilesAreNotExportIgnored() * @test * @ticket 15 (https://github.com/raphaelstolt/lean-package-validator/issues/15) */ - public function licenseFileIsNotExportIgnored() + public function licenseFileIsNotExportIgnored(): void { $artifactFilenames = [ 'LICENSE.txt', @@ -1160,7 +1161,7 @@ public function licenseFileIsNotExportIgnored() * @test * @ticket 24 (https://github.com/raphaelstolt/lean-package-validator/issues/24) */ - public function directoriesOnlyExportIgnoredOnce() + public function directoriesOnlyExportIgnoredOnce(): void { $artifactFilenames = [ 'LICENSE.md', @@ -1208,7 +1209,7 @@ public function directoriesOnlyExportIgnoredOnce() /** * @test */ - public function exportIgnoresAreAligned() + public function exportIgnoresAreAligned(): void { $artifactFilenames = [ 'LICENSE.txt', @@ -1246,7 +1247,7 @@ public function exportIgnoresAreAligned() * @test * @ticket 4 (https://github.com/raphaelstolt/lean-package-validator/issues/4) */ - public function precedingSlashesAreDetected() + public function precedingSlashesAreDetected(): void { $artifactFilenames = [ 'changelog-generator', @@ -1281,7 +1282,7 @@ public function precedingSlashesAreDetected() * @test * @ticket 12 (https://github.com/raphaelstolt/lean-package-validator/issues/12) */ - public function missingTextAutoConfigurationIsDetected() + public function missingTextAutoConfigurationIsDetected(): void { $artifactFilenames = [ 'README.md', @@ -1311,7 +1312,7 @@ public function missingTextAutoConfigurationIsDetected() * @test * @ticket 12 (https://github.com/raphaelstolt/lean-package-validator/issues/12) */ - public function presentTextAutoConfigurationIsDetected() + public function presentTextAutoConfigurationIsDetected(): void { $artifactFilenames = [ 'README.md', @@ -1343,7 +1344,7 @@ public function presentTextAutoConfigurationIsDetected() /** * @test */ - public function returnsEmptyPatternsWhenNoGitignoreFilePresent() + public function returnsEmptyPatternsWhenNoGitignoreFilePresent(): void { $analyser = (new Analyser())->setDirectory($this->temporaryDirectory); $this->assertEquals([], $analyser->getGitignoredPatterns()); @@ -1352,7 +1353,7 @@ public function returnsEmptyPatternsWhenNoGitignoreFilePresent() /** * @test */ - public function returnsExpectedGitignoredPatterns() + public function returnsExpectedGitignoredPatterns(): void { $gitignoreContent = <<setDirectory($this->temporaryDirectory); diff --git a/tests/ApplicationTest.php b/tests/ApplicationTest.php index 2c81fb3..6bf269e 100644 --- a/tests/ApplicationTest.php +++ b/tests/ApplicationTest.php @@ -1,5 +1,7 @@ temporaryDirectory, 'archive-tmp'); @@ -48,7 +50,7 @@ public function getFoundUnexpectedArchiveArtifactsOnNonValidatedArchiveThrowsExp /** * @test */ - public function ranValidateAllowsAccessorCallOnUnexpectedArchiveArtifacts() + public function ranValidateAllowsAccessorCallOnUnexpectedArchiveArtifacts(): void { $unexpectedArchiveArtifacts = ['mock-foo']; @@ -73,7 +75,7 @@ public function ranValidateAllowsAccessorCallOnUnexpectedArchiveArtifacts() /** * @test */ - public function findingUnexpectedArchiveArtifactsFailsValidation() + public function findingUnexpectedArchiveArtifactsFailsValidation(): void { $unexpectedArchiveArtifacts = ['mock-foo']; diff --git a/tests/ArchiveTest.php b/tests/ArchiveTest.php index ac46d1a..0f46a80 100755 --- a/tests/ArchiveTest.php +++ b/tests/ArchiveTest.php @@ -1,5 +1,7 @@ setUpTemporaryDirectory(); } @@ -21,7 +22,7 @@ public function setUp():void * * @return void */ - protected function tearDown():void + protected function tearDown(): void { if (\is_dir($this->temporaryDirectory)) { $this->removeDirectory($this->temporaryDirectory); @@ -31,7 +32,7 @@ protected function tearDown():void /** * @test */ - public function filenameHasAnAccessor() + public function filenameHasAnAccessor(): void { $analyser = new Archive(__DIR__, 'foo'); @@ -44,7 +45,7 @@ public function filenameHasAnAccessor() /** * @test */ - public function isGitCommandAvailableReturnsFalseOnNonExistingCommand() + public function isGitCommandAvailableReturnsFalseOnNonExistingCommand(): void { $this->assertFalse((new Archive(__DIR__, 'foo'))->isGitCommandAvailable('no-way-i-exists')); } @@ -53,7 +54,7 @@ public function isGitCommandAvailableReturnsFalseOnNonExistingCommand() * @test * @group travis-ci-exclude */ - public function isGitCommandAvailableReturnsTrueOnExistingCommand() + public function isGitCommandAvailableReturnsTrueOnExistingCommand(): void { $this->assertTrue((new Archive(__DIR__, 'foo'))->isGitCommandAvailable('ping')); } @@ -61,7 +62,7 @@ public function isGitCommandAvailableReturnsTrueOnExistingCommand() /** * @test */ - public function hasHeadThrowsExpectedExceptionWhenGitCommandNotAvailable() + public function hasHeadThrowsExpectedExceptionWhenGitCommandNotAvailable(): void { $mock = Mockery::mock( 'Stolt\LeanPackage\Archive[isGitCommandAvailable]', @@ -82,7 +83,7 @@ public function hasHeadThrowsExpectedExceptionWhenGitCommandNotAvailable() /** * @test */ - public function createArchiveThrowsExpectedExceptionWhenNoGitHeadPresent() + public function createArchiveThrowsExpectedExceptionWhenNoGitHeadPresent(): void { $mock = Mockery::mock( 'Stolt\LeanPackage\Archive[hasHead]', @@ -103,7 +104,7 @@ public function createArchiveThrowsExpectedExceptionWhenNoGitHeadPresent() /** * @test */ - public function removeArchiveRemovesArchive() + public function removeArchiveRemovesArchive(): void { $this->createTemporaryFiles( ['archive-tmp.tar.gz'] @@ -118,7 +119,7 @@ public function removeArchiveRemovesArchive() /** * @test */ - public function removeArchiveRemovesArchiveReturnsFalseOnNonExtistentFile() + public function removeArchiveRemovesArchiveReturnsFalseOnNonExtistentFile(): void { $removed = (new Archive($this->temporaryDirectory, 'archive-nonexistent')) ->removeArchive(); @@ -129,7 +130,7 @@ public function removeArchiveRemovesArchiveReturnsFalseOnNonExtistentFile() /** * @test */ - public function compareArchiveReturnsExpectedFoundUnexpectedArtifacts() + public function compareArchiveReturnsExpectedFoundUnexpectedArtifacts(): void { $unexpectedArtifacts = [ '.travis.yml', @@ -149,7 +150,7 @@ public function compareArchiveReturnsExpectedFoundUnexpectedArtifacts() /** * @test */ - public function compareArchiveReturnsNoFoundUnexpectedArtifactsOnLeanArchive() + public function compareArchiveReturnsNoFoundUnexpectedArtifactsOnLeanArchive(): void { $fixturesDirectory = __DIR__ . DIRECTORY_SEPARATOR . 'fixtures'; @@ -170,7 +171,7 @@ public function compareArchiveReturnsNoFoundUnexpectedArtifactsOnLeanArchive() * @test * @ticket 15 (https://github.com/raphaelstolt/lean-package-validator/issues/15) */ - public function compareArchiveThrowsExpectedExceptionWhenLicenseFileIsMissing() + public function compareArchiveThrowsExpectedExceptionWhenLicenseFileIsMissing(): void { $fixturesDirectory = __DIR__ . DIRECTORY_SEPARATOR . 'fixtures'; @@ -189,7 +190,7 @@ public function compareArchiveThrowsExpectedExceptionWhenLicenseFileIsMissing() * @test * @ticket 15 (https://github.com/raphaelstolt/lean-package-validator/issues/15) */ - public function compareArchiveDoesNotThrowsExceptionOnPresentLicenseFile() + public function compareArchiveDoesNotThrowsExceptionOnPresentLicenseFile(): void { $fixturesDirectory = __DIR__ . DIRECTORY_SEPARATOR . 'fixtures'; @@ -204,7 +205,7 @@ public function compareArchiveDoesNotThrowsExceptionOnPresentLicenseFile() /** * @test */ - public function getUnexpectedArchiveArtifactsDelegatesWork() + public function getUnexpectedArchiveArtifactsDelegatesWork(): void { $mock = Mockery::mock( 'Stolt\LeanPackage\Archive[createArchive,compareArchive,removeArchive]', diff --git a/tests/Commands/InitCommandTest.php b/tests/Commands/InitCommandTest.php index 8b3d89e..17f7f6d 100644 --- a/tests/Commands/InitCommandTest.php +++ b/tests/Commands/InitCommandTest.php @@ -47,7 +47,7 @@ protected function tearDown(): void /** * @test */ - public function createsExpectedDefaultLpvFile() + public function createsExpectedDefaultLpvFile(): void { $command = $this->application->find('init'); $commandTester = new CommandTester($command); @@ -98,7 +98,7 @@ public function createsExpectedDefaultLpvFile() * @test * @runInSeparateProcess */ - public function failingInitReturnsExpectedStatusCode() + public function failingInitReturnsExpectedStatusCode(): void { $builder = new MockBuilder(); $builder->setNamespace('Stolt\LeanPackage\Commands') @@ -129,7 +129,7 @@ public function failingInitReturnsExpectedStatusCode() /** * @test */ - public function existingDefaultLpvFileIsNotOverwritten() + public function existingDefaultLpvFileIsNotOverwritten(): void { $expectedDefaultLpvFile = $this->temporaryDirectory . DIRECTORY_SEPARATOR @@ -155,7 +155,7 @@ public function existingDefaultLpvFileIsNotOverwritten() /** * @test */ - public function verboseOutputIsAvailableWhenDesired() + public function verboseOutputIsAvailableWhenDesired(): void { $expectedDefaultLpvFile = $this->temporaryDirectory . DIRECTORY_SEPARATOR @@ -182,7 +182,7 @@ public function verboseOutputIsAvailableWhenDesired() /** * @test */ - public function existingDefaultLpvFileIsOverwrittenWhenDesired() + public function existingDefaultLpvFileIsOverwrittenWhenDesired(): void { $expectedDefaultLpvFile = $this->temporaryDirectory . DIRECTORY_SEPARATOR @@ -210,7 +210,7 @@ public function existingDefaultLpvFileIsOverwrittenWhenDesired() /** * @return \Symfony\Component\Console\Application */ - protected function getApplication() + protected function getApplication(): Application { $application = new Application(); $application->add(new InitCommand(new Analyser)); diff --git a/tests/Commands/ValidateCommandTest.php b/tests/Commands/ValidateCommandTest.php index 2000420..cb842a1 100644 --- a/tests/Commands/ValidateCommandTest.php +++ b/tests/Commands/ValidateCommandTest.php @@ -1,5 +1,7 @@ application->find('validate'); @@ -933,7 +934,7 @@ public function usageOfInvalidGlobFailsValidation() * @group glob * @ticket 38 (https://github.com/raphaelstolt/lean-package-validator/issues/38) */ - public function missingGlobPatternProducesUserFriendlyErrorMessage() + public function missingGlobPatternProducesUserFriendlyErrorMessage(): void { $missingGlobPattern = ''; $command = $this->application->find('validate'); @@ -956,7 +957,7 @@ public function missingGlobPatternProducesUserFriendlyErrorMessage() /** * @test */ - public function overwriteOptionOnNonExistentGitattributesFileImplicatesCreate() + public function overwriteOptionOnNonExistentGitattributesFileImplicatesCreate(): void { $artifactFilenames = ['CONDUCT.md']; @@ -998,7 +999,7 @@ public function overwriteOptionOnNonExistentGitattributesFileImplicatesCreate() /** * @test */ - public function leanArchiveIsConsideredLean() + public function leanArchiveIsConsideredLean(): void { $mock = Mockery::mock( 'Stolt\LeanPackage\Archive\Validator[validate]', @@ -1037,7 +1038,7 @@ public function leanArchiveIsConsideredLean() /** * @test */ - public function notLeanArchiveIsNotConsideredLeanPlural() + public function nonLeanArchiveIsNotConsideredLeanPlural(): void { $mock = Mockery::mock( 'Stolt\LeanPackage\Archive\Validator[validate, getFoundUnexpectedArchiveArtifacts]', @@ -1086,7 +1087,7 @@ public function notLeanArchiveIsNotConsideredLeanPlural() /** * @test */ - public function notLeanArchiveIsNotConsideredLeanSingular() + public function nonLeanArchiveIsNotConsideredLeanSingular(): void { $mock = Mockery::mock( 'Stolt\LeanPackage\Archive\Validator[validate, getFoundUnexpectedArchiveArtifacts]', @@ -1134,7 +1135,7 @@ public function notLeanArchiveIsNotConsideredLeanSingular() /** * @test */ - public function impossibilityToResolveExpectedGitattributesFileContentIsInfoed() + public function impossibilityToResolveExpectedGitattributesFileContentIsInfoed(): void { $mock = Mockery::mock( 'Stolt\LeanPackage\Analyser[getExpectedGitattributesContent]' @@ -1167,7 +1168,7 @@ public function impossibilityToResolveExpectedGitattributesFileContentIsInfoed() /** * @test */ - public function invalidDirectoryAgumentReturnsExpectedStatusCode() + public function invalidDirectoryAgumentReturnsExpectedStatusCode(): void { $nonExistentDirectoryOrFile = WORKING_DIRECTORY . DIRECTORY_SEPARATOR @@ -1192,7 +1193,7 @@ public function invalidDirectoryAgumentReturnsExpectedStatusCode() /** * @test */ - public function incompleteGitattributesFileIsOverwrittenWithAlignment() + public function incompleteGitattributesFileIsOverwrittenWithAlignment(): void { $gitattributesContent = <<isWindows()) { diff --git a/tests/TestCase.php b/tests/TestCase.php index 7f72158..322e0fc 100755 --- a/tests/TestCase.php +++ b/tests/TestCase.php @@ -1,5 +1,7 @@ isDir()) { @\rmdir($fileinfo->getRealPath()); @@ -88,13 +91,16 @@ protected function createTemporaryFiles(array $files, array $directories = []) * * @return boolean */ - protected function createTemporaryGitattributesFile($content) + protected function createTemporaryGitattributesFile($content): bool { $temporaryGitattributesFile = $this->temporaryDirectory . DIRECTORY_SEPARATOR . '.gitattributes'; - return file_put_contents($temporaryGitattributesFile, $content) >= 0; + + $bytesWritten = file_put_contents($temporaryGitattributesFile, $content); + + return $bytesWritten >= 0; } /** From d0df795df8e80a8d98c395c79382930db5f59295 Mon Sep 17 00:00:00 2001 From: Raphael Stolt Date: Fri, 13 Oct 2023 12:00:56 +0200 Subject: [PATCH 034/152] Uses correct directory in verbose message --- src/Commands/ValidateCommand.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Commands/ValidateCommand.php b/src/Commands/ValidateCommand.php index afe290f..257a251 100755 --- a/src/Commands/ValidateCommand.php +++ b/src/Commands/ValidateCommand.php @@ -283,7 +283,7 @@ protected function execute(InputInterface $input, OutputInterface $output) } } - $verboseOutput = '+ Checking .gitattribute file existence in ' . WORKING_DIRECTORY . '.'; + $verboseOutput = '+ Checking .gitattribute file existence in ' . $directory . '.'; $output->writeln($verboseOutput, OutputInterface::VERBOSITY_VERBOSE); if (!$this->analyser->hasGitattributesFile()) { From 8786638b96efb346a040f18a5b03df7d4c9030d3 Mon Sep 17 00:00:00 2001 From: Raphael Stolt Date: Fri, 13 Oct 2023 16:41:33 +0200 Subject: [PATCH 035/152] Adds header as comment --- src/Commands/ValidateCommand.php | 4 ++-- tests/Commands/ValidateCommandTest.php | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/Commands/ValidateCommand.php b/src/Commands/ValidateCommand.php index 257a251..b6f1c3c 100755 --- a/src/Commands/ValidateCommand.php +++ b/src/Commands/ValidateCommand.php @@ -301,10 +301,10 @@ protected function execute(InputInterface $input, OutputInterface $output) if ($createGitattributesFile || $overwriteGitattributesFile) { try { if ($omitHeader === false) { - $headerContent = 'This file was partly modified by the lean package validator (http://git.io/lean-package-validator).' . PHP_EOL; + $headerContent = '# This file was partly modified by the lean package validator (http://git.io/lean-package-validator).' . PHP_EOL; if ($createGitattributesFile) { - $headerContent = 'This file was generated by the lean package validator (http://git.io/lean-package-validator).' . PHP_EOL; + $headerContent = '# This file was generated by the lean package validator (http://git.io/lean-package-validator).' . PHP_EOL; } $expectedGitattributesFileContent = $headerContent . PHP_EOL . $expectedGitattributesFileContent; } diff --git a/tests/Commands/ValidateCommandTest.php b/tests/Commands/ValidateCommandTest.php index cb842a1..c6cf6af 100644 --- a/tests/Commands/ValidateCommandTest.php +++ b/tests/Commands/ValidateCommandTest.php @@ -694,7 +694,7 @@ public function validateOnNonExistentGitattributesFilesWithCreationOptionCreates Warning: There is no .gitattributes file present in /tmp/lpv. Created a .gitattributes file with the shown content: -This file was generated by the lean package validator (http://git.io/lean-package-validator). +# This file was generated by the lean package validator (http://git.io/lean-package-validator). * text=auto eol=lf @@ -737,7 +737,7 @@ public function validateOnNonExistentGitattributesFilesWithCreationOptionCreates Warning: There is no .gitattributes file present in {$this->temporaryDirectory}. Created a .gitattributes file with the shown content: -This file was generated by the lean package validator (http://git.io/lean-package-validator). +# This file was generated by the lean package validator (http://git.io/lean-package-validator). * text=auto eol=lf @@ -749,7 +749,7 @@ public function validateOnNonExistentGitattributesFilesWithCreationOptionCreates CONTENT; $expectedGitattributesContent = <<temporaryDirectory}. Created a .gitattributes file with the shown content: -This file was partly modified by the lean package validator (http://git.io/lean-package-validator). +# This file was partly modified by the lean package validator (http://git.io/lean-package-validator). * text=auto eol=lf From 37053a29e2a37885550bc4e68a8fab2fb25ea830 Mon Sep 17 00:00:00 2001 From: Raphael Stolt Date: Fri, 13 Oct 2023 16:43:29 +0200 Subject: [PATCH 036/152] Release version 3.1.1 --- CHANGELOG.md | 10 +++++++++- bin/lean-package-validator | 2 +- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0053741..11a4e07 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,11 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/) and this p ## [Unreleased] +## [v3.1.1] - 2023-10-13 + +### Fixed +- Header in generated or modified `.gitattributes` file is set as a comment. + ## [v3.1.0] - 2023-10-10 ### Added - Global .gitignore'd files are excluded from validation. Closes [#36](https://github.com/raphaelstolt/lean-package-validator/issues/36). @@ -17,12 +22,14 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/) and this p ## [v3.0.1] - 2023-09-26 ### Removed - Removed support for PHP `7.4`. + ### Added - Header in generated or modified `.gitattributes` file. ## [v3.0.0] - 2022-04-28 ### Removed - Removed support for PHP `7.3` and `7.2`. + ### Added - Introduced GitHub Actions. @@ -145,7 +152,8 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/) and this p ## v1.0.0 - 2016-09-04 - Initial release. -[Unreleased]: https://github.com/raphaelstolt/lean-package-validator/compare/v3.1.0...HEAD +[Unreleased]: https://github.com/raphaelstolt/lean-package-validator/compare/v3.1.1...HEAD +[v3.1.1]: https://github.com/raphaelstolt/lean-package-validator/compare/v3.1.0...v3.1.1 [v3.1.0]: https://github.com/raphaelstolt/lean-package-validator/compare/v3.0.1...v3.1.0 [v3.0.1]: https://github.com/raphaelstolt/lean-package-validator/compare/v3.0.0...v3.0.1 [v3.0.0]: https://github.com/raphaelstolt/lean-package-validator/compare/v2.1.0...v3.0.0 diff --git a/bin/lean-package-validator b/bin/lean-package-validator index 4939977..4e5350a 100755 --- a/bin/lean-package-validator +++ b/bin/lean-package-validator @@ -22,7 +22,7 @@ if (false === $autoloaded) { } \define('WORKING_DIRECTORY', \getcwd()); -\define('VERSION', '3.10.0'); +\define('VERSION', '3.10.1'); use Stolt\LeanPackage\Commands\InitCommand; use Stolt\LeanPackage\Commands\ValidateCommand; From d4f308fa6dd4fd698a5a204b630172e14246a531 Mon Sep 17 00:00:00 2001 From: Raphael Stolt Date: Mon, 16 Oct 2023 13:07:17 +0200 Subject: [PATCH 037/152] Adds --report-stale-export-ignores option --- CHANGELOG.md | 2 + README.md | 4 +- src/Analyser.php | 77 ++++++++++++++++++++++---- src/Commands/ValidateCommand.php | 16 ++++++ tests/Commands/ValidateCommandTest.php | 56 +++++++++++++++++++ 5 files changed, 144 insertions(+), 11 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 11a4e07..20fd7ef 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,8 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](http://keepachangelog.com/) and this project adheres to [Semantic Versioning](http://semver.org/). ## [Unreleased] +### Added +- New `--report-stale-export-ignores` option. Closes [#41](https://github.com/raphaelstolt/lean-package-validator/issues/41). ## [v3.1.1] - 2023-10-13 diff --git a/README.md b/README.md index c0fce86..85ee2b7 100755 --- a/README.md +++ b/README.md @@ -97,7 +97,7 @@ The `--validate-git-archive` option will validate that no common repository arti lean-package-validator validate [] --validate-git-archive ``` -The `--diff` option will show a visual diff betweeen the actual and expected .gitattributes content. +The `--diff` option will show a visual diff between the actual and expected .gitattributes content. ``` bash lean-package-validator validate --diff @@ -119,6 +119,8 @@ Would expect the following .gitattributes file content: bin/release-version export-ignore ``` +The `--report-stale-export-ignores` option extends the validation to look for export-ignore statements referencing non-existent +repository artifacts. In combination with the `--diff` option these will be shown in the output. #### Additional commands diff --git a/src/Analyser.php b/src/Analyser.php index c8bba2f..a86059c 100755 --- a/src/Analyser.php +++ b/src/Analyser.php @@ -61,6 +61,15 @@ class Analyser */ private $strictOrderComparison = false; + /** + * Whether to do a strict comparsion for stale export-ignores + * in the .gitattributes files against the expected ones + * or not. + * + * @var boolean + */ + private $staleExportIgnoresCamparison = false; + /** * Whether to do a strict alignment comparsion of the export-ignores * in the .gitattributes files against the expected ones @@ -308,6 +317,28 @@ public function isStrictOrderCamparisonEnabled() return $this->strictOrderComparison === true; } + /** + * Enable stale export ignores camparison. + * + * @return \Stolt\LeanPackage\Analyser + */ + public function enableStaleExportIgnoresCamparison() + { + $this->staleExportIgnoresCamparison = true; + + return $this; + } + + /** + * Guard for stale export ignores camparison. + * + * @return boolean + */ + public function isStaleExportIgnoresCamparisonEnabled() + { + return $this->staleExportIgnoresCamparison === true; + } + /** * Enable strict alignment camparison. * @@ -744,9 +775,10 @@ public function getPresentNonExportIgnoresContent(): string * Get the present export-ignore entries of * the .gitattributes file. * + * @param bool $applyGlob * @return array */ - public function getPresentExportIgnores(): array + public function getPresentExportIgnores(bool $applyGlob = true): array { if ($this->hasGitattributesFile() === false) { return []; @@ -760,15 +792,27 @@ public function getPresentExportIgnores(): array ); $exportIgnores = []; - \array_filter($gitattributesLines, function ($line) use (&$exportIgnores) { + \array_filter($gitattributesLines, function ($line) use (&$exportIgnores, &$applyGlob) { if (\strstr($line, 'export-ignore', true)) { list($line, $void) = \explode('export-ignore', $line); - if ($this->patternHasMatch(\trim($line))) { - if (\substr($line, 0, 1) === '/') { - $line = \substr($line, 1); - } + if ($applyGlob) { + if ($this->patternHasMatch(\trim($line))) { + if (\substr($line, 0, 1) === '/') { + $line = \substr($line, 1); + } - return $exportIgnores[] = \trim($line); + return $exportIgnores[] = \trim($line); + } + } else { + if ($this->patternHasMatch(\trim($line))) { + if (\substr($line, 0, 1) === '/') { + $line = \substr($line, 1); + } + + return $exportIgnores[] = \trim($line); + } else { + return $exportIgnores[] = \trim($line); + } } } }); @@ -800,11 +844,10 @@ private function getAlignedExportIgnoreArtifacts(array $artifacts) } /** - * Is existing .gitattributes file has all export-ignore(s). + * Is existing .gitattributes file having all export-ignore(s). * - * @return boolean */ - public function hasCompleteExportIgnores() + public function hasCompleteExportIgnores(): bool { $expectedExportIgnores = $this->collectExpectedExportIgnores(); @@ -814,12 +857,26 @@ public function hasCompleteExportIgnores() $actualExportIgnores = $this->getPresentExportIgnores(); + if ($this->isStaleExportIgnoresCamparisonEnabled()) { + $staleExportIgnores = []; + $unfilteredExportIgnores = $this->getPresentExportIgnores(false); + foreach ($unfilteredExportIgnores as $unfilteredExportIgnore) { + if (false === \file_exists($unfilteredExportIgnore)) { + $staleExportIgnores[] = $unfilteredExportIgnore; + } + } + } + if ($this->isStrictAlignmentCamparisonEnabled()) { $expectedExportIgnores = $this->getAlignedExportIgnoreArtifacts( $expectedExportIgnores ); } + if ($this->isStaleExportIgnoresCamparisonEnabled()) { + $actualExportIgnores = \array_merge($actualExportIgnores, $staleExportIgnores); + } + return \array_values($expectedExportIgnores) === \array_values($actualExportIgnores); } } diff --git a/src/Commands/ValidateCommand.php b/src/Commands/ValidateCommand.php index b6f1c3c..1e37da3 100755 --- a/src/Commands/ValidateCommand.php +++ b/src/Commands/ValidateCommand.php @@ -88,6 +88,7 @@ protected function configure() $validateArchiveDescription = 'Validate Git archive against current HEAD'; $omitHeaderDescription = 'Omit adding a header to created or modified .gitattributes file'; $diffDescription = 'Show difference between expected and actual .gitattributes content'; + $reportStaleExportIgnoresDescription = 'Filter stale export-ignores referencing non existent artifacts. Requires --diff option to be set'; $exampleGlobPattern = '{.*,*.md}'; $globPatternDescription = 'Use this glob pattern e.g. ' @@ -158,6 +159,12 @@ protected function configure() InputOption::VALUE_NONE, $diffDescription ); + $this->addOption( + 'report-stale-export-ignores', + null, + InputOption::VALUE_NONE, + $reportStaleExportIgnoresDescription + ); } /** @@ -197,6 +204,7 @@ protected function execute(InputInterface $input, OutputInterface $output) $globPatternFile = (string) $input->getOption('glob-pattern-file'); $omitHeader = $input->getOption('omit-header'); $showDifference = $input->getOption('diff'); + $reportStaleExportIgnores = $input->getOption('report-stale-export-ignores'); $enforceStrictOrderComparison = $input->getOption('enforce-strict-order'); @@ -207,6 +215,13 @@ protected function execute(InputInterface $input, OutputInterface $output) $this->analyser->enableStrictOrderCamparison(); } + if ($reportStaleExportIgnores) { + $verboseOutput = '+ Enforcing stale export ignores comparison.'; + $output->writeln($verboseOutput, OutputInterface::VERBOSITY_VERBOSE); + + $this->analyser->enableStaleExportIgnoresCamparison(); + } + $enforceExportIgnoresAlignment = $input->getOption('enforce-alignment'); if ($enforceExportIgnoresAlignment) { @@ -427,6 +442,7 @@ protected function execute(InputInterface $input, OutputInterface $output) $differ = new Differ($builder); $expectedGitattributesFileContent = $differ->diff($actual, $expectedGitattributesFileContent); } + $outputContent .= $this->getExpectedGitattributesFileContentOutput( $expectedGitattributesFileContent ); diff --git a/tests/Commands/ValidateCommandTest.php b/tests/Commands/ValidateCommandTest.php index c6cf6af..c96011f 100644 --- a/tests/Commands/ValidateCommandTest.php +++ b/tests/Commands/ValidateCommandTest.php @@ -1286,6 +1286,62 @@ public function incompleteGitattributesFileIsOverwrittenWithAlignment(): void ); } + /** + * @test + * @ticket 41 (https://github.com/raphaelstolt/lean-package-validator/issues/41) + */ + public function staleExportIgnoresAreConsideredAsInvalid(): void + { + $gitattributesContent = <<createTemporaryGitattributesFile($gitattributesContent); + + $artifactFilenames = ['.editorconfig', '.gitattributes', 'CHANGELOG.md', 'LICENSE.md']; + + $this->createTemporaryFiles( + $artifactFilenames, + ['.github', 'tests'] + ); + + $command = $this->application->find('validate'); + $commandTester = new CommandTester($command); + $commandTester->execute([ + 'command' => $command->getName(), + 'directory' => WORKING_DIRECTORY, + '--diff' => true, + '--report-stale-export-ignores' => true + ]); + + $expectedDisplay = <<assertSame($expectedDisplay, $commandTester->getDisplay()); + $this->assertTrue($commandTester->getStatusCode() > 0); + } + /** * @test * @ticket 8 (https://github.com/raphaelstolt/lean-package-validator/issues/8) From 3d6defd6fe7de1033e67c3111e434aa3ea56e704 Mon Sep 17 00:00:00 2001 From: Raphael Stolt Date: Mon, 16 Oct 2023 15:11:20 +0200 Subject: [PATCH 038/152] Checks leanness of package on build --- .github/workflows/lint.yml | 7 ++----- composer.json | 6 ++++-- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index df4959c..82de09d 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -28,8 +28,5 @@ jobs: - name: Check coding styles run: composer run-script lpv:cs-lint -# - name: Check leanness of package -# uses: raphaelstolt/lean-package-validator-action@v0.1.0 -# with: -# php-version: "${{ matrix.php }}" -# lpv-version: "3.0.0" + - name: Check leanness of package + run: composer run-script lpv:validate-gitattributes diff --git a/composer.json b/composer.json index 567dc36..5c6bc91 100755 --- a/composer.json +++ b/composer.json @@ -36,7 +36,8 @@ "lpv:configure-commit-template": "Configures a local commit message template.", "lpv:application-version-guard": "Checks that the application version matches the given Git tag.", "lpv:application-phar-version-guard": "Checks that the PHAR version matches the given Git tag.", - "lpv:static-analyse": "Runs a static code analysis via PHPStan." + "lpv:static-analyse": "Runs a static code analysis via PHPStan.", + "lpv:validate-gitattributes": "Checks the leanness of this package." }, "scripts": { "lpv:test": "phpunit", @@ -46,7 +47,8 @@ "lpv:configure-commit-template": "git config --add commit.template .gitmessage", "lpv:application-version-guard": "php bin/application-version --verify-tag-match=bin", "lpv:application-phar-version-guard": "php bin/application-version --verify-tag-match=phar", - "lpv:static-analyse": "phpstan analyse --configuration phpstan.neon.dist" + "lpv:static-analyse": "phpstan analyse --configuration phpstan.neon.dist", + "lpv:validate-gitattributes": "bin/lean-package-validator validate" }, "config": { "sort-packages": true From 7362459c584b332724656618279b8700ab1eab91 Mon Sep 17 00:00:00 2001 From: Raphael Stolt Date: Mon, 16 Oct 2023 17:18:30 +0200 Subject: [PATCH 039/152] Replaces appveyor build step --- .appveyor.yml | 43 -------------------------- .gitattributes | 1 - .github/workflows/test-windows.yml | 28 +++++++++++++++++ README.md | 1 - tests/Commands/InitCommandTest.php | 2 +- tests/Commands/ValidateCommandTest.php | 10 ++++-- 6 files changed, 36 insertions(+), 49 deletions(-) delete mode 100644 .appveyor.yml create mode 100644 .github/workflows/test-windows.yml diff --git a/.appveyor.yml b/.appveyor.yml deleted file mode 100644 index 9217862..0000000 --- a/.appveyor.yml +++ /dev/null @@ -1,43 +0,0 @@ -build: false -clone_depth: 1 -platform: x86 - -environment: - matrix: - - php_ver_target: 8.0 - -cache: - - C:\php -> .appveyor.yml - - C:\ProgramData\chocolatey\bin -> .appveyor.yml - - C:\ProgramData\chocolatey\lib -> .appveyor.yml - - '%LOCALAPPDATA%\Composer' - -init: - - SET PATH=C:\php;%PATH% - - SET COMPOSER_NO_INTERACTION=1 - - SET PHP=1 - - SET ANSICON=121x90 (121x90) - - git config --global core.autocrlf input - -install: - - IF EXIST C:\php (SET PHP=0) ELSE (mkdir C:\php) - - cd C:\php - # Enable Windows update service - - ps: Set-Service wuauserv -StartupType Manual - # Install PHP - - ps: appveyor-retry cinst --params '""/InstallDir:C:\php""' --ignore-checksums -y php --version ((choco search php --exact --all-versions -r | select-string -pattern $env:php_ver_target | sort { [version]($_ -split '\|' | select -last 1) } -Descending | Select-Object -first 1) -replace '[php|]','') - - IF %PHP%==1 echo @php %%~dp0composer.phar %%* > composer.bat - - appveyor DownloadFile https://getcomposer.org/composer.phar - - copy php.ini-production php.ini /Y - - echo date.timezone="UTC" >> php.ini - - echo extension_dir=ext >> php.ini - - echo extension=php_openssl.dll >> php.ini - - echo extension=php_curl.dll >> php.ini - - echo extension=php_mbstring.dll >> php.ini - - echo extension=php_fileinfo.dll >> php.ini - - cd %APPVEYOR_BUILD_FOLDER% - - composer update --no-progress --ansi - -test_script: - - cd %APPVEYOR_BUILD_FOLDER% - - composer lpv:test diff --git a/.gitattributes b/.gitattributes index 02be349..8beba37 100755 --- a/.gitattributes +++ b/.gitattributes @@ -1,6 +1,5 @@ * text=auto eol=lf -.appveyor.yml export-ignore .ctl.cache export-ignore .editorconfig export-ignore .gitattributes export-ignore diff --git a/.github/workflows/test-windows.yml b/.github/workflows/test-windows.yml new file mode 100644 index 0000000..860c045 --- /dev/null +++ b/.github/workflows/test-windows.yml @@ -0,0 +1,28 @@ +name: test-windows + +on: push + +jobs: + test: + name: "PHPUnit (PHP ${{ matrix.php }})" + runs-on: "windows-latest" + + strategy: + matrix: + php: + - "8.1" + + steps: + - name: Checkout + uses: actions/checkout@v3 + + - name: Install PHP + uses: shivammathur/setup-php@v2 + with: + php-version: "${{ matrix.php }}" + + - name: Install Composer dependencies + run: composer update --no-progress --prefer-dist --optimize-autoloader + + - name: Run tests + run: composer run-script lpv:test diff --git a/README.md b/README.md index 85ee2b7..93043fb 100755 --- a/README.md +++ b/README.md @@ -1,6 +1,5 @@ # LeanPackageValidator ![Test Status](https://github.com/raphaelstolt/lean-package-validator/workflows/test/badge.svg) -[![Build Status](https://ci.appveyor.com/api/projects/status/github/raphaelstolt/lean-package-validator?svg=true)](https://ci.appveyor.com/project/raphaelstolt/lean-package-validator) [![Version](http://img.shields.io/packagist/v/stolt/lean-package-validator.svg?style=flat)](https://packagist.org/packages/stolt/lean-package-validator) ![PHP Version](https://img.shields.io/badge/php-8.0+-ff69b4.svg) [![composer.lock available](https://poser.pugx.org/stolt/lean-package-validator/composerlock)](https://packagist.org/packages/stolt/lean-package-validator) diff --git a/tests/Commands/InitCommandTest.php b/tests/Commands/InitCommandTest.php index 17f7f6d..3e272c2 100644 --- a/tests/Commands/InitCommandTest.php +++ b/tests/Commands/InitCommandTest.php @@ -171,7 +171,7 @@ public function verboseOutputIsAvailableWhenDesired(): void ); $expectedDisplay = <<temporaryDirectory}. Warning: A default .lpv file already exists. CONTENT; diff --git a/tests/Commands/ValidateCommandTest.php b/tests/Commands/ValidateCommandTest.php index c96011f..54d8950 100644 --- a/tests/Commands/ValidateCommandTest.php +++ b/tests/Commands/ValidateCommandTest.php @@ -12,6 +12,7 @@ use Stolt\LeanPackage\Archive\Validator; use Stolt\LeanPackage\Commands\ValidateCommand; use Stolt\LeanPackage\Exceptions\NoLicenseFilePresent; +use Stolt\LeanPackage\Helpers\Str as OsHelper; use Stolt\LeanPackage\Tests\CommandTester; use Stolt\LeanPackage\Tests\TestCase; use Symfony\Component\Console\Application; @@ -144,6 +145,10 @@ public function validateOnNonExistentGitattributesFilesSuggestsCreationWithAlign */ public function showsDifferenceBetweenActualAndExpectedGitattributesContent(): void { + if ((new OsHelper())->isWindows()) { + $this->markTestSkipped('Skipping test on Windows systems'); + } + $artifactFilenames = [ '.gitattributes', ]; @@ -168,7 +173,6 @@ public function showsDifferenceBetweenActualAndExpectedGitattributesContent(): v ]); $actualDisplayRows = \array_values(\explode(PHP_EOL, $commandTester->getDisplay())); - $expectedDiffRows = ['--- Original', '+++ Expected', '@@ -1 +1,2 @@']; foreach ($expectedDiffRows as $expectedDiffRow) { @@ -651,7 +655,7 @@ public function validateOnNonExistentGitattributesFilesWithCreationOptionCreates ]); $expectedDisplay = <<temporaryDirectory}. Created a .gitattributes file with the shown content: * text=auto eol=lf @@ -691,7 +695,7 @@ public function validateOnNonExistentGitattributesFilesWithCreationOptionCreates ]); $expectedDisplay = <<temporaryDirectory}. Created a .gitattributes file with the shown content: # This file was generated by the lean package validator (http://git.io/lean-package-validator). From 956afac55c2eb60ae5e1fb1c093fa2ae616924df Mon Sep 17 00:00:00 2001 From: Raphael Stolt Date: Wed, 18 Oct 2023 09:52:15 +0200 Subject: [PATCH 040/152] Updates GitHub Action version --- .github/workflows/distribute.yml | 2 +- .github/workflows/static-analyse.yml | 2 +- .github/workflows/test-windows.yml | 2 +- .github/workflows/test.yml | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/distribute.yml b/.github/workflows/distribute.yml index b7aaea4..34dcab6 100644 --- a/.github/workflows/distribute.yml +++ b/.github/workflows/distribute.yml @@ -18,7 +18,7 @@ jobs: steps: - name: Checkout - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Install PHP uses: shivammathur/setup-php@v2 diff --git a/.github/workflows/static-analyse.yml b/.github/workflows/static-analyse.yml index 8b03569..f50be4e 100644 --- a/.github/workflows/static-analyse.yml +++ b/.github/workflows/static-analyse.yml @@ -15,7 +15,7 @@ jobs: steps: - name: Checkout - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Install PHP uses: shivammathur/setup-php@v2 diff --git a/.github/workflows/test-windows.yml b/.github/workflows/test-windows.yml index 860c045..ffcdfdb 100644 --- a/.github/workflows/test-windows.yml +++ b/.github/workflows/test-windows.yml @@ -14,7 +14,7 @@ jobs: steps: - name: Checkout - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Install PHP uses: shivammathur/setup-php@v2 diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 1587ae6..c619914 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -17,7 +17,7 @@ jobs: steps: - name: Checkout - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Install PHP uses: shivammathur/setup-php@v2 From e521f83dd21bd2596cc0a89939343a9fc0cff272 Mon Sep 17 00:00:00 2001 From: Raphael Stolt Date: Wed, 18 Oct 2023 15:00:08 +0200 Subject: [PATCH 041/152] Checks if expected commands exist --- tests/ApplicationTest.php | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/tests/ApplicationTest.php b/tests/ApplicationTest.php index 6bf269e..4c793bd 100644 --- a/tests/ApplicationTest.php +++ b/tests/ApplicationTest.php @@ -6,7 +6,7 @@ use PHPUnit\Framework\TestCase as PHPUnit; -class ApplicationTest extends PHPUnit +final class ApplicationTest extends PHPUnit { /** * @test @@ -25,4 +25,27 @@ public function executableIsAvailable(): void ); $this->assertEquals(0, $returnValue); } + + /** + * @test + * @group integration + */ + public function expectedCommandsAreListed(): void + { + $binaryCommand = 'php bin/lean-package-validator list'; + + \exec($binaryCommand, $output, $returnValue); + + $this->assertStringContainsString( + 'init', + $output[17], + 'Expected init command not listed.' + ); + $this->assertStringContainsString( + 'validate', + $output[19], + 'Expected validate command not listed.' + ); + $this->assertEquals(0, $returnValue); + } } From 252867081f726d6480124d656cb9777fcd674b3e Mon Sep 17 00:00:00 2001 From: Raphael Stolt Date: Tue, 24 Oct 2023 11:07:27 +0200 Subject: [PATCH 042/152] Improves documentation --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 93043fb..47759aa 100755 --- a/README.md +++ b/README.md @@ -33,7 +33,7 @@ As of release `v1.9.0` it's also possible to install and use the LeanPackageVali Therefor download a released version i.e. v1.9.0 and move it to `/usr/local/bin` as shown next. ``` bash -wget https://github.com/raphaelstolt/lean-package-validator/releases/download/v1.9.0/lean-package-validator.phar +wget --quiet https://github.com/raphaelstolt/lean-package-validator/releases/download/v1.9.0/lean-package-validator.phar mv lean-package-validator.phar /usr/local/bin/lean-package-validator ``` From 29b9873560252026bb4fc8cd9d5c049319290fc6 Mon Sep 17 00:00:00 2001 From: Raphael Stolt Date: Thu, 26 Oct 2023 10:13:39 +0200 Subject: [PATCH 043/152] Removes unnecessary file --- .ctl.cache | 1 - .gitattributes | 2 -- 2 files changed, 3 deletions(-) delete mode 100644 .ctl.cache diff --git a/.ctl.cache b/.ctl.cache deleted file mode 100644 index 5aa2ad7..0000000 --- a/.ctl.cache +++ /dev/null @@ -1 +0,0 @@ -9294cdd2ffb5c8301c2799a125340d3b diff --git a/.gitattributes b/.gitattributes index 8beba37..a37bc09 100755 --- a/.gitattributes +++ b/.gitattributes @@ -1,12 +1,10 @@ * text=auto eol=lf -.ctl.cache export-ignore .editorconfig export-ignore .gitattributes export-ignore .github/ export-ignore .gitignore export-ignore .gitmessage export-ignore -.gub export-ignore .php-cs-fixer.php export-ignore .phpunit.result.cache export-ignore bin/application-version export-ignore From 87109c3c811dd53e2fb9dfffa360b1a0d59d04ae Mon Sep 17 00:00:00 2001 From: Raphael Stolt Date: Thu, 26 Oct 2023 15:39:57 +0200 Subject: [PATCH 044/152] Utilises assertCommandIsSuccessful --- tests/Commands/InitCommandTest.php | 4 ++-- tests/Commands/ValidateCommandTest.php | 32 +++++++++++++------------- 2 files changed, 18 insertions(+), 18 deletions(-) diff --git a/tests/Commands/InitCommandTest.php b/tests/Commands/InitCommandTest.php index 3e272c2..3eec95e 100644 --- a/tests/Commands/InitCommandTest.php +++ b/tests/Commands/InitCommandTest.php @@ -89,7 +89,7 @@ public function createsExpectedDefaultLpvFile(): void CONTENT; $this->assertSame($expectedDisplay, $commandTester->getDisplay()); - $this->assertTrue($commandTester->getStatusCode() == 0); + $commandTester->assertCommandIsSuccessful(); $this->assertFileExists($expectedDefaultLpvFile); $this->assertEquals($expectedDefaultLpvFileContent, \file_get_contents($expectedDefaultLpvFile)); } @@ -203,7 +203,7 @@ public function existingDefaultLpvFileIsOverwrittenWhenDesired(): void CONTENT; $this->assertSame($expectedDisplay, $commandTester->getDisplay()); - $this->assertTrue($commandTester->getStatusCode() == 0); + $commandTester->assertCommandIsSuccessful(); $this->assertFileExists($expectedDefaultLpvFile); } diff --git a/tests/Commands/ValidateCommandTest.php b/tests/Commands/ValidateCommandTest.php index 54d8950..f84208d 100644 --- a/tests/Commands/ValidateCommandTest.php +++ b/tests/Commands/ValidateCommandTest.php @@ -585,7 +585,7 @@ public function archiveWithLicenseFileIsConsideredValid(): void CONTENT; $this->assertSame($expectedDisplay, $commandTester->getDisplay()); - $this->assertTrue($commandTester->getStatusCode() == 0); + $commandTester->assertCommandIsSuccessful(); } /** @@ -668,7 +668,7 @@ public function validateOnNonExistentGitattributesFilesWithCreationOptionCreates CONTENT; $this->assertEquals($expectedDisplay, $commandTester->getDisplay()); - $this->assertTrue($commandTester->getStatusCode() == 0); + $commandTester->assertCommandIsSuccessful(); $this->assertFileExists( WORKING_DIRECTORY . DIRECTORY_SEPARATOR . '.gitattributes' ); @@ -710,7 +710,7 @@ public function validateOnNonExistentGitattributesFilesWithCreationOptionCreates CONTENT; $this->assertEquals($expectedDisplay, $commandTester->getDisplay()); - $this->assertTrue($commandTester->getStatusCode() == 0); + $commandTester->assertCommandIsSuccessful(); $this->assertFileExists( WORKING_DIRECTORY . DIRECTORY_SEPARATOR . '.gitattributes' ); @@ -764,7 +764,7 @@ public function validateOnNonExistentGitattributesFilesWithCreationOptionCreates CONTENT; $this->assertEquals($expectedDisplay, $commandTester->getDisplay()); - $this->assertTrue($commandTester->getStatusCode() == 0); + $commandTester->assertCommandIsSuccessful(); $this->assertStringEqualsFile( WORKING_DIRECTORY . DIRECTORY_SEPARATOR . '.gitattributes', $expectedGitattributesContent @@ -812,7 +812,7 @@ public function validGitattributesReturnsExpectedStatusCode(): void CONTENT; $this->assertSame($expectedDisplay, $commandTester->getDisplay()); - $this->assertTrue($commandTester->getStatusCode() == 0); + $commandTester->assertCommandIsSuccessful(); } /** @@ -994,7 +994,7 @@ public function overwriteOptionOnNonExistentGitattributesFileImplicatesCreate(): CONTENT; $this->assertSame($expectedDisplay, $commandTester->getDisplay()); - $this->assertTrue($commandTester->getStatusCode() == 0); + $commandTester->assertCommandIsSuccessful(); $this->assertFileExists( WORKING_DIRECTORY . DIRECTORY_SEPARATOR . '.gitattributes' ); @@ -1036,7 +1036,7 @@ public function leanArchiveIsConsideredLean(): void CONTENT; $this->assertSame($expectedDisplay, $commandTester->getDisplay()); - $this->assertTrue($commandTester->getStatusCode() == 0); + $commandTester->assertCommandIsSuccessful(); } /** @@ -1283,7 +1283,7 @@ public function incompleteGitattributesFileIsOverwrittenWithAlignment(): void CONTENT; $this->assertSame($expectedDisplay, $commandTester->getDisplay()); - $this->assertTrue($commandTester->getStatusCode() == 0); + $commandTester->assertCommandIsSuccessful(); $this->assertStringEqualsFile( WORKING_DIRECTORY . DIRECTORY_SEPARATOR . '.gitattributes', $expectedGitattributesContent @@ -1393,7 +1393,7 @@ public function incompleteGitattributesFileIsOverwritten(string $option): void CONTENT; $this->assertSame($expectedDisplay, $commandTester->getDisplay()); - $this->assertTrue($commandTester->getStatusCode() == 0); + $commandTester->assertCommandIsSuccessful(); $this->assertFileExists( WORKING_DIRECTORY . DIRECTORY_SEPARATOR . '.gitattributes' ); @@ -1497,7 +1497,7 @@ public function nonExistentArtifactsWhichAreExportIgnoredAreIgnoredOnComparison( CONTENT; $this->assertSame($expectedDisplay, $commandTester->getDisplay()); - $this->assertTrue($commandTester->getStatusCode() === 0); + $commandTester->assertCommandIsSuccessful(); } /** @@ -1714,7 +1714,7 @@ public function givenGlobPatternTakesPrecedenceOverDefaultGlobPatternFile(): voi CONTENT; $this->assertSame($expectedDisplay, $commandTester->getDisplay()); - $this->assertTrue($commandTester->getStatusCode() === 0); + $commandTester->assertCommandIsSuccessful(); } /** @@ -1774,7 +1774,7 @@ public function presentGlobPatternFileTakesPrecedenceOverDefaultGlobPattern(): v CONTENT; $this->assertSame($expectedDisplay, $commandTester->getDisplay()); - $this->assertTrue($commandTester->getStatusCode() === 0); + $commandTester->assertCommandIsSuccessful(); } /** @@ -1829,7 +1829,7 @@ public function presentLpvPatternFileIsUsed(): void CONTENT; $this->assertSame($expectedDisplay, $commandTester->getDisplay()); - $this->assertTrue($commandTester->getStatusCode() === 0); + $commandTester->assertCommandIsSuccessful(); } /** @@ -1954,7 +1954,7 @@ public function precedingSlashesInExportIgnorePatternsRaiseAWarning(): void CONTENT; $this->assertSame($expectedDisplay, $commandTester->getDisplay()); - $this->assertTrue($commandTester->getStatusCode() == 0); + $commandTester->assertCommandIsSuccessful(); } /** @@ -1999,7 +1999,7 @@ public function missingTextAutoConfigurationRaisesAWarning(): void CONTENT; $this->assertSame($expectedDisplay, $commandTester->getDisplay()); - $this->assertTrue($commandTester->getStatusCode() == 0); + $commandTester->assertCommandIsSuccessful(); } /** @@ -2056,7 +2056,7 @@ public function gitignoredFilesAreExcludedFromValidation(): void CONTENT; $this->assertSame($expectedDisplay, $commandTester->getDisplay()); - $this->assertTrue($commandTester->getStatusCode() == 0); + $commandTester->assertCommandIsSuccessful(); } /** From f5ec441d4166b3ae208ce1347d1e5b12df499133 Mon Sep 17 00:00:00 2001 From: Raphael Stolt Date: Thu, 26 Oct 2023 16:23:34 +0200 Subject: [PATCH 045/152] Fixes ticket links --- tests/Commands/ValidateCommandTest.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/Commands/ValidateCommandTest.php b/tests/Commands/ValidateCommandTest.php index f84208d..a641ba0 100644 --- a/tests/Commands/ValidateCommandTest.php +++ b/tests/Commands/ValidateCommandTest.php @@ -141,7 +141,7 @@ public function validateOnNonExistentGitattributesFilesSuggestsCreationWithAlign /** * @test - * @ticket 39 (https://github.com/raphaelstolt/lean-package-validator/issues/19) + * @ticket 39 (https://github.com/raphaelstolt/lean-package-validator/issues/39) */ public function showsDifferenceBetweenActualAndExpectedGitattributesContent(): void { @@ -1780,7 +1780,7 @@ public function presentGlobPatternFileTakesPrecedenceOverDefaultGlobPattern(): v /** * @test * @group glob - * @ticket 35 https://github.com/raphaelstolt/lean-package-validator/issues/35 + * @ticket 35 (https://github.com/raphaelstolt/lean-package-validator/issues/35) */ public function presentLpvPatternFileIsUsed(): void { From 73484813d5bc90c14ba1ea7fef47cc85a329379f Mon Sep 17 00:00:00 2001 From: Raphael Stolt Date: Fri, 27 Oct 2023 08:18:06 +0200 Subject: [PATCH 046/152] Lints Markdown files on build --- .gitattributes | 1 + .github/workflows/lint.yml | 7 ++++ .markdownlint.json | 8 ++++ CHANGELOG.md | 71 ++++++++++++++++++++++++++++++- README.md | 85 ++++++++++++++++++++++++++++---------- 5 files changed, 148 insertions(+), 24 deletions(-) create mode 100644 .markdownlint.json diff --git a/.gitattributes b/.gitattributes index a37bc09..9521d17 100755 --- a/.gitattributes +++ b/.gitattributes @@ -5,6 +5,7 @@ .github/ export-ignore .gitignore export-ignore .gitmessage export-ignore +.markdownlint.json export-ignore .php-cs-fixer.php export-ignore .phpunit.result.cache export-ignore bin/application-version export-ignore diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 82de09d..d1d4581 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -30,3 +30,10 @@ jobs: - name: Check leanness of package run: composer run-script lpv:validate-gitattributes + + - name: Check Markdown files + uses: DavidAnson/markdownlint-cli2-action@v11 + with: + globs: | + README.md + CHANGELOG.md diff --git a/.markdownlint.json b/.markdownlint.json new file mode 100644 index 0000000..8065767 --- /dev/null +++ b/.markdownlint.json @@ -0,0 +1,8 @@ +{ + "MD013": { + "line_length": 200 + }, + "MD024": { + "allow_different_nesting": true + } +} diff --git a/CHANGELOG.md b/CHANGELOG.md index 20fd7ef..0610989 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,157 +1,224 @@ # Change Log + All notable changes to this project will be documented in this file. -The format is based on [Keep a Changelog](http://keepachangelog.com/) and this project adheres to [Semantic Versioning](http://semver.org/). +The format is based on [Keep a Changelog](http://keepachangelog.com/) and this project adheres to +[Semantic Versioning](http://semver.org/). ## [Unreleased] + ### Added + - New `--report-stale-export-ignores` option. Closes [#41](https://github.com/raphaelstolt/lean-package-validator/issues/41). ## [v3.1.1] - 2023-10-13 ### Fixed + - Header in generated or modified `.gitattributes` file is set as a comment. ## [v3.1.0] - 2023-10-10 + ### Added + - Global .gitignore'd files are excluded from validation. Closes [#36](https://github.com/raphaelstolt/lean-package-validator/issues/36). - Added `--diff` option to show differences between expected and actual .gitattributes content. Closes [#39](https://github.com/raphaelstolt/lean-package-validator/issues/39). - Added verbose output. Closes [#37](https://github.com/raphaelstolt/lean-package-validator/issues/37). ### Fixed + - Empty glob pattern is catched as invalid. Closes [#38](https://github.com/raphaelstolt/lean-package-validator/issues/38). ## [v3.0.1] - 2023-09-26 + ### Removed + - Removed support for PHP `7.4`. ### Added + - Header in generated or modified `.gitattributes` file. ## [v3.0.0] - 2022-04-28 + ### Removed + - Removed support for PHP `7.3` and `7.2`. ### Added + - Introduced GitHub Actions. ## [v2.1.0] - 2019-12-16 + ### Removed + - Removed support for PHP `7.1`. ## [v2.0.2] - 2019-09-04 + - Added zend-stdlib glob fallback for alpine based systems. ## [v2.0.1] - 2019-09-04 + - Upgraded development dependencies - Fixed appearing static analysis errors ## [v2.0.0] - 2019-01-02 + ### Removed + - Removed support for PHP `5.6` and `7.0.`. Closes [#29](https://github.com/raphaelstolt/lean-package-validator/issues/29). ## [v1.9.0] - 2018-11-03 + ### Added + - Enabled distribution via PHAR. Closes [#27](https://github.com/raphaelstolt/lean-package-validator/issues/27). ## [v1.8.1] - 2017-10-18 + ### Fixed + - Matched directories e.g. `tests` or `specs` are export-ignored only once. Closes [#24](https://github.com/raphaelstolt/lean-package-validator/issues/24). ## [v1.8.0] - 2017-10-12 + ### Added + - Additional `--align-export-ignores|-a` option to align the export-ignores which improves readability. Closes [#23](https://github.com/raphaelstolt/lean-package-validator/issues/23). - Additional `--enforce-alignment` option to enforce that all export-ignores are aligned. ## [v1.7.3] - 2017-10-02 + ### Fixed + - Fix dist file pattern to also match `*.dist` files. ## [v1.7.2] - 2017-05-08 + ### Fixed + - Fix non existent export ignored artifacts are excluded from validation. Fixes [#22](https://github.com/raphaelstolt/lean-package-validator/issues/22). ## [v1.7.1] - 2017-05-06 + ### Fixed + - Fix gitignored files with a pre- and postfixed directory separator are excluded from validation. Fixes [#21](https://github.com/raphaelstolt/lean-package-validator/issues/21). ## [v1.7.0] - 2017-03-31 + ### Added + - Additional artifacts glob pattern expansion to match AppVeyor configuration files. ## [v1.6.0] - 2016-10-08 + ### Added + - New `init` command to create a `.lpv` file with the default glob patterns. Closes [#18](https://github.com/raphaelstolt/lean-package-validator/issues/18). ## [v1.5.2] - 2016-10-08 + ### Added + - Internal Composer scripts have a namespace. ### Fixed -- Fix gitignored files are excluded from validation. Fixes [#17](https://github.com/raphaelstolt/lean-package-validator/issues/17). +- Fix gitignored files are excluded from validation. Fixes [#17](https://github.com/raphaelstolt/lean-package-validator/issues/17). ## [v1.5.1] - 2016-10-05 + ### Fixed + - Fix missing export-ignore patterns on existing `.gitattributes` file with no export-ignore entries. Fixes [#16](https://github.com/raphaelstolt/lean-package-validator/issues/16). ## [v1.5.0] - 2016-10-04 + ### Added + - New `--keep-license` option to allow license files in releases. Closes [#15](https://github.com/raphaelstolt/lean-package-validator/issues/15). ## [v1.4.0] - 2016-10-04 + ### Added + - Additional artifacts glob pattern expansion to match CaptainHook configuration files. Closes [#14](https://github.com/raphaelstolt/lean-package-validator/issues/14). ### Fixed + - Fix missing `.gitattributes export-ignore` in suggested and generated `.gitattributes` file content. Closes [#13](https://github.com/raphaelstolt/lean-package-validator/issues/13). ## [v1.3.1] - 2016-10-04 + ### Fixed + - Fix dependency constraint. ## [v1.3.0] - 2016-09-30 + ### Added + - Leading slashes in export-ignore patterns are considered as a smell and raise a warning. Closes [#4](https://github.com/raphaelstolt/lean-package-validator/issues/4). - A missing text auto configuration is considered as a smell and raises a warning. Closes [#12](https://github.com/raphaelstolt/lean-package-validator/issues/12). ## [v1.2.0] - 2016-09-22 + ### Added + - New `--glob-pattern-file` option to load custom glob patterns from a file. Closes [#9](https://github.com/raphaelstolt/lean-package-validator/issues/9). ## [v1.1.0] - 2016-09-18 + ### Added + - Additional artifacts glob pattern expansion to match Phulp files. - New `--enforce-strict-order` option to enforce a strict order comparison of export-ignores in the .gitattributes file. Closes [#6](https://github.com/raphaelstolt/lean-package-validator/issues/6). ## [v1.0.6] - 2016-09-11 + ### Fixed + - Fix present, invalid `.gitattributes` files are overwritable. Closes [#8](https://github.com/raphaelstolt/lean-package-validator/issues/8). ## [v1.0.5] - 2016-09-09 + ### Fixed + - Fix expected and actual `export-ignores` comparison. Related to [#3](https://github.com/raphaelstolt/lean-package-validator/issues/3). ## [v1.0.4] - 2016-09-09 + ### Added + - Additional artifacts glob pattern expansion to match Vagrant and Box files. ### Fixed + - Fix present `.gitattributes` files are really validated. Closes [#3](https://github.com/raphaelstolt/lean-package-validator/issues/3). ## [v1.0.3] - 2016-09-05 + ### Fixed + - Fix `directory` argument usage and validation. ## [v1.0.2] - 2016-09-05 + ### Added + - Additional validation of glob patterns injected via the `--glob-pattern` option. Closes [#2](https://github.com/raphaelstolt/lean-package-validator/issues/2). ## [v1.0.1] - 2016-09-04 + ### Fixed + - Fix for autoloading in global installations. ## v1.0.0 - 2016-09-04 + - Initial release. [Unreleased]: https://github.com/raphaelstolt/lean-package-validator/compare/v3.1.1...HEAD diff --git a/README.md b/README.md index 47759aa..c875127 100755 --- a/README.md +++ b/README.md @@ -1,51 +1,68 @@ # LeanPackageValidator + ![Test Status](https://github.com/raphaelstolt/lean-package-validator/workflows/test/badge.svg) [![Version](http://img.shields.io/packagist/v/stolt/lean-package-validator.svg?style=flat)](https://packagist.org/packages/stolt/lean-package-validator) ![PHP Version](https://img.shields.io/badge/php-8.0+-ff69b4.svg) [![composer.lock available](https://poser.pugx.org/stolt/lean-package-validator/composerlock)](https://packagist.org/packages/stolt/lean-package-validator) [![PDS Skeleton](https://img.shields.io/badge/pds-skeleton-blue.svg?style=flat)](https://github.com/php-pds/skeleton) -The LeanPackageValidator is an utility tool that validates a project/micro-package for its `leanness`. A project/micro-package is considered `lean` when its common repository artifacts won't be included in release assets. +The LeanPackageValidator is an utility tool that validates a project/micro-package +for its `leanness`. A project/micro-package is considered `lean` when its common +repository artifacts won't be included in release assets. ## Installation + The LeanPackageValidator CLI should be installed globally through Composer. ``` bash composer global require stolt/lean-package-validator ``` -Make sure that the path to your global vendor binaries directory is in your `$PATH`. You can determine the location of your global vendor binaries directory via `composer global config bin-dir --absolute`. This way the `lean-package-validator` executable can be located. - +Make sure that the path to your global vendor binaries directory is in your `$PATH`. +You can determine the location of your global vendor binaries directory via +`composer global config bin-dir --absolute`. This way the `lean-package-validator` +executable can be located. -Since the default name of the CLI is quite a mouthful, an alias which can be placed in `~/.aliases`, `~/.zshrc` or the like might come in handy. The alias shown next assumes that `$COMPOSER_HOME` is `~/.config/composer` and not `~/.composer`. +Since the default name of the CLI is quite a mouthful, an alias which can be placed +in `~/.aliases`, `~/.zshrc` or the like might come in handy. The alias shown next +assumes that `$COMPOSER_HOME` is `~/.config/composer` and not `~/.composer`. ```bash alias lpv='~/.config/composer/vendor/bin/lean-package-validator $@' ``` -The LeanPackageValidator also can be installed locally to a project which allows further utilisation via [Composer scripts](https://getcomposer.org/doc/articles/scripts.md). +The LeanPackageValidator also can be installed locally to a project which allows +further utilisation via [Composer scripts](https://getcomposer.org/doc/articles/scripts.md). ``` bash composer require --dev stolt/lean-package-validator ``` -As of release `v1.9.0` it's also possible to install and use the LeanPackageValidator via a PHAR [file](https://github.com/raphaelstolt/lean-package-validator/releases/tag/v1.9.0). -Therefor download a released version i.e. v1.9.0 and move it to `/usr/local/bin` as shown next. +As of release `v1.9.0` it's also possible to install and use the LeanPackageValidator +via a PHAR [file](https://github.com/raphaelstolt/lean-package-validator/releases/tag/v1.9.0). Therefor download a released version e.g. v3.1.1 and move it +to `/usr/local/bin` as shown next. ``` bash -wget --quiet https://github.com/raphaelstolt/lean-package-validator/releases/download/v1.9.0/lean-package-validator.phar +wget --quiet https://github.com/raphaelstolt/lean-package-validator/releases/download/v3.1.1/lean-package-validator.phar mv lean-package-validator.phar /usr/local/bin/lean-package-validator ``` ## Usage -Run the LeanPackageValidator CLI within or against a project/micro-package directory and it will validate the [export-ignore](https://git-scm.com/book/en/v2/Customizing-Git-Git-Attributes#Exporting-Your-Repository) entries present in a `.gitattributes` file against a set of common repository artifacts. If no `.gitattributes` file is present it will suggest to create one. + +Run the LeanPackageValidator CLI within or against a project/micro-package +directory, and it will validate the [export-ignore](https://git-scm.com/book/en/v2/Customizing-Git-Git-Attributes#Exporting-Your-Repository) entries present in +a `.gitattributes` file against a set of common repository artifacts. If no +`.gitattributes` file is present it will suggest to create one. ``` bash lean-package-validator validate [] ``` -#### Available options -The `--enforce-strict-order` option will enforce a strict order comparison of export-ignores in the .gitattributes file and fail validation if the order differs. Per __default__ the order comparison is done in a non strict fashion. +### Available options + +The `--enforce-strict-order` option will enforce a strict order comparison +of export-ignores in the .gitattributes file and fail validation if the order +differs. Per __default__ the order comparison is done in a non-strict fashion. ``` bash lean-package-validator validate [] --enforce-strict-order @@ -57,20 +74,31 @@ The `--create|-c` option creates an `.gitattributes` file if nonexistent. lean-package-validator validate [] --create ``` -The `--overwrite|-o` option overwrites an existing `.gitattributes` file when there are any `export-ignore` entries missing. Using this option on a directory with a nonexistent `.gitattributes` file implicates the `--create` option. +The `--overwrite|-o` option overwrites an existing `.gitattributes` file when +there are any `export-ignore` entries missing. Using this option on a directory +with a nonexistent `.gitattributes` file implicates the `--create` option. ``` bash lean-package-validator validate [] --overwrite ``` -The `--glob-pattern` option allows you to overwrite the default pattern used to match common repository artifacts. The amount of pattern in the grouping braces is expected to be `>1`. As shown next this utility could thereby also be used for projects (i.e. Python) outside of the PHP ecosystem. +The `--glob-pattern` option allows you to overwrite the default pattern used +to match common repository artifacts. The amount of pattern in the grouping +braces is expected to be `>1`. As shown next this utility could thereby also +be used for projects (i.e. Python) outside the PHP ecosystem. ``` bash lean-package-validator validate [] --glob-pattern '{.*,*.rst,*.py[cod],dist/}' ``` + The default pattern is `{.*,*.lock,*.txt,*.rst,*.{md,MD},*.xml,*.yml,appveyor.yml,box.json,captainhook.json,*.dist.*,*.dist,{B,b}uild*,{D,d}oc*,{T,t}ool*,{T,t}est*,{S,s}pec*,{E,e}xample*,LICENSE,{{M,m}ake,{B,b}ox,{V,v}agrant,{P,p}hulp}file,RMT}*`. -The `--glob-pattern-file` option allows you to load patterns, which should be used to match the common repository artifacts, from a given file. You can put a `.lpv` file in the repository which will be used per default and overwrite the default pattern. The structure of such a glob pattern file can be taken from the [example](example/.lpv) directory or be created via `lean-package-validator init`. +The `--glob-pattern-file` option allows you to load patterns, which should +be used to match the common repository artifacts, from a given file. You +can put a `.lpv` file in the repository which will be used per default and +overwrite the default pattern. The structure of such a glob pattern file +can be taken from the [example](example/.lpv) directory or be created +via `lean-package-validator init`. ``` bash lean-package-validator validate [] --glob-pattern-file /path/to/glob-pattern-file @@ -88,9 +116,14 @@ The `--align-export-ignores|-a` option will align the created or overwritten exp lean-package-validator validate [] --align-export-ignores --create ``` -The `--enforce-alignment` option will enforce a strict alignment of export-ignores in the .gitattributes file and fail validation if they aren't aligned. Per __default__ no alignment is enforced. +The `--enforce-alignment` option will enforce a strict alignment of export-ignores +in the .gitattributes file and fail validation if they aren't aligned. Per __default__ +no alignment is enforced. -The `--validate-git-archive` option will validate that no common repository artifacts slip into the release/dist archive file. It will do so by creating a `temporary archive` from the current Git `HEAD` and inspecting its content. With a set `--keep-license` option a license file becomes mandatory and will fail the archive validation if not present. +The `--validate-git-archive` option will validate that no common repository artifacts slip +into the release/dist archive file. It will do so by creating a `temporary archive` from the +current Git `HEAD` and inspecting its content. With a set `--keep-license` option a license +file becomes mandatory and will fail the archive validation if not present. ``` bash lean-package-validator validate [] --validate-git-archive @@ -132,9 +165,13 @@ lean-package-validator init [] The `--overwrite|-o` option overwrites an existing `.lpv` file. ## Utilisation via Composer scripts or it's dedicated GitHub Action -To avoid that changes coming from contributions or own modifications slip into release/dist archives it might be helpful to use a guarding [Composer script](https://getcomposer.org/doc/articles/scripts.md), which will be available at everyone's fingertips. -By adding the following to the project/micro-package its `composer.json` the ` .gitattributes` file can now be easily validated via `composer validate-gitattributes`. +To avoid that changes coming from contributions or own modifications slip into release/dist archives it +might be helpful to use a guarding [Composer script](https://getcomposer.org/doc/articles/scripts.md), +which will be available at everyone's fingertips. + +By adding the following to the project/micro-package its `composer.json` the `.gitattributes` file can +now be easily validated via `composer validate-gitattributes`. ``` json { @@ -146,16 +183,20 @@ By adding the following to the project/micro-package its `composer.json` the ` . For utilising a dedicated GitHub Action have a look at the documentation over [here](https://github.com/raphaelstolt/lean-package-validator-action). -#### Running tests +### Running tests + ``` bash composer lpv:test ``` -#### License +### License + This library and its CLI are licensed under the MIT license. Please see [LICENSE.md](LICENSE.md) for more details. -#### Changelog +### Changelog + Please see [CHANGELOG.md](CHANGELOG.md) for more details. -#### Contributing +### Contributing + Please see [CONTRIBUTING.md](.github/CONTRIBUTING.md) for more details. From 63a611fd15adec24cc2757889b9ce2b78936ed3c Mon Sep 17 00:00:00 2001 From: Raphael Stolt Date: Fri, 27 Oct 2023 22:15:17 +0200 Subject: [PATCH 047/152] Fixes version number --- bin/lean-package-validator | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bin/lean-package-validator b/bin/lean-package-validator index 4e5350a..1a65ccb 100755 --- a/bin/lean-package-validator +++ b/bin/lean-package-validator @@ -22,7 +22,7 @@ if (false === $autoloaded) { } \define('WORKING_DIRECTORY', \getcwd()); -\define('VERSION', '3.10.1'); +\define('VERSION', '3.1.1'); use Stolt\LeanPackage\Commands\InitCommand; use Stolt\LeanPackage\Commands\ValidateCommand; From 5e632f905d1e4723a9ac57f6e353a6c0f694a6b8 Mon Sep 17 00:00:00 2001 From: Raphael Stolt Date: Wed, 1 Nov 2023 23:41:37 +0100 Subject: [PATCH 048/152] Prompts Composer's --dev option --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 5c6bc91..8708216 100755 --- a/composer.json +++ b/composer.json @@ -1,7 +1,7 @@ { "name": "stolt/lean-package-validator", "description": "Library and CLI for validating if a project or package has and will have lean releases.", - "keywords": ["project", "package", "release", "lean", "gitattributes" , "dist", "validation", "cli"], + "keywords": ["project", "package", "release", "lean", "gitattributes" , "dist", "validation", "cli", "dev"], "license": "MIT", "authors": [ { From 65d726d1b4e972c2928867aa090bdc8c3fb55ab8 Mon Sep 17 00:00:00 2001 From: Raphael Stolt Date: Mon, 6 Nov 2023 08:36:26 +0100 Subject: [PATCH 049/152] Improves readability --- phpunit.xml.dist | 6 +++++- tests/Commands/InitCommandTest.php | 26 ++++++++++++----------- tests/Commands/ValidateCommandTest.php | 29 ++++++++++++++------------ 3 files changed, 35 insertions(+), 26 deletions(-) diff --git a/phpunit.xml.dist b/phpunit.xml.dist index ece54d7..d51182e 100755 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -1,5 +1,9 @@ - + diff --git a/tests/Commands/InitCommandTest.php b/tests/Commands/InitCommandTest.php index 3eec95e..82ef328 100644 --- a/tests/Commands/InitCommandTest.php +++ b/tests/Commands/InitCommandTest.php @@ -121,7 +121,7 @@ public function failingInitReturnsExpectedStatusCode(): void CONTENT; $this->assertSame($expectedDisplay, $commandTester->getDisplay()); - $this->assertTrue($commandTester->getStatusCode() > 0); + $this->assertTrue($commandTester->getStatusCode() !== 0); $mock->disable(); } @@ -131,10 +131,10 @@ public function failingInitReturnsExpectedStatusCode(): void */ public function existingDefaultLpvFileIsNotOverwritten(): void { - $expectedDefaultLpvFile = $this->temporaryDirectory + $defaultLpvFile = $this->temporaryDirectory . DIRECTORY_SEPARATOR . '.lpv'; - \touch($expectedDefaultLpvFile); + \touch($defaultLpvFile); $command = $this->application->find('init'); $commandTester = new CommandTester($command); @@ -149,7 +149,7 @@ public function existingDefaultLpvFileIsNotOverwritten(): void CONTENT; $this->assertSame($expectedDisplay, $commandTester->getDisplay()); - $this->assertTrue($commandTester->getStatusCode() > 0); + $this->assertTrue($commandTester->getStatusCode() !== 0); } /** @@ -157,10 +157,17 @@ public function existingDefaultLpvFileIsNotOverwritten(): void */ public function verboseOutputIsAvailableWhenDesired(): void { - $expectedDefaultLpvFile = $this->temporaryDirectory + $defaultLpvFile = $this->temporaryDirectory . DIRECTORY_SEPARATOR . '.lpv'; - \touch($expectedDefaultLpvFile); + + $expectedDisplay = <<temporaryDirectory}. +Warning: A default .lpv file already exists. + +CONTENT; + + \touch($defaultLpvFile); $command = $this->application->find('init'); $commandTester = new CommandTester($command); @@ -170,13 +177,8 @@ public function verboseOutputIsAvailableWhenDesired(): void ['verbosity' => OutputInterface::VERBOSITY_VERBOSE] ); - $expectedDisplay = <<temporaryDirectory}. -Warning: A default .lpv file already exists. - -CONTENT; - $this->assertSame($expectedDisplay, $commandTester->getDisplay()); + $this->assertTrue($commandTester->getStatusCode() !== 0); } /** diff --git a/tests/Commands/ValidateCommandTest.php b/tests/Commands/ValidateCommandTest.php index a641ba0..0451a72 100644 --- a/tests/Commands/ValidateCommandTest.php +++ b/tests/Commands/ValidateCommandTest.php @@ -187,17 +187,17 @@ public function showsDifferenceBetweenActualAndExpectedGitattributesContent(): v * @test * @ticket 16 (https://github.com/raphaelstolt/lean-package-validator/issues/16) */ - public function gitattributesFileWithNonExportIgnoreContentShowsExpectedContent(): void + public function gitattributesFileWithNoExportIgnoresContentShowsExpectedContent(): void { - $mock = Mockery::mock( + $analyserMock = Mockery::mock( 'Stolt\LeanPackage\Analyser[getGlobalGitignorePatterns]' ); - $mock->shouldReceive('getGlobalGitignorePatterns') + $analyserMock->shouldReceive('getGlobalGitignorePatterns') ->once() ->withAnyArgs() ->andReturn([]); - $application = $this->getApplicationWithMockedAnalyser($mock); + $application = $this->getApplicationWithMockedAnalyser($analyserMock); $artifactFilenames = [ '.gitattributes', @@ -234,6 +234,7 @@ public function gitattributesFileWithNonExportIgnoreContentShowsExpectedContent( 'command' => $command->getName(), 'directory' => WORKING_DIRECTORY, '--enforce-strict-order' => true, + '--enforce-alignment' => true, ]); $expectedDisplay = << Date: Tue, 7 Nov 2023 10:57:06 +0100 Subject: [PATCH 050/152] Improves domain code by adding types --- src/Analyser.php | 94 +++++++++++++++++++-------------------- src/Archive.php | 32 ++++++------- src/Archive/Validator.php | 16 ++++--- src/Helpers/Str.php | 2 +- 4 files changed, 73 insertions(+), 71 deletions(-) diff --git a/src/Analyser.php b/src/Analyser.php index a86059c..c344af1 100755 --- a/src/Analyser.php +++ b/src/Analyser.php @@ -15,42 +15,42 @@ class Analyser * * @var string */ - private $directory; + private string $directory; /** * The .gitattributes file to analyse * * @var string */ - private $gitattributesFile; + private string $gitattributesFile; /** * Files to ignore in glob matches. * * @var array */ - private $ignoredGlobMatches = ['.', '..', '.git', '.DS_Store']; + private array $ignoredGlobMatches = ['.', '..', '.git', '.DS_Store']; /** * The default glob patterns. * * @var array */ - private $defaultGlobPatterns = []; + private array $defaultGlobPatterns = []; /** * The .gitattributes glob pattern * * @var string */ - private $globPattern; + private string $globPattern; /** * The preferred end of line sequence * * @var string */ - private $preferredEol = "\n"; + private string $preferredEol = "\n"; /** * Whether to do a strict comparsion of the export-ignores @@ -59,7 +59,7 @@ class Analyser * * @var boolean */ - private $strictOrderComparison = false; + private bool $strictOrderComparison = false; /** * Whether to do a strict comparsion for stale export-ignores @@ -68,7 +68,7 @@ class Analyser * * @var boolean */ - private $staleExportIgnoresCamparison = false; + private bool $staleExportIgnoresCamparison = false; /** * Whether to do a strict alignment comparsion of the export-ignores @@ -77,7 +77,7 @@ class Analyser * * @var boolean */ - private $strictAlignmentComparison = false; + private bool $strictAlignmentComparison = false; /** * Whether at least one export-ignore pattern has @@ -85,14 +85,14 @@ class Analyser * * @var boolean */ - private $hasPrecedingSlashesInExportIgnorePattern = false; + private bool $hasPrecedingSlashesInExportIgnorePattern = false; /** * Whether a text auto configuration is present or not. * * @var boolean */ - private $hasTextAutoConfiguration = false; + private bool $hasTextAutoConfiguration = false; /** * Whether to exclude a license file from the export-ignores @@ -100,7 +100,7 @@ class Analyser * * @var boolean */ - private $keepLicense = false; + private bool $keepLicense = false; /** * Whether to align the export-ignores on create or overwrite @@ -108,7 +108,7 @@ class Analyser * * @var boolean */ - private $alignExportIgnores = false; + private bool $alignExportIgnores = false; /** * Initialize. @@ -147,7 +147,7 @@ public function __construct() * * @return array */ - public function getDefaultGlobPatterns() + public function getDefaultGlobPatterns(): array { return $this->defaultGlobPatterns; } @@ -157,7 +157,7 @@ public function getDefaultGlobPatterns() * * @return boolean */ - public function hasPrecedingSlashesInExportIgnorePattern() + public function hasPrecedingSlashesInExportIgnorePattern(): bool { return $this->hasPrecedingSlashesInExportIgnorePattern; } @@ -167,7 +167,7 @@ public function hasPrecedingSlashesInExportIgnorePattern() * * @return boolean */ - public function hasTextAutoConfiguration() + public function hasTextAutoConfiguration(): bool { return $this->hasTextAutoConfiguration; } @@ -176,11 +176,11 @@ public function hasTextAutoConfiguration() * Set the glob pattern file. * * @param string $file - * @throws \Stolt\LeanPackage\Exceptions\NonExistentGlobPatternFile * @throws \Stolt\LeanPackage\Exceptions\InvalidGlobPatternFile - * @return \Stolt\LeanPackage\Analyser + * @throws \Stolt\LeanPackage\Exceptions\NonExistentGlobPatternFile + * @return Analyser */ - public function setGlobPatternFromFile($file) + public function setGlobPatternFromFile($file): Analyser { if (!\is_file($file)) { $message = "Glob pattern file {$file} doesn't exist."; @@ -219,7 +219,7 @@ public function setGlobPatternFromFile($file) * @throws \Stolt\LeanPackage\Exceptions\InvalidGlobPattern * @return void */ - private function guardGlobPattern() + private function guardGlobPattern(): void { $invalidGlobPattern = false; @@ -252,10 +252,10 @@ private function guardGlobPattern() * export-ignores files. * * @throws \Stolt\LeanPackage\Exceptions\InvalidGlobPattern + * @return Analyser * - * @return \Stolt\LeanPackage\Analyser */ - public function setGlobPattern($pattern) + public function setGlobPattern($pattern): Analyser { $this->globPattern = \trim($pattern); $this->guardGlobPattern(); @@ -268,10 +268,10 @@ public function setGlobPattern($pattern) * * @param string $directory The directory to analyse. * @throws \RuntimeException + * @return Analyser * - * @return \Stolt\LeanPackage\Analyser */ - public function setDirectory($directory = __DIR__) + public function setDirectory($directory = __DIR__): Analyser { if (!\is_dir($directory)) { $message = "Directory {$directory} doesn't exist."; @@ -290,7 +290,7 @@ public function setDirectory($directory = __DIR__) * * @return string */ - public function getDirectory() + public function getDirectory(): string { return $this->directory; } @@ -298,9 +298,9 @@ public function getDirectory() /** * Enable strict order camparison. * - * @return \Stolt\LeanPackage\Analyser + * @return Analyser */ - public function enableStrictOrderCamparison() + public function enableStrictOrderCamparison(): Analyser { $this->strictOrderComparison = true; @@ -312,7 +312,7 @@ public function enableStrictOrderCamparison() * * @return boolean */ - public function isStrictOrderCamparisonEnabled() + public function isStrictOrderCamparisonEnabled(): bool { return $this->strictOrderComparison === true; } @@ -320,9 +320,9 @@ public function isStrictOrderCamparisonEnabled() /** * Enable stale export ignores camparison. * - * @return \Stolt\LeanPackage\Analyser + * @return Analyser */ - public function enableStaleExportIgnoresCamparison() + public function enableStaleExportIgnoresCamparison(): Analyser { $this->staleExportIgnoresCamparison = true; @@ -334,7 +334,7 @@ public function enableStaleExportIgnoresCamparison() * * @return boolean */ - public function isStaleExportIgnoresCamparisonEnabled() + public function isStaleExportIgnoresCamparisonEnabled(): bool { return $this->staleExportIgnoresCamparison === true; } @@ -342,9 +342,9 @@ public function isStaleExportIgnoresCamparisonEnabled() /** * Enable strict alignment camparison. * - * @return \Stolt\LeanPackage\Analyser + * @return Analyser */ - public function enableStrictAlignmentCamparison() + public function enableStrictAlignmentCamparison(): Analyser { $this->strictAlignmentComparison = true; @@ -356,7 +356,7 @@ public function enableStrictAlignmentCamparison() * * @return boolean */ - public function isStrictAlignmentCamparisonEnabled() + public function isStrictAlignmentCamparisonEnabled(): bool { return $this->strictAlignmentComparison === true; } @@ -364,9 +364,9 @@ public function isStrictAlignmentCamparisonEnabled() /** * Keep license file in releases. * - * @return \Stolt\LeanPackage\Analyser + * @return Analyser */ - public function keepLicense() + public function keepLicense(): Analyser { $this->keepLicense = true; @@ -378,7 +378,7 @@ public function keepLicense() * * @return boolean */ - public function isKeepLicenseEnabled() + public function isKeepLicenseEnabled(): bool { return $this->keepLicense === true; } @@ -386,9 +386,9 @@ public function isKeepLicenseEnabled() /** * Align export-ignores. * - * @return \Stolt\LeanPackage\Analyser + * @return Analyser */ - public function alignExportIgnores() + public function alignExportIgnores(): Analyser { $this->alignExportIgnores = true; @@ -400,7 +400,7 @@ public function alignExportIgnores() * * @return boolean */ - public function isAlignExportIgnoresEnabled() + public function isAlignExportIgnoresEnabled(): bool { return $this->alignExportIgnores === true; } @@ -410,7 +410,7 @@ public function isAlignExportIgnoresEnabled() * * @return string */ - public function getGitattributesFilePath() + public function getGitattributesFilePath(): string { return $this->gitattributesFile; } @@ -420,7 +420,7 @@ public function getGitattributesFilePath() * * @return boolean */ - public function hasGitattributesFile() + public function hasGitattributesFile(): bool { return \file_exists($this->gitattributesFile) && \is_readable($this->gitattributesFile); @@ -555,7 +555,7 @@ public function getExpectedGitattributesContent(array $postfixlessExportIgnores * * @return array */ - public function getPresentExportIgnoresToPreserve(array $globPatternMatchingExportIgnores) + public function getPresentExportIgnoresToPreserve(array $globPatternMatchingExportIgnores): array { $gitattributesContent = (string) \file_get_contents($this->gitattributesFile); @@ -608,7 +608,7 @@ public function getPresentExportIgnoresToPreserve(array $globPatternMatchingExpo * * @return array */ - public function collectExpectedExportIgnores() + public function collectExpectedExportIgnores(): array { $expectedExportIgnores = []; @@ -672,7 +672,7 @@ public function collectExpectedExportIgnores() * * @return string */ - private function detectEol($content) + private function detectEol($content): string { $maxCount = 0; $preferredEol = $this->preferredEol; @@ -697,7 +697,7 @@ private function detectEol($content) * @param string $globPattern * @return boolean */ - private function patternHasMatch($globPattern) + private function patternHasMatch($globPattern): bool { if (\substr(\trim($globPattern), 0, 1) === '/') { $globPattern = \trim(\substr($globPattern, 1)); @@ -828,7 +828,7 @@ public function getPresentExportIgnores(bool $applyGlob = true): array * @param array $artifacts The export-ignore artifacts to align. * @return array */ - private function getAlignedExportIgnoreArtifacts(array $artifacts) + private function getAlignedExportIgnoreArtifacts(array $artifacts): array { $longestArtifact = \max(\array_map('strlen', $artifacts)); diff --git a/src/Archive.php b/src/Archive.php index 85967b4..d454634 100755 --- a/src/Archive.php +++ b/src/Archive.php @@ -13,29 +13,29 @@ class Archive /** * @var string */ - private $directory; + private string $directory; /** * @var string */ - private $name; + private string $name; /** * @var string */ - private $filename; + private string $filename; /** * @var array */ - private $foundUnexpectedArtifacts = []; + private array $foundUnexpectedArtifacts = []; /** * Whether the archive should have a license file or not. * * @var boolean */ - private $shouldHaveLicenseFile = false; + private bool $shouldHaveLicenseFile = false; /** * Initialize. @@ -58,9 +58,9 @@ public function __construct(string $directory, string $name = '') /** * Set if license file presence should be validated. * - * @return \Stolt\LeanPackage\Archive + * @return Archive */ - public function shouldHaveLicenseFile() + public function shouldHaveLicenseFile(): Archive { $this->shouldHaveLicenseFile = true; @@ -72,7 +72,7 @@ public function shouldHaveLicenseFile() * * @return boolean */ - public function validateLicenseFilePresence() + public function validateLicenseFilePresence(): bool { return $this->shouldHaveLicenseFile === true; } @@ -82,7 +82,7 @@ public function validateLicenseFilePresence() * * @return string */ - public function getFilename() + public function getFilename(): string { return $this->filename; } @@ -92,7 +92,7 @@ public function getFilename() * * @return array */ - public function getFoundUnexpectedArtifacts() + public function getFoundUnexpectedArtifacts(): array { return $this->foundUnexpectedArtifacts; } @@ -104,7 +104,7 @@ public function getFoundUnexpectedArtifacts() * * @return boolean */ - public function hasHead() + public function hasHead(): bool { if ($this->isGitCommandAvailable()) { \exec('git show-ref --head 2>&1', $output, $returnValue); @@ -121,7 +121,7 @@ public function hasHead() * * @return boolean */ - public function isGitCommandAvailable($command = 'git') + public function isGitCommandAvailable($command = 'git'): bool { \exec('where ' . $command . ' 2>&1', $output, $returnValue); if ((new OsHelper())->isWindows() === false) { @@ -138,7 +138,7 @@ public function isGitCommandAvailable($command = 'git') * * @return boolean */ - public function createArchive() + public function createArchive(): bool { if ($this->hasHead()) { $command = 'git archive -o ' . $this->getFilename() . ' HEAD 2>&1'; @@ -157,7 +157,7 @@ public function createArchive() * @throws \Stolt\LeanPackage\Exceptions\NoLicenseFilePresent * @return array */ - public function compareArchive(array $unexpectedArtifacts) + public function compareArchive(array $unexpectedArtifacts): array { $foundUnexpectedArtifacts = []; $archive = new PharData($this->getFilename()); @@ -200,7 +200,7 @@ public function compareArchive(array $unexpectedArtifacts) * * @return boolean */ - public function removeArchive() + public function removeArchive(): bool { if (\file_exists($this->getFilename())) { return \unlink($this->getFilename()); @@ -220,7 +220,7 @@ public function removeArchive() * * @return array */ - public function getUnexpectedArchiveArtifacts(array $unexpectedArtifacts) + public function getUnexpectedArchiveArtifacts(array $unexpectedArtifacts): array { $this->createArchive(); $this->foundUnexpectedArtifacts = $this->compareArchive($unexpectedArtifacts); diff --git a/src/Archive/Validator.php b/src/Archive/Validator.php index aaad708..e62954e 100755 --- a/src/Archive/Validator.php +++ b/src/Archive/Validator.php @@ -10,12 +10,12 @@ class Validator /** * @var \Stolt\LeanPackage\Archive */ - private $archive; + private Archive $archive; /** * @var boolean */ - private $ranValidate = false; + private bool $ranValidate = false; /** * Initialise. @@ -32,7 +32,7 @@ public function __construct(Archive $archive) * * @return \Stolt\LeanPackage\Archive\Validator */ - public function shouldHaveLicenseFile() + public function shouldHaveLicenseFile(): Validator { $this->archive->shouldHaveLicenseFile(); @@ -44,7 +44,7 @@ public function shouldHaveLicenseFile() * * @return \Stolt\LeanPackage\Archive */ - public function getArchive() + public function getArchive(): Archive { return $this->archive; } @@ -52,11 +52,13 @@ public function getArchive() /** * Validate archive against unexpected artifacts. * - * @param array $unexpectedArtifacts Artifacts not expected in archive. + * @param array $unexpectedArtifacts Artifacts not expected in archive. * + * @throws \Stolt\LeanPackage\Exceptions\GitHeadNotAvailable + * @throws \Stolt\LeanPackage\Exceptions\GitNotAvailable * @return boolean */ - public function validate(array $unexpectedArtifacts) + public function validate(array $unexpectedArtifacts): bool { $foundUnexpectedArtifacts = $this->archive->getUnexpectedArchiveArtifacts( $unexpectedArtifacts @@ -77,7 +79,7 @@ public function validate(array $unexpectedArtifacts) * * @return array */ - public function getFoundUnexpectedArchiveArtifacts() + public function getFoundUnexpectedArchiveArtifacts(): array { if ($this->ranValidate === false) { $message = 'Git archive ' . $this->archive->getFilename() diff --git a/src/Helpers/Str.php b/src/Helpers/Str.php index fe388cf..0a5f219 100644 --- a/src/Helpers/Str.php +++ b/src/Helpers/Str.php @@ -11,7 +11,7 @@ class Str * * @return boolean */ - public function isWindows($os = PHP_OS) + public function isWindows($os = PHP_OS): bool { if (\strtoupper(\substr($os, 0, 3)) !== 'WIN') { return false; From b1650b71177b5d694aa8e3249b11dbec044454e2 Mon Sep 17 00:00:00 2001 From: Raphael Stolt Date: Tue, 7 Nov 2023 10:57:06 +0100 Subject: [PATCH 051/152] Adds glob pattern presets --- CHANGELOG.md | 4 + README.md | 3 + bin/lean-package-validator | 5 +- src/Analyser.php | 58 ++++++------- src/Archive/Validator.php | 2 + src/Commands/InitCommand.php | 62 +++++++++++++- src/Exceptions/PresetNotAvailable.php | 8 ++ src/Preset.php | 10 +++ src/Presets/Finder.php | 70 ++++++++++++++++ src/Presets/GoPreset.php | 33 ++++++++ src/Presets/PhpPreset.php | 37 +++++++++ src/Presets/PythonPreset.php | 34 ++++++++ tests/AnalyserTest.php | 108 +++++++++++++------------ tests/Commands/InitCommandTest.php | 26 +++++- tests/Commands/ValidateCommandTest.php | 22 +++-- tests/Presets/FinderTest.php | 59 ++++++++++++++ 16 files changed, 445 insertions(+), 96 deletions(-) create mode 100644 src/Exceptions/PresetNotAvailable.php create mode 100644 src/Preset.php create mode 100644 src/Presets/Finder.php create mode 100644 src/Presets/GoPreset.php create mode 100644 src/Presets/PhpPreset.php create mode 100644 src/Presets/PythonPreset.php create mode 100644 tests/Presets/FinderTest.php diff --git a/CHANGELOG.md b/CHANGELOG.md index 0610989..cda9ff0 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,10 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/) and this p ### Added +- New `--preset` option. Closes [#43](https://github.com/raphaelstolt/lean-package-validator/issues/43). + +### Added + - New `--report-stale-export-ignores` option. Closes [#41](https://github.com/raphaelstolt/lean-package-validator/issues/41). ## [v3.1.1] - 2023-10-13 diff --git a/README.md b/README.md index c875127..7695095 100755 --- a/README.md +++ b/README.md @@ -164,6 +164,9 @@ lean-package-validator init [] The `--overwrite|-o` option overwrites an existing `.lpv` file. +The `--preset` option allows to choose from a predefined set of glob pattern. +Available presets are `PHP`, `Python` and `Go`. With `PHP` being the default. + ## Utilisation via Composer scripts or it's dedicated GitHub Action To avoid that changes coming from contributions or own modifications slip into release/dist archives it diff --git a/bin/lean-package-validator b/bin/lean-package-validator index 1a65ccb..619e61e 100755 --- a/bin/lean-package-validator +++ b/bin/lean-package-validator @@ -29,10 +29,13 @@ use Stolt\LeanPackage\Commands\ValidateCommand; use Stolt\LeanPackage\Analyser; use Stolt\LeanPackage\Archive; use Stolt\LeanPackage\Archive\Validator; +use Stolt\LeanPackage\Presets\Finder; +use Stolt\LeanPackage\Presets\PhpPreset; use Symfony\Component\Console\Application; +$finder = new Finder(new PhpPreset()); $archive = new Archive(WORKING_DIRECTORY); -$analyser = new Analyser; +$analyser = new Analyser($finder); $initCommand = new InitCommand( $analyser diff --git a/src/Analyser.php b/src/Analyser.php index c344af1..7f9600e 100755 --- a/src/Analyser.php +++ b/src/Analyser.php @@ -6,6 +6,7 @@ use Stolt\LeanPackage\Exceptions\InvalidGlobPattern; use Stolt\LeanPackage\Exceptions\InvalidGlobPatternFile; use Stolt\LeanPackage\Exceptions\NonExistentGlobPatternFile; +use Stolt\LeanPackage\Presets\Finder; class Analyser { @@ -32,11 +33,11 @@ class Analyser private array $ignoredGlobMatches = ['.', '..', '.git', '.DS_Store']; /** - * The default glob patterns. + * The default glob pattern. * * @var array */ - private array $defaultGlobPatterns = []; + private array $defaultGlobPattern = []; /** * The .gitattributes glob pattern @@ -88,7 +89,7 @@ class Analyser private bool $hasPrecedingSlashesInExportIgnorePattern = false; /** - * Whether a text auto configuration is present or not. + * Whether a text autoconfiguration is present or not. * * @var boolean */ @@ -110,36 +111,27 @@ class Analyser */ private bool $alignExportIgnores = false; + private Finder $finder; + /** * Initialize. */ - public function __construct() - { - $this->defaultGlobPatterns = [ - '.*', - '*.lock', - '*.txt', - '*.rst', - '*.{md,MD}', - '*.xml', - '*.yml', - 'appveyor.yml', - 'box.json', - 'captainhook.json', - '*.dist.*', - '*.dist', - '{B,b}uild*', - '{D,d}oc*', - '{T,t}ool*', - '{T,t}est*', - '{S,s}pec*', - '{E,e}xample*', - 'LICENSE', - '{{M,m}ake,{B,b}ox,{V,v}agrant,{P,p}hulp}file', - 'RMT' - ]; - - $this->globPattern = '{' . \implode(',', $this->defaultGlobPatterns) . '}*'; + public function __construct(Finder $finder) + { + $this->finder = $finder; + $this->defaultGlobPattern = $finder->getDefaultPreset(); + + $this->globPattern = '{' . \implode(',', $this->defaultGlobPattern) . '}*'; + } + + /** + * Accessor for the injected finder. + * + * @return Finder + */ + public function getFinder(): Finder + { + return $this->finder; } /** @@ -147,9 +139,9 @@ public function __construct() * * @return array */ - public function getDefaultGlobPatterns(): array + public function getDefaultGlobPattern(): array { - return $this->defaultGlobPatterns; + return $this->defaultGlobPattern; } /** @@ -253,6 +245,7 @@ private function guardGlobPattern(): void * * @throws \Stolt\LeanPackage\Exceptions\InvalidGlobPattern * @return Analyser + * @return Analyser * */ public function setGlobPattern($pattern): Analyser @@ -269,6 +262,7 @@ public function setGlobPattern($pattern): Analyser * @param string $directory The directory to analyse. * @throws \RuntimeException * @return Analyser + * @return Analyser * */ public function setDirectory($directory = __DIR__): Analyser diff --git a/src/Archive/Validator.php b/src/Archive/Validator.php index e62954e..2cdf11b 100755 --- a/src/Archive/Validator.php +++ b/src/Archive/Validator.php @@ -56,6 +56,8 @@ public function getArchive(): Archive * * @throws \Stolt\LeanPackage\Exceptions\GitHeadNotAvailable * @throws \Stolt\LeanPackage\Exceptions\GitNotAvailable + * @throws \Stolt\LeanPackage\Exceptions\GitHeadNotAvailable + * @throws \Stolt\LeanPackage\Exceptions\GitNotAvailable * @return boolean */ public function validate(array $unexpectedArtifacts): bool diff --git a/src/Commands/InitCommand.php b/src/Commands/InitCommand.php index f025f3b..863db96 100644 --- a/src/Commands/InitCommand.php +++ b/src/Commands/InitCommand.php @@ -5,6 +5,7 @@ namespace Stolt\LeanPackage\Commands; use Stolt\LeanPackage\Analyser; +use Stolt\LeanPackage\Presets\Finder; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Input\InputInterface; @@ -13,6 +14,8 @@ class InitCommand extends Command { + private const DEFAULT_PRESET = 'PHP'; + /** * Package analyser. * @@ -20,12 +23,18 @@ class InitCommand extends Command */ protected $analyser; + /** + * @var \Stolt\LeanPackage\Presets\Finder + */ + private Finder $finder; + /** * @param Analyser $analyser */ public function __construct(Analyser $analyser) { $this->analyser = $analyser; + $this->finder = $analyser->getFinder(); parent::__construct(); } @@ -43,8 +52,13 @@ protected function configure() . 'project/micro-package repository'; $this->setDescription($description); + $availablePresets = $this->formatAvailablePresetDefinitionsForDescription( + $this->finder->getAvailablePresets() + ); + $directoryDescription = 'The directory of a project/micro-package repository'; $overwriteDescription = 'Overwrite existing default .lpv file file'; + $presetDescription = 'The preset to use for the .lpv file. Available ones are ' . $availablePresets . '.'; $this->addArgument( 'directory', @@ -53,6 +67,31 @@ protected function configure() $this->analyser->getDirectory() ); $this->addOption('overwrite', 'o', InputOption::VALUE_NONE, $overwriteDescription); + $this->addOption( + 'preset', + null, + InputOption::VALUE_REQUIRED, + $presetDescription, + self::DEFAULT_PRESET + ); + } + + /** + * @param array $presets + * @return string + */ + private function formatAvailablePresetDefinitionsForDescription(array $presets): string + { + $presets = \array_map(function ($preset) { + return '' . $preset . ''; + }, $presets); + + if (\count($presets) > 2) { + $lastPreset = \array_pop($presets); + return \implode(', ', $presets) . ', and ' . $lastPreset; + } + + return $presets[0] . ' and ' . $presets[1]; } /** @@ -67,6 +106,7 @@ protected function execute(InputInterface $input, OutputInterface $output) { $directory = (string) $input->getArgument('directory'); $overwriteDefaultLpvFile = $input->getOption('overwrite'); + $chosenPreset = (string) $input->getOption('preset'); if ($directory !== WORKING_DIRECTORY) { try { @@ -96,8 +136,23 @@ protected function execute(InputInterface $input, OutputInterface $output) return 1; } - $defaultGlobPatterns = $this->analyser->getDefaultGlobPatterns(); - $lpvFileContent = \implode("\n", $defaultGlobPatterns); + $defaultGlobPattern = $this->analyser->getDefaultGlobPattern(); + $globPatternFromPreset = false; + + if ($chosenPreset && \in_array(\strtolower($chosenPreset), \array_map('strtolower', $this->finder->getAvailablePresets()))) { + $verboseOutput = '+ Loadind preset ' . $chosenPreset . '.'; + $output->writeln($verboseOutput, OutputInterface::VERBOSITY_VERBOSE); + $globPatternFromPreset = true; + $defaultGlobPattern = $this->finder->getPresetGlobByLanguageName($chosenPreset); + } else { + $warning = 'Warning: Chosen preset ' . $chosenPreset . ' is not available. Maybe contribute it?.'; + $outputContent = '' . $warning . ''; + $output->writeln($outputContent); + + return 1; + } + + $lpvFileContent = \implode("\n", $defaultGlobPattern); $bytesWritten = file_put_contents( $defaultLpvFile, @@ -105,6 +160,9 @@ protected function execute(InputInterface $input, OutputInterface $output) ); $verboseOutput = '+ Writing default glob pattern to .lpv file in ' . WORKING_DIRECTORY . '.'; + if ($globPatternFromPreset) { + $verboseOutput = '+ Writing glob pattern for preset ' . $chosenPreset . ' to .lpv file in ' . WORKING_DIRECTORY . '.'; + } $output->writeln($verboseOutput, OutputInterface::VERBOSITY_VERBOSE); if ($bytesWritten === false) { diff --git a/src/Exceptions/PresetNotAvailable.php b/src/Exceptions/PresetNotAvailable.php new file mode 100644 index 0000000..f3750c3 --- /dev/null +++ b/src/Exceptions/PresetNotAvailable.php @@ -0,0 +1,8 @@ +defaultPreset = $defaultPreset; + } + + /** + * @return array + */ + public function getAvailablePresets(): array + { + $dir = new \DirectoryIterator(\dirname(__FILE__)); + $availablePresets = []; + foreach ($dir as $fileinfo) { + if (!$fileinfo->isDot()) { + $presetsParts = \explode(self::PRESET_SUFFIX, $fileinfo->getBasename()); + if (\count($presetsParts) == 2) { + $availablePresets[] = $presetsParts[0]; + } + } + } + + return $availablePresets; + } + + /** + * @param $name + * @throws PresetNotAvailable|\ReflectionException + * @return array + */ + public function getPresetGlobByLanguageName($name): array + { + $name = \ucfirst(\strtolower($name)); + + if (!\in_array($name, $this->getAvailablePresets())) { + throw new PresetNotAvailable('Preset for Kotlin not available. Maybe contribute it?.'); + } + + $presetClassName = \sprintf('Stolt\LeanPackage\Presets\%sPreset', $name); + + $reflectionClass = new \ReflectionClass($presetClassName); + $preset = $reflectionClass->newInstance(); + + return $preset->getPresetGlob(); + } + + /** + * Returns the default Preset glob array + * + * @return array + */ + public function getDefaultPreset(): array + { + return $this->defaultPreset->getPresetGlob(); + } +} diff --git a/src/Presets/GoPreset.php b/src/Presets/GoPreset.php new file mode 100644 index 0000000..1a28555 --- /dev/null +++ b/src/Presets/GoPreset.php @@ -0,0 +1,33 @@ +setDirectory($this->temporaryDirectory); + $analyser = (new Analyser(new Finder(new PhpPreset())))->setDirectory($this->temporaryDirectory); $this->assertFalse( $analyser->hasCompleteExportIgnores() ); @@ -45,12 +47,14 @@ public function hasCompleteExportIgnoresFailsOnEmptyExportIgnores(): void /** * @test + * @throws InvalidGlobPattern */ public function hasCompleteExportIgnoresFailsOnNonExistingGitattributesFile(): void { - $mock = Mockery::mock( - 'Stolt\LeanPackage\Analyser[hasGitattributesFile]' - ); + $mock = Mockery::mock(Analyser::class)->makePartial(); + + $globPattern = '{' . \implode(',', (new PhpPreset())->getPresetGlob()) . '}*'; + $mock->setGlobPattern($globPattern); $mock->shouldReceive('hasGitattributesFile') ->once() @@ -93,7 +97,7 @@ public function returnsTrueWhenDirectoryHasCompleteExportIgnores(): void ['specs'] ); - $analyser = (new Analyser())->setDirectory($this->temporaryDirectory); + $analyser = (new Analyser(new Finder(new PhpPreset())))->setDirectory($this->temporaryDirectory); $this->assertTrue( $analyser->hasCompleteExportIgnores() @@ -110,7 +114,7 @@ public function analyseOnNonExistingDirectoryThrowsExpectedException(): void $this->expectExceptionMessage( "Directory {$nonExistingDirectory} doesn't exist." ); - $analyser = (new Analyser())->setDirectory($nonExistingDirectory); + (new Analyser(new Finder(new PhpPreset())))->setDirectory($nonExistingDirectory); } /** @@ -118,7 +122,7 @@ public function analyseOnNonExistingDirectoryThrowsExpectedException(): void */ public function gitattributesFileHasAnAccessor(): void { - $analyser = (new Analyser())->setDirectory($this->temporaryDirectory); + $analyser = (new Analyser(new Finder(new PhpPreset())))->setDirectory($this->temporaryDirectory); $expectedGitattributesFilePath = $this->temporaryDirectory . DIRECTORY_SEPARATOR . '.gitattributes'; @@ -134,7 +138,7 @@ public function gitattributesFileHasAnAccessor(): void */ public function directoryHasAnAccessor(): void { - $analyser = (new Analyser())->setDirectory($this->temporaryDirectory); + $analyser = (new Analyser(new Finder(new PhpPreset())))->setDirectory($this->temporaryDirectory); $this->assertEquals($this->temporaryDirectory, $analyser->getDirectory()); } @@ -163,7 +167,7 @@ public function returnsExpectedGitattributesContent(): void CONTENT; - $analyser = (new Analyser())->setDirectory($this->temporaryDirectory); + $analyser = (new Analyser(new Finder(new PhpPreset())))->setDirectory($this->temporaryDirectory); $actualGitattributesContent = $analyser->getExpectedGitattributesContent( $artifactsWithoutExportIgnore @@ -200,7 +204,7 @@ public function expectedFileMatchesAreInExpectedGitattributesContent(): void CONTENT; - $analyser = (new Analyser())->setDirectory($this->temporaryDirectory); + $analyser = (new Analyser(new Finder(new PhpPreset())))->setDirectory($this->temporaryDirectory); $actualGitattributesContent = $analyser->getExpectedGitattributesContent(); @@ -215,7 +219,7 @@ public function expectedFileMatchesAreInExpectedGitattributesContent(): void */ public function nonExportIgnoresContentIsEmptyForNonexistentGitattributesFile(): void { - $analyser = (new Analyser())->setDirectory($this->temporaryDirectory); + $analyser = (new Analyser(new Finder(new PhpPreset())))->setDirectory($this->temporaryDirectory); $this->assertEquals('', $analyser->getPresentNonExportIgnoresContent()); } @@ -242,7 +246,7 @@ public function nonExportIgnoresContentOfGitattributesFileIsReturned(): void $this->createTemporaryGitattributesFile($gitattributesContent); - $analyser = (new Analyser())->setDirectory($this->temporaryDirectory); + $analyser = (new Analyser(new Finder(new PhpPreset())))->setDirectory($this->temporaryDirectory); $actualGitattributesContent = $analyser->getPresentNonExportIgnoresContent(); @@ -313,7 +317,7 @@ public function getExpectedGitattributesContentKeepsNonExportIgnoreEntries(): vo specs/ export-ignore CONTENT; - $analyser = (new Analyser())->setDirectory($this->temporaryDirectory); + $analyser = (new Analyser(new Finder(new PhpPreset())))->setDirectory($this->temporaryDirectory); $actualGitattributesContent = $analyser->getExpectedGitattributesContent( $artifactsWithoutExportIgnore @@ -334,7 +338,7 @@ public function addsAutoEolToGitattributesContentWhenNoGitattributesFilePresent( 'README.md', '.travis.yml' ]; - $analyser = (new Analyser())->setDirectory($this->temporaryDirectory); + $analyser = (new Analyser(new Finder(new PhpPreset())))->setDirectory($this->temporaryDirectory); $actualGitattributesContent = $analyser->getExpectedGitattributesContent( $artifactFilenames ); @@ -368,7 +372,7 @@ public function returnsEmptyExpectedGitattributesContent(): void $artifactFilenames ); - $analyser = (new Analyser())->setDirectory($this->temporaryDirectory); + $analyser = (new Analyser(new Finder(new PhpPreset())))->setDirectory($this->temporaryDirectory); $actualGitattributesContent = $analyser->getExpectedGitattributesContent(); $this->assertEquals( @@ -398,7 +402,7 @@ public function returnsFalseWhenGitattributesFileHasGaps(): void $artifactFilenames ); - $analyser = (new Analyser())->setDirectory($this->temporaryDirectory); + $analyser = (new Analyser(new Finder(new PhpPreset())))->setDirectory($this->temporaryDirectory); $this->assertFalse( $analyser->hasCompleteExportIgnores() @@ -416,7 +420,7 @@ public function hasGitattributesFileOnExistingGitattributesFile(): void \touch($temporaryGitattributesFile); - $analyser = (new Analyser())->setDirectory($this->temporaryDirectory); + $analyser = (new Analyser(new Finder(new PhpPreset())))->setDirectory($this->temporaryDirectory); $this->assertTrue( $analyser->hasGitattributesFile() @@ -434,7 +438,7 @@ public function hasGitattributesFileFailsOnNonExistingGitattributesFile(): void \touch($temporaryGitattributesFile); - $analyser = (new Analyser())->setDirectory($this->temporaryDirectory); + $analyser = (new Analyser(new Finder(new PhpPreset())))->setDirectory($this->temporaryDirectory); $this->assertFalse( $analyser->hasGitattributesFile() @@ -470,7 +474,7 @@ public function collectExpectedExportIgnoresReturnsExpectedEntries(): void 'README.md', ]; - $analyser = (new Analyser())->setDirectory($this->temporaryDirectory); + $analyser = (new Analyser(new Finder(new PhpPreset())))->setDirectory($this->temporaryDirectory); $actualExportIgnores = $analyser->collectExpectedExportIgnores(); @@ -485,7 +489,7 @@ public function collectExpectedExportIgnoresReturnsExpectedEntries(): void */ public function returnsAnEmptyArrayOnNonExistingGitattributesFile(): void { - $analyser = (new Analyser())->setDirectory($this->temporaryDirectory); + $analyser = (new Analyser(new Finder(new PhpPreset())))->setDirectory($this->temporaryDirectory); $actualExportIgnores = $analyser->getPresentExportIgnores(); @@ -532,7 +536,7 @@ public function returnsExpectedPresentExportIgnores(): void 'specs/' ]; - $analyser = (new Analyser())->setDirectory($this->temporaryDirectory); + $analyser = (new Analyser(new Finder(new PhpPreset())))->setDirectory($this->temporaryDirectory); $actualExportIgnores = $analyser->getPresentExportIgnores(); @@ -577,7 +581,7 @@ public function nonExportIgnoresContentHasPlaceholderForExportIgnoresPlacement() CONTENT; - $analyser = (new Analyser())->setDirectory($this->temporaryDirectory); + $analyser = (new Analyser(new Finder(new PhpPreset())))->setDirectory($this->temporaryDirectory); $actualNonExportIgnoresContentContent = $analyser->getPresentNonExportIgnoresContent(); @@ -640,7 +644,7 @@ public function returnsExpectedGitattributesContentWithPreservedLocation(): void CONTENT; - $analyser = (new Analyser())->setDirectory($this->temporaryDirectory); + $analyser = (new Analyser(new Finder(new PhpPreset())))->setDirectory($this->temporaryDirectory); $actualGitattributesContent = $analyser->getExpectedGitattributesContent(); $this->assertEquals( @@ -682,7 +686,7 @@ public function varyingOrderDoesNotFailCompletenessCheck(): void $this->createTemporaryGitattributesFile($gitattributesContent); - $analyser = (new Analyser())->setDirectory($this->temporaryDirectory); + $analyser = (new Analyser(new Finder(new PhpPreset())))->setDirectory($this->temporaryDirectory); $this->assertTrue($analyser->hasCompleteExportIgnores()); } @@ -720,7 +724,7 @@ public function varyingOrderDoesFailCompletenessCheckWhenEnforced(): void $this->createTemporaryGitattributesFile($gitattributesContent); - $analyser = (new Analyser())->setDirectory($this->temporaryDirectory); + $analyser = (new Analyser(new Finder(new PhpPreset())))->setDirectory($this->temporaryDirectory); $analyser->enableStrictOrderCamparison(); $this->assertFalse($analyser->hasCompleteExportIgnores()); @@ -771,7 +775,7 @@ public function notPatternMatchingExportIgnoresArePreservedAssumedFileExists(): CONTENT; - $analyser = (new Analyser())->setDirectory($this->temporaryDirectory); + $analyser = (new Analyser(new Finder(new PhpPreset())))->setDirectory($this->temporaryDirectory); $actualGitattributesContent = $analyser->getExpectedGitattributesContent(); $this->assertEquals( @@ -820,7 +824,7 @@ public function nonPatternsMatchingButMatchingExistingFilesArePreservedExportIgn '.gitattributes', ]; - $analyser = (new Analyser())->setDirectory($this->temporaryDirectory); + $analyser = (new Analyser(new Finder(new PhpPreset())))->setDirectory($this->temporaryDirectory); $actualExportIgnoresToPreserve = $analyser->getPresentExportIgnoresToPreserve( $globPatternMatchingExportIgnores @@ -862,7 +866,7 @@ public function notPatternMatchingExportIgnoresDoNotFailCompletenessCheck(): voi $this->createTemporaryGitattributesFile($gitattributesContent); - $analyser = (new Analyser())->setDirectory($this->temporaryDirectory); + $analyser = (new Analyser(new Finder(new PhpPreset())))->setDirectory($this->temporaryDirectory); $this->assertTrue($analyser->hasCompleteExportIgnores()); } @@ -891,7 +895,7 @@ public function captainHookConfigurationFileIsInDefaultPattern(): void CONTENT; - $analyser = (new Analyser())->setDirectory($this->temporaryDirectory); + $analyser = (new Analyser(new Finder(new PhpPreset())))->setDirectory($this->temporaryDirectory); $actualGitattributesContent = $analyser->getExpectedGitattributesContent(); $this->assertEquals( @@ -912,7 +916,7 @@ public function nonExistingGlobPatternFileThrowsExpectedException(): void $this->expectException(NonExistentGlobPatternFile::class); - $analyser = (new Analyser()) + $analyser = (new Analyser(new Finder(new PhpPreset()))) ->setDirectory($this->temporaryDirectory) ->setGlobPatternFromFile($globPatternFile); } @@ -932,7 +936,7 @@ public function emptyGlobPatternFileThrowsExpectedException(): void $this->createTemporaryGlobPatternFile($lpvContent); $this->expectException(InvalidGlobPatternFile::class); - $analyser = (new Analyser()) + $analyser = (new Analyser(new Finder(new PhpPreset()))) ->setDirectory($this->temporaryDirectory) ->setGlobPatternFromFile($temporaryLpvFile); } @@ -966,7 +970,7 @@ public function defaultExportIgnoresGlobPatternIsOverwritableFromFile(): void $artifactFilenamesMatchingGlob ); - $analyser = (new Analyser()) + $analyser = (new Analyser(new Finder(new PhpPreset()))) ->setDirectory($this->temporaryDirectory) ->setGlobPatternFromFile($temporaryLpvFile); @@ -986,7 +990,7 @@ public function defaultExportIgnoresGlobPatternIsOverwritableFromFile(): void */ public function defaultExportIgnoresGlobPatternIsOverwritable(): void { - $analyser = (new Analyser()) + $analyser = (new Analyser(new Finder(new PhpPreset()))) ->setDirectory($this->temporaryDirectory) ->setGlobPattern('{*.txt,*.yml}*'); @@ -1017,7 +1021,7 @@ public function defaultExportIgnoresGlobPatternIsOverwritable(): void public function emptyGlobPatternThrowsExpectedException(): void { $this->expectException(InvalidGlobPattern::class); - (new Analyser()) + (new Analyser(new Finder(new PhpPreset()))) ->setDirectory($this->temporaryDirectory) ->setGlobPattern(''); } @@ -1029,7 +1033,7 @@ public function emptyGlobPatternThrowsExpectedException(): void public function invalidGlobPatternBracesThrowsExpectedException(): void { $this->expectException(InvalidGlobPattern::class); - $analyser = (new Analyser()) + $analyser = (new Analyser(new Finder(new PhpPreset()))) ->setDirectory($this->temporaryDirectory) ->setGlobPattern('[fdofodsppfosdp]'); // TODO: Fix smelly test @@ -1042,7 +1046,7 @@ public function invalidGlobPatternBracesThrowsExpectedException(): void */ public function wildcardAfterBracesIsNotRaisingAnException(): void { - $analyser = (new Analyser()) + $analyser = (new Analyser(new Finder(new PhpPreset()))) ->setDirectory($this->temporaryDirectory) ->setGlobPattern('{*.ymk, test.php}*'); // TODO: Fix smelly test @@ -1056,7 +1060,7 @@ public function wildcardAfterBracesIsNotRaisingAnException(): void public function emptyGlobPatternBracesContentThrowsExpectedException(): void { $this->expectException(InvalidGlobPattern::class); - $analyser = (new Analyser()) + $analyser = (new Analyser(new Finder(new PhpPreset()))) ->setDirectory($this->temporaryDirectory) ->setGlobPattern('{ }'); } @@ -1068,7 +1072,7 @@ public function emptyGlobPatternBracesContentThrowsExpectedException(): void public function singleGlobPatternThrowsExpectedException(): void { $this->expectException(InvalidGlobPattern::class); - $analyser = (new Analyser()) + $analyser = (new Analyser(new Finder(new PhpPreset()))) ->setDirectory($this->temporaryDirectory) ->setGlobPattern('{*.go}'); } @@ -1079,7 +1083,7 @@ public function singleGlobPatternThrowsExpectedException(): void */ public function globPatternWithEnclosedBracesAreConsideredValid(): void { - $analyser = (new Analyser()) + $analyser = (new Analyser(new Finder(new PhpPreset()))) ->setDirectory($this->temporaryDirectory) ->setGlobPattern('{{{M,m}ake,{B,b}ox,{V,v}agrant}file,RMT}'); // TODO: Fix smelly test @@ -1111,7 +1115,7 @@ public function withDistEndingFilesAreNotExportIgnored(): void CONTENT; - $analyser = (new Analyser())->setDirectory($this->temporaryDirectory); + $analyser = (new Analyser(new Finder(new PhpPreset())))->setDirectory($this->temporaryDirectory); $actualGitattributesContent = $analyser->getExpectedGitattributesContent(); $this->assertEquals( @@ -1147,7 +1151,7 @@ public function licenseFileIsNotExportIgnored(): void CONTENT; - $analyser = (new Analyser())->setDirectory($this->temporaryDirectory)->keepLicense(); + $analyser = (new Analyser(new Finder(new PhpPreset())))->setDirectory($this->temporaryDirectory)->keepLicense(); $actualGitattributesContent = $analyser->getExpectedGitattributesContent(); $this->assertTrue($analyser->isKeepLicenseEnabled()); @@ -1197,7 +1201,7 @@ public function directoriesOnlyExportIgnoredOnce(): void tests/ export-ignore CONTENT; - $analyser = (new Analyser())->setDirectory($this->temporaryDirectory); + $analyser = (new Analyser(new Finder(new PhpPreset())))->setDirectory($this->temporaryDirectory); $actualGitattributesContent = $analyser->getExpectedGitattributesContent(); $this->assertEquals( @@ -1233,7 +1237,7 @@ public function exportIgnoresAreAligned(): void CONTENT; - $analyser = (new Analyser())->setDirectory($this->temporaryDirectory)->alignExportIgnores(); + $analyser = (new Analyser(new Finder(new PhpPreset())))->setDirectory($this->temporaryDirectory)->alignExportIgnores(); $actualGitattributesContent = $analyser->getExpectedGitattributesContent(); $this->assertTrue($analyser->isAlignExportIgnoresEnabled()); @@ -1272,7 +1276,7 @@ public function precedingSlashesAreDetected(): void $this->createTemporaryGitattributesFile($gitattributesContent); - $analyser = (new Analyser())->setDirectory($this->temporaryDirectory); + $analyser = (new Analyser(new Finder(new PhpPreset())))->setDirectory($this->temporaryDirectory); $this->assertFalse($analyser->hasPrecedingSlashesInExportIgnorePattern()); $this->assertTrue($analyser->hasCompleteExportIgnores()); $this->assertTrue($analyser->hasPrecedingSlashesInExportIgnorePattern()); @@ -1303,7 +1307,7 @@ public function missingTextAutoConfigurationIsDetected(): void $this->createTemporaryGitattributesFile($gitattributesContent); - $analyser = (new Analyser())->setDirectory($this->temporaryDirectory); + $analyser = (new Analyser(new Finder(new PhpPreset())))->setDirectory($this->temporaryDirectory); $this->assertTrue($analyser->hasCompleteExportIgnores()); $this->assertFalse($analyser->hasTextAutoConfiguration()); } @@ -1336,7 +1340,7 @@ public function presentTextAutoConfigurationIsDetected(): void $this->createTemporaryGitattributesFile($gitattributesContent); - $analyser = (new Analyser())->setDirectory($this->temporaryDirectory); + $analyser = (new Analyser(new Finder(new PhpPreset())))->setDirectory($this->temporaryDirectory); $this->assertTrue($analyser->hasCompleteExportIgnores()); $this->assertTrue($analyser->hasTextAutoConfiguration()); } @@ -1346,7 +1350,7 @@ public function presentTextAutoConfigurationIsDetected(): void */ public function returnsEmptyPatternsWhenNoGitignoreFilePresent(): void { - $analyser = (new Analyser())->setDirectory($this->temporaryDirectory); + $analyser = (new Analyser(new Finder(new PhpPreset())))->setDirectory($this->temporaryDirectory); $this->assertEquals([], $analyser->getGitignoredPatterns()); } @@ -1370,7 +1374,7 @@ public function returnsExpectedGitignoredPatterns(): void $this->createTemporaryGitignoreFile($gitignoreContent); - $analyser = (new Analyser())->setDirectory($this->temporaryDirectory); + $analyser = (new Analyser(new Finder(new PhpPreset())))->setDirectory($this->temporaryDirectory); $expectedGitignorePatterns = [ 'vendor/*', @@ -1424,7 +1428,7 @@ public function presentGitignoredFileIsExcludedFromValidation(): void $this->createTemporaryGitignoreFile($gitignoreContent); - $analyser = (new Analyser())->setDirectory($this->temporaryDirectory); + $analyser = (new Analyser(new Finder(new PhpPreset())))->setDirectory($this->temporaryDirectory); $this->assertTrue($analyser->hasCompleteExportIgnores()); } @@ -1468,7 +1472,7 @@ public function presentGitignoredSpecsCoverageDirectoryIsExcludedFromValidation( $this->createTemporaryGitignoreFile($gitignoreContent); - $analyser = (new Analyser())->setDirectory($this->temporaryDirectory); + $analyser = (new Analyser(new Finder(new PhpPreset())))->setDirectory($this->temporaryDirectory); $this->assertTrue($analyser->hasCompleteExportIgnores()); } @@ -1478,7 +1482,7 @@ public function presentGitignoredSpecsCoverageDirectoryIsExcludedFromValidation( */ public function returnsExpectedDefaultGlobPatterns(): void { - $analyser = (new Analyser())->setDirectory($this->temporaryDirectory); + $analyser = (new Analyser(new Finder(new PhpPreset())))->setDirectory($this->temporaryDirectory); $expectedDefaultGlobPatterns = [ '.*', @@ -1506,7 +1510,7 @@ public function returnsExpectedDefaultGlobPatterns(): void $this->assertEquals( $expectedDefaultGlobPatterns, - $analyser->getDefaultGlobPatterns() + $analyser->getDefaultGlobPattern() ); } } diff --git a/tests/Commands/InitCommandTest.php b/tests/Commands/InitCommandTest.php index 82ef328..047394d 100644 --- a/tests/Commands/InitCommandTest.php +++ b/tests/Commands/InitCommandTest.php @@ -8,6 +8,8 @@ use phpmock\MockBuilder; use Stolt\LeanPackage\Analyser; use Stolt\LeanPackage\Commands\InitCommand; +use Stolt\LeanPackage\Presets\Finder; +use Stolt\LeanPackage\Presets\PhpPreset; use Stolt\LeanPackage\Tests\CommandTester; use Stolt\LeanPackage\Tests\TestCase; use Symfony\Component\Console\Application; @@ -152,6 +154,28 @@ public function existingDefaultLpvFileIsNotOverwritten(): void $this->assertTrue($commandTester->getStatusCode() !== 0); } + /** + * @test + */ + public function usingANonAvailablePresetShowsWarning(): void + { + $expectedDisplay = <<application->find('init'); + $commandTester = new CommandTester($command); + $commandTester->execute( + ['command' => $command->getName(), + 'directory' => WORKING_DIRECTORY, + '--preset' => 'rust'], + ); + + $this->assertSame($expectedDisplay, $commandTester->getDisplay()); + $this->assertTrue($commandTester->getStatusCode() !== 0); + } + /** * @test */ @@ -215,7 +239,7 @@ public function existingDefaultLpvFileIsOverwrittenWhenDesired(): void protected function getApplication(): Application { $application = new Application(); - $application->add(new InitCommand(new Analyser)); + $application->add(new InitCommand(new Analyser(new Finder(new PhpPreset())))); return $application; } diff --git a/tests/Commands/ValidateCommandTest.php b/tests/Commands/ValidateCommandTest.php index 0451a72..7481048 100644 --- a/tests/Commands/ValidateCommandTest.php +++ b/tests/Commands/ValidateCommandTest.php @@ -13,6 +13,8 @@ use Stolt\LeanPackage\Commands\ValidateCommand; use Stolt\LeanPackage\Exceptions\NoLicenseFilePresent; use Stolt\LeanPackage\Helpers\Str as OsHelper; +use Stolt\LeanPackage\Presets\Finder; +use Stolt\LeanPackage\Presets\PhpPreset; use Stolt\LeanPackage\Tests\CommandTester; use Stolt\LeanPackage\Tests\TestCase; use Symfony\Component\Console\Application; @@ -189,9 +191,11 @@ public function showsDifferenceBetweenActualAndExpectedGitattributesContent(): v */ public function gitattributesFileWithNoExportIgnoresContentShowsExpectedContent(): void { - $analyserMock = Mockery::mock( - 'Stolt\LeanPackage\Analyser[getGlobalGitignorePatterns]' - ); + $analyserMock = Mockery::mock(Analyser::class)->makePartial(); + + $globPattern = '{' . \implode(',', (new PhpPreset())->getPresetGlob()) . '}*'; + $analyserMock->setGlobPattern($globPattern); + $analyserMock->shouldReceive('getGlobalGitignorePatterns') ->once() ->withAnyArgs() @@ -1142,9 +1146,11 @@ public function nonLeanArchiveIsNotConsideredLeanSingular(): void */ public function impossibilityToResolveExpectedGitattributesFileContentIsInfoed(): void { - $mock = Mockery::mock( - 'Stolt\LeanPackage\Analyser[getExpectedGitattributesContent]' - ); + $mock = Mockery::mock(Analyser::class)->makePartial(); + + $globPattern = '{' . \implode(',', (new PhpPreset())->getPresetGlob()) . '}*'; + $mock->setGlobPattern($globPattern); + $mock->shouldReceive('getExpectedGitattributesContent') ->once() ->withAnyArgs() @@ -2102,7 +2108,7 @@ protected function getApplicationWithMockedArchiveValidator(MockInterface $mocke $application = new Application(); $analyserCommand = new ValidateCommand( - new Analyser, + new Analyser(new Finder(new PhpPreset())), $mockedArchiveValidator ); @@ -2122,7 +2128,7 @@ protected function getApplication(): Application ); $analyserCommand = new ValidateCommand( - new Analyser, + new Analyser(new Finder(new PhpPreset())), new Validator($archive) ); diff --git a/tests/Presets/FinderTest.php b/tests/Presets/FinderTest.php new file mode 100644 index 0000000..a6b2efa --- /dev/null +++ b/tests/Presets/FinderTest.php @@ -0,0 +1,59 @@ +assertSame(['Go', 'Php', 'Python'], $finder->getAvailablePresets()); + } + + /** + * @test + * @dataProvider languageProvider + */ + public function findsExpectedPresetGlobByLanguageNames($languageName): void + { + $finder = new Finder(new PhpPreset()); + $presetGlob = $finder->getPresetGlobByLanguageName($languageName); + $this->assertTrue(\is_array($presetGlob)); + } + + /** + * @test + */ + public function forNonAvailableLanguagePresetItThrowsExpectedException(): void + { + $this->expectException(PresetNotAvailable::class); + $expectedExceptionMessage ='Preset for Kotlin not available. Maybe contribute it?.'; + $this->expectExceptionMessage($expectedExceptionMessage); + + $finder = new Finder(new PhpPreset()); + $finder->getPresetGlobByLanguageName('Kotlin'); + } + + /** + * @return array + */ + public static function languageProvider(): array + { + return [ + ['php'], + ['Python'], + ['Go'] + ]; + } + +} From a2b01411eb878e5e4cc1f923a362d52038cbca4a Mon Sep 17 00:00:00 2001 From: Raphael Stolt Date: Wed, 8 Nov 2023 11:40:15 +0100 Subject: [PATCH 052/152] Release version 3.2.0 --- CHANGELOG.md | 5 ++++- bin/lean-package-validator | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index cda9ff0..9016c35 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,8 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/) and this p ## [Unreleased] +## [v3.2.0] - 2023-11-08 + ### Added - New `--preset` option. Closes [#43](https://github.com/raphaelstolt/lean-package-validator/issues/43). @@ -225,7 +227,8 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/) and this p - Initial release. -[Unreleased]: https://github.com/raphaelstolt/lean-package-validator/compare/v3.1.1...HEAD +[Unreleased]: https://github.com/raphaelstolt/lean-package-validator/compare/v3.2.0...HEAD +[v3.2.0]: https://github.com/raphaelstolt/lean-package-validator/compare/v3.1.1...v3.2.0 [v3.1.1]: https://github.com/raphaelstolt/lean-package-validator/compare/v3.1.0...v3.1.1 [v3.1.0]: https://github.com/raphaelstolt/lean-package-validator/compare/v3.0.1...v3.1.0 [v3.0.1]: https://github.com/raphaelstolt/lean-package-validator/compare/v3.0.0...v3.0.1 diff --git a/bin/lean-package-validator b/bin/lean-package-validator index 619e61e..dc5e933 100755 --- a/bin/lean-package-validator +++ b/bin/lean-package-validator @@ -22,7 +22,7 @@ if (false === $autoloaded) { } \define('WORKING_DIRECTORY', \getcwd()); -\define('VERSION', '3.1.1'); +\define('VERSION', '3.2.0'); use Stolt\LeanPackage\Commands\InitCommand; use Stolt\LeanPackage\Commands\ValidateCommand; From f3b6632dfc6e47b2a5decd5183b0bf0c342fc5cd Mon Sep 17 00:00:00 2001 From: Raphael Stolt Date: Wed, 8 Nov 2023 11:43:41 +0100 Subject: [PATCH 053/152] Improves documentation --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 7695095..30cc862 100755 --- a/README.md +++ b/README.md @@ -165,7 +165,7 @@ lean-package-validator init [] The `--overwrite|-o` option overwrites an existing `.lpv` file. The `--preset` option allows to choose from a predefined set of glob pattern. -Available presets are `PHP`, `Python` and `Go`. With `PHP` being the default. +Available presets are `PHP`, `Python`, and `Go`. With `PHP` being the default. ## Utilisation via Composer scripts or it's dedicated GitHub Action From 006bac3262637f9c14781cf9cb9c108c749be743 Mon Sep 17 00:00:00 2001 From: Raphael Stolt Date: Wed, 8 Nov 2023 22:12:29 +0100 Subject: [PATCH 054/152] Fixes broken test --- tests/Presets/FinderTest.php | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/tests/Presets/FinderTest.php b/tests/Presets/FinderTest.php index a6b2efa..eda071a 100644 --- a/tests/Presets/FinderTest.php +++ b/tests/Presets/FinderTest.php @@ -17,7 +17,14 @@ class FinderTest extends TestCase public function findsExpectedPresets(): void { $finder = new Finder(new PhpPreset()); - $this->assertSame(['Go', 'Php', 'Python'], $finder->getAvailablePresets()); + + $actualPresets = $finder->getAvailablePresets(); + $expectedPrests = ['Php', 'Go', 'Python']; + + \sort($actualPresets); + \sort($expectedPrests); + + $this->assertSame($expectedPrests, $actualPresets); } /** From 7487cd552f072e1fd22ed7d36b961e156c81ee27 Mon Sep 17 00:00:00 2001 From: Raphael Stolt Date: Thu, 9 Nov 2023 08:36:28 +0100 Subject: [PATCH 055/152] Fixes static-analyse errors --- src/Commands/InitCommand.php | 2 +- src/Presets/Finder.php | 6 +++--- tests/Presets/FinderTest.php | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/Commands/InitCommand.php b/src/Commands/InitCommand.php index 863db96..df8f270 100644 --- a/src/Commands/InitCommand.php +++ b/src/Commands/InitCommand.php @@ -160,7 +160,7 @@ protected function execute(InputInterface $input, OutputInterface $output) ); $verboseOutput = '+ Writing default glob pattern to .lpv file in ' . WORKING_DIRECTORY . '.'; - if ($globPatternFromPreset) { + if ($globPatternFromPreset === true) { $verboseOutput = '+ Writing glob pattern for preset ' . $chosenPreset . ' to .lpv file in ' . WORKING_DIRECTORY . '.'; } $output->writeln($verboseOutput, OutputInterface::VERBOSITY_VERBOSE); diff --git a/src/Presets/Finder.php b/src/Presets/Finder.php index b8ecb23..ef8e658 100644 --- a/src/Presets/Finder.php +++ b/src/Presets/Finder.php @@ -42,7 +42,7 @@ public function getAvailablePresets(): array * @throws PresetNotAvailable|\ReflectionException * @return array */ - public function getPresetGlobByLanguageName($name): array + public function getPresetGlobByLanguageName(string $name): array { $name = \ucfirst(\strtolower($name)); @@ -52,8 +52,8 @@ public function getPresetGlobByLanguageName($name): array $presetClassName = \sprintf('Stolt\LeanPackage\Presets\%sPreset', $name); - $reflectionClass = new \ReflectionClass($presetClassName); - $preset = $reflectionClass->newInstance(); + /** @var Preset **/ + $preset = new $presetClassName(); return $preset->getPresetGlob(); } diff --git a/tests/Presets/FinderTest.php b/tests/Presets/FinderTest.php index eda071a..bd7f479 100644 --- a/tests/Presets/FinderTest.php +++ b/tests/Presets/FinderTest.php @@ -31,7 +31,7 @@ public function findsExpectedPresets(): void * @test * @dataProvider languageProvider */ - public function findsExpectedPresetGlobByLanguageNames($languageName): void + public function findsExpectedPresetGlobByLanguageNames(string $languageName): void { $finder = new Finder(new PhpPreset()); $presetGlob = $finder->getPresetGlobByLanguageName($languageName); From 6f45f43d71e6cc9896201ff5eab276f99a28d0f4 Mon Sep 17 00:00:00 2001 From: Raphael Stolt Date: Thu, 9 Nov 2023 08:41:49 +0100 Subject: [PATCH 056/152] Fixes markdown linting --- CHANGELOG.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9016c35..c5377b8 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,8 +13,6 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/) and this p - New `--preset` option. Closes [#43](https://github.com/raphaelstolt/lean-package-validator/issues/43). -### Added - - New `--report-stale-export-ignores` option. Closes [#41](https://github.com/raphaelstolt/lean-package-validator/issues/41). ## [v3.1.1] - 2023-10-13 From d2a46973de688f91a4450ea214079f8e693ad9dd Mon Sep 17 00:00:00 2001 From: Raphael Stolt Date: Thu, 9 Nov 2023 09:10:09 +0100 Subject: [PATCH 057/152] Fixes spelling --- tests/Presets/FinderTest.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/Presets/FinderTest.php b/tests/Presets/FinderTest.php index bd7f479..3c8a99d 100644 --- a/tests/Presets/FinderTest.php +++ b/tests/Presets/FinderTest.php @@ -19,12 +19,12 @@ public function findsExpectedPresets(): void $finder = new Finder(new PhpPreset()); $actualPresets = $finder->getAvailablePresets(); - $expectedPrests = ['Php', 'Go', 'Python']; + $expectedPresets = ['Php', 'Go', 'Python']; \sort($actualPresets); - \sort($expectedPrests); + \sort($expectedPresets); - $this->assertSame($expectedPrests, $actualPresets); + $this->assertSame($expectedPresets, $actualPresets); } /** From 18079ec521277c67447937beb7f3ce493d1cf244 Mon Sep 17 00:00:00 2001 From: Raphael Stolt Date: Mon, 27 Nov 2023 14:54:43 +0100 Subject: [PATCH 058/152] Adds \ prefix to internal PHP function calls --- tests/TestCase.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/TestCase.php b/tests/TestCase.php index 322e0fc..0e31860 100755 --- a/tests/TestCase.php +++ b/tests/TestCase.php @@ -98,7 +98,7 @@ protected function createTemporaryGitattributesFile($content): bool . '.gitattributes'; - $bytesWritten = file_put_contents($temporaryGitattributesFile, $content); + $bytesWritten = \file_put_contents($temporaryGitattributesFile, $content); return $bytesWritten >= 0; } @@ -116,7 +116,7 @@ protected function createTemporaryGitignoreFile($content) . DIRECTORY_SEPARATOR . '.gitignore'; - return file_put_contents($temporaryGitignoreFile, $content) >= 0; + return \file_put_contents($temporaryGitignoreFile, $content) >= 0; } /** @@ -132,6 +132,6 @@ protected function createTemporaryGlobPatternFile($content) . DIRECTORY_SEPARATOR . '.lpv'; - return file_put_contents($temporaryLpvFile, $content) >= 0; + return \file_put_contents($temporaryLpvFile, $content) >= 0; } } From a9957be87ff56382a31823d815b1262eff3070db Mon Sep 17 00:00:00 2001 From: Raphael Stolt Date: Tue, 28 Nov 2023 08:50:21 +0100 Subject: [PATCH 059/152] Fixes spelling --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 30cc862..2a0c5b7 100755 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ [![composer.lock available](https://poser.pugx.org/stolt/lean-package-validator/composerlock)](https://packagist.org/packages/stolt/lean-package-validator) [![PDS Skeleton](https://img.shields.io/badge/pds-skeleton-blue.svg?style=flat)](https://github.com/php-pds/skeleton) -The LeanPackageValidator is an utility tool that validates a project/micro-package +The LeanPackageValidator is a utility tool that validates a project/micro-package for its `leanness`. A project/micro-package is considered `lean` when its common repository artifacts won't be included in release assets. From 6a4fa1e8cce9a2e93efd3c098c2e607fe2b06fae Mon Sep 17 00:00:00 2001 From: Raphael Stolt Date: Tue, 28 Nov 2023 10:48:48 +0100 Subject: [PATCH 060/152] Drop support for eoled PHP 8.0 --- .github/workflows/test-windows.yml | 2 +- .github/workflows/test.yml | 1 - README.md | 2 +- composer.json | 2 +- 4 files changed, 3 insertions(+), 4 deletions(-) diff --git a/.github/workflows/test-windows.yml b/.github/workflows/test-windows.yml index ffcdfdb..c6d1ac7 100644 --- a/.github/workflows/test-windows.yml +++ b/.github/workflows/test-windows.yml @@ -22,7 +22,7 @@ jobs: php-version: "${{ matrix.php }}" - name: Install Composer dependencies - run: composer update --no-progress --prefer-dist --optimize-autoloader + run: composer install --no-progress --prefer-dist --optimize-autoloader - name: Run tests run: composer run-script lpv:test diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index c619914..3bc27e5 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -10,7 +10,6 @@ jobs: strategy: matrix: php: - - "8.0" - "8.1" - "8.2" - "8.3" diff --git a/README.md b/README.md index 2a0c5b7..e1de11e 100755 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ ![Test Status](https://github.com/raphaelstolt/lean-package-validator/workflows/test/badge.svg) [![Version](http://img.shields.io/packagist/v/stolt/lean-package-validator.svg?style=flat)](https://packagist.org/packages/stolt/lean-package-validator) -![PHP Version](https://img.shields.io/badge/php-8.0+-ff69b4.svg) +![PHP Version](https://img.shields.io/badge/php-8.1+-ff69b4.svg) [![composer.lock available](https://poser.pugx.org/stolt/lean-package-validator/composerlock)](https://packagist.org/packages/stolt/lean-package-validator) [![PDS Skeleton](https://img.shields.io/badge/pds-skeleton-blue.svg?style=flat)](https://github.com/php-pds/skeleton) diff --git a/composer.json b/composer.json index 8708216..bd1eaf9 100755 --- a/composer.json +++ b/composer.json @@ -10,7 +10,7 @@ } ], "require": { - "php": ">=8.0", + "php": ">=8.1", "laminas/laminas-stdlib": "^3.7", "sebastian/diff": "^5.0||^4.0.3", "symfony/console": "^v6.3||^v5.4.8" From 78f6bbd1f0708d635935ad252669521033e05029 Mon Sep 17 00:00:00 2001 From: Raphael Stolt Date: Tue, 28 Nov 2023 10:49:49 +0100 Subject: [PATCH 061/152] Release version 3.3.0 --- CHANGELOG.md | 9 ++++++++- bin/lean-package-validator | 2 +- tests/TestCase.php | 6 +++--- 3 files changed, 12 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c5377b8..337f1c5 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,12 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/) and this p ## [Unreleased] +## [v3.3.0] - 2023-11-28 + +### Removed + +- Removed support for PHP `8.0`. + ## [v3.2.0] - 2023-11-08 ### Added @@ -225,7 +231,8 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/) and this p - Initial release. -[Unreleased]: https://github.com/raphaelstolt/lean-package-validator/compare/v3.2.0...HEAD +[Unreleased]: https://github.com/raphaelstolt/lean-package-validator/compare/v3.3.0...HEAD +[v3.3.0]: https://github.com/raphaelstolt/lean-package-validator/compare/v3.2.0...v3.3.0 [v3.2.0]: https://github.com/raphaelstolt/lean-package-validator/compare/v3.1.1...v3.2.0 [v3.1.1]: https://github.com/raphaelstolt/lean-package-validator/compare/v3.1.0...v3.1.1 [v3.1.0]: https://github.com/raphaelstolt/lean-package-validator/compare/v3.0.1...v3.1.0 diff --git a/bin/lean-package-validator b/bin/lean-package-validator index dc5e933..d36dc8a 100755 --- a/bin/lean-package-validator +++ b/bin/lean-package-validator @@ -22,7 +22,7 @@ if (false === $autoloaded) { } \define('WORKING_DIRECTORY', \getcwd()); -\define('VERSION', '3.2.0'); +\define('VERSION', '3.3.0'); use Stolt\LeanPackage\Commands\InitCommand; use Stolt\LeanPackage\Commands\ValidateCommand; diff --git a/tests/TestCase.php b/tests/TestCase.php index 0e31860..322e0fc 100755 --- a/tests/TestCase.php +++ b/tests/TestCase.php @@ -98,7 +98,7 @@ protected function createTemporaryGitattributesFile($content): bool . '.gitattributes'; - $bytesWritten = \file_put_contents($temporaryGitattributesFile, $content); + $bytesWritten = file_put_contents($temporaryGitattributesFile, $content); return $bytesWritten >= 0; } @@ -116,7 +116,7 @@ protected function createTemporaryGitignoreFile($content) . DIRECTORY_SEPARATOR . '.gitignore'; - return \file_put_contents($temporaryGitignoreFile, $content) >= 0; + return file_put_contents($temporaryGitignoreFile, $content) >= 0; } /** @@ -132,6 +132,6 @@ protected function createTemporaryGlobPatternFile($content) . DIRECTORY_SEPARATOR . '.lpv'; - return \file_put_contents($temporaryLpvFile, $content) >= 0; + return file_put_contents($temporaryLpvFile, $content) >= 0; } } From 45910325c5c44245f4bc4938c27d48dc0fdce0c1 Mon Sep 17 00:00:00 2001 From: Raphael Stolt Date: Tue, 28 Nov 2023 10:59:31 +0100 Subject: [PATCH 062/152] Fixes broken Windows integration tests --- tests/Commands/ValidateCommandTest.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tests/Commands/ValidateCommandTest.php b/tests/Commands/ValidateCommandTest.php index 7481048..237c422 100644 --- a/tests/Commands/ValidateCommandTest.php +++ b/tests/Commands/ValidateCommandTest.php @@ -726,6 +726,10 @@ public function validateOnNonExistentGitattributesFilesWithCreationOptionCreates */ public function validateOnNonExistentGitattributesFilesWithCreationOptionCreatesOneWithAlignment(): void { + if ((new OsHelper())->isWindows()) { + $this->markTestSkipped('Skipping test on Windows systems'); + } + $artifactFilenames = ['CONDUCT.md']; $this->createTemporaryFiles( From 61696e0fb4bbea6b3c0762bea7d74c2b06fe417a Mon Sep 17 00:00:00 2001 From: Raphael Stolt Date: Thu, 30 Nov 2023 09:33:13 +0100 Subject: [PATCH 063/152] Expands the PHP preset --- src/Presets/PhpPreset.php | 1 + tests/AnalyserTest.php | 1 + tests/Commands/InitCommandTest.php | 1 + 3 files changed, 3 insertions(+) diff --git a/src/Presets/PhpPreset.php b/src/Presets/PhpPreset.php index 76498a0..2e72340 100644 --- a/src/Presets/PhpPreset.php +++ b/src/Presets/PhpPreset.php @@ -18,6 +18,7 @@ public function getPresetGlob(): array '*.{md,MD}', '*.xml', '*.yml', + 'phpunit*', 'appveyor.yml', 'box.json', 'captainhook.json', diff --git a/tests/AnalyserTest.php b/tests/AnalyserTest.php index 42e7ea3..a1b3990 100755 --- a/tests/AnalyserTest.php +++ b/tests/AnalyserTest.php @@ -1492,6 +1492,7 @@ public function returnsExpectedDefaultGlobPatterns(): void '*.{md,MD}', '*.xml', '*.yml', + 'phpunit*', 'appveyor.yml', 'box.json', 'captainhook.json', diff --git a/tests/Commands/InitCommandTest.php b/tests/Commands/InitCommandTest.php index 047394d..e879c50 100644 --- a/tests/Commands/InitCommandTest.php +++ b/tests/Commands/InitCommandTest.php @@ -74,6 +74,7 @@ public function createsExpectedDefaultLpvFile(): void *.{md,MD} *.xml *.yml +phpunit* appveyor.yml box.json captainhook.json From 1f6776c8ccb23cd4c457e7dcdb1c9251faaade94 Mon Sep 17 00:00:00 2001 From: Raphael Stolt Date: Thu, 30 Nov 2023 16:44:37 +0100 Subject: [PATCH 064/152] Fixes bug #44 --- CHANGELOG.md | 4 ++++ src/Commands/ValidateCommand.php | 12 +++++++----- tests/Commands/ValidateCommandTest.php | 17 +++++++++++++++-- 3 files changed, 26 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 337f1c5..f44833d 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,10 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/) and this p ## [Unreleased] +### Fixed + +- The header is written on existent .gitattributes file. Closes [#44](https://github.com/raphaelstolt/lean-package-validator/issues/44). + ## [v3.3.0] - 2023-11-28 ### Removed diff --git a/src/Commands/ValidateCommand.php b/src/Commands/ValidateCommand.php index 1e37da3..2b3c5f2 100755 --- a/src/Commands/ValidateCommand.php +++ b/src/Commands/ValidateCommand.php @@ -316,11 +316,7 @@ protected function execute(InputInterface $input, OutputInterface $output) if ($createGitattributesFile || $overwriteGitattributesFile) { try { if ($omitHeader === false) { - $headerContent = '# This file was partly modified by the lean package validator (http://git.io/lean-package-validator).' . PHP_EOL; - - if ($createGitattributesFile) { - $headerContent = '# This file was generated by the lean package validator (http://git.io/lean-package-validator).' . PHP_EOL; - } + $headerContent = '# This file was generated by the lean package validator (http://git.io/lean-package-validator).' . PHP_EOL; $expectedGitattributesFileContent = $headerContent . PHP_EOL . $expectedGitattributesFileContent; } @@ -416,6 +412,12 @@ protected function execute(InputInterface $input, OutputInterface $output) } $output->writeln($verboseOutput, OutputInterface::VERBOSITY_VERBOSE); + + if ($omitHeader === false) { + $headerContent = '# This file was partly modified by the lean package validator (http://git.io/lean-package-validator).' . PHP_EOL; + $expectedGitattributesFileContent = $headerContent . PHP_EOL . $expectedGitattributesFileContent; + } + $outputContent .= $this->overwriteGitattributesFile( $expectedGitattributesFileContent ); diff --git a/tests/Commands/ValidateCommandTest.php b/tests/Commands/ValidateCommandTest.php index 237c422..26d3bae 100644 --- a/tests/Commands/ValidateCommandTest.php +++ b/tests/Commands/ValidateCommandTest.php @@ -729,7 +729,7 @@ public function validateOnNonExistentGitattributesFilesWithCreationOptionCreates if ((new OsHelper())->isWindows()) { $this->markTestSkipped('Skipping test on Windows systems'); } - + $artifactFilenames = ['CONDUCT.md']; $this->createTemporaryFiles( @@ -991,7 +991,7 @@ public function overwriteOptionOnNonExistentGitattributesFileImplicatesCreate(): Warning: There is no .gitattributes file present in {$this->temporaryDirectory}. Created a .gitattributes file with the shown content: -# This file was partly modified by the lean package validator (http://git.io/lean-package-validator). +# This file was generated by the lean package validator (http://git.io/lean-package-validator). * text=auto eol=lf @@ -1207,10 +1207,16 @@ public function invalidDirectoryAgumentReturnsExpectedStatusCode(): void /** * @test + * @ticket 44 (https://github.com/raphaelstolt/lean-package-validator/issues/44) */ public function incompleteGitattributesFileIsOverwrittenWithAlignment(): void { + if ((new OsHelper())->isWindows()) { + $this->markTestSkipped('Skipping test on Windows systems'); + } + $gitattributesContent = << $command->getName(), 'directory' => WORKING_DIRECTORY, $option => true, + '--omit-header' => true, ]); $expectedDisplay = << Date: Fri, 1 Dec 2023 07:35:52 +0100 Subject: [PATCH 065/152] Release version 3.3.1 --- CHANGELOG.md | 5 ++++- bin/lean-package-validator | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f44833d..b8ae574 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,8 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/) and this p ## [Unreleased] +## [v3.3.1] - 2023-12-01 + ### Fixed - The header is written on existent .gitattributes file. Closes [#44](https://github.com/raphaelstolt/lean-package-validator/issues/44). @@ -235,7 +237,8 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/) and this p - Initial release. -[Unreleased]: https://github.com/raphaelstolt/lean-package-validator/compare/v3.3.0...HEAD +[Unreleased]: https://github.com/raphaelstolt/lean-package-validator/compare/v3.3.1...HEAD +[v3.3.1]: https://github.com/raphaelstolt/lean-package-validator/compare/v3.3.0...v3.3.1 [v3.3.0]: https://github.com/raphaelstolt/lean-package-validator/compare/v3.2.0...v3.3.0 [v3.2.0]: https://github.com/raphaelstolt/lean-package-validator/compare/v3.1.1...v3.2.0 [v3.1.1]: https://github.com/raphaelstolt/lean-package-validator/compare/v3.1.0...v3.1.1 diff --git a/bin/lean-package-validator b/bin/lean-package-validator index d36dc8a..c5e513a 100755 --- a/bin/lean-package-validator +++ b/bin/lean-package-validator @@ -22,7 +22,7 @@ if (false === $autoloaded) { } \define('WORKING_DIRECTORY', \getcwd()); -\define('VERSION', '3.3.0'); +\define('VERSION', '3.3.1'); use Stolt\LeanPackage\Commands\InitCommand; use Stolt\LeanPackage\Commands\ValidateCommand; From 59409b8322d67b8354ab1ee12a9af8553bcd05b8 Mon Sep 17 00:00:00 2001 From: Raphael Stolt Date: Fri, 1 Dec 2023 08:05:01 +0100 Subject: [PATCH 066/152] Improves documentation --- README.md | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index e1de11e..ffab77a 100755 --- a/README.md +++ b/README.md @@ -27,7 +27,7 @@ Since the default name of the CLI is quite a mouthful, an alias which can be pla in `~/.aliases`, `~/.zshrc` or the like might come in handy. The alias shown next assumes that `$COMPOSER_HOME` is `~/.config/composer` and not `~/.composer`. -```bash +``` bash alias lpv='~/.config/composer/vendor/bin/lean-package-validator $@' ``` @@ -38,12 +38,14 @@ further utilisation via [Composer scripts](https://getcomposer.org/doc/articles/ composer require --dev stolt/lean-package-validator ``` -As of release `v1.9.0` it's also possible to install and use the LeanPackageValidator -via a PHAR [file](https://github.com/raphaelstolt/lean-package-validator/releases/tag/v1.9.0). Therefor download a released version e.g. v3.1.1 and move it -to `/usr/local/bin` as shown next. +> [!TIP] +> As of release `v1.9.0` it's also possible to install and use the LeanPackageValidator +> via a PHAR [file](https://github.com/raphaelstolt/lean-package-validator/releases/tag/v1.9.0). + +Therefor download a released version e.g. v3.3.1 and move it to `/usr/local/bin` as shown next. ``` bash -wget --quiet https://github.com/raphaelstolt/lean-package-validator/releases/download/v3.1.1/lean-package-validator.phar +wget --quiet https://github.com/raphaelstolt/lean-package-validator/releases/download/v3.3.1/lean-package-validator.phar mv lean-package-validator.phar /usr/local/bin/lean-package-validator ``` @@ -61,7 +63,7 @@ lean-package-validator validate [] ### Available options The `--enforce-strict-order` option will enforce a strict order comparison -of export-ignores in the .gitattributes file and fail validation if the order +of export-ignores in the `.gitattributes` file and fail validation if the order differs. Per __default__ the order comparison is done in a non-strict fashion. ``` bash @@ -117,7 +119,7 @@ lean-package-validator validate [] --align-export-ignores --create ``` The `--enforce-alignment` option will enforce a strict alignment of export-ignores -in the .gitattributes file and fail validation if they aren't aligned. Per __default__ +in the `.gitattributes` file and fail validation if they aren't aligned. Per __default__ no alignment is enforced. The `--validate-git-archive` option will validate that no common repository artifacts slip @@ -129,7 +131,7 @@ file becomes mandatory and will fail the archive validation if not present. lean-package-validator validate [] --validate-git-archive ``` -The `--diff` option will show a visual diff between the actual and expected .gitattributes content. +The `--diff` option will show a visual diff between the actual and expected `.gitattributes` content. ``` bash lean-package-validator validate --diff From 895b967eab4a482ae722145e1262cba5295d6fc4 Mon Sep 17 00:00:00 2001 From: Raphael Stolt Date: Fri, 1 Dec 2023 11:29:09 +0100 Subject: [PATCH 067/152] Removes Markdown linting --- .gitattributes | 1 - .github/workflows/lint.yml | 7 ------- .markdownlint.json | 8 -------- 3 files changed, 16 deletions(-) delete mode 100644 .markdownlint.json diff --git a/.gitattributes b/.gitattributes index 9521d17..a37bc09 100755 --- a/.gitattributes +++ b/.gitattributes @@ -5,7 +5,6 @@ .github/ export-ignore .gitignore export-ignore .gitmessage export-ignore -.markdownlint.json export-ignore .php-cs-fixer.php export-ignore .phpunit.result.cache export-ignore bin/application-version export-ignore diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index d1d4581..82de09d 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -30,10 +30,3 @@ jobs: - name: Check leanness of package run: composer run-script lpv:validate-gitattributes - - - name: Check Markdown files - uses: DavidAnson/markdownlint-cli2-action@v11 - with: - globs: | - README.md - CHANGELOG.md diff --git a/.markdownlint.json b/.markdownlint.json deleted file mode 100644 index 8065767..0000000 --- a/.markdownlint.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "MD013": { - "line_length": 200 - }, - "MD024": { - "allow_different_nesting": true - } -} From 4d773e05ce0d41cca4defaef82197478f2d7aae6 Mon Sep 17 00:00:00 2001 From: Raphael Stolt Date: Mon, 4 Dec 2023 08:01:42 +0100 Subject: [PATCH 068/152] Expands the PHP preset --- src/Presets/PhpPreset.php | 3 +++ tests/AnalyserTest.php | 3 +++ tests/Commands/InitCommandTest.php | 3 +++ 3 files changed, 9 insertions(+) diff --git a/src/Presets/PhpPreset.php b/src/Presets/PhpPreset.php index 2e72340..c191e7d 100644 --- a/src/Presets/PhpPreset.php +++ b/src/Presets/PhpPreset.php @@ -22,6 +22,9 @@ public function getPresetGlob(): array 'appveyor.yml', 'box.json', 'captainhook.json', + 'infection*', + 'phpstan*', + 'sonar*', '*.dist.*', '*.dist', '{B,b}uild*', diff --git a/tests/AnalyserTest.php b/tests/AnalyserTest.php index a1b3990..275fed1 100755 --- a/tests/AnalyserTest.php +++ b/tests/AnalyserTest.php @@ -1496,6 +1496,9 @@ public function returnsExpectedDefaultGlobPatterns(): void 'appveyor.yml', 'box.json', 'captainhook.json', + 'infection*', + 'phpstan*', + 'sonar*', '*.dist.*', '*.dist', '{B,b}uild*', diff --git a/tests/Commands/InitCommandTest.php b/tests/Commands/InitCommandTest.php index e879c50..6f19d05 100644 --- a/tests/Commands/InitCommandTest.php +++ b/tests/Commands/InitCommandTest.php @@ -78,6 +78,9 @@ public function createsExpectedDefaultLpvFile(): void appveyor.yml box.json captainhook.json +infection* +phpstan* +sonar* *.dist.* *.dist {B,b}uild* From e4e9dc420120e51923ba5fe1bbb58218c92bf279 Mon Sep 17 00:00:00 2001 From: Raphael Stolt Date: Mon, 4 Dec 2023 08:03:52 +0100 Subject: [PATCH 069/152] Release version 3.3.2 --- CHANGELOG.md | 9 ++++++++- bin/lean-package-validator | 2 +- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b8ae574..bf742e9 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,12 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/) and this p ## [Unreleased] +## [v3.3.2] - 2023-12-04 + +### Fixed + +- Expands the PHP preset. + ## [v3.3.1] - 2023-12-01 ### Fixed @@ -237,7 +243,8 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/) and this p - Initial release. -[Unreleased]: https://github.com/raphaelstolt/lean-package-validator/compare/v3.3.1...HEAD +[Unreleased]: https://github.com/raphaelstolt/lean-package-validator/compare/v3.3.2...HEAD +[v3.3.2]: https://github.com/raphaelstolt/lean-package-validator/compare/v3.3.1...v3.3.2 [v3.3.1]: https://github.com/raphaelstolt/lean-package-validator/compare/v3.3.0...v3.3.1 [v3.3.0]: https://github.com/raphaelstolt/lean-package-validator/compare/v3.2.0...v3.3.0 [v3.2.0]: https://github.com/raphaelstolt/lean-package-validator/compare/v3.1.1...v3.2.0 diff --git a/bin/lean-package-validator b/bin/lean-package-validator index c5e513a..a7a0467 100755 --- a/bin/lean-package-validator +++ b/bin/lean-package-validator @@ -22,7 +22,7 @@ if (false === $autoloaded) { } \define('WORKING_DIRECTORY', \getcwd()); -\define('VERSION', '3.3.1'); +\define('VERSION', '3.3.2'); use Stolt\LeanPackage\Commands\InitCommand; use Stolt\LeanPackage\Commands\ValidateCommand; From 3ce9f19458f36b44cc3752856bcc0f2a6d99bdf5 Mon Sep 17 00:00:00 2001 From: Raphael Stolt Date: Tue, 5 Dec 2023 08:54:56 +0100 Subject: [PATCH 070/152] Expands the PHP preset --- CHANGELOG.md | 4 ++++ src/Presets/PhpPreset.php | 1 + tests/AnalyserTest.php | 1 + tests/Commands/InitCommandTest.php | 1 + 4 files changed, 7 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index bf742e9..19be6fb 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,10 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/) and this p ## [Unreleased] +### Fixed + +- Further PHP preset expansion. + ## [v3.3.2] - 2023-12-04 ### Fixed diff --git a/src/Presets/PhpPreset.php b/src/Presets/PhpPreset.php index c191e7d..8d6f717 100644 --- a/src/Presets/PhpPreset.php +++ b/src/Presets/PhpPreset.php @@ -25,6 +25,7 @@ public function getPresetGlob(): array 'infection*', 'phpstan*', 'sonar*', + 'rector*', '*.dist.*', '*.dist', '{B,b}uild*', diff --git a/tests/AnalyserTest.php b/tests/AnalyserTest.php index 275fed1..0cbe0a6 100755 --- a/tests/AnalyserTest.php +++ b/tests/AnalyserTest.php @@ -1499,6 +1499,7 @@ public function returnsExpectedDefaultGlobPatterns(): void 'infection*', 'phpstan*', 'sonar*', + 'rector*', '*.dist.*', '*.dist', '{B,b}uild*', diff --git a/tests/Commands/InitCommandTest.php b/tests/Commands/InitCommandTest.php index 6f19d05..f7e0bcc 100644 --- a/tests/Commands/InitCommandTest.php +++ b/tests/Commands/InitCommandTest.php @@ -81,6 +81,7 @@ public function createsExpectedDefaultLpvFile(): void infection* phpstan* sonar* +rector* *.dist.* *.dist {B,b}uild* From cbaedf1242e8baf46df7d7cbf323211658f72931 Mon Sep 17 00:00:00 2001 From: Raphael Stolt Date: Wed, 6 Dec 2023 11:06:17 +0100 Subject: [PATCH 071/152] Improves documentation --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index ffab77a..d31129d 100755 --- a/README.md +++ b/README.md @@ -93,7 +93,7 @@ be used for projects (i.e. Python) outside the PHP ecosystem. lean-package-validator validate [] --glob-pattern '{.*,*.rst,*.py[cod],dist/}' ``` -The default pattern is `{.*,*.lock,*.txt,*.rst,*.{md,MD},*.xml,*.yml,appveyor.yml,box.json,captainhook.json,*.dist.*,*.dist,{B,b}uild*,{D,d}oc*,{T,t}ool*,{T,t}est*,{S,s}pec*,{E,e}xample*,LICENSE,{{M,m}ake,{B,b}ox,{V,v}agrant,{P,p}hulp}file,RMT}*`. +The default pattern is defined in the PHP preset [file](./src/Presets/PhpPreset.php). The `--glob-pattern-file` option allows you to load patterns, which should be used to match the common repository artifacts, from a given file. You From 2ac2df2c754305e3bfa008a5bbaaa6d8d2b99323 Mon Sep 17 00:00:00 2001 From: Raphael Stolt Date: Fri, 26 Apr 2024 12:56:32 +0200 Subject: [PATCH 072/152] Upgrades symfony/console --- composer.json | 2 +- src/Commands/InitCommand.php | 2 +- src/Commands/ValidateCommand.php | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/composer.json b/composer.json index bd1eaf9..24a8783 100755 --- a/composer.json +++ b/composer.json @@ -13,7 +13,7 @@ "php": ">=8.1", "laminas/laminas-stdlib": "^3.7", "sebastian/diff": "^5.0||^4.0.3", - "symfony/console": "^v6.3||^v5.4.8" + "symfony/console": "^7.0.6||^v5.4.8" }, "autoload": { "psr-4": { diff --git a/src/Commands/InitCommand.php b/src/Commands/InitCommand.php index df8f270..9ef2c5e 100644 --- a/src/Commands/InitCommand.php +++ b/src/Commands/InitCommand.php @@ -102,7 +102,7 @@ private function formatAvailablePresetDefinitionsForDescription(array $presets): * * @return integer */ - protected function execute(InputInterface $input, OutputInterface $output) + protected function execute(InputInterface $input, OutputInterface $output): int { $directory = (string) $input->getArgument('directory'); $overwriteDefaultLpvFile = $input->getOption('overwrite'); diff --git a/src/Commands/ValidateCommand.php b/src/Commands/ValidateCommand.php index 2b3c5f2..96725b4 100755 --- a/src/Commands/ValidateCommand.php +++ b/src/Commands/ValidateCommand.php @@ -175,7 +175,7 @@ protected function configure() * * @return integer */ - protected function execute(InputInterface $input, OutputInterface $output) + protected function execute(InputInterface $input, OutputInterface $output): int { $directory = (string) $input->getArgument('directory'); From 38c0000d15fea3955498397ea1cb8d34ddf7b904 Mon Sep 17 00:00:00 2001 From: Raphael Stolt Date: Fri, 26 Apr 2024 13:45:12 +0200 Subject: [PATCH 073/152] Release version 4.0.0 --- CHANGELOG.md | 6 +++++- bin/lean-package-validator | 2 +- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 19be6fb..0184928 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,8 +7,11 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/) and this p ## [Unreleased] +## [v4.0.0] - 2024-04-26 + ### Fixed +- Updated the symfony/console dependency. - Further PHP preset expansion. ## [v3.3.2] - 2023-12-04 @@ -247,7 +250,8 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/) and this p - Initial release. -[Unreleased]: https://github.com/raphaelstolt/lean-package-validator/compare/v3.3.2...HEAD +[Unreleased]: https://github.com/raphaelstolt/lean-package-validator/compare/v4.0.0...HEAD +[v4.0.0]: https://github.com/raphaelstolt/lean-package-validator/compare/v3.3.2...v4.0.0 [v3.3.2]: https://github.com/raphaelstolt/lean-package-validator/compare/v3.3.1...v3.3.2 [v3.3.1]: https://github.com/raphaelstolt/lean-package-validator/compare/v3.3.0...v3.3.1 [v3.3.0]: https://github.com/raphaelstolt/lean-package-validator/compare/v3.2.0...v3.3.0 diff --git a/bin/lean-package-validator b/bin/lean-package-validator index a7a0467..2e5e528 100755 --- a/bin/lean-package-validator +++ b/bin/lean-package-validator @@ -22,7 +22,7 @@ if (false === $autoloaded) { } \define('WORKING_DIRECTORY', \getcwd()); -\define('VERSION', '3.3.2'); +\define('VERSION', '4.0.0'); use Stolt\LeanPackage\Commands\InitCommand; use Stolt\LeanPackage\Commands\ValidateCommand; From c736c63675a3d67bea74737000f7f572526df15c Mon Sep 17 00:00:00 2001 From: Raphael Stolt Date: Fri, 26 Apr 2024 15:18:39 +0200 Subject: [PATCH 074/152] Expands the PHP preset --- src/Presets/PhpPreset.php | 1 + tests/AnalyserTest.php | 1 + tests/Commands/InitCommandTest.php | 1 + 3 files changed, 3 insertions(+) diff --git a/src/Presets/PhpPreset.php b/src/Presets/PhpPreset.php index 8d6f717..258936a 100644 --- a/src/Presets/PhpPreset.php +++ b/src/Presets/PhpPreset.php @@ -26,6 +26,7 @@ public function getPresetGlob(): array 'phpstan*', 'sonar*', 'rector*', + 'pint.json', '*.dist.*', '*.dist', '{B,b}uild*', diff --git a/tests/AnalyserTest.php b/tests/AnalyserTest.php index 0cbe0a6..16015a0 100755 --- a/tests/AnalyserTest.php +++ b/tests/AnalyserTest.php @@ -1500,6 +1500,7 @@ public function returnsExpectedDefaultGlobPatterns(): void 'phpstan*', 'sonar*', 'rector*', + 'pint.json', '*.dist.*', '*.dist', '{B,b}uild*', diff --git a/tests/Commands/InitCommandTest.php b/tests/Commands/InitCommandTest.php index f7e0bcc..5865ad8 100644 --- a/tests/Commands/InitCommandTest.php +++ b/tests/Commands/InitCommandTest.php @@ -82,6 +82,7 @@ public function createsExpectedDefaultLpvFile(): void phpstan* sonar* rector* +pint.json *.dist.* *.dist {B,b}uild* From c73653c88d9c6b479496da9813f2d4e3711b0e42 Mon Sep 17 00:00:00 2001 From: Raphael Stolt Date: Fri, 26 Apr 2024 16:09:28 +0200 Subject: [PATCH 075/152] Utilises constants --- src/Commands/InitCommand.php | 10 +++++----- src/Commands/ValidateCommand.php | 26 +++++++++++++------------- 2 files changed, 18 insertions(+), 18 deletions(-) diff --git a/src/Commands/InitCommand.php b/src/Commands/InitCommand.php index 9ef2c5e..6b85a11 100644 --- a/src/Commands/InitCommand.php +++ b/src/Commands/InitCommand.php @@ -119,7 +119,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int $output->writeln($e->getMessage(), OutputInterface::VERBOSITY_DEBUG); - return 1; + return Command::FAILURE; } } @@ -133,7 +133,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int $outputContent = '' . $warning . ''; $output->writeln($outputContent); - return 1; + return Command::FAILURE; } $defaultGlobPattern = $this->analyser->getDefaultGlobPattern(); @@ -149,7 +149,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int $outputContent = '' . $warning . ''; $output->writeln($outputContent); - return 1; + return Command::FAILURE; } $lpvFileContent = \implode("\n", $defaultGlobPattern); @@ -170,12 +170,12 @@ protected function execute(InputInterface $input, OutputInterface $output): int $outputContent = '' . $warning . ''; $output->writeln($outputContent); - return 1; + return Command::FAILURE; } $info = "Created default '$defaultLpvFile' file."; $output->writeln($info); - return 0; + return Command::SUCCESS; } } diff --git a/src/Commands/ValidateCommand.php b/src/Commands/ValidateCommand.php index 96725b4..13007f2 100755 --- a/src/Commands/ValidateCommand.php +++ b/src/Commands/ValidateCommand.php @@ -190,7 +190,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int $output->writeln($e->getMessage(), OutputInterface::VERBOSITY_DEBUG); - return 1; + return Command::FAILURE; } } @@ -263,7 +263,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int $output->writeln($e->getMessage(), OutputInterface::VERBOSITY_DEBUG); - return 1; + return Command::FAILURE; } } elseif($this->isGlobPatternFileSetable($globPatternFile)) { try { @@ -285,7 +285,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int $output->writeln($e->getMessage(), OutputInterface::VERBOSITY_DEBUG); - return 1; + return Command::FAILURE; } catch (InvalidGlobPatternFile $e) { $warning = "Warning: The provided glob pattern file " . "'$globPatternFile' is considered invalid."; @@ -294,7 +294,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int $output->writeln($e->getMessage(), OutputInterface::VERBOSITY_DEBUG); - return 1; + return Command::FAILURE; } } @@ -327,14 +327,14 @@ protected function execute(InputInterface $input, OutputInterface $output): int $output->writeln($outputContent); - return 0; + return Command::SUCCESS; } catch (GitattributesCreationFailed $e) { $outputContent .= PHP_EOL . PHP_EOL . $e->getMessage(); $output->writeln($outputContent); $output->writeln($e->getMessage(), OutputInterface::VERBOSITY_DEBUG); - return 1; + return Command::FAILURE; } } else { $verboseOutput = '+ Suggesting .gitattribute file content.'; @@ -346,7 +346,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int $output->writeln($outputContent); - return 1; + return Command::FAILURE; } } @@ -364,7 +364,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int $info = 'The archive file of the current HEAD is considered lean.'; $output->writeln($info); - return 0; + return Command::SUCCESS; } $foundUnexpectedArchiveArtifacts = $this->archiveValidator ->getFoundUnexpectedArchiveArtifacts(); @@ -390,7 +390,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int $output->writeln($info); - return 1; + return Command::FAILURE; } else { $verboseOutput = '+ Analysing the .gitattribute content.'; $output->writeln($verboseOutput, OutputInterface::VERBOSITY_VERBOSE); @@ -424,14 +424,14 @@ protected function execute(InputInterface $input, OutputInterface $output): int $output->writeln($outputContent); - return 0; + return Command::SUCCESS; } catch (GitattributesCreationFailed $e) { $outputContent .= PHP_EOL . PHP_EOL . $e->getMessage(); $output->writeln($outputContent); $output->writeln($e->getMessage(), OutputInterface::VERBOSITY_DEBUG); - return 1; + return Command::FAILURE; } } @@ -451,7 +451,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int $output->writeln($outputContent); - return 1; + return Command::FAILURE; } $info = 'The present .gitattributes file is considered valid.'; @@ -476,7 +476,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int $output->writeln($outputContent); } - return 0; + return Command::SUCCESS; } } From 391b458df7044bfa4850a19fc2d61dc8902e3e88 Mon Sep 17 00:00:00 2001 From: Raphael Stolt Date: Fri, 26 Apr 2024 16:23:41 +0200 Subject: [PATCH 076/152] Fixes naming --- README.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index d31129d..d891e3e 100755 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# LeanPackageValidator +# lean package validator ![Test Status](https://github.com/raphaelstolt/lean-package-validator/workflows/test/badge.svg) [![Version](http://img.shields.io/packagist/v/stolt/lean-package-validator.svg?style=flat)](https://packagist.org/packages/stolt/lean-package-validator) @@ -6,13 +6,13 @@ [![composer.lock available](https://poser.pugx.org/stolt/lean-package-validator/composerlock)](https://packagist.org/packages/stolt/lean-package-validator) [![PDS Skeleton](https://img.shields.io/badge/pds-skeleton-blue.svg?style=flat)](https://github.com/php-pds/skeleton) -The LeanPackageValidator is a utility tool that validates a project/micro-package +The lean package validator is a utility tool that validates a project/micro-package for its `leanness`. A project/micro-package is considered `lean` when its common repository artifacts won't be included in release assets. ## Installation -The LeanPackageValidator CLI should be installed globally through Composer. +The lean package validator CLI should be installed globally through Composer. ``` bash composer global require stolt/lean-package-validator @@ -31,7 +31,7 @@ assumes that `$COMPOSER_HOME` is `~/.config/composer` and not `~/.composer`. alias lpv='~/.config/composer/vendor/bin/lean-package-validator $@' ``` -The LeanPackageValidator also can be installed locally to a project which allows +The lean package validator also can be installed locally to a project which allows further utilisation via [Composer scripts](https://getcomposer.org/doc/articles/scripts.md). ``` bash @@ -39,7 +39,7 @@ composer require --dev stolt/lean-package-validator ``` > [!TIP] -> As of release `v1.9.0` it's also possible to install and use the LeanPackageValidator +> As of release `v1.9.0` it's also possible to install and use the lean package validator > via a PHAR [file](https://github.com/raphaelstolt/lean-package-validator/releases/tag/v1.9.0). Therefor download a released version e.g. v3.3.1 and move it to `/usr/local/bin` as shown next. @@ -51,7 +51,7 @@ mv lean-package-validator.phar /usr/local/bin/lean-package-validator ## Usage -Run the LeanPackageValidator CLI within or against a project/micro-package +Run the lean package validator CLI within or against a project/micro-package directory, and it will validate the [export-ignore](https://git-scm.com/book/en/v2/Customizing-Git-Git-Attributes#Exporting-Your-Repository) entries present in a `.gitattributes` file against a set of common repository artifacts. If no `.gitattributes` file is present it will suggest to create one. From 90f2f1a5dd81bfc543caefdac8499777985919b0 Mon Sep 17 00:00:00 2001 From: Raphael Stolt Date: Mon, 6 May 2024 18:01:35 +0200 Subject: [PATCH 077/152] Expands the PHP preset --- src/Presets/PhpPreset.php | 1 + tests/AnalyserTest.php | 1 + tests/Commands/InitCommandTest.php | 1 + 3 files changed, 3 insertions(+) diff --git a/src/Presets/PhpPreset.php b/src/Presets/PhpPreset.php index 258936a..4b612c5 100644 --- a/src/Presets/PhpPreset.php +++ b/src/Presets/PhpPreset.php @@ -27,6 +27,7 @@ public function getPresetGlob(): array 'sonar*', 'rector*', 'pint.json', + 'ecs*', '*.dist.*', '*.dist', '{B,b}uild*', diff --git a/tests/AnalyserTest.php b/tests/AnalyserTest.php index 16015a0..c82d907 100755 --- a/tests/AnalyserTest.php +++ b/tests/AnalyserTest.php @@ -1501,6 +1501,7 @@ public function returnsExpectedDefaultGlobPatterns(): void 'sonar*', 'rector*', 'pint.json', + 'ecs*', '*.dist.*', '*.dist', '{B,b}uild*', diff --git a/tests/Commands/InitCommandTest.php b/tests/Commands/InitCommandTest.php index 5865ad8..223c3c6 100644 --- a/tests/Commands/InitCommandTest.php +++ b/tests/Commands/InitCommandTest.php @@ -83,6 +83,7 @@ public function createsExpectedDefaultLpvFile(): void sonar* rector* pint.json +ecs* *.dist.* *.dist {B,b}uild* From 8476c4be58f39ba94b239cb9344286646ba651bf Mon Sep 17 00:00:00 2001 From: Raphael Stolt Date: Mon, 6 May 2024 18:05:43 +0200 Subject: [PATCH 078/152] Release version 4.0.1 --- CHANGELOG.md | 9 ++++++++- bin/lean-package-validator | 2 +- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0184928..b9b9e28 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,12 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/) and this p ## [Unreleased] +## [v4.0.1] - 2024-05-07 + +### Added + +- Further PHP preset expansion. + ## [v4.0.0] - 2024-04-26 ### Fixed @@ -250,7 +256,8 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/) and this p - Initial release. -[Unreleased]: https://github.com/raphaelstolt/lean-package-validator/compare/v4.0.0...HEAD +[Unreleased]: https://github.com/raphaelstolt/lean-package-validator/compare/v4.0.1...HEAD +[v4.0.1]: https://github.com/raphaelstolt/lean-package-validator/compare/v4.0.0...v4.0.1 [v4.0.0]: https://github.com/raphaelstolt/lean-package-validator/compare/v3.3.2...v4.0.0 [v3.3.2]: https://github.com/raphaelstolt/lean-package-validator/compare/v3.3.1...v3.3.2 [v3.3.1]: https://github.com/raphaelstolt/lean-package-validator/compare/v3.3.0...v3.3.1 diff --git a/bin/lean-package-validator b/bin/lean-package-validator index 2e5e528..68d4392 100755 --- a/bin/lean-package-validator +++ b/bin/lean-package-validator @@ -22,7 +22,7 @@ if (false === $autoloaded) { } \define('WORKING_DIRECTORY', \getcwd()); -\define('VERSION', '4.0.0'); +\define('VERSION', '4.0.1'); use Stolt\LeanPackage\Commands\InitCommand; use Stolt\LeanPackage\Commands\ValidateCommand; From 4eaf01b44a12c97c6182ff88b0092ba5fd902906 Mon Sep 17 00:00:00 2001 From: Raphael Stolt Date: Tue, 7 May 2024 09:59:24 +0200 Subject: [PATCH 079/152] Makes static-analyse CI step pass --- phpstan.neon.dist | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/phpstan.neon.dist b/phpstan.neon.dist index 83c2878..a0f27d7 100644 --- a/phpstan.neon.dist +++ b/phpstan.neon.dist @@ -1,5 +1,5 @@ parameters: - level: max + level: 4 paths: - src - tests @@ -15,3 +15,6 @@ parameters: - '#Cannot cast#' - '#is never read#' - '#Comparison operation ">="#' + - '#unresolvable type.#' + - '#TMock#' + - '#unknown class#' From b47ae4fff67b8b7eee34f369b88755a8ca426a8f Mon Sep 17 00:00:00 2001 From: Raphael Stolt Date: Tue, 7 May 2024 11:07:29 +0200 Subject: [PATCH 080/152] Fixes naming --- .github/CONTRIBUTING.md | 2 +- README.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md index ec28efe..d73be63 100755 --- a/.github/CONTRIBUTING.md +++ b/.github/CONTRIBUTING.md @@ -1,6 +1,6 @@ # How to contribute -Thanks for considering to contribute to the `LeanPackageValidator`. Please follow these guidelines: +Thanks for considering to contribute to the `lean package validator`. Please follow these guidelines: - All code __MUST__ follow the PSR-2 coding standard. Please see [PSR-2](http://www.php-fig.org/psr/psr-2/) for more details. diff --git a/README.md b/README.md index d891e3e..86e9108 100755 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# lean package validator +# Lean package validator ![Test Status](https://github.com/raphaelstolt/lean-package-validator/workflows/test/badge.svg) [![Version](http://img.shields.io/packagist/v/stolt/lean-package-validator.svg?style=flat)](https://packagist.org/packages/stolt/lean-package-validator) From d28606ad8f4d162184389b1795446d65c7a25987 Mon Sep 17 00:00:00 2001 From: Raphael Stolt Date: Mon, 13 May 2024 09:52:13 +0200 Subject: [PATCH 081/152] Expands the PHP preset --- CHANGELOG.md | 6 ++++++ src/Presets/PhpPreset.php | 1 + tests/AnalyserTest.php | 1 + tests/Commands/InitCommandTest.php | 1 + 4 files changed, 9 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index b9b9e28..0fb26c5 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,12 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/) and this p ## [Unreleased] +## [v4.0.2] - 2024-05-13 + +### Added + +- Further PHP preset expansion. + ## [v4.0.1] - 2024-05-07 ### Added diff --git a/src/Presets/PhpPreset.php b/src/Presets/PhpPreset.php index 4b612c5..5bc5e47 100644 --- a/src/Presets/PhpPreset.php +++ b/src/Presets/PhpPreset.php @@ -26,6 +26,7 @@ public function getPresetGlob(): array 'phpstan*', 'sonar*', 'rector*', + 'package*', 'pint.json', 'ecs*', '*.dist.*', diff --git a/tests/AnalyserTest.php b/tests/AnalyserTest.php index c82d907..1f68c6c 100755 --- a/tests/AnalyserTest.php +++ b/tests/AnalyserTest.php @@ -1500,6 +1500,7 @@ public function returnsExpectedDefaultGlobPatterns(): void 'phpstan*', 'sonar*', 'rector*', + 'package*', 'pint.json', 'ecs*', '*.dist.*', diff --git a/tests/Commands/InitCommandTest.php b/tests/Commands/InitCommandTest.php index 223c3c6..dae247e 100644 --- a/tests/Commands/InitCommandTest.php +++ b/tests/Commands/InitCommandTest.php @@ -82,6 +82,7 @@ public function createsExpectedDefaultLpvFile(): void phpstan* sonar* rector* +package* pint.json ecs* *.dist.* From 858aca047950ef22f40654bd78e003f48b1c39f7 Mon Sep 17 00:00:00 2001 From: Raphael Stolt Date: Mon, 13 May 2024 09:54:25 +0200 Subject: [PATCH 082/152] Ignores global gitignore patterns --- CHANGELOG.md | 4 ++ src/Analyser.php | 22 +------- tests/Commands/ValidateCommandTest.php | 75 ++++++++++++++++++++++++-- 3 files changed, 75 insertions(+), 26 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0fb26c5..178ee43 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,10 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/) and this p - Further PHP preset expansion. +### Fixed + +- Ignore global gitignore patterns. + ## [v4.0.1] - 2024-05-07 ### Added diff --git a/src/Analyser.php b/src/Analyser.php index 7f9600e..185891d 100755 --- a/src/Analyser.php +++ b/src/Analyser.php @@ -420,25 +420,6 @@ public function hasGitattributesFile(): bool \is_readable($this->gitattributesFile); } - /** - * @return array - */ - public function getGlobalGitignorePatterns(): array - { - $gitConfigGetCommand = 'git config --get core.excludesfile'; - - \exec($gitConfigGetCommand, $output, $statusCode); - - if ($statusCode !== 0) { - return []; - } - - $homeDirectory = \getenv('HOME') ? \getenv('HOME') : __DIR__; - $excludesFile = \str_replace('~', $homeDirectory, \trim($output[0])); - - return $this->getGitignorePatterns($excludesFile); - } - /** * @param string $gitignoreFile * @return array @@ -612,8 +593,7 @@ public function collectExpectedExportIgnores(): array $ignoredGlobMatches = \array_merge( $this->ignoredGlobMatches, - $this->getGitignoredPatterns(), - $this->getGlobalGitignorePatterns() + $this->getGitignoredPatterns() ); $globMatches = Glob::glob($this->globPattern, Glob::GLOB_BRACE); diff --git a/tests/Commands/ValidateCommandTest.php b/tests/Commands/ValidateCommandTest.php index 26d3bae..a3f313d 100644 --- a/tests/Commands/ValidateCommandTest.php +++ b/tests/Commands/ValidateCommandTest.php @@ -184,6 +184,76 @@ public function showsDifferenceBetweenActualAndExpectedGitattributesContent(): v $this->assertTrue($commandTester->getStatusCode() > 0); } + /** + * @test + */ + public function filesInGlobalGitignoreAreExportIgnored(): void + { + $analyserMock = Mockery::mock(Analyser::class)->makePartial(); + + $globPattern = '{' . \implode(',', (new PhpPreset())->getPresetGlob()) . '}*'; + $analyserMock->setGlobPattern($globPattern); + + $application = $this->getApplicationWithMockedAnalyser($analyserMock); + + $artifactFilenames = [ + '.gitattributes', + '.gitignore', + 'captainhook.json', + 'CODE_OF_CONDUCT.md', + 'CONTRIBUTING.md', + 'infection.json5', + 'LICENSE.txt', + 'phpstan.neon', + 'phpunit.xml', + 'README.md', + 'sonar-project.properties', + 'package.json', + 'package-lock.json' + ]; + + $this->createTemporaryFiles( + $artifactFilenames, + ['tests', '.github', 'docs'] + ); + + $command = $application->find('validate'); + $commandTester = new CommandTester($command); + $commandTester->execute([ + 'command' => $command->getName(), + 'directory' => WORKING_DIRECTORY, + '--enforce-strict-order' => true, + '--enforce-alignment' => true, + ]); + + $expectedDisplay = <<assertStringEqualsStringIgnoringLineEndings($expectedDisplay, $commandTester->getDisplay()); + $this->assertTrue($commandTester->getStatusCode() > 0); + } /** * @test @@ -196,11 +266,6 @@ public function gitattributesFileWithNoExportIgnoresContentShowsExpectedContent( $globPattern = '{' . \implode(',', (new PhpPreset())->getPresetGlob()) . '}*'; $analyserMock->setGlobPattern($globPattern); - $analyserMock->shouldReceive('getGlobalGitignorePatterns') - ->once() - ->withAnyArgs() - ->andReturn([]); - $application = $this->getApplicationWithMockedAnalyser($analyserMock); $artifactFilenames = [ From 9fe5b422208ff7a83c964a4dfae806b318308fd8 Mon Sep 17 00:00:00 2001 From: Raphael Stolt Date: Mon, 13 May 2024 09:55:45 +0200 Subject: [PATCH 083/152] Release version 4.0.2 --- CHANGELOG.md | 3 ++- bin/lean-package-validator | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 178ee43..00e87bc 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -266,7 +266,8 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/) and this p - Initial release. -[Unreleased]: https://github.com/raphaelstolt/lean-package-validator/compare/v4.0.1...HEAD +[Unreleased]: https://github.com/raphaelstolt/lean-package-validator/compare/v4.0.2...HEAD +[v4.0.2]: https://github.com/raphaelstolt/lean-package-validator/compare/v4.0.1...v4.0.2 [v4.0.1]: https://github.com/raphaelstolt/lean-package-validator/compare/v4.0.0...v4.0.1 [v4.0.0]: https://github.com/raphaelstolt/lean-package-validator/compare/v3.3.2...v4.0.0 [v3.3.2]: https://github.com/raphaelstolt/lean-package-validator/compare/v3.3.1...v3.3.2 diff --git a/bin/lean-package-validator b/bin/lean-package-validator index 68d4392..83837d4 100755 --- a/bin/lean-package-validator +++ b/bin/lean-package-validator @@ -22,7 +22,7 @@ if (false === $autoloaded) { } \define('WORKING_DIRECTORY', \getcwd()); -\define('VERSION', '4.0.1'); +\define('VERSION', '4.0.2'); use Stolt\LeanPackage\Commands\InitCommand; use Stolt\LeanPackage\Commands\ValidateCommand; From a3cda50c7e79f33fe0be8eff780e91dc2f6fd335 Mon Sep 17 00:00:00 2001 From: Raphael Stolt Date: Thu, 16 May 2024 08:16:18 +0200 Subject: [PATCH 084/152] Utilises parallel runner --- .php-cs-fixer.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.php-cs-fixer.php b/.php-cs-fixer.php index 5a71278..59c1a79 100755 --- a/.php-cs-fixer.php +++ b/.php-cs-fixer.php @@ -2,6 +2,7 @@ use PhpCsFixer\Config; use PhpCsFixer\Finder; +use PhpCsFixer\Runner\Parallel\ParallelConfigFactory; $finder = Finder::create() ->in([__DIR__, __DIR__ . DIRECTORY_SEPARATOR . 'tests']); @@ -22,5 +23,6 @@ $config = new Config(); return $config->setRules($rules) + ->setParallelConfig(ParallelConfigFactory::detect()) ->setFinder($finder) ->setCacheFile($cacheDir . '/.php-cs-fixer.cache'); From 09f0e1612a0b61def71cc39453ae97bc814b9004 Mon Sep 17 00:00:00 2001 From: Raphael Stolt Date: Fri, 31 May 2024 10:37:34 +0200 Subject: [PATCH 085/152] Updates symfony/console package --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 24a8783..dc0efcd 100755 --- a/composer.json +++ b/composer.json @@ -13,7 +13,7 @@ "php": ">=8.1", "laminas/laminas-stdlib": "^3.7", "sebastian/diff": "^5.0||^4.0.3", - "symfony/console": "^7.0.6||^v5.4.8" + "symfony/console": "^7.1.0||^v5.4.8" }, "autoload": { "psr-4": { From e1de5de284c3a1ddce255fdc24d06dbaa3c4085e Mon Sep 17 00:00:00 2001 From: Raphael Stolt Date: Mon, 3 Jun 2024 10:00:36 +0200 Subject: [PATCH 086/152] Updates tests towards PHPUnit attributes --- tests/AnalyserTest.php | 250 ++++++++---------------- tests/ApplicationTest.php | 14 +- tests/Archive/ValidatorTest.php | 13 +- tests/ArchiveTest.php | 59 ++---- tests/Commands/InitCommandTest.php | 32 ++-- tests/Commands/ValidateCommandTest.php | 251 +++++++++---------------- tests/Helpers/StrTest.php | 8 +- tests/Presets/FinderTest.php | 21 +-- 8 files changed, 214 insertions(+), 434 deletions(-) diff --git a/tests/AnalyserTest.php b/tests/AnalyserTest.php index 1f68c6c..cd2bc36 100755 --- a/tests/AnalyserTest.php +++ b/tests/AnalyserTest.php @@ -5,6 +5,9 @@ namespace Stolt\LeanPackage\Tests; use Mockery; +use PHPUnit\Framework\Attributes\Group; +use PHPUnit\Framework\Attributes\Test; +use PHPUnit\Framework\Attributes\Ticket; use Stolt\LeanPackage\Analyser; use Stolt\LeanPackage\Exceptions\InvalidGlobPattern; use Stolt\LeanPackage\Exceptions\InvalidGlobPatternFile; @@ -34,9 +37,7 @@ protected function tearDown(): void } } - /** - * @test - */ + #[Test] public function hasCompleteExportIgnoresFailsOnEmptyExportIgnores(): void { $analyser = (new Analyser(new Finder(new PhpPreset())))->setDirectory($this->temporaryDirectory); @@ -45,10 +46,7 @@ public function hasCompleteExportIgnoresFailsOnEmptyExportIgnores(): void ); } - /** - * @test - * @throws InvalidGlobPattern - */ + #[Test] public function hasCompleteExportIgnoresFailsOnNonExistingGitattributesFile(): void { $mock = Mockery::mock(Analyser::class)->makePartial(); @@ -68,9 +66,7 @@ public function hasCompleteExportIgnoresFailsOnNonExistingGitattributesFile(): v ); } - /** - * @test - */ + #[Test] public function returnsTrueWhenDirectoryHasCompleteExportIgnores(): void { $gitattributesContent = <<setDirectory($nonExistingDirectory); } - /** - * @test - */ + #[Test] public function gitattributesFileHasAnAccessor(): void { $analyser = (new Analyser(new Finder(new PhpPreset())))->setDirectory($this->temporaryDirectory); @@ -133,18 +125,14 @@ public function gitattributesFileHasAnAccessor(): void ); } - /** - * @test - */ + #[Test] public function directoryHasAnAccessor(): void { $analyser = (new Analyser(new Finder(new PhpPreset())))->setDirectory($this->temporaryDirectory); $this->assertEquals($this->temporaryDirectory, $analyser->getDirectory()); } - /** - * @test - */ + #[Test] public function returnsExpectedGitattributesContent(): void { $artifactsWithoutExportIgnore = [ @@ -179,9 +167,7 @@ public function returnsExpectedGitattributesContent(): void ); } - /** - * @test - */ + #[Test] public function expectedFileMatchesAreInExpectedGitattributesContent(): void { $artifactFilenames = [ @@ -214,9 +200,7 @@ public function expectedFileMatchesAreInExpectedGitattributesContent(): void ); } - /** - * @test - */ + #[Test] public function nonExportIgnoresContentIsEmptyForNonexistentGitattributesFile(): void { $analyser = (new Analyser(new Finder(new PhpPreset())))->setDirectory($this->temporaryDirectory); @@ -224,9 +208,7 @@ public function nonExportIgnoresContentIsEmptyForNonexistentGitattributesFile(): $this->assertEquals('', $analyser->getPresentNonExportIgnoresContent()); } - /** - * @test - */ + #[Test] public function nonExportIgnoresContentOfGitattributesFileIsReturned(): void { $gitattributesContent = <<temporaryDirectory @@ -427,9 +399,7 @@ public function hasGitattributesFileOnExistingGitattributesFile(): void ); } - /** - * @test - */ + #[Test] public function hasGitattributesFileFailsOnNonExistingGitattributesFile(): void { $temporaryGitattributesFile = $this->temporaryDirectory @@ -445,9 +415,7 @@ public function hasGitattributesFileFailsOnNonExistingGitattributesFile(): void ); } - /** - * @test - */ + #[Test] public function collectExpectedExportIgnoresReturnsExpectedEntries(): void { $temporaryGitattributesFile = $this->temporaryDirectory @@ -484,9 +452,7 @@ public function collectExpectedExportIgnoresReturnsExpectedEntries(): void ); } - /** - * @test - */ + #[Test] public function returnsAnEmptyArrayOnNonExistingGitattributesFile(): void { $analyser = (new Analyser(new Finder(new PhpPreset())))->setDirectory($this->temporaryDirectory); @@ -499,9 +465,7 @@ public function returnsAnEmptyArrayOnNonExistingGitattributesFile(): void ); } - /** - * @test - */ + #[Test] public function returnsExpectedPresentExportIgnores(): void { $gitattributesContent = <<assertTrue($analyser->hasCompleteExportIgnores()); } - /** - * @test - * @ticket 6 (https://github.com/raphaelstolt/lean-package-validator/issues/6) - */ + #[Test] + #[Ticket('https://github.com/raphaelstolt/lean-package-validator/issues/6')] public function varyingOrderDoesFailCompletenessCheckWhenEnforced(): void { $artifactFilenames = [ @@ -730,9 +686,7 @@ public function varyingOrderDoesFailCompletenessCheckWhenEnforced(): void $this->assertFalse($analyser->hasCompleteExportIgnores()); } - /** - * @test - */ + #[Test] public function notPatternMatchingExportIgnoresArePreservedAssumedFileExists(): void { $artifactFilenames = [ @@ -784,9 +738,7 @@ public function notPatternMatchingExportIgnoresArePreservedAssumedFileExists(): ); } - /** - * @test - */ + #[Test] public function nonPatternsMatchingButMatchingExistingFilesArePreservedExportIgnores(): void { $artifactFilenames = [ @@ -836,9 +788,7 @@ public function nonPatternsMatchingButMatchingExistingFilesArePreservedExportIgn ); } - /** - * @test - */ + #[Test] public function notPatternMatchingExportIgnoresDoNotFailCompletenessCheck(): void { $artifactFilenames = [ @@ -870,11 +820,9 @@ public function notPatternMatchingExportIgnoresDoNotFailCompletenessCheck(): voi $this->assertTrue($analyser->hasCompleteExportIgnores()); } - /** - * @test - * @group glob - * @ticket 14 (https://github.com/raphaelstolt/lean-package-validator/issues/14) - */ + #[Test] + #[Group('glob')] + #[Ticket('https://github.com/raphaelstolt/lean-package-validator/issues/5')] public function captainHookConfigurationFileIsInDefaultPattern(): void { $artifactFilenames = [ @@ -904,11 +852,9 @@ public function captainHookConfigurationFileIsInDefaultPattern(): void ); } - /** - * @test - * @group glob - * @ticket 9 (https://github.com/raphaelstolt/lean-package-validator/issues/9) - */ + #[Test] + #[Group('glob')] + #[Ticket('https://github.com/raphaelstolt/lean-package-validator/issues/9')] public function nonExistingGlobPatternFileThrowsExpectedException(): void { $fixturesDirectory = __DIR__ . DIRECTORY_SEPARATOR . 'fixtures'; @@ -921,11 +867,9 @@ public function nonExistingGlobPatternFileThrowsExpectedException(): void ->setGlobPatternFromFile($globPatternFile); } - /** - * @test - * @group glob - * @ticket 9 (https://github.com/raphaelstolt/lean-package-validator/issues/9) - */ + #[Test] + #[Group('glob')] + #[Ticket('https://github.com/raphaelstolt/lean-package-validator/issues/9')] public function emptyGlobPatternFileThrowsExpectedException(): void { $temporaryLpvFile = $this->temporaryDirectory @@ -941,11 +885,9 @@ public function emptyGlobPatternFileThrowsExpectedException(): void ->setGlobPatternFromFile($temporaryLpvFile); } - /** - * @test - * @group glob - * @ticket 9 (https://github.com/raphaelstolt/lean-package-validator/issues/9) - */ + #[Test] + #[Group('glob')] + #[Ticket('https://github.com/raphaelstolt/lean-package-validator/issues/9')] public function defaultExportIgnoresGlobPatternIsOverwritableFromFile(): void { $temporaryLpvFile = $this->temporaryDirectory @@ -984,10 +926,8 @@ public function defaultExportIgnoresGlobPatternIsOverwritableFromFile(): void ); } - /** - * @test - * @group glob - */ + #[Test] + #[Group('glob')] public function defaultExportIgnoresGlobPatternIsOverwritable(): void { $analyser = (new Analyser(new Finder(new PhpPreset()))) @@ -1014,10 +954,8 @@ public function defaultExportIgnoresGlobPatternIsOverwritable(): void ); } - /** - * @test - * @group glob - */ + #[Test] + #[Group('glob')] public function emptyGlobPatternThrowsExpectedException(): void { $this->expectException(InvalidGlobPattern::class); @@ -1026,10 +964,8 @@ public function emptyGlobPatternThrowsExpectedException(): void ->setGlobPattern(''); } - /** - * @test - * @group glob - */ + #[Test] + #[Group('glob')] public function invalidGlobPatternBracesThrowsExpectedException(): void { $this->expectException(InvalidGlobPattern::class); @@ -1040,10 +976,8 @@ public function invalidGlobPatternBracesThrowsExpectedException(): void $this->assertEquals($this->temporaryDirectory, $analyser->getDirectory()); } - /** - * @test - * @group glob - */ + #[Test] + #[Group('glob')] public function wildcardAfterBracesIsNotRaisingAnException(): void { $analyser = (new Analyser(new Finder(new PhpPreset()))) @@ -1053,10 +987,8 @@ public function wildcardAfterBracesIsNotRaisingAnException(): void $this->assertEquals($this->temporaryDirectory, $analyser->getDirectory()); } - /** - * @test - * @group glob - */ + #[Test] + #[Group('glob')] public function emptyGlobPatternBracesContentThrowsExpectedException(): void { $this->expectException(InvalidGlobPattern::class); @@ -1065,10 +997,8 @@ public function emptyGlobPatternBracesContentThrowsExpectedException(): void ->setGlobPattern('{ }'); } - /** - * @test - * @group glob - */ + #[Test] + #[Group('glob')] public function singleGlobPatternThrowsExpectedException(): void { $this->expectException(InvalidGlobPattern::class); @@ -1077,10 +1007,8 @@ public function singleGlobPatternThrowsExpectedException(): void ->setGlobPattern('{*.go}'); } - /** - * @test - * @group glob - */ + #[Test] + #[Group('glob')] public function globPatternWithEnclosedBracesAreConsideredValid(): void { $analyser = (new Analyser(new Finder(new PhpPreset()))) @@ -1090,9 +1018,7 @@ public function globPatternWithEnclosedBracesAreConsideredValid(): void $this->assertEquals($this->temporaryDirectory, $analyser->getDirectory()); } - /** - * @test - */ + #[Test] public function withDistEndingFilesAreNotExportIgnored(): void { $artifactFilenames = [ @@ -1124,10 +1050,8 @@ public function withDistEndingFilesAreNotExportIgnored(): void ); } - /** - * @test - * @ticket 15 (https://github.com/raphaelstolt/lean-package-validator/issues/15) - */ + #[Test] + #[Ticket('https://github.com/raphaelstolt/lean-package-validator/issues/15')] public function licenseFileIsNotExportIgnored(): void { $artifactFilenames = [ @@ -1161,10 +1085,8 @@ public function licenseFileIsNotExportIgnored(): void ); } - /** - * @test - * @ticket 24 (https://github.com/raphaelstolt/lean-package-validator/issues/24) - */ + #[Test] + #[Ticket('https://github.com/raphaelstolt/lean-package-validator/issues/24')] public function directoriesOnlyExportIgnoredOnce(): void { $artifactFilenames = [ @@ -1210,9 +1132,7 @@ public function directoriesOnlyExportIgnoredOnce(): void ); } - /** - * @test - */ + #[Test] public function exportIgnoresAreAligned(): void { $artifactFilenames = [ @@ -1247,10 +1167,8 @@ public function exportIgnoresAreAligned(): void ); } - /** - * @test - * @ticket 4 (https://github.com/raphaelstolt/lean-package-validator/issues/4) - */ + #[Test] + #[Ticket('https://github.com/raphaelstolt/lean-package-validator/issues/4')] public function precedingSlashesAreDetected(): void { $artifactFilenames = [ @@ -1282,10 +1200,8 @@ public function precedingSlashesAreDetected(): void $this->assertTrue($analyser->hasPrecedingSlashesInExportIgnorePattern()); } - /** - * @test - * @ticket 12 (https://github.com/raphaelstolt/lean-package-validator/issues/12) - */ + #[Test] + #[Ticket('https://github.com/raphaelstolt/lean-package-validator/issues/12')] public function missingTextAutoConfigurationIsDetected(): void { $artifactFilenames = [ @@ -1312,10 +1228,8 @@ public function missingTextAutoConfigurationIsDetected(): void $this->assertFalse($analyser->hasTextAutoConfiguration()); } - /** - * @test - * @ticket 12 (https://github.com/raphaelstolt/lean-package-validator/issues/12) - */ + #[Test] + #[Ticket('https://github.com/raphaelstolt/lean-package-validator/issues/12')] public function presentTextAutoConfigurationIsDetected(): void { $artifactFilenames = [ @@ -1345,18 +1259,14 @@ public function presentTextAutoConfigurationIsDetected(): void $this->assertTrue($analyser->hasTextAutoConfiguration()); } - /** - * @test - */ + #[Test] public function returnsEmptyPatternsWhenNoGitignoreFilePresent(): void { $analyser = (new Analyser(new Finder(new PhpPreset())))->setDirectory($this->temporaryDirectory); $this->assertEquals([], $analyser->getGitignoredPatterns()); } - /** - * @test - */ + #[Test] public function returnsExpectedGitignoredPatterns(): void { $gitignoreContent = <<assertTrue($analyser->hasCompleteExportIgnores()); } - /** - * @test - * @ticket 21 (https://github.com/raphaelstolt/lean-package-validator/issues/21) - */ + #[Test] + #[Ticket('https://github.com/raphaelstolt/lean-package-validator/issues/21')] public function presentGitignoredSpecsCoverageDirectoryIsExcludedFromValidation(): void { $artifactFilenames = [ @@ -1476,10 +1382,8 @@ public function presentGitignoredSpecsCoverageDirectoryIsExcludedFromValidation( $this->assertTrue($analyser->hasCompleteExportIgnores()); } - /** - * @test - * @group glob - */ + #[Test] + #[Group('glob')] public function returnsExpectedDefaultGlobPatterns(): void { $analyser = (new Analyser(new Finder(new PhpPreset())))->setDirectory($this->temporaryDirectory); diff --git a/tests/ApplicationTest.php b/tests/ApplicationTest.php index 4c793bd..a467993 100644 --- a/tests/ApplicationTest.php +++ b/tests/ApplicationTest.php @@ -4,14 +4,14 @@ namespace Stolt\LeanPackage\Tests; +use PHPUnit\Framework\Attributes\Group; +use PHPUnit\Framework\Attributes\Test; use PHPUnit\Framework\TestCase as PHPUnit; final class ApplicationTest extends PHPUnit { - /** - * @test - * @group integration - */ + #[Test] + #[Group('integration')] public function executableIsAvailable(): void { $binaryCommand = 'php bin/lean-package-validator'; @@ -26,10 +26,8 @@ public function executableIsAvailable(): void $this->assertEquals(0, $returnValue); } - /** - * @test - * @group integration - */ + #[Test] + #[Group('integration')] public function expectedCommandsAreListed(): void { $binaryCommand = 'php bin/lean-package-validator list'; diff --git a/tests/Archive/ValidatorTest.php b/tests/Archive/ValidatorTest.php index d78d1e5..b99cc12 100755 --- a/tests/Archive/ValidatorTest.php +++ b/tests/Archive/ValidatorTest.php @@ -5,6 +5,7 @@ namespace Stolt\LeanPackage\Tests\Archive; use Mockery; +use PHPUnit\Framework\Attributes\Test; use Stolt\LeanPackage\Archive; use Stolt\LeanPackage\Archive\Validator; use Stolt\LeanPackage\Exceptions\GitArchiveNotValidatedYet; @@ -32,9 +33,7 @@ protected function tearDown(): void } } - /** - * @test - */ + #[Test] public function getFoundUnexpectedArchiveArtifactsOnNonValidatedArchiveThrowsExpectedException(): void { $archive = new Archive($this->temporaryDirectory, 'archive-tmp'); @@ -47,9 +46,7 @@ public function getFoundUnexpectedArchiveArtifactsOnNonValidatedArchiveThrowsExp (new Validator($archive))->getFoundUnexpectedArchiveArtifacts(); } - /** - * @test - */ + #[Test] public function ranValidateAllowsAccessorCallOnUnexpectedArchiveArtifacts(): void { $unexpectedArchiveArtifacts = ['mock-foo']; @@ -72,9 +69,7 @@ public function ranValidateAllowsAccessorCallOnUnexpectedArchiveArtifacts(): voi ); } - /** - * @test - */ + #[Test] public function findingUnexpectedArchiveArtifactsFailsValidation(): void { $unexpectedArchiveArtifacts = ['mock-foo']; diff --git a/tests/ArchiveTest.php b/tests/ArchiveTest.php index 0f46a80..a3d648f 100755 --- a/tests/ArchiveTest.php +++ b/tests/ArchiveTest.php @@ -5,6 +5,9 @@ namespace Stolt\LeanPackage\Tests; use Mockery; +use PHPUnit\Framework\Attributes\Group; +use PHPUnit\Framework\Attributes\Test; +use PHPUnit\Framework\Attributes\Ticket; use Stolt\LeanPackage\Archive; use Stolt\LeanPackage\Exceptions\GitHeadNotAvailable; use Stolt\LeanPackage\Exceptions\GitNotAvailable; @@ -29,9 +32,7 @@ protected function tearDown(): void } } - /** - * @test - */ + #[Test] public function filenameHasAnAccessor(): void { $analyser = new Archive(__DIR__, 'foo'); @@ -42,26 +43,22 @@ public function filenameHasAnAccessor(): void $this->assertEquals($expectedFilename, $analyser->getFilename()); } - /** - * @test - */ + + #[Test] public function isGitCommandAvailableReturnsFalseOnNonExistingCommand(): void { $this->assertFalse((new Archive(__DIR__, 'foo'))->isGitCommandAvailable('no-way-i-exists')); } - /** - * @test - * @group travis-ci-exclude - */ + #[Test] + #[Group('travis-ci-exclude')] public function isGitCommandAvailableReturnsTrueOnExistingCommand(): void { $this->assertTrue((new Archive(__DIR__, 'foo'))->isGitCommandAvailable('ping')); } - /** - * @test - */ + + #[Test] public function hasHeadThrowsExpectedExceptionWhenGitCommandNotAvailable(): void { $mock = Mockery::mock( @@ -80,9 +77,7 @@ public function hasHeadThrowsExpectedExceptionWhenGitCommandNotAvailable(): void $mock->hasHead(); } - /** - * @test - */ + #[Test] public function createArchiveThrowsExpectedExceptionWhenNoGitHeadPresent(): void { $mock = Mockery::mock( @@ -101,9 +96,7 @@ public function createArchiveThrowsExpectedExceptionWhenNoGitHeadPresent(): void $mock->createArchive(); } - /** - * @test - */ + #[Test] public function removeArchiveRemovesArchive(): void { $this->createTemporaryFiles( @@ -116,9 +109,7 @@ public function removeArchiveRemovesArchive(): void $this->assertTrue($removed); } - /** - * @test - */ + #[Test] public function removeArchiveRemovesArchiveReturnsFalseOnNonExtistentFile(): void { $removed = (new Archive($this->temporaryDirectory, 'archive-nonexistent')) @@ -127,9 +118,7 @@ public function removeArchiveRemovesArchiveReturnsFalseOnNonExtistentFile(): voi $this->assertFalse($removed); } - /** - * @test - */ + #[Test] public function compareArchiveReturnsExpectedFoundUnexpectedArtifacts(): void { $unexpectedArtifacts = [ @@ -147,9 +136,7 @@ public function compareArchiveReturnsExpectedFoundUnexpectedArtifacts(): void $this->assertEquals($unexpectedArtifacts, $foundUnexpectedArtifacts); } - /** - * @test - */ + #[Test] public function compareArchiveReturnsNoFoundUnexpectedArtifactsOnLeanArchive(): void { $fixturesDirectory = __DIR__ . DIRECTORY_SEPARATOR . 'fixtures'; @@ -167,10 +154,8 @@ public function compareArchiveReturnsNoFoundUnexpectedArtifactsOnLeanArchive(): $this->assertEquals([], $foundUnexpectedArtifacts); } - /** - * @test - * @ticket 15 (https://github.com/raphaelstolt/lean-package-validator/issues/15) - */ + #[Test] + #[Ticket('https://github.com/raphaelstolt/lean-package-validator/issues/15')] public function compareArchiveThrowsExpectedExceptionWhenLicenseFileIsMissing(): void { $fixturesDirectory = __DIR__ . DIRECTORY_SEPARATOR . 'fixtures'; @@ -186,10 +171,8 @@ public function compareArchiveThrowsExpectedExceptionWhenLicenseFileIsMissing(): $archive->compareArchive([]); } - /** - * @test - * @ticket 15 (https://github.com/raphaelstolt/lean-package-validator/issues/15) - */ + #[Test] + #[Ticket('https://github.com/raphaelstolt/lean-package-validator/issues/15')] public function compareArchiveDoesNotThrowsExceptionOnPresentLicenseFile(): void { $fixturesDirectory = __DIR__ . DIRECTORY_SEPARATOR . 'fixtures'; @@ -202,9 +185,7 @@ public function compareArchiveDoesNotThrowsExceptionOnPresentLicenseFile(): void $archive->compareArchive([]); } - /** - * @test - */ + #[Test] public function getUnexpectedArchiveArtifactsDelegatesWork(): void { $mock = Mockery::mock( diff --git a/tests/Commands/InitCommandTest.php b/tests/Commands/InitCommandTest.php index dae247e..19fe0dc 100644 --- a/tests/Commands/InitCommandTest.php +++ b/tests/Commands/InitCommandTest.php @@ -6,6 +6,8 @@ use phpmock\functions\FixedValueFunction; use phpmock\MockBuilder; +use PHPUnit\Framework\Attributes\RunInSeparateProcess; +use PHPUnit\Framework\Attributes\Test; use Stolt\LeanPackage\Analyser; use Stolt\LeanPackage\Commands\InitCommand; use Stolt\LeanPackage\Presets\Finder; @@ -18,7 +20,7 @@ class InitCommandTest extends TestCase { /** - * @var \Symfony\Component\Console\Application + * @var Application */ private $application; @@ -46,9 +48,7 @@ protected function tearDown(): void } } - /** - * @test - */ + #[Test] public function createsExpectedDefaultLpvFile(): void { $command = $this->application->find('init'); @@ -104,10 +104,8 @@ public function createsExpectedDefaultLpvFile(): void $this->assertEquals($expectedDefaultLpvFileContent, \file_get_contents($expectedDefaultLpvFile)); } - /** - * @test - * @runInSeparateProcess - */ + #[Test] + #[RunInSeparateProcess] public function failingInitReturnsExpectedStatusCode(): void { $builder = new MockBuilder(); @@ -136,9 +134,7 @@ public function failingInitReturnsExpectedStatusCode(): void $mock->disable(); } - /** - * @test - */ + #[Test] public function existingDefaultLpvFileIsNotOverwritten(): void { $defaultLpvFile = $this->temporaryDirectory @@ -162,9 +158,7 @@ public function existingDefaultLpvFileIsNotOverwritten(): void $this->assertTrue($commandTester->getStatusCode() !== 0); } - /** - * @test - */ + #[Test] public function usingANonAvailablePresetShowsWarning(): void { $expectedDisplay = <<assertTrue($commandTester->getStatusCode() !== 0); } - /** - * @test - */ + #[Test] public function verboseOutputIsAvailableWhenDesired(): void { $defaultLpvFile = $this->temporaryDirectory @@ -213,9 +205,7 @@ public function verboseOutputIsAvailableWhenDesired(): void $this->assertTrue($commandTester->getStatusCode() !== 0); } - /** - * @test - */ + #[Test] public function existingDefaultLpvFileIsOverwrittenWhenDesired(): void { $expectedDefaultLpvFile = $this->temporaryDirectory @@ -242,7 +232,7 @@ public function existingDefaultLpvFileIsOverwrittenWhenDesired(): void } /** - * @return \Symfony\Component\Console\Application + * @return Application */ protected function getApplication(): Application { diff --git a/tests/Commands/ValidateCommandTest.php b/tests/Commands/ValidateCommandTest.php index a3f313d..c834d87 100644 --- a/tests/Commands/ValidateCommandTest.php +++ b/tests/Commands/ValidateCommandTest.php @@ -7,6 +7,10 @@ use Mockery; use Mockery\MockInterface; use phpmock\MockBuilder; +use PHPUnit\Framework\Attributes\DataProvider; +use PHPUnit\Framework\Attributes\Group; +use PHPUnit\Framework\Attributes\Test; +use PHPUnit\Framework\Attributes\Ticket; use Stolt\LeanPackage\Analyser; use Stolt\LeanPackage\Archive; use Stolt\LeanPackage\Archive\Validator; @@ -22,9 +26,9 @@ class ValidateCommandTest extends TestCase { /** - * @var \Symfony\Component\Console\Application + * @var Application */ - private $application; + private Application $application; /** * Set up test environment. @@ -50,9 +54,7 @@ protected function tearDown(): void } } - /** - * @test - */ + #[Test] public function validateOnNonExistentGitattributesFilesSuggestsCreation(): void { $artifactFilenames = [ @@ -95,9 +97,7 @@ public function validateOnNonExistentGitattributesFilesSuggestsCreation(): void $this->assertTrue($commandTester->getStatusCode() > 0); } - /** - * @test - */ + #[Test] public function validateOnNonExistentGitattributesFilesSuggestsCreationWithAlignment(): void { $artifactFilenames = [ @@ -141,10 +141,8 @@ public function validateOnNonExistentGitattributesFilesSuggestsCreationWithAlign $this->assertTrue($commandTester->getStatusCode() > 0); } - /** - * @test - * @ticket 39 (https://github.com/raphaelstolt/lean-package-validator/issues/39) - */ + #[Test] + #[Ticket('https://github.com/raphaelstolt/lean-package-validator/issues/39')] public function showsDifferenceBetweenActualAndExpectedGitattributesContent(): void { if ((new OsHelper())->isWindows()) { @@ -184,9 +182,7 @@ public function showsDifferenceBetweenActualAndExpectedGitattributesContent(): v $this->assertTrue($commandTester->getStatusCode() > 0); } - /** - * @test - */ + #[Test] public function filesInGlobalGitignoreAreExportIgnored(): void { $analyserMock = Mockery::mock(Analyser::class)->makePartial(); @@ -255,10 +251,8 @@ public function filesInGlobalGitignoreAreExportIgnored(): void $this->assertTrue($commandTester->getStatusCode() > 0); } - /** - * @test - * @ticket 16 (https://github.com/raphaelstolt/lean-package-validator/issues/16) - */ + #[Test] + #[Ticket('https://github.com/raphaelstolt/lean-package-validator/issues/16')] public function gitattributesFileWithNoExportIgnoresContentShowsExpectedContent(): void { $analyserMock = Mockery::mock(Analyser::class)->makePartial(); @@ -334,10 +328,8 @@ public function gitattributesFileWithNoExportIgnoresContentShowsExpectedContent( $this->assertTrue($commandTester->getStatusCode() > 0); } - /** - * @test - * @ticket 13 (https://github.com/raphaelstolt/lean-package-validator/issues/13) - */ + #[Test] + #[Ticket('https://github.com/raphaelstolt/lean-package-validator/issues/13')] public function gitattributesIsInSuggestedFileContent(): void { $artifactFilenames = [ @@ -376,10 +368,8 @@ public function gitattributesIsInSuggestedFileContent(): void $this->assertTrue($commandTester->getStatusCode() > 0); } - /** - * @test - * @ticket 15 (https://github.com/raphaelstolt/lean-package-validator/issues/15) - */ + #[Test] + #[Ticket('https://github.com/raphaelstolt/lean-package-validator/issues/15')] public function licenseIsInSuggestedFileContentPerDefault(): void { $artifactFilenames = [ @@ -420,10 +410,8 @@ public function licenseIsInSuggestedFileContentPerDefault(): void $this->assertTrue($commandTester->getStatusCode() > 0); } - /** - * @test - * @ticket 15 (https://github.com/raphaelstolt/lean-package-validator/issues/15) - */ + #[Test] + #[Ticket('https://github.com/raphaelstolt/lean-package-validator/issues/15')] public function licenseIsNotInSuggestedFileContent(): void { $artifactFilenames = [ @@ -464,11 +452,9 @@ public function licenseIsNotInSuggestedFileContent(): void $this->assertTrue($commandTester->getStatusCode() > 0); } - /** - * @test - * @group glob - * @ticket 15 (https://github.com/raphaelstolt/lean-package-validator/issues/15) - */ + #[Test] + #[Group('glob')] + #[Ticket('https://github.com/raphaelstolt/lean-package-validator/issues/13')] public function licenseIsNotInSuggestedFileContentWithCustomGlobPattern(): void { $artifactFilenames = [ @@ -510,10 +496,8 @@ public function licenseIsNotInSuggestedFileContentWithCustomGlobPattern(): void $this->assertTrue($commandTester->getStatusCode() > 0); } - /** - * @test - * @ticket 15 (https://github.com/raphaelstolt/lean-package-validator/issues/15) - */ + #[Test] + #[Ticket('https://github.com/raphaelstolt/lean-package-validator/issues/15')] public function presentExportIgnoredLicenseWithKeepLicenseOptionInvalidatesResult(): void { $artifactFilenames = [ @@ -563,10 +547,8 @@ public function presentExportIgnoredLicenseWithKeepLicenseOptionInvalidatesResul $this->assertTrue($commandTester->getStatusCode() > 0); } - /** - * @test - * @ticket 15 (https://github.com/raphaelstolt/lean-package-validator/issues/15) - */ + #[Test] + #[Ticket('https://github.com/raphaelstolt/lean-package-validator/issues/15')] public function archiveWithoutLicenseFileIsConsideredInvalid(): void { $mock = Mockery::mock( @@ -611,10 +593,8 @@ public function archiveWithoutLicenseFileIsConsideredInvalid(): void $this->assertTrue($commandTester->getStatusCode() > 0); } - /** - * @test - * @ticket 15 (https://github.com/raphaelstolt/lean-package-validator/issues/15) - */ + #[Test] + #[Ticket('https://github.com/raphaelstolt/lean-package-validator/issues/15')] public function archiveWithLicenseFileIsConsideredValid(): void { $mock = Mockery::mock( @@ -658,9 +638,7 @@ public function archiveWithLicenseFileIsConsideredValid(): void $commandTester->assertCommandIsSuccessful(); } - /** - * @test - */ + #[Test] public function failingGitattributesFilesCreationReturnsExpectedStatusCode(): void { $artifactFilenames = ['CONDUCT.md']; @@ -703,9 +681,7 @@ function () { $mock->disable(); } - /** - * @test - */ + #[Test] public function validateOnNonExistentGitattributesFilesWithCreationOptionCreatesOneWithoutHeader(): void { $artifactFilenames = ['CONDUCT.md']; @@ -744,9 +720,7 @@ public function validateOnNonExistentGitattributesFilesWithCreationOptionCreates ); } - /** - * @test - */ + #[Test] public function validateOnNonExistentGitattributesFilesWithCreationOptionCreatesOne(): void { $artifactFilenames = ['CONDUCT.md']; @@ -786,9 +760,7 @@ public function validateOnNonExistentGitattributesFilesWithCreationOptionCreates ); } - /** - * @test - */ + #[Test] public function validateOnNonExistentGitattributesFilesWithCreationOptionCreatesOneWithAlignment(): void { if ((new OsHelper())->isWindows()) { @@ -845,9 +817,7 @@ public function validateOnNonExistentGitattributesFilesWithCreationOptionCreates ); } - /** - * @test - */ + #[Test] public function validGitattributesReturnsExpectedStatusCode(): void { $artifactFilenames = [ @@ -889,9 +859,7 @@ public function validGitattributesReturnsExpectedStatusCode(): void $commandTester->assertCommandIsSuccessful(); } - /** - * @test - */ + #[Test] public function invalidGitattributesReturnsExpectedStatusCode(): void { $artifactFilenames = [ @@ -934,10 +902,8 @@ public function invalidGitattributesReturnsExpectedStatusCode(): void $this->assertTrue($commandTester->getStatusCode() > 0); } - /** - * @test - * @group glob - */ + #[Test] + #[Group('glob')] public function optionalGlobPatternIsApplied(): void { $artifactFilenames = [ @@ -983,10 +949,8 @@ public function optionalGlobPatternIsApplied(): void $this->assertTrue($commandTester->getStatusCode() > 0); } - /** - * @test - * @group glob - */ + #[Test] + #[Group('glob')] public function usageOfInvalidGlobFailsValidation(): void { $failingGlobPattern = '{single-pattern*}'; @@ -1007,11 +971,9 @@ public function usageOfInvalidGlobFailsValidation(): void $this->assertTrue($commandTester->getStatusCode() > 0); } - /** - * @test - * @group glob - * @ticket 38 (https://github.com/raphaelstolt/lean-package-validator/issues/38) - */ + #[Test] + #[Group('glob')] + #[Ticket('https://github.com/raphaelstolt/lean-package-validator/issues/38')] public function missingGlobPatternProducesUserFriendlyErrorMessage(): void { $missingGlobPattern = ''; @@ -1032,9 +994,7 @@ public function missingGlobPatternProducesUserFriendlyErrorMessage(): void $this->assertTrue($commandTester->getStatusCode() > 0); } - /** - * @test - */ + #[Test] public function overwriteOptionOnNonExistentGitattributesFileImplicatesCreate(): void { $artifactFilenames = ['CONDUCT.md']; @@ -1074,9 +1034,7 @@ public function overwriteOptionOnNonExistentGitattributesFileImplicatesCreate(): ); } - /** - * @test - */ + #[Test] public function leanArchiveIsConsideredLean(): void { $mock = Mockery::mock( @@ -1113,9 +1071,7 @@ public function leanArchiveIsConsideredLean(): void $commandTester->assertCommandIsSuccessful(); } - /** - * @test - */ + #[Test] public function nonLeanArchiveIsNotConsideredLeanPlural(): void { $mock = Mockery::mock( @@ -1162,9 +1118,7 @@ public function nonLeanArchiveIsNotConsideredLeanPlural(): void $this->assertTrue($commandTester->getStatusCode() > 0); } - /** - * @test - */ + #[Test] public function nonLeanArchiveIsNotConsideredLeanSingular(): void { $mock = Mockery::mock( @@ -1210,9 +1164,7 @@ public function nonLeanArchiveIsNotConsideredLeanSingular(): void $this->assertTrue($commandTester->getStatusCode() > 0); } - /** - * @test - */ + #[Test] public function impossibilityToResolveExpectedGitattributesFileContentIsInfoed(): void { $mock = Mockery::mock(Analyser::class)->makePartial(); @@ -1245,9 +1197,7 @@ public function impossibilityToResolveExpectedGitattributesFileContentIsInfoed() $this->assertTrue($commandTester->getStatusCode() > 0); } - /** - * @test - */ + #[Test] public function invalidDirectoryAgumentReturnsExpectedStatusCode(): void { $nonExistentDirectoryOrFile = WORKING_DIRECTORY @@ -1270,10 +1220,8 @@ public function invalidDirectoryAgumentReturnsExpectedStatusCode(): void $this->assertTrue($commandTester->getStatusCode() > 0); } - /** - * @test - * @ticket 44 (https://github.com/raphaelstolt/lean-package-validator/issues/44) - */ + #[Test] + #[Ticket('https://github.com/raphaelstolt/lean-package-validator/issues/44')] public function incompleteGitattributesFileIsOverwrittenWithAlignment(): void { if ((new OsHelper())->isWindows()) { @@ -1378,10 +1326,8 @@ public function incompleteGitattributesFileIsOverwrittenWithAlignment(): void ); } - /** - * @test - * @ticket 41 (https://github.com/raphaelstolt/lean-package-validator/issues/41) - */ + #[Test] + #[Ticket('https://github.com/raphaelstolt/lean-package-validator/issues/41')] public function staleExportIgnoresAreConsideredAsInvalid(): void { $gitattributesContent = <<assertTrue($commandTester->getStatusCode() > 0); } - /** - * @test - * @ticket 8 (https://github.com/raphaelstolt/lean-package-validator/issues/8) - * @dataProvider optionProvider - * @param string $option - */ + #[Test] + #[Ticket('https://github.com/raphaelstolt/lean-package-validator/issues/8')] + #[DataProvider('optionProvider')] public function incompleteGitattributesFileIsOverwritten(string $option): void { $gitattributesContent = <<disable(); } - /** - * @test - * @ticket 22 (https://github.com/raphaelstolt/lean-package-validator/issues/22) - */ + #[Test] + #[Ticket('https://github.com/raphaelstolt/lean-package-validator/issues/22')] public function nonExistentArtifactsWhichAreExportIgnoredAreIgnoredOnComparison(): void { $artifactFilenames = [ @@ -1589,9 +1528,7 @@ public function nonExistentArtifactsWhichAreExportIgnoredAreIgnoredOnComparison( $commandTester->assertCommandIsSuccessful(); } - /** - * @test - */ + #[Test] public function strictAlignmentOfExportIgnoresCanBeEnforced(): void { $artifactFilenames = [ @@ -1641,9 +1578,7 @@ public function strictAlignmentOfExportIgnoresCanBeEnforced(): void $this->assertTrue($commandTester->getStatusCode() > 0); } - /** - * @test - */ + #[Test] public function strictAlignmentAndOrderOfExportIgnoresCanBeEnforced(): void { $artifactFilenames = [ @@ -1694,10 +1629,8 @@ public function strictAlignmentAndOrderOfExportIgnoresCanBeEnforced(): void $this->assertTrue($commandTester->getStatusCode() > 0); } - /** - * @test - * @ticket 6 (https://github.com/raphaelstolt/lean-package-validator/issues/6) - */ + #[Test] + #[Ticket('https://github.com/raphaelstolt/lean-package-validator/issues/6')] public function strictOrderOfExportIgnoresCanBeEnforced(): void { $artifactFilenames = [ @@ -1748,11 +1681,9 @@ public function strictOrderOfExportIgnoresCanBeEnforced(): void $this->assertTrue($commandTester->getStatusCode() > 0); } - /** - * @test - * @group glob - * @ticket 9 (https://github.com/raphaelstolt/lean-package-validator/issues/9) - */ + #[Test] + #[Group('glob')] + #[Ticket('https://github.com/raphaelstolt/lean-package-validator/issues/9')] public function givenGlobPatternTakesPrecedenceOverDefaultGlobPatternFile(): void { $artifactFilenames = [ @@ -1806,11 +1737,9 @@ public function givenGlobPatternTakesPrecedenceOverDefaultGlobPatternFile(): voi $commandTester->assertCommandIsSuccessful(); } - /** - * @test - * @group glob - * @ticket 9 (https://github.com/raphaelstolt/lean-package-validator/issues/9) - */ + #[Test] + #[Group('glob')] + #[Ticket('https://github.com/raphaelstolt/lean-package-validator/issues/9')] public function presentGlobPatternFileTakesPrecedenceOverDefaultGlobPattern(): void { $artifactFilenames = [ @@ -1866,11 +1795,9 @@ public function presentGlobPatternFileTakesPrecedenceOverDefaultGlobPattern(): v $commandTester->assertCommandIsSuccessful(); } - /** - * @test - * @group glob - * @ticket 35 (https://github.com/raphaelstolt/lean-package-validator/issues/35) - */ + #[Test] + #[Group('glob')] + #[Ticket('https://github.com/raphaelstolt/lean-package-validator/issues/35')] public function presentLpvPatternFileIsUsed(): void { $artifactFilenames = [ @@ -1921,11 +1848,9 @@ public function presentLpvPatternFileIsUsed(): void $commandTester->assertCommandIsSuccessful(); } - /** - * @test - * @group glob - * @ticket 9 (https://github.com/raphaelstolt/lean-package-validator/issues/9) - */ + #[Test] + #[Group('glob')] + #[Ticket('https://github.com/raphaelstolt/lean-package-validator/issues/9')] public function providedNonExistentGlobPatternFileFailsValidation(): void { $gitattributesContent = <<assertTrue($commandTester->getStatusCode() > 0); } - /** - * @test - * @group glob - * @ticket 9 (https://github.com/raphaelstolt/lean-package-validator/issues/9) - */ + #[Test] + #[Group('glob')] + #[Ticket('https://github.com/raphaelstolt/lean-package-validator/issues/9')] public function providedInvalidGlobPatternFileFailsValidation(): void { $gitattributesContent = <<assertTrue($commandTester->getStatusCode() > 0); } - /** - * @test - * @ticket 4 (https://github.com/raphaelstolt/lean-package-validator/issues/4) - */ + #[Test] + #[Ticket('https://github.com/raphaelstolt/lean-package-validator/issues/4')] public function precedingSlashesInExportIgnorePatternsRaiseAWarning(): void { $artifactFilenames = [ @@ -2046,10 +1967,8 @@ public function precedingSlashesInExportIgnorePatternsRaiseAWarning(): void $commandTester->assertCommandIsSuccessful(); } - /** - * @test - * @ticket 12 (https://github.com/raphaelstolt/lean-package-validator/issues/12) - */ + #[Test] + #[Ticket('https://github.com/raphaelstolt/lean-package-validator/issues/12')] public function missingTextAutoConfigurationRaisesAWarning(): void { $artifactFilenames = [ @@ -2091,10 +2010,8 @@ public function missingTextAutoConfigurationRaisesAWarning(): void $commandTester->assertCommandIsSuccessful(); } - /** - * @test - * @ticket 17 (https://github.com/raphaelstolt/lean-package-validator/issues/17) - */ + #[Test] + #[Ticket('https://github.com/raphaelstolt/lean-package-validator/issues/17')] public function gitignoredFilesAreExcludedFromValidation(): void { $artifactFilenames = [ @@ -2200,7 +2117,7 @@ protected function getApplicationWithMockedArchiveValidator(MockInterface $mocke } /** - * @return \Symfony\Component\Console\Application + * @return Application */ protected function getApplication(): Application { diff --git a/tests/Helpers/StrTest.php b/tests/Helpers/StrTest.php index 670b214..fc4d25e 100644 --- a/tests/Helpers/StrTest.php +++ b/tests/Helpers/StrTest.php @@ -4,15 +4,15 @@ namespace Stolt\LeanPackage\Tests\Helpers; +use PHPUnit\Framework\Attributes\Group; +use PHPUnit\Framework\Attributes\Test; use PHPUnit\Framework\TestCase; use Stolt\LeanPackage\Helpers\Str as OsHelper; class StrTest extends TestCase { - /** - * @test - * @group unit - */ + #[Test] + #[Group('unit')] public function canDetermineIfWindowsOrNot(): void { $osHelper = new OsHelper(); diff --git a/tests/Presets/FinderTest.php b/tests/Presets/FinderTest.php index 3c8a99d..76cd28b 100644 --- a/tests/Presets/FinderTest.php +++ b/tests/Presets/FinderTest.php @@ -4,6 +4,8 @@ namespace Stolt\LeanPackage\Tests\Presets; +use PHPUnit\Framework\Attributes\DataProvider; +use PHPUnit\Framework\Attributes\Test; use Stolt\LeanPackage\Exceptions\PresetNotAvailable; use Stolt\LeanPackage\Presets\Finder; use Stolt\LeanPackage\Presets\PhpPreset; @@ -11,26 +13,22 @@ class FinderTest extends TestCase { - /** - * @test - */ + #[Test] public function findsExpectedPresets(): void { $finder = new Finder(new PhpPreset()); - + $actualPresets = $finder->getAvailablePresets(); $expectedPresets = ['Php', 'Go', 'Python']; - + \sort($actualPresets); \sort($expectedPresets); $this->assertSame($expectedPresets, $actualPresets); } - /** - * @test - * @dataProvider languageProvider - */ + #[Test] + #[DataProvider('languageProvider')] public function findsExpectedPresetGlobByLanguageNames(string $languageName): void { $finder = new Finder(new PhpPreset()); @@ -38,9 +36,7 @@ public function findsExpectedPresetGlobByLanguageNames(string $languageName): vo $this->assertTrue(\is_array($presetGlob)); } - /** - * @test - */ + #[Test] public function forNonAvailableLanguagePresetItThrowsExpectedException(): void { $this->expectException(PresetNotAvailable::class); @@ -62,5 +58,4 @@ public static function languageProvider(): array ['Go'] ]; } - } From f15452d04a4164c4b35fb1b6ad10b93daf22eb23 Mon Sep 17 00:00:00 2001 From: Raphael Stolt Date: Fri, 14 Jun 2024 16:08:38 +0200 Subject: [PATCH 087/152] Aligns mock setup --- tests/Commands/ValidateCommandTest.php | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/tests/Commands/ValidateCommandTest.php b/tests/Commands/ValidateCommandTest.php index c834d87..cadd121 100644 --- a/tests/Commands/ValidateCommandTest.php +++ b/tests/Commands/ValidateCommandTest.php @@ -6,6 +6,7 @@ use Mockery; use Mockery\MockInterface; +use phpmock\functions\FixedValueFunction; use phpmock\MockBuilder; use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\Attributes\Group; @@ -651,11 +652,7 @@ public function failingGitattributesFilesCreationReturnsExpectedStatusCode(): vo $builder = new MockBuilder(); $builder->setNamespace('Stolt\LeanPackage\Commands') ->setName('file_put_contents') - ->setFunction( - function () { - return false; - } - ); + ->setFunctionProvider(new FixedValueFunction(false)); $mock = $builder->build(); $mock->enable(); @@ -1454,11 +1451,7 @@ public function failingGitattributesFilesOverwriteReturnsExpectedStatusCode(): v $builder = new MockBuilder(); $builder->setNamespace('Stolt\LeanPackage\Commands') ->setName('file_put_contents') - ->setFunction( - function () { - return false; - } - ); + ->setFunctionProvider(new FixedValueFunction(false)); $mock = $builder->build(); $mock->enable(); From addae088f7667c65565777ab5ffeb5deac756554 Mon Sep 17 00:00:00 2001 From: Raphael Stolt Date: Fri, 14 Jun 2024 17:23:58 +0200 Subject: [PATCH 088/152] Fixes from static code analysis --- phpstan.neon.dist | 8 ++------ tests/TestCase.php | 6 +++--- 2 files changed, 5 insertions(+), 9 deletions(-) diff --git a/phpstan.neon.dist b/phpstan.neon.dist index a0f27d7..3df0d78 100644 --- a/phpstan.neon.dist +++ b/phpstan.neon.dist @@ -1,20 +1,16 @@ parameters: - level: 4 + level: 7 paths: - src - tests reportUnmatchedIgnoredErrors: false - checkMissingIterableValueType: false ignoreErrors: + - identifier: missingType.iterableValue - '#Constant WORKING_DIRECTORY not found.#' - '#Mockery\\MockInterface#' - '#Mockery\\LegacyMockInterface#' - '#Mockery\\ExpectationInterface#' - '#array_filter#' - - '#cannot be cast to string#' - - '#Cannot cast#' - '#is never read#' - - '#Comparison operation ">="#' - - '#unresolvable type.#' - '#TMock#' - '#unknown class#' diff --git a/tests/TestCase.php b/tests/TestCase.php index 322e0fc..a394281 100755 --- a/tests/TestCase.php +++ b/tests/TestCase.php @@ -100,7 +100,7 @@ protected function createTemporaryGitattributesFile($content): bool $bytesWritten = file_put_contents($temporaryGitattributesFile, $content); - return $bytesWritten >= 0; + return $bytesWritten > 0; } /** @@ -116,7 +116,7 @@ protected function createTemporaryGitignoreFile($content) . DIRECTORY_SEPARATOR . '.gitignore'; - return file_put_contents($temporaryGitignoreFile, $content) >= 0; + return file_put_contents($temporaryGitignoreFile, $content) > 0; } /** @@ -132,6 +132,6 @@ protected function createTemporaryGlobPatternFile($content) . DIRECTORY_SEPARATOR . '.lpv'; - return file_put_contents($temporaryLpvFile, $content) >= 0; + return file_put_contents($temporaryLpvFile, $content) > 0; } } From bca142da8be063da5d192e66beec844e0c851751 Mon Sep 17 00:00:00 2001 From: Raphael Stolt Date: Wed, 26 Jun 2024 13:04:13 +0200 Subject: [PATCH 089/152] Adds attestation build step --- .github/workflows/distribute.yml | 16 +++++++++++++--- CHANGELOG.md | 4 ++++ 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/.github/workflows/distribute.yml b/.github/workflows/distribute.yml index 34dcab6..dd9594c 100644 --- a/.github/workflows/distribute.yml +++ b/.github/workflows/distribute.yml @@ -6,10 +6,15 @@ on: - 'v*' jobs: - tests: + build: name: distribute runs-on: ubuntu-latest + permissions: + id-token: write + contents: write + attestations: write + strategy: fail-fast: true matrix: @@ -38,8 +43,13 @@ jobs: - name: Check generated PHAR run: bin/lean-package-validator.phar --version - - name: Create Release - uses: softprops/action-gh-release@v1 + - name: Create release + uses: softprops/action-gh-release@v2 if: startsWith(github.ref, 'refs/tags/') with: files: bin/lean-package-validator.phar + + - name: Create attestation + uses: actions/attest-build-provenance@v1 + with: + subject-path: bin/lean-package-validator.phar diff --git a/CHANGELOG.md b/CHANGELOG.md index 00e87bc..b7434b7 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,10 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/) and this p ## [Unreleased] +### Added + +- Attested dist builds. + ## [v4.0.2] - 2024-05-13 ### Added From 8751fa77172a70ae2fc1014c05f26edb7c6e2051 Mon Sep 17 00:00:00 2001 From: Raphael Stolt Date: Fri, 28 Jun 2024 13:15:10 +0200 Subject: [PATCH 090/152] Updates distribute workflow to latest box release --- .github/workflows/distribute.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/distribute.yml b/.github/workflows/distribute.yml index dd9594c..6991c13 100644 --- a/.github/workflows/distribute.yml +++ b/.github/workflows/distribute.yml @@ -34,7 +34,7 @@ jobs: run: composer install --no-progress --prefer-dist --optimize-autoloader - name: Install Box Phar bundler - run: wget --quiet https://github.com/box-project/box/releases/download/4.3.8/box.phar && sudo mv box.phar /usr/bin/box && sudo chmod u+x /usr/bin/box + run: wget --quiet https://github.com/box-project/box/releases/download/4.6.1/box.phar && sudo mv box.phar /usr/bin/box && sudo chmod u+x /usr/bin/box shell: bash - name: Build PHAR From 2bbff246de30c4a5a6a02d5bfc3d5f0347cfd654 Mon Sep 17 00:00:00 2001 From: Raphael Stolt Date: Mon, 1 Jul 2024 11:24:59 +0200 Subject: [PATCH 091/152] Adds minor code tweaks --- src/Commands/InitCommand.php | 19 +++++----- src/Commands/ValidateCommand.php | 65 +++++++++++++++++--------------- src/Presets/Finder.php | 6 +-- 3 files changed, 47 insertions(+), 43 deletions(-) diff --git a/src/Commands/InitCommand.php b/src/Commands/InitCommand.php index 6b85a11..adfbb0e 100644 --- a/src/Commands/InitCommand.php +++ b/src/Commands/InitCommand.php @@ -5,6 +5,7 @@ namespace Stolt\LeanPackage\Commands; use Stolt\LeanPackage\Analyser; +use Stolt\LeanPackage\Exceptions\PresetNotAvailable; use Stolt\LeanPackage\Presets\Finder; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Input\InputArgument; @@ -19,12 +20,12 @@ class InitCommand extends Command /** * Package analyser. * - * @var \Stolt\LeanPackage\Analyser + * @var Analyser */ - protected $analyser; + protected Analyser $analyser; /** - * @var \Stolt\LeanPackage\Presets\Finder + * @var Finder */ private Finder $finder; @@ -44,7 +45,7 @@ public function __construct(Analyser $analyser) * * @return void */ - protected function configure() + protected function configure(): void { $this->analyser->setDirectory(WORKING_DIRECTORY); $this->setName('init'); @@ -97,9 +98,10 @@ private function formatAvailablePresetDefinitionsForDescription(array $presets): /** * Execute command. * - * @param \Symfony\Component\Console\Input\InputInterface $input - * @param \Symfony\Component\Console\Output\OutputInterface $output + * @param InputInterface $input + * @param OutputInterface $output * + * @throws PresetNotAvailable * @return integer */ protected function execute(InputInterface $input, OutputInterface $output): int @@ -136,11 +138,8 @@ protected function execute(InputInterface $input, OutputInterface $output): int return Command::FAILURE; } - $defaultGlobPattern = $this->analyser->getDefaultGlobPattern(); - $globPatternFromPreset = false; - if ($chosenPreset && \in_array(\strtolower($chosenPreset), \array_map('strtolower', $this->finder->getAvailablePresets()))) { - $verboseOutput = '+ Loadind preset ' . $chosenPreset . '.'; + $verboseOutput = '+ Loading preset ' . $chosenPreset . '.'; $output->writeln($verboseOutput, OutputInterface::VERBOSITY_VERBOSE); $globPatternFromPreset = true; $defaultGlobPattern = $this->finder->getPresetGlobByLanguageName($chosenPreset); diff --git a/src/Commands/ValidateCommand.php b/src/Commands/ValidateCommand.php index 13007f2..55cad5a 100755 --- a/src/Commands/ValidateCommand.php +++ b/src/Commands/ValidateCommand.php @@ -9,12 +9,14 @@ use SplFileInfo; use Stolt\LeanPackage\Analyser; use Stolt\LeanPackage\Archive\Validator; +use Stolt\LeanPackage\Exceptions\GitArchiveNotValidatedYet; use Stolt\LeanPackage\Exceptions\GitattributesCreationFailed; +use Stolt\LeanPackage\Exceptions\GitHeadNotAvailable; +use Stolt\LeanPackage\Exceptions\GitNotAvailable; use Stolt\LeanPackage\Exceptions\InvalidGlobPattern; use Stolt\LeanPackage\Exceptions\InvalidGlobPatternFile; use Stolt\LeanPackage\Exceptions\NoLicenseFilePresent; use Stolt\LeanPackage\Exceptions\NonExistentGlobPatternFile; -use Stolt\LeanPackage\Generator; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Input\InputInterface; @@ -28,21 +30,21 @@ class ValidateCommand extends Command * * @var string */ - protected $defaultLpvFile = WORKING_DIRECTORY . DIRECTORY_SEPARATOR . '.lpv'; + protected string $defaultLpvFile = WORKING_DIRECTORY . DIRECTORY_SEPARATOR . '.lpv'; /** * Package analyser. * - * @var \Stolt\LeanPackage\Analyser + * @var Analyser */ - protected $analyser; + protected Analyser $analyser; /** * Archive validator. * - * @var \Stolt\LeanPackage\Archive\Validator + * @var Validator */ - protected $archiveValidator; + protected Validator $archiveValidator; /** * @param Analyser $analyser @@ -61,7 +63,7 @@ public function __construct(Analyser $analyser, Validator $archiveValidator) * * @return void */ - protected function configure() + protected function configure(): void { $this->analyser->setDirectory(WORKING_DIRECTORY); $this->setName('validate'); @@ -81,7 +83,7 @@ protected function configure() $createDescription = 'Create a .gitattributes file if not present'; $enforceStrictOrderDescription = 'Enforce a strict order comparison of ' . 'export-ignores in the .gitattributes file'; - $enforceExportIgnoreAligmentDescription = 'Enforce a strict alignment of ' + $enforceExportIgnoreAlignmentDescription = 'Enforce a strict alignment of ' . 'export-ignores in the .gitattributes file'; $overwriteDescription = 'Overwrite existing .gitattributes file ' . 'with missing export-ignores'; @@ -112,7 +114,7 @@ protected function configure() 'enforce-alignment', null, InputOption::VALUE_NONE, - $enforceExportIgnoreAligmentDescription + $enforceExportIgnoreAlignmentDescription ); $this->addOption('overwrite', 'o', InputOption::VALUE_NONE, $overwriteDescription); @@ -170,9 +172,12 @@ protected function configure() /** * Execute command. * - * @param \Symfony\Component\Console\Input\InputInterface $input - * @param \Symfony\Component\Console\Output\OutputInterface $output + * @param InputInterface $input + * @param OutputInterface $output * + * @throws GitArchiveNotValidatedYet + * @throws GitHeadNotAvailable + * @throws GitNotAvailable * @return integer */ protected function execute(InputInterface $input, OutputInterface $output): int @@ -265,7 +270,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int return Command::FAILURE; } - } elseif($this->isGlobPatternFileSetable($globPatternFile)) { + } elseif($this->isGlobPatternFileSettable($globPatternFile)) { try { if ($this->isDefaultGlobPatternFilePresent()) { $this->analyser->setGlobPatternFromFile($globPatternFile); @@ -320,7 +325,6 @@ protected function execute(InputInterface $input, OutputInterface $output): int $expectedGitattributesFileContent = $headerContent . PHP_EOL . $expectedGitattributesFileContent; } - $expectedGitattributesFileContent = $expectedGitattributesFileContent; $outputContent .= $this->createGitattributesFile( $expectedGitattributesFileContent ); @@ -481,12 +485,12 @@ protected function execute(InputInterface $input, OutputInterface $output): int } /** - * Check if a glob pattern file is setable. + * Check if a glob pattern file is settable. * * @param string $file The glob pattern file to check. * @return boolean */ - protected function isGlobPatternFileSetable($file) + protected function isGlobPatternFileSettable(string $file): bool { if ($this->isGlobPatternFileProvided($file)) { return true; @@ -501,7 +505,7 @@ protected function isGlobPatternFileSetable($file) * @param string $file The glob pattern file provided. * @return boolean */ - protected function isGlobPatternFileProvided($file) + protected function isGlobPatternFileProvided(string $file): bool { return $file !== $this->defaultLpvFile; } @@ -511,7 +515,7 @@ protected function isGlobPatternFileProvided($file) * * @return boolean */ - protected function isDefaultGlobPatternFilePresent() + protected function isDefaultGlobPatternFilePresent(): bool { return \file_exists($this->defaultLpvFile); } @@ -519,11 +523,12 @@ protected function isDefaultGlobPatternFilePresent() /** * Validate archive of current Git HEAD. * - * @param boolean $validateLicenseFilePresence Whether the archive should have a license file or not. - * @throws \Stolt\LeanPackage\Exceptions\NoLicenseFilePresent + * @param boolean $validateLicenseFilePresence Whether the archive should have a license file or not. + * @throws GitHeadNotAvailable + * @throws GitNotAvailable * @return boolean */ - protected function isValidArchive($validateLicenseFilePresence = false) + protected function isValidArchive(bool $validateLicenseFilePresence = false): bool { if ($validateLicenseFilePresence) { return $this->archiveValidator->shouldHaveLicenseFile()->validate( @@ -539,13 +544,13 @@ protected function isValidArchive($validateLicenseFilePresence = false) /** * Get expected gitattributes file content output content. * - * @param string $expectedGitattributesFileContent + * @param string $expectedGitattributesFileContent * * @return string */ protected function getExpectedGitattributesFileContentOutput( - $expectedGitattributesFileContent - ) { + string $expectedGitattributesFileContent + ): string { $content = 'Would expect the following .gitattributes file content:' . PHP_EOL . '' . $expectedGitattributesFileContent . ''; @@ -555,13 +560,13 @@ protected function getExpectedGitattributesFileContentOutput( /** * Get suggest gitattributes file creation output content. * - * @param string $expectedGitattributesFileContent + * @param string $expectedGitattributesFileContent * * @return string */ protected function getSuggestGitattributesFileCreationOptionOutput( - $expectedGitattributesFileContent - ) { + string $expectedGitattributesFileContent + ): string { $content = 'Would expect the following .gitattributes file content:' . PHP_EOL . '' . $expectedGitattributesFileContent . '' . PHP_EOL . 'Use the --create|-c option to create a ' @@ -574,11 +579,11 @@ protected function getSuggestGitattributesFileCreationOptionOutput( * Create the gitattributes file. * * @param string $content The content of the gitattributes file - * @throws \Stolt\LeanPackage\Exceptions\GitattributesCreationFailed + * @throws GitattributesCreationFailed * * @return string */ - protected function createGitattributesFile($content) + protected function createGitattributesFile(string $content): string { $bytesWritten = file_put_contents( $this->analyser->getGitattributesFilePath(), @@ -600,11 +605,11 @@ protected function createGitattributesFile($content) * Overwrite an existing gitattributes file. * * @param string $content The content of the gitattributes file - * @throws \Stolt\LeanPackage\Exceptions\GitattributesCreationFailed + * @throws GitattributesCreationFailed * * @return string */ - protected function overwriteGitattributesFile($content) + protected function overwriteGitattributesFile(string $content): string { $bytesWritten = file_put_contents( $this->analyser->getGitattributesFilePath(), diff --git a/src/Presets/Finder.php b/src/Presets/Finder.php index ef8e658..bd0db41 100644 --- a/src/Presets/Finder.php +++ b/src/Presets/Finder.php @@ -38,8 +38,8 @@ public function getAvailablePresets(): array } /** - * @param $name - * @throws PresetNotAvailable|\ReflectionException + * @param string $name + * @throws PresetNotAvailable * @return array */ public function getPresetGlobByLanguageName(string $name): array @@ -52,7 +52,7 @@ public function getPresetGlobByLanguageName(string $name): array $presetClassName = \sprintf('Stolt\LeanPackage\Presets\%sPreset', $name); - /** @var Preset **/ + /** @var Preset $preset **/ $preset = new $presetClassName(); return $preset->getPresetGlob(); From 25edf1fdde4f81d8e2b1b00e1a5e487338bf9d56 Mon Sep 17 00:00:00 2001 From: Raphael Stolt Date: Mon, 1 Jul 2024 14:30:17 +0200 Subject: [PATCH 092/152] Updates CI/CD workflows --- .github/workflows/lint.yml | 2 +- .github/workflows/static-analyse.yml | 2 +- .github/workflows/test-windows.yml | 2 +- .github/workflows/test.yml | 4 ++-- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 82de09d..0768f1b 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -3,7 +3,7 @@ name: lint on: push jobs: - tests: + build: name: lint runs-on: ubuntu-latest diff --git a/.github/workflows/static-analyse.yml b/.github/workflows/static-analyse.yml index f50be4e..d8a84f8 100644 --- a/.github/workflows/static-analyse.yml +++ b/.github/workflows/static-analyse.yml @@ -3,7 +3,7 @@ name: static-analyse on: push jobs: - tests: + build: name: static-analyse runs-on: ubuntu-latest diff --git a/.github/workflows/test-windows.yml b/.github/workflows/test-windows.yml index c6d1ac7..59d5c7c 100644 --- a/.github/workflows/test-windows.yml +++ b/.github/workflows/test-windows.yml @@ -3,7 +3,7 @@ name: test-windows on: push jobs: - test: + build: name: "PHPUnit (PHP ${{ matrix.php }})" runs-on: "windows-latest" diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 3bc27e5..9182daa 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -3,7 +3,7 @@ name: test on: push jobs: - test: + build: name: "PHPUnit (PHP ${{ matrix.php }})" runs-on: "ubuntu-20.04" @@ -24,7 +24,7 @@ jobs: php-version: "${{ matrix.php }}" - name: Install Composer dependencies - run: composer update --no-progress --prefer-dist --optimize-autoloader + run: composer install --no-progress --prefer-dist --optimize-autoloader - name: Run tests run: composer run-script lpv:test From 5e62dfadbd4887e75aa0c9893ba0b10648a0b9c6 Mon Sep 17 00:00:00 2001 From: Raphael Stolt Date: Mon, 1 Jul 2024 18:06:09 +0200 Subject: [PATCH 093/152] Emphasizes validation result --- src/Commands/ValidateCommand.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Commands/ValidateCommand.php b/src/Commands/ValidateCommand.php index 55cad5a..6962189 100755 --- a/src/Commands/ValidateCommand.php +++ b/src/Commands/ValidateCommand.php @@ -400,7 +400,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int $output->writeln($verboseOutput, OutputInterface::VERBOSITY_VERBOSE); if ($this->analyser->hasCompleteExportIgnores() === false) { - $outputContent = 'The present .gitattributes file is considered invalid.'; + $outputContent = 'The present .gitattributes file is considered invalid.'; $verboseOutput = "+ Gathering expected .gitattribute content."; $output->writeln($verboseOutput, OutputInterface::VERBOSITY_VERBOSE); @@ -458,7 +458,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int return Command::FAILURE; } - $info = 'The present .gitattributes file is considered valid.'; + $info = 'The present .gitattributes file is considered valid.'; $output->writeln($info); if ($this->analyser->hasPrecedingSlashesInExportIgnorePattern()) { From eb7c41e0f7cac8e69d2963508ba8718a32d92845 Mon Sep 17 00:00:00 2001 From: Raphael Stolt Date: Tue, 2 Jul 2024 10:47:45 +0200 Subject: [PATCH 094/152] Adds minor code tweaks --- src/Commands/ValidateCommand.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Commands/ValidateCommand.php b/src/Commands/ValidateCommand.php index 6962189..a20a525 100755 --- a/src/Commands/ValidateCommand.php +++ b/src/Commands/ValidateCommand.php @@ -466,13 +466,14 @@ protected function execute(InputInterface $input, OutputInterface $output): int $output->writeln($verboseOutput, OutputInterface::VERBOSITY_VERBOSE); $warning = "Warning: At least one export-ignore pattern has a leading '/', " - . $warning = 'which is considered as a smell.'; + . 'which is considered as a smell.'; $outputContent = '' . $warning . ''; $output->writeln($outputContent); } if ($this->analyser->hasTextAutoConfiguration() === false) { $verboseOutput = '+ Checking for text auto configuration.'; + $output->writeln($verboseOutput, OutputInterface::VERBOSITY_VERBOSE); $warning = 'Warning: Missing a text auto configuration. ' . 'Consider adding one.'; From 5e70e13c05e8264c9d5ac1bd50493538fbecdbdf Mon Sep 17 00:00:00 2001 From: Raphael Stolt Date: Tue, 2 Jul 2024 13:46:08 +0200 Subject: [PATCH 095/152] Fixes exception message --- src/Presets/Finder.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Presets/Finder.php b/src/Presets/Finder.php index bd0db41..b956057 100644 --- a/src/Presets/Finder.php +++ b/src/Presets/Finder.php @@ -47,7 +47,8 @@ public function getPresetGlobByLanguageName(string $name): array $name = \ucfirst(\strtolower($name)); if (!\in_array($name, $this->getAvailablePresets())) { - throw new PresetNotAvailable('Preset for Kotlin not available. Maybe contribute it?.'); + $message = \sprintf('Preset for %s not available. Maybe contribute it?.', $name); + throw new PresetNotAvailable($message); } $presetClassName = \sprintf('Stolt\LeanPackage\Presets\%sPreset', $name); From 9a4fdc71540abba07b88d33a8bb7cfe697d8e6e4 Mon Sep 17 00:00:00 2001 From: Raphael Stolt Date: Thu, 4 Jul 2024 15:33:45 +0200 Subject: [PATCH 096/152] Updates phpstan/phpstan package --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index dc0efcd..847dab0 100755 --- a/composer.json +++ b/composer.json @@ -58,7 +58,7 @@ "mockery/mockery": "^1.0", "phlak/semver": "^4.1", "php-mock/php-mock-phpunit": "^2.7||^1.1", - "phpstan/phpstan": "^1.6.2", + "phpstan/phpstan": "^1.11", "phpunit/phpunit": "^10.3||^9.6.13" } } From 746b08da63006509d80d3e3002f6931dbaa41ed0 Mon Sep 17 00:00:00 2001 From: Raphael Stolt Date: Thu, 4 Jul 2024 15:34:31 +0200 Subject: [PATCH 097/152] Bumps PHPStan level --- phpstan.neon.dist | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/phpstan.neon.dist b/phpstan.neon.dist index 3df0d78..12df076 100644 --- a/phpstan.neon.dist +++ b/phpstan.neon.dist @@ -1,5 +1,5 @@ parameters: - level: 7 + level: 8 paths: - src - tests From 382bca044ab3724a06d357bbd5309c314531ed1a Mon Sep 17 00:00:00 2001 From: Raphael Stolt Date: Thu, 4 Jul 2024 15:38:17 +0200 Subject: [PATCH 098/152] Fixes spelling mistake --- src/Analyser.php | 40 ++++++++++++++++---------------- src/Commands/ValidateCommand.php | 6 ++--- tests/AnalyserTest.php | 2 +- 3 files changed, 24 insertions(+), 24 deletions(-) diff --git a/src/Analyser.php b/src/Analyser.php index 185891d..d950abc 100755 --- a/src/Analyser.php +++ b/src/Analyser.php @@ -69,7 +69,7 @@ class Analyser * * @var boolean */ - private bool $staleExportIgnoresCamparison = false; + private bool $staleExportIgnoresComparison = false; /** * Whether to do a strict alignment comparsion of the export-ignores @@ -290,11 +290,11 @@ public function getDirectory(): string } /** - * Enable strict order camparison. + * Enable strict order comparison. * * @return Analyser */ - public function enableStrictOrderCamparison(): Analyser + public function enableStrictOrderComparison(): Analyser { $this->strictOrderComparison = true; @@ -302,43 +302,43 @@ public function enableStrictOrderCamparison(): Analyser } /** - * Guard for strict order camparison. + * Guard for strict order comparison. * * @return boolean */ - public function isStrictOrderCamparisonEnabled(): bool + public function isStrictOrderComparisonEnabled(): bool { return $this->strictOrderComparison === true; } /** - * Enable stale export ignores camparison. + * Enable stale export ignores comparison. * * @return Analyser */ - public function enableStaleExportIgnoresCamparison(): Analyser + public function enableStaleExportIgnoresComparison(): Analyser { - $this->staleExportIgnoresCamparison = true; + $this->staleExportIgnoresComparison = true; return $this; } /** - * Guard for stale export ignores camparison. + * Guard for stale export ignores comparison. * * @return boolean */ - public function isStaleExportIgnoresCamparisonEnabled(): bool + public function isStaleExportIgnoresComparisonEnabled(): bool { - return $this->staleExportIgnoresCamparison === true; + return $this->staleExportIgnoresComparison === true; } /** - * Enable strict alignment camparison. + * Enable strict alignment comparison. * * @return Analyser */ - public function enableStrictAlignmentCamparison(): Analyser + public function enableStrictAlignmentComparison(): Analyser { $this->strictAlignmentComparison = true; @@ -346,11 +346,11 @@ public function enableStrictAlignmentCamparison(): Analyser } /** - * Guard for strict alignment camparison. + * Guard for strict alignment comparison. * * @return boolean */ - public function isStrictAlignmentCamparisonEnabled(): bool + public function isStrictAlignmentComparisonEnabled(): bool { return $this->strictAlignmentComparison === true; } @@ -487,7 +487,7 @@ public function getExpectedGitattributesContent(array $postfixlessExportIgnores \sort($postfixlessExportIgnores, SORT_STRING | SORT_FLAG_CASE); if (\count($postfixlessExportIgnores) > 0) { - if ($this->isAlignExportIgnoresEnabled() || $this->isStrictAlignmentCamparisonEnabled()) { + if ($this->isAlignExportIgnoresEnabled() || $this->isStrictAlignmentComparisonEnabled()) { $postfixlessExportIgnores = $this->getAlignedExportIgnoreArtifacts( $postfixlessExportIgnores ); @@ -791,7 +791,7 @@ public function getPresentExportIgnores(bool $applyGlob = true): array } }); - if ($this->isStrictOrderCamparisonEnabled() === false) { + if ($this->isStrictOrderComparisonEnabled() === false) { \sort($exportIgnores, SORT_STRING | SORT_FLAG_CASE); } @@ -831,7 +831,7 @@ public function hasCompleteExportIgnores(): bool $actualExportIgnores = $this->getPresentExportIgnores(); - if ($this->isStaleExportIgnoresCamparisonEnabled()) { + if ($this->isStaleExportIgnoresComparisonEnabled()) { $staleExportIgnores = []; $unfilteredExportIgnores = $this->getPresentExportIgnores(false); foreach ($unfilteredExportIgnores as $unfilteredExportIgnore) { @@ -841,13 +841,13 @@ public function hasCompleteExportIgnores(): bool } } - if ($this->isStrictAlignmentCamparisonEnabled()) { + if ($this->isStrictAlignmentComparisonEnabled()) { $expectedExportIgnores = $this->getAlignedExportIgnoreArtifacts( $expectedExportIgnores ); } - if ($this->isStaleExportIgnoresCamparisonEnabled()) { + if ($this->isStaleExportIgnoresComparisonEnabled()) { $actualExportIgnores = \array_merge($actualExportIgnores, $staleExportIgnores); } diff --git a/src/Commands/ValidateCommand.php b/src/Commands/ValidateCommand.php index a20a525..4de2793 100755 --- a/src/Commands/ValidateCommand.php +++ b/src/Commands/ValidateCommand.php @@ -217,14 +217,14 @@ protected function execute(InputInterface $input, OutputInterface $output): int $verboseOutput = '+ Enforcing strict order comparison.'; $output->writeln($verboseOutput, OutputInterface::VERBOSITY_VERBOSE); - $this->analyser->enableStrictOrderCamparison(); + $this->analyser->enableStrictOrderComparison(); } if ($reportStaleExportIgnores) { $verboseOutput = '+ Enforcing stale export ignores comparison.'; $output->writeln($verboseOutput, OutputInterface::VERBOSITY_VERBOSE); - $this->analyser->enableStaleExportIgnoresCamparison(); + $this->analyser->enableStaleExportIgnoresComparison(); } $enforceExportIgnoresAlignment = $input->getOption('enforce-alignment'); @@ -233,7 +233,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int $verboseOutput = '+ Enforcing alignment comparison.'; $output->writeln($verboseOutput, OutputInterface::VERBOSITY_VERBOSE); - $this->analyser->enableStrictAlignmentCamparison(); + $this->analyser->enableStrictAlignmentComparison(); } $keepLicense = (boolean) $input->getOption('keep-license'); diff --git a/tests/AnalyserTest.php b/tests/AnalyserTest.php index cd2bc36..bbc3d59 100755 --- a/tests/AnalyserTest.php +++ b/tests/AnalyserTest.php @@ -681,7 +681,7 @@ public function varyingOrderDoesFailCompletenessCheckWhenEnforced(): void $this->createTemporaryGitattributesFile($gitattributesContent); $analyser = (new Analyser(new Finder(new PhpPreset())))->setDirectory($this->temporaryDirectory); - $analyser->enableStrictOrderCamparison(); + $analyser->enableStrictOrderComparison(); $this->assertFalse($analyser->hasCompleteExportIgnores()); } From e1c6c1d21956c4aee7158e5676dc7e10d7e8d773 Mon Sep 17 00:00:00 2001 From: Raphael Stolt Date: Thu, 4 Jul 2024 15:39:11 +0200 Subject: [PATCH 099/152] Adds parameter type --- src/Analyser.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Analyser.php b/src/Analyser.php index d950abc..78d85b6 100755 --- a/src/Analyser.php +++ b/src/Analyser.php @@ -167,12 +167,12 @@ public function hasTextAutoConfiguration(): bool /** * Set the glob pattern file. * - * @param string $file - * @throws \Stolt\LeanPackage\Exceptions\InvalidGlobPatternFile + * @param string $file * @throws \Stolt\LeanPackage\Exceptions\NonExistentGlobPatternFile + * @throws \Stolt\LeanPackage\Exceptions\InvalidGlobPatternFile * @return Analyser */ - public function setGlobPatternFromFile($file): Analyser + public function setGlobPatternFromFile(string $file): Analyser { if (!\is_file($file)) { $message = "Glob pattern file {$file} doesn't exist."; From 58e59cf592d323346c7f3abe1238e3c10cfbc832 Mon Sep 17 00:00:00 2001 From: Raphael Stolt Date: Thu, 4 Jul 2024 16:10:26 +0200 Subject: [PATCH 100/152] Updates phpunit/phpunit package --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 847dab0..ef13d29 100755 --- a/composer.json +++ b/composer.json @@ -59,6 +59,6 @@ "phlak/semver": "^4.1", "php-mock/php-mock-phpunit": "^2.7||^1.1", "phpstan/phpstan": "^1.11", - "phpunit/phpunit": "^10.3||^9.6.13" + "phpunit/phpunit": "^11.2.6||^10.5.25" } } From a42b906f9b1741f6220bd440926e169bb05bbb1e Mon Sep 17 00:00:00 2001 From: Raphael Stolt Date: Thu, 4 Jul 2024 18:23:34 +0200 Subject: [PATCH 101/152] Adds minor code tweaks --- src/Archive.php | 70 ++++++++++++++++++--------------------- src/Archive/Validator.php | 21 +++++++----- 2 files changed, 45 insertions(+), 46 deletions(-) diff --git a/src/Archive.php b/src/Archive.php index d454634..6ce8cae 100755 --- a/src/Archive.php +++ b/src/Archive.php @@ -100,7 +100,7 @@ public function getFoundUnexpectedArtifacts(): array /** * Has repository a HEAD. * - * @throws \Stolt\LeanPackage\Exceptions\GitNotAvailable + * @throws GitNotAvailable * * @return boolean */ @@ -115,46 +115,45 @@ public function hasHead(): bool } /** - * Is the Git command available? - * - * @param string $command The command to check availabilty of. Defaults to git. + * Create a Git archive from the current HEAD. * + * @throws GitHeadNotAvailable|GitNotAvailable * @return boolean */ - public function isGitCommandAvailable($command = 'git'): bool + public function createArchive(): bool { - \exec('where ' . $command . ' 2>&1', $output, $returnValue); - if ((new OsHelper())->isWindows() === false) { - \exec('which ' . $command . ' 2>&1', $output, $returnValue); + if ($this->hasHead()) { + $command = 'git archive -o ' . $this->getFilename() . ' HEAD 2>&1'; + \exec($command, $output, $returnValue); + + return $returnValue === 0; } - return $returnValue === 0; + throw new GitHeadNotAvailable('No Git HEAD present to create an archive from.'); } /** - * Create a Git archive from the current HEAD. + * Is the Git command available? * - * @throws \Stolt\LeanPackage\Exceptions\GitHeadNotAvailable + * @param string $command The command to check availabilty of. Defaults to git. * * @return boolean */ - public function createArchive(): bool + public function isGitCommandAvailable($command = 'git'): bool { - if ($this->hasHead()) { - $command = 'git archive -o ' . $this->getFilename() . ' HEAD 2>&1'; - \exec($command, $output, $returnValue); - - return $returnValue === 0; + \exec('where ' . $command . ' 2>&1', $output, $returnValue); + if ((new OsHelper())->isWindows() === false) { + \exec('which ' . $command . ' 2>&1', $output, $returnValue); } - throw new GitHeadNotAvailable('No Git HEAD present to create an archive from.'); + return $returnValue === 0; } /** * Compare archive against unexpected artifacts. * * @param array $unexpectedArtifacts The unexpected artifacts. - * @throws \Stolt\LeanPackage\Exceptions\NoLicenseFilePresent + * @throws NoLicenseFilePresent * @return array */ public function compareArchive(array $unexpectedArtifacts): array @@ -195,29 +194,12 @@ public function compareArchive(array $unexpectedArtifacts): array return $foundUnexpectedArtifacts; } - /** - * Remove temporary Git archive. - * - * @return boolean - */ - public function removeArchive(): bool - { - if (\file_exists($this->getFilename())) { - return \unlink($this->getFilename()); - } - - return false; - } - /** * Delegator for temporary archive creation and comparison against * a set of unexpected artifacts. * * @param array $unexpectedArtifacts The unexpected artifacts of the archive. - * - * @throws \Stolt\LeanPackage\Exceptions\GitNotAvailable - * @throws \Stolt\LeanPackage\Exceptions\GitHeadNotAvailable - * + * @throws GitHeadNotAvailable|NoLicenseFilePresent|GitNotAvailable * @return array */ public function getUnexpectedArchiveArtifacts(array $unexpectedArtifacts): array @@ -228,4 +210,18 @@ public function getUnexpectedArchiveArtifacts(array $unexpectedArtifacts): array return $this->foundUnexpectedArtifacts; } + + /** + * Remove temporary Git archive. + * + * @return boolean + */ + public function removeArchive(): bool + { + if (\file_exists($this->getFilename())) { + return \unlink($this->getFilename()); + } + + return false; + } } diff --git a/src/Archive/Validator.php b/src/Archive/Validator.php index 2cdf11b..cc56976 100755 --- a/src/Archive/Validator.php +++ b/src/Archive/Validator.php @@ -4,11 +4,14 @@ use Stolt\LeanPackage\Archive; use Stolt\LeanPackage\Exceptions\GitArchiveNotValidatedYet; +use Stolt\LeanPackage\Exceptions\GitHeadNotAvailable; +use Stolt\LeanPackage\Exceptions\GitNotAvailable; +use Stolt\LeanPackage\Exceptions\NoLicenseFilePresent; class Validator { /** - * @var \Stolt\LeanPackage\Archive + * @var Archive */ private Archive $archive; @@ -20,7 +23,7 @@ class Validator /** * Initialise. * - * @param \Stolt\LeanPackage\Archive $archive The archive to validate. + * @param Archive $archive The archive to validate. */ public function __construct(Archive $archive) { @@ -30,7 +33,7 @@ public function __construct(Archive $archive) /** * Set if license file presence should be validated. * - * @return \Stolt\LeanPackage\Archive\Validator + * @return Validator */ public function shouldHaveLicenseFile(): Validator { @@ -42,7 +45,7 @@ public function shouldHaveLicenseFile(): Validator /** * Accessor for injected archive instance. * - * @return \Stolt\LeanPackage\Archive + * @return Archive */ public function getArchive(): Archive { @@ -54,10 +57,10 @@ public function getArchive(): Archive * * @param array $unexpectedArtifacts Artifacts not expected in archive. * - * @throws \Stolt\LeanPackage\Exceptions\GitHeadNotAvailable - * @throws \Stolt\LeanPackage\Exceptions\GitNotAvailable - * @throws \Stolt\LeanPackage\Exceptions\GitHeadNotAvailable - * @throws \Stolt\LeanPackage\Exceptions\GitNotAvailable + * @throws GitNotAvailable + * @throws GitHeadNotAvailable + * @throws GitNotAvailable|NoLicenseFilePresent + * @throws GitHeadNotAvailable * @return boolean */ public function validate(array $unexpectedArtifacts): bool @@ -77,7 +80,7 @@ public function validate(array $unexpectedArtifacts): bool /** * Accessor for found unexpected archive artifacts. * - * @throws \Stolt\LeanPackage\Exceptions\GitArchiveNotValidatedYet + * @throws GitArchiveNotValidatedYet * * @return array */ From 100725dd8879722c3e85e697a2c18659e0cbf5f5 Mon Sep 17 00:00:00 2001 From: Raphael Stolt Date: Tue, 9 Jul 2024 04:08:07 +0200 Subject: [PATCH 102/152] Release version 4.0.3 --- .github/workflows/distribute.yml | 2 +- CHANGELOG.md | 5 ++++- bin/lean-package-validator | 2 +- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/.github/workflows/distribute.yml b/.github/workflows/distribute.yml index 6991c13..9ceefba 100644 --- a/.github/workflows/distribute.yml +++ b/.github/workflows/distribute.yml @@ -19,7 +19,7 @@ jobs: fail-fast: true matrix: php: - - "8.1" + - "8.2" steps: - name: Checkout diff --git a/CHANGELOG.md b/CHANGELOG.md index b7434b7..28e1a74 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,8 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/) and this p ## [Unreleased] +## [v4.0.3] - 2024-07-10 + ### Added - Attested dist builds. @@ -270,7 +272,8 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/) and this p - Initial release. -[Unreleased]: https://github.com/raphaelstolt/lean-package-validator/compare/v4.0.2...HEAD +[Unreleased]: https://github.com/raphaelstolt/lean-package-validator/compare/v4.0.3...HEAD +[v4.0.3]: https://github.com/raphaelstolt/lean-package-validator/compare/v4.0.2...v4.0.3 [v4.0.2]: https://github.com/raphaelstolt/lean-package-validator/compare/v4.0.1...v4.0.2 [v4.0.1]: https://github.com/raphaelstolt/lean-package-validator/compare/v4.0.0...v4.0.1 [v4.0.0]: https://github.com/raphaelstolt/lean-package-validator/compare/v3.3.2...v4.0.0 diff --git a/bin/lean-package-validator b/bin/lean-package-validator index 83837d4..c7a92fd 100755 --- a/bin/lean-package-validator +++ b/bin/lean-package-validator @@ -22,7 +22,7 @@ if (false === $autoloaded) { } \define('WORKING_DIRECTORY', \getcwd()); -\define('VERSION', '4.0.2'); +\define('VERSION', '4.0.3'); use Stolt\LeanPackage\Commands\InitCommand; use Stolt\LeanPackage\Commands\ValidateCommand; From 402fedacd39e64dce07bc61dedcc75d8562d430e Mon Sep 17 00:00:00 2001 From: Raphael Stolt Date: Tue, 9 Jul 2024 06:05:16 +0200 Subject: [PATCH 103/152] Expands Composer configuration --- composer.json | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/composer.json b/composer.json index ef13d29..86c28d8 100755 --- a/composer.json +++ b/composer.json @@ -51,7 +51,9 @@ "lpv:validate-gitattributes": "bin/lean-package-validator validate" }, "config": { - "sort-packages": true + "preferred-install": "dist", + "sort-packages": true, + "optimize-autoloader": true }, "require-dev": { "friendsofphp/php-cs-fixer": "^3.0", From 255b7021740fe1ffa112ac15245c80b3806d014c Mon Sep 17 00:00:00 2001 From: Raphael Stolt Date: Thu, 18 Jul 2024 18:56:25 +0200 Subject: [PATCH 104/152] Utilises zenstruck/console-test --- composer.json | 3 ++- tests/Commands/ValidateCommandTest.php | 15 ++++++++------- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/composer.json b/composer.json index 86c28d8..61e571e 100755 --- a/composer.json +++ b/composer.json @@ -61,6 +61,7 @@ "phlak/semver": "^4.1", "php-mock/php-mock-phpunit": "^2.7||^1.1", "phpstan/phpstan": "^1.11", - "phpunit/phpunit": "^11.2.6||^10.5.25" + "phpunit/phpunit": "^11.2.6||^10.5.25", + "zenstruck/console-test": "^1.5" } } diff --git a/tests/Commands/ValidateCommandTest.php b/tests/Commands/ValidateCommandTest.php index cadd121..45d7a60 100644 --- a/tests/Commands/ValidateCommandTest.php +++ b/tests/Commands/ValidateCommandTest.php @@ -23,9 +23,13 @@ use Stolt\LeanPackage\Tests\CommandTester; use Stolt\LeanPackage\Tests\TestCase; use Symfony\Component\Console\Application; +use Zenstruck\Console\Test\InteractsWithConsole; +use Zenstruck\Console\Test\TestCommand; class ValidateCommandTest extends TestCase { + use InteractsWithConsole; + /** * @var Application */ @@ -344,11 +348,6 @@ public function gitattributesIsInSuggestedFileContent(): void ); $command = $this->application->find('validate'); - $commandTester = new CommandTester($command); - $commandTester->execute([ - 'command' => $command->getName(), - 'directory' => WORKING_DIRECTORY, - ]); $expectedDisplay = <<temporaryDirectory}. @@ -365,8 +364,10 @@ public function gitattributesIsInSuggestedFileContent(): void CONTENT; - $this->assertSame($expectedDisplay, $commandTester->getDisplay()); - $this->assertTrue($commandTester->getStatusCode() > 0); + TestCommand::for($command) + ->execute(WORKING_DIRECTORY) + ->assertOutputContains($expectedDisplay) + ->assertStatusCode(1); } #[Test] From 286a138068dba92d85d2cbcb5b638cab38f4014f Mon Sep 17 00:00:00 2001 From: Raphael Stolt Date: Fri, 19 Jul 2024 12:02:02 +0200 Subject: [PATCH 105/152] Adds PHP 8.4 to the testing matrix --- .github/workflows/test.yml | 1 + composer.json | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 9182daa..033e454 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -13,6 +13,7 @@ jobs: - "8.1" - "8.2" - "8.3" + - "8.4" steps: - name: Checkout diff --git a/composer.json b/composer.json index 61e571e..d166869 100755 --- a/composer.json +++ b/composer.json @@ -11,7 +11,7 @@ ], "require": { "php": ">=8.1", - "laminas/laminas-stdlib": "^3.7", + "laminas/laminas-stdlib": "^3.19", "sebastian/diff": "^5.0||^4.0.3", "symfony/console": "^7.1.0||^v5.4.8" }, From 79bf502fad254c85f48c55aa9c3876cbe6ceafa5 Mon Sep 17 00:00:00 2001 From: Raphael Stolt Date: Tue, 23 Jul 2024 19:54:52 +0200 Subject: [PATCH 106/152] Utilises symfony/console constants --- tests/ApplicationTest.php | 5 ++- tests/Commands/InitCommandTest.php | 11 +++--- tests/Commands/ValidateCommandTest.php | 53 +++++++++++++------------- 3 files changed, 36 insertions(+), 33 deletions(-) diff --git a/tests/ApplicationTest.php b/tests/ApplicationTest.php index a467993..f47e306 100644 --- a/tests/ApplicationTest.php +++ b/tests/ApplicationTest.php @@ -7,6 +7,7 @@ use PHPUnit\Framework\Attributes\Group; use PHPUnit\Framework\Attributes\Test; use PHPUnit\Framework\TestCase as PHPUnit; +use Symfony\Component\Console\Command\Command; final class ApplicationTest extends PHPUnit { @@ -23,7 +24,7 @@ public function executableIsAvailable(): void $output[1], 'Expected application name not present.' ); - $this->assertEquals(0, $returnValue); + $this->assertEquals(Command::SUCCESS, $returnValue); } #[Test] @@ -44,6 +45,6 @@ public function expectedCommandsAreListed(): void $output[19], 'Expected validate command not listed.' ); - $this->assertEquals(0, $returnValue); + $this->assertEquals(Command::SUCCESS, $returnValue); } } diff --git a/tests/Commands/InitCommandTest.php b/tests/Commands/InitCommandTest.php index 19fe0dc..ccdf7e2 100644 --- a/tests/Commands/InitCommandTest.php +++ b/tests/Commands/InitCommandTest.php @@ -15,6 +15,7 @@ use Stolt\LeanPackage\Tests\CommandTester; use Stolt\LeanPackage\Tests\TestCase; use Symfony\Component\Console\Application; +use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Output\OutputInterface; class InitCommandTest extends TestCase @@ -129,7 +130,7 @@ public function failingInitReturnsExpectedStatusCode(): void CONTENT; $this->assertSame($expectedDisplay, $commandTester->getDisplay()); - $this->assertTrue($commandTester->getStatusCode() !== 0); + $this->assertTrue($commandTester->getStatusCode() !== Command::SUCCESS); $mock->disable(); } @@ -155,7 +156,7 @@ public function existingDefaultLpvFileIsNotOverwritten(): void CONTENT; $this->assertSame($expectedDisplay, $commandTester->getDisplay()); - $this->assertTrue($commandTester->getStatusCode() !== 0); + $this->assertTrue($commandTester->getStatusCode() !== Command::SUCCESS); } #[Test] @@ -175,7 +176,7 @@ public function usingANonAvailablePresetShowsWarning(): void ); $this->assertSame($expectedDisplay, $commandTester->getDisplay()); - $this->assertTrue($commandTester->getStatusCode() !== 0); + $this->assertTrue($commandTester->getStatusCode() !== Command::SUCCESS); } #[Test] @@ -202,7 +203,7 @@ public function verboseOutputIsAvailableWhenDesired(): void ); $this->assertSame($expectedDisplay, $commandTester->getDisplay()); - $this->assertTrue($commandTester->getStatusCode() !== 0); + $this->assertTrue($commandTester->getStatusCode() !== Command::SUCCESS); } #[Test] @@ -218,7 +219,7 @@ public function existingDefaultLpvFileIsOverwrittenWhenDesired(): void $commandTester->execute([ 'command' => $command->getName(), 'directory' => WORKING_DIRECTORY, - '-o' => true, + '--overwrite' => true, ]); $expectedDisplay = <<assertSame($expectedDisplay, $commandTester->getDisplay()); - $this->assertTrue($commandTester->getStatusCode() > 0); + $this->assertTrue($commandTester->getStatusCode() > Command::SUCCESS); } #[Test] @@ -143,7 +144,7 @@ public function validateOnNonExistentGitattributesFilesSuggestsCreationWithAlign CONTENT; $this->assertSame($expectedDisplay, $commandTester->getDisplay()); - $this->assertTrue($commandTester->getStatusCode() > 0); + $this->assertTrue($commandTester->getStatusCode() > Command::SUCCESS); } #[Test] @@ -184,7 +185,7 @@ public function showsDifferenceBetweenActualAndExpectedGitattributesContent(): v $this->assertContains($expectedDiffRow, $actualDisplayRows); } - $this->assertTrue($commandTester->getStatusCode() > 0); + $this->assertTrue($commandTester->getStatusCode() > Command::SUCCESS); } #[Test] @@ -253,7 +254,7 @@ public function filesInGlobalGitignoreAreExportIgnored(): void CONTENT; $this->assertStringEqualsStringIgnoringLineEndings($expectedDisplay, $commandTester->getDisplay()); - $this->assertTrue($commandTester->getStatusCode() > 0); + $this->assertTrue($commandTester->getStatusCode() > Command::SUCCESS); } #[Test] @@ -330,7 +331,7 @@ public function gitattributesFileWithNoExportIgnoresContentShowsExpectedContent( CONTENT; $this->assertSame($expectedDisplay, $commandTester->getDisplay()); - $this->assertTrue($commandTester->getStatusCode() > 0); + $this->assertTrue($commandTester->getStatusCode() > Command::SUCCESS); } #[Test] @@ -409,7 +410,7 @@ public function licenseIsInSuggestedFileContentPerDefault(): void CONTENT; $this->assertSame($expectedDisplay, $commandTester->getDisplay()); - $this->assertTrue($commandTester->getStatusCode() > 0); + $this->assertTrue($commandTester->getStatusCode() > Command::SUCCESS); } #[Test] @@ -451,7 +452,7 @@ public function licenseIsNotInSuggestedFileContent(): void CONTENT; $this->assertSame($expectedDisplay, $commandTester->getDisplay()); - $this->assertTrue($commandTester->getStatusCode() > 0); + $this->assertTrue($commandTester->getStatusCode() > Command::SUCCESS); } #[Test] @@ -495,7 +496,7 @@ public function licenseIsNotInSuggestedFileContentWithCustomGlobPattern(): void CONTENT; $this->assertSame($expectedDisplay, $commandTester->getDisplay()); - $this->assertTrue($commandTester->getStatusCode() > 0); + $this->assertTrue($commandTester->getStatusCode() > Command::SUCCESS); } #[Test] @@ -546,7 +547,7 @@ public function presentExportIgnoredLicenseWithKeepLicenseOptionInvalidatesResul CONTENT; $this->assertSame($expectedDisplay, $commandTester->getDisplay()); - $this->assertTrue($commandTester->getStatusCode() > 0); + $this->assertTrue($commandTester->getStatusCode() > Command::SUCCESS); } #[Test] @@ -592,7 +593,7 @@ public function archiveWithoutLicenseFileIsConsideredInvalid(): void CONTENT; $this->assertSame($expectedDisplay, $commandTester->getDisplay()); - $this->assertTrue($commandTester->getStatusCode() > 0); + $this->assertTrue($commandTester->getStatusCode() > Command::SUCCESS); } #[Test] @@ -674,7 +675,7 @@ public function failingGitattributesFilesCreationReturnsExpectedStatusCode(): vo CONTENT; $this->assertSame($expectedDisplay, $commandTester->getDisplay()); - $this->assertTrue($commandTester->getStatusCode() > 0); + $this->assertTrue($commandTester->getStatusCode() > Command::SUCCESS); $mock->disable(); } @@ -897,7 +898,7 @@ public function invalidGitattributesReturnsExpectedStatusCode(): void CONTENT; $this->assertSame($expectedDisplay, $commandTester->getDisplay()); - $this->assertTrue($commandTester->getStatusCode() > 0); + $this->assertTrue($commandTester->getStatusCode() > Command::SUCCESS); } #[Test] @@ -944,7 +945,7 @@ public function optionalGlobPatternIsApplied(): void CONTENT; $this->assertSame($expectedDisplay, $commandTester->getDisplay()); - $this->assertTrue($commandTester->getStatusCode() > 0); + $this->assertTrue($commandTester->getStatusCode() > Command::SUCCESS); } #[Test] @@ -966,7 +967,7 @@ public function usageOfInvalidGlobFailsValidation(): void CONTENT; $this->assertSame($expectedDisplay, $commandTester->getDisplay()); - $this->assertTrue($commandTester->getStatusCode() > 0); + $this->assertTrue($commandTester->getStatusCode() > Command::SUCCESS); } #[Test] @@ -989,7 +990,7 @@ public function missingGlobPatternProducesUserFriendlyErrorMessage(): void CONTENT; $this->assertSame($expectedDisplay, $commandTester->getDisplay()); - $this->assertTrue($commandTester->getStatusCode() > 0); + $this->assertTrue($commandTester->getStatusCode() > Command::SUCCESS); } #[Test] @@ -1113,7 +1114,7 @@ public function nonLeanArchiveIsNotConsideredLeanPlural(): void CONTENT; $this->assertSame($expectedDisplay, $commandTester->getDisplay()); - $this->assertTrue($commandTester->getStatusCode() > 0); + $this->assertTrue($commandTester->getStatusCode() > Command::SUCCESS); } #[Test] @@ -1159,7 +1160,7 @@ public function nonLeanArchiveIsNotConsideredLeanSingular(): void CONTENT; $this->assertSame($expectedDisplay, $commandTester->getDisplay()); - $this->assertTrue($commandTester->getStatusCode() > 0); + $this->assertTrue($commandTester->getStatusCode() > Command::SUCCESS); } #[Test] @@ -1192,7 +1193,7 @@ public function impossibilityToResolveExpectedGitattributesFileContentIsInfoed() CONTENT; $this->assertSame($expectedDisplay, $commandTester->getDisplay()); - $this->assertTrue($commandTester->getStatusCode() > 0); + $this->assertTrue($commandTester->getStatusCode() > Command::SUCCESS); } #[Test] @@ -1215,7 +1216,7 @@ public function invalidDirectoryAgumentReturnsExpectedStatusCode(): void CONTENT; $this->assertSame($expectedDisplay, $commandTester->getDisplay()); - $this->assertTrue($commandTester->getStatusCode() > 0); + $this->assertTrue($commandTester->getStatusCode() > Command::SUCCESS); } #[Test] @@ -1375,7 +1376,7 @@ public function staleExportIgnoresAreConsideredAsInvalid(): void CONTENT; $this->assertSame($expectedDisplay, $commandTester->getDisplay()); - $this->assertTrue($commandTester->getStatusCode() > 0); + $this->assertTrue($commandTester->getStatusCode() > Command::SUCCESS); } #[Test] @@ -1473,7 +1474,7 @@ public function failingGitattributesFilesOverwriteReturnsExpectedStatusCode(): v CONTENT; $this->assertSame($expectedDisplay, $commandTester->getDisplay()); - $this->assertTrue($commandTester->getStatusCode() > 0); + $this->assertTrue($commandTester->getStatusCode() > Command::SUCCESS); $mock->disable(); } @@ -1569,7 +1570,7 @@ public function strictAlignmentOfExportIgnoresCanBeEnforced(): void CONTENT; $this->assertSame($expectedDisplay, $commandTester->getDisplay()); - $this->assertTrue($commandTester->getStatusCode() > 0); + $this->assertTrue($commandTester->getStatusCode() > Command::SUCCESS); } #[Test] @@ -1620,7 +1621,7 @@ public function strictAlignmentAndOrderOfExportIgnoresCanBeEnforced(): void CONTENT; $this->assertSame($expectedDisplay, $commandTester->getDisplay()); - $this->assertTrue($commandTester->getStatusCode() > 0); + $this->assertTrue($commandTester->getStatusCode() > Command::SUCCESS); } #[Test] @@ -1672,7 +1673,7 @@ public function strictOrderOfExportIgnoresCanBeEnforced(): void CONTENT; $this->assertSame($expectedDisplay, $commandTester->getDisplay()); - $this->assertTrue($commandTester->getStatusCode() > 0); + $this->assertTrue($commandTester->getStatusCode() > Command::SUCCESS); } #[Test] @@ -1872,7 +1873,7 @@ public function providedNonExistentGlobPatternFileFailsValidation(): void CONTENT; $this->assertSame($expectedDisplay, $commandTester->getDisplay()); - $this->assertTrue($commandTester->getStatusCode() > 0); + $this->assertTrue($commandTester->getStatusCode() > Command::SUCCESS); } #[Test] @@ -1912,7 +1913,7 @@ public function providedInvalidGlobPatternFileFailsValidation(): void CONTENT; $this->assertSame($expectedDisplay, $commandTester->getDisplay()); - $this->assertTrue($commandTester->getStatusCode() > 0); + $this->assertTrue($commandTester->getStatusCode() > Command::SUCCESS); } #[Test] From 9b70be549c84103927b00dcb8775ebf90cf85cb0 Mon Sep 17 00:00:00 2001 From: Raphael Stolt Date: Wed, 24 Jul 2024 16:16:15 +0200 Subject: [PATCH 107/152] Updates zenstruck/console-test package --- composer.json | 2 +- tests/Commands/ValidateCommandTest.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/composer.json b/composer.json index d166869..a7bffb8 100755 --- a/composer.json +++ b/composer.json @@ -62,6 +62,6 @@ "php-mock/php-mock-phpunit": "^2.7||^1.1", "phpstan/phpstan": "^1.11", "phpunit/phpunit": "^11.2.6||^10.5.25", - "zenstruck/console-test": "^1.5" + "zenstruck/console-test": "^1.6" } } diff --git a/tests/Commands/ValidateCommandTest.php b/tests/Commands/ValidateCommandTest.php index 8be92fe..fe8ca2c 100644 --- a/tests/Commands/ValidateCommandTest.php +++ b/tests/Commands/ValidateCommandTest.php @@ -368,7 +368,7 @@ public function gitattributesIsInSuggestedFileContent(): void TestCommand::for($command) ->execute(WORKING_DIRECTORY) ->assertOutputContains($expectedDisplay) - ->assertStatusCode(1); + ->assertFaulty(); } #[Test] From f92675dd72fab91bb7c0976cc46a09c00c798bd0 Mon Sep 17 00:00:00 2001 From: Raphael Stolt Date: Wed, 24 Jul 2024 18:23:25 +0200 Subject: [PATCH 108/152] Improves readability --- tests/Commands/ValidateCommandTest.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tests/Commands/ValidateCommandTest.php b/tests/Commands/ValidateCommandTest.php index fe8ca2c..3277fcc 100644 --- a/tests/Commands/ValidateCommandTest.php +++ b/tests/Commands/ValidateCommandTest.php @@ -12,6 +12,7 @@ use PHPUnit\Framework\Attributes\Group; use PHPUnit\Framework\Attributes\Test; use PHPUnit\Framework\Attributes\Ticket; +use SebastianBergmann\CodeCoverage\Driver\WriteOperationFailedException; use Stolt\LeanPackage\Analyser; use Stolt\LeanPackage\Archive; use Stolt\LeanPackage\Archive\Validator; @@ -366,7 +367,8 @@ public function gitattributesIsInSuggestedFileContent(): void CONTENT; TestCommand::for($command) - ->execute(WORKING_DIRECTORY) + ->addArgument(WORKING_DIRECTORY) + ->execute() ->assertOutputContains($expectedDisplay) ->assertFaulty(); } From c76ec24e8273fc2ef630795607a0cf6cbdeabc39 Mon Sep 17 00:00:00 2001 From: Raphael Stolt Date: Tue, 17 Sep 2024 07:52:08 +0200 Subject: [PATCH 109/152] Removes laminas/laminas-stdlib dependency --- CHANGELOG.md | 4 + composer.json | 3 +- phpstan.neon.dist | 1 + src/Analyser.php | 1 - src/Commands/ValidateCommand.php | 2 +- src/ErrorHandler.php | 116 +++++++++++++ src/Glob.php | 224 +++++++++++++++++++++++++ tests/Commands/ValidateCommandTest.php | 4 + 8 files changed, 351 insertions(+), 4 deletions(-) create mode 100644 src/ErrorHandler.php create mode 100644 src/Glob.php diff --git a/CHANGELOG.md b/CHANGELOG.md index 28e1a74..3881314 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,10 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/) and this p ## [Unreleased] +### Removed + +- Removed laminas/laminas-stdlib dependency. + ## [v4.0.3] - 2024-07-10 ### Added diff --git a/composer.json b/composer.json index a7bffb8..08b6eec 100755 --- a/composer.json +++ b/composer.json @@ -11,8 +11,7 @@ ], "require": { "php": ">=8.1", - "laminas/laminas-stdlib": "^3.19", - "sebastian/diff": "^5.0||^4.0.3", + "sebastian/diff": "^6.0.1||^5.0||^4.0.3", "symfony/console": "^7.1.0||^v5.4.8" }, "autoload": { diff --git a/phpstan.neon.dist b/phpstan.neon.dist index 12df076..192071a 100644 --- a/phpstan.neon.dist +++ b/phpstan.neon.dist @@ -14,3 +14,4 @@ parameters: - '#is never read#' - '#TMock#' - '#unknown class#' + - '#set_error_handler expects#' diff --git a/src/Analyser.php b/src/Analyser.php index 78d85b6..23dc9c2 100755 --- a/src/Analyser.php +++ b/src/Analyser.php @@ -2,7 +2,6 @@ namespace Stolt\LeanPackage; -use Laminas\Stdlib\Glob; use Stolt\LeanPackage\Exceptions\InvalidGlobPattern; use Stolt\LeanPackage\Exceptions\InvalidGlobPatternFile; use Stolt\LeanPackage\Exceptions\NonExistentGlobPatternFile; diff --git a/src/Commands/ValidateCommand.php b/src/Commands/ValidateCommand.php index 4de2793..fc0c009 100755 --- a/src/Commands/ValidateCommand.php +++ b/src/Commands/ValidateCommand.php @@ -270,7 +270,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int return Command::FAILURE; } - } elseif($this->isGlobPatternFileSettable($globPatternFile)) { + } elseif ($this->isGlobPatternFileSettable($globPatternFile)) { try { if ($this->isDefaultGlobPatternFilePresent()) { $this->analyser->setGlobPatternFromFile($globPatternFile); diff --git a/src/ErrorHandler.php b/src/ErrorHandler.php new file mode 100644 index 0000000..3b49943 --- /dev/null +++ b/src/ErrorHandler.php @@ -0,0 +1,116 @@ + + */ + protected static $stack = []; + + /** + * Check if this error handler is active + * + * @return bool + */ + public static function started() + { + return (bool) static::getNestedLevel(); + } + + /** + * Get the current nested level + * + * @return int + */ + public static function getNestedLevel() + { + return \count(static::$stack); + } + + /** + * Starting the error handler + * + * @param int $errorLevel + * @return void + */ + public static function start($errorLevel = E_WARNING) + { + if (! static::$stack) { + \set_error_handler([static::class, 'addError'], $errorLevel); + } + + static::$stack[] = null; + } + + /** + * Stopping the error handler + * + * @param bool $throw Throw the ErrorException if any + * @throws ErrorException If an error has been caught and $throw is true. + * @return null|ErrorException + */ + public static function stop($throw = false) + { + $errorException = null; + + if (static::$stack) { + $errorException = \array_pop(static::$stack); + + if (! static::$stack) { + \restore_error_handler(); + } + + if ($errorException && $throw) { + throw $errorException; + } + } + + return $errorException; + } + + /** + * Stop all active handler + * + * @return void + */ + public static function clean() + { + if (static::$stack) { + \restore_error_handler(); + } + + static::$stack = []; + } + + /** + * Add an error to the stack + * + * @param int $errno + * @param string $errstr + * @param string $errfile + * @param int $errline + * @return void + */ + public static function addError($errno, $errstr = '', $errfile = '', $errline = 0) + { + $stack = &static::$stack[\count(static::$stack) - 1]; + $stack = new ErrorException($errstr, 0, $errno, $errfile, $errline, $stack); + } +} diff --git a/src/Glob.php b/src/Glob.php new file mode 100644 index 0000000..2379fcd --- /dev/null +++ b/src/Glob.php @@ -0,0 +1,224 @@ + GLOB_MARK, + self::GLOB_NOSORT => GLOB_NOSORT, + self::GLOB_NOCHECK => GLOB_NOCHECK, + self::GLOB_NOESCAPE => GLOB_NOESCAPE, + self::GLOB_BRACE => \defined('GLOB_BRACE') ? GLOB_BRACE : 0, + self::GLOB_ONLYDIR => GLOB_ONLYDIR, + self::GLOB_ERR => GLOB_ERR, + ]; + + $globFlags = 0; + + foreach ($flagMap as $internalFlag => $globFlag) { + if ($flags & $internalFlag) { + $globFlags |= $globFlag; + } + } + } else { + $globFlags = 0; + } + + ErrorHandler::start(); + $res = \glob($pattern, $globFlags); + $err = ErrorHandler::stop(); + if ($res === false) { + throw new RuntimeException("glob('{$pattern}', {$globFlags}) failed", 0, $err); + } + return $res; + } + + /** + * Expand braces manually, then use the system glob. + * + * @param string $pattern + * @param int $flags + * @throws RuntimeException + * @return array + */ + protected static function fallbackGlob($pattern, $flags) + { + if (! self::flagsIsEqualTo($flags, self::GLOB_BRACE)) { + return static::systemGlob($pattern, $flags); + } + + $flags &= ~self::GLOB_BRACE; + $length = \strlen($pattern); + $paths = []; + + if ($flags & self::GLOB_NOESCAPE) { + $begin = \strpos($pattern, '{'); + } else { + $begin = 0; + + while (true) { + if ($begin === $length) { + $begin = false; + break; + } elseif ($pattern[$begin] === '\\' && ($begin + 1) < $length) { + $begin++; + } elseif ($pattern[$begin] === '{') { + break; + } + + $begin++; + } + } + + if ($begin === false) { + return static::systemGlob($pattern, $flags); + } + + $next = static::nextBraceSub($pattern, $begin + 1, $flags); + + if ($next === null) { + return static::systemGlob($pattern, $flags); + } + + $rest = $next; + + while ($pattern[$rest] !== '}') { + $rest = static::nextBraceSub($pattern, $rest + 1, $flags); + + if ($rest === null) { + return static::systemGlob($pattern, $flags); + } + } + + $p = $begin + 1; + + while (true) { + $subPattern = \substr($pattern, 0, $begin) + . \substr($pattern, $p, $next - $p) + . \substr($pattern, $rest + 1); + + $result = static::fallbackGlob($subPattern, $flags | self::GLOB_BRACE); + + if ($result) { + $paths = \array_merge($paths, $result); + } + + if ($pattern[$next] === '}') { + break; + } + + $p = $next + 1; + $next = static::nextBraceSub($pattern, $p, $flags); + } + + return \array_unique($paths); + } + + /** + * Find the end of the sub-pattern in a brace expression. + * + * @param string $pattern + * @param int $begin + * @param int $flags + * @return int|null + */ + protected static function nextBraceSub($pattern, $begin, $flags) + { + $length = \strlen($pattern); + $depth = 0; + $current = $begin; + + while ($current < $length) { + $flagsEqualsNoEscape = self::flagsIsEqualTo($flags, self::GLOB_NOESCAPE); + + if ($flagsEqualsNoEscape && $pattern[$current] === '\\') { + if (++$current === $length) { + break; + } + + $current++; + } else { + if ( + ($pattern[$current] === '}' && $depth-- === 0) + || ($pattern[$current] === ',' && $depth === 0) + ) { + break; + } elseif ($pattern[$current++] === '{') { + $depth++; + } + } + } + + return $current < $length ? $current : null; + } + + /** @internal */ + public static function flagsIsEqualTo(int $flags, int $otherFlags): bool + { + return (bool) ($flags & $otherFlags); + } +} diff --git a/tests/Commands/ValidateCommandTest.php b/tests/Commands/ValidateCommandTest.php index 3277fcc..a6108b4 100644 --- a/tests/Commands/ValidateCommandTest.php +++ b/tests/Commands/ValidateCommandTest.php @@ -339,6 +339,10 @@ public function gitattributesFileWithNoExportIgnoresContentShowsExpectedContent( #[Ticket('https://github.com/raphaelstolt/lean-package-validator/issues/13')] public function gitattributesIsInSuggestedFileContent(): void { + if ((new OsHelper())->isWindows()) { + $this->markTestSkipped('Skipping test on Windows systems'); + } + $artifactFilenames = [ 'CONDUCT.md', 'phpspec.yml.dist', From f3a09d1003d6ebe049382cd31b87280e88fd0e57 Mon Sep 17 00:00:00 2001 From: Raphael Stolt Date: Fri, 27 Sep 2024 16:03:48 +0200 Subject: [PATCH 110/152] Expands the PHP preset --- CHANGELOG.md | 4 ++++ src/Presets/PhpPreset.php | 2 ++ tests/AnalyserTest.php | 2 ++ tests/Commands/InitCommandTest.php | 2 ++ 4 files changed, 10 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3881314..4487bf5 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,10 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/) and this p ## [Unreleased] +### Added + +- Further PHP preset expansion. + ### Removed - Removed laminas/laminas-stdlib dependency. diff --git a/src/Presets/PhpPreset.php b/src/Presets/PhpPreset.php index 5bc5e47..15f4699 100644 --- a/src/Presets/PhpPreset.php +++ b/src/Presets/PhpPreset.php @@ -21,6 +21,8 @@ public function getPresetGlob(): array 'phpunit*', 'appveyor.yml', 'box.json', + 'composer-dependency-analyser*', + 'collision-detector*', 'captainhook.json', 'infection*', 'phpstan*', diff --git a/tests/AnalyserTest.php b/tests/AnalyserTest.php index bbc3d59..ed99b8e 100755 --- a/tests/AnalyserTest.php +++ b/tests/AnalyserTest.php @@ -1399,6 +1399,8 @@ public function returnsExpectedDefaultGlobPatterns(): void 'phpunit*', 'appveyor.yml', 'box.json', + 'composer-dependency-analyser*', + 'collision-detector*', 'captainhook.json', 'infection*', 'phpstan*', diff --git a/tests/Commands/InitCommandTest.php b/tests/Commands/InitCommandTest.php index ccdf7e2..bbdcff5 100644 --- a/tests/Commands/InitCommandTest.php +++ b/tests/Commands/InitCommandTest.php @@ -78,6 +78,8 @@ public function createsExpectedDefaultLpvFile(): void phpunit* appveyor.yml box.json +composer-dependency-analyser* +collision-detector* captainhook.json infection* phpstan* From a1bd03f5df53a7d596acb0bcdd47855041ad33d4 Mon Sep 17 00:00:00 2001 From: Raphael Stolt Date: Fri, 27 Sep 2024 16:23:06 +0200 Subject: [PATCH 111/152] Release version 4.0.4 --- CHANGELOG.md | 5 ++++- bin/lean-package-validator | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4487bf5..769e776 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,8 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/) and this p ## [Unreleased] +## [v4.0.3] - 2024-09-27 + ### Added - Further PHP preset expansion. @@ -280,7 +282,8 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/) and this p - Initial release. -[Unreleased]: https://github.com/raphaelstolt/lean-package-validator/compare/v4.0.3...HEAD +[Unreleased]: https://github.com/raphaelstolt/lean-package-validator/compare/v4.0.4...HEAD +[v4.0.4]: https://github.com/raphaelstolt/lean-package-validator/compare/v4.0.3...v4.0.4 [v4.0.3]: https://github.com/raphaelstolt/lean-package-validator/compare/v4.0.2...v4.0.3 [v4.0.2]: https://github.com/raphaelstolt/lean-package-validator/compare/v4.0.1...v4.0.2 [v4.0.1]: https://github.com/raphaelstolt/lean-package-validator/compare/v4.0.0...v4.0.1 diff --git a/bin/lean-package-validator b/bin/lean-package-validator index c7a92fd..19e9ce9 100755 --- a/bin/lean-package-validator +++ b/bin/lean-package-validator @@ -22,7 +22,7 @@ if (false === $autoloaded) { } \define('WORKING_DIRECTORY', \getcwd()); -\define('VERSION', '4.0.3'); +\define('VERSION', '4.0.4'); use Stolt\LeanPackage\Commands\InitCommand; use Stolt\LeanPackage\Commands\ValidateCommand; From 7563baafe2aef2eb9b2419ae85f2dd2c6c5bf5b9 Mon Sep 17 00:00:00 2001 From: Raphael Stolt Date: Tue, 1 Oct 2024 14:27:54 +0200 Subject: [PATCH 112/152] Documents usage via cpx --- README.md | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 86e9108..f821d85 100755 --- a/README.md +++ b/README.md @@ -12,7 +12,7 @@ repository artifacts won't be included in release assets. ## Installation -The lean package validator CLI should be installed globally through Composer. +The lean package validator CLI can be installed globally through Composer. ``` bash composer global require stolt/lean-package-validator @@ -38,6 +38,12 @@ further utilisation via [Composer scripts](https://getcomposer.org/doc/articles/ composer require --dev stolt/lean-package-validator ``` +A third option to use the lean package validator is via [cpx](https://cpx.dev/). + +``` bash +cpx stolt/lean-package-validator validate +``` + > [!TIP] > As of release `v1.9.0` it's also possible to install and use the lean package validator > via a PHAR [file](https://github.com/raphaelstolt/lean-package-validator/releases/tag/v1.9.0). From b9ee0e1d2cbdf599777ec05544e3d24aff9560d5 Mon Sep 17 00:00:00 2001 From: Raphael Stolt Date: Sat, 2 Nov 2024 16:50:01 +0100 Subject: [PATCH 113/152] Expands the PHP preset --- src/Presets/PhpPreset.php | 1 + tests/AnalyserTest.php | 32 ++++++++++++++++++++++++++++++ tests/Commands/InitCommandTest.php | 1 + 3 files changed, 34 insertions(+) diff --git a/src/Presets/PhpPreset.php b/src/Presets/PhpPreset.php index 15f4699..5aa493e 100644 --- a/src/Presets/PhpPreset.php +++ b/src/Presets/PhpPreset.php @@ -16,6 +16,7 @@ public function getPresetGlob(): array '*.txt', '*.rst', '*.{md,MD}', + '*.{png,gif,jpeg,jpg,webp}', '*.xml', '*.yml', 'phpunit*', diff --git a/tests/AnalyserTest.php b/tests/AnalyserTest.php index ed99b8e..7df6323 100755 --- a/tests/AnalyserTest.php +++ b/tests/AnalyserTest.php @@ -1382,6 +1382,37 @@ public function presentGitignoredSpecsCoverageDirectoryIsExcludedFromValidation( $this->assertTrue($analyser->hasCompleteExportIgnores()); } + #[Test] + public function exportIgnoresExpectedImages(): void + { + $artifactFilenames = [ + 'test.png', + 'test.gif', + 'test.jpg', + 'test.jpeg', + 'test.webp', + ]; + + $this->createTemporaryFiles( + $artifactFilenames + ); + + $gitattributesContent = <<createTemporaryGitattributesFile($gitattributesContent); + + $analyser = (new Analyser(new Finder(new PhpPreset())))->setDirectory($this->temporaryDirectory); + $this->assertTrue($analyser->hasCompleteExportIgnores()); + } + #[Test] #[Group('glob')] public function returnsExpectedDefaultGlobPatterns(): void @@ -1394,6 +1425,7 @@ public function returnsExpectedDefaultGlobPatterns(): void '*.txt', '*.rst', '*.{md,MD}', + '*.{png,gif,jpeg,jpg,webp}', '*.xml', '*.yml', 'phpunit*', diff --git a/tests/Commands/InitCommandTest.php b/tests/Commands/InitCommandTest.php index bbdcff5..901d169 100644 --- a/tests/Commands/InitCommandTest.php +++ b/tests/Commands/InitCommandTest.php @@ -73,6 +73,7 @@ public function createsExpectedDefaultLpvFile(): void *.txt *.rst *.{md,MD} +*.{png,gif,jpeg,jpg,webp} *.xml *.yml phpunit* From 64ad64dca2dd1f6cc39ac4cf523750f2c5a1f5e1 Mon Sep 17 00:00:00 2001 From: Raphael Stolt Date: Sat, 2 Nov 2024 16:50:48 +0100 Subject: [PATCH 114/152] Release version 4.0.5 --- CHANGELOG.md | 11 +++++++++-- bin/lean-package-validator | 2 +- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 769e776..73b02be 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,7 +7,13 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/) and this p ## [Unreleased] -## [v4.0.3] - 2024-09-27 +## [v4.0.5] - 2024-11-06 + +### Added + +- Further PHP preset expansion. + +## [v4.0.4] - 2024-09-27 ### Added @@ -282,7 +288,8 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/) and this p - Initial release. -[Unreleased]: https://github.com/raphaelstolt/lean-package-validator/compare/v4.0.4...HEAD +[Unreleased]: https://github.com/raphaelstolt/lean-package-validator/compare/v4.0.5...HEAD +[v4.0.5]: https://github.com/raphaelstolt/lean-package-validator/compare/v4.0.4...v4.0.5 [v4.0.4]: https://github.com/raphaelstolt/lean-package-validator/compare/v4.0.3...v4.0.4 [v4.0.3]: https://github.com/raphaelstolt/lean-package-validator/compare/v4.0.2...v4.0.3 [v4.0.2]: https://github.com/raphaelstolt/lean-package-validator/compare/v4.0.1...v4.0.2 diff --git a/bin/lean-package-validator b/bin/lean-package-validator index 19e9ce9..912729e 100755 --- a/bin/lean-package-validator +++ b/bin/lean-package-validator @@ -22,7 +22,7 @@ if (false === $autoloaded) { } \define('WORKING_DIRECTORY', \getcwd()); -\define('VERSION', '4.0.4'); +\define('VERSION', '4.0.5'); use Stolt\LeanPackage\Commands\InitCommand; use Stolt\LeanPackage\Commands\ValidateCommand; From 549bd2f9cb61b0c8c0992f94f3d204e37aed0fff Mon Sep 17 00:00:00 2001 From: Raphael Stolt Date: Thu, 7 Nov 2024 13:38:09 +0100 Subject: [PATCH 115/152] Adds Dependabot configuration --- .github/dependabot.yml | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 .github/dependabot.yml diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..34a1047 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,6 @@ +version: 2 +updates: + - package-ecosystem: "composer" + directory: "/" + schedule: + interval: "monthly" From 5616665feb1b1fd65ec789525b040d8fca1ec630 Mon Sep 17 00:00:00 2001 From: Raphael Stolt Date: Thu, 7 Nov 2024 19:58:36 +0100 Subject: [PATCH 116/152] Adds project logo --- .gitattributes | 1 + README.md | 5 +++++ lpv-logo.png | Bin 0 -> 10670 bytes 3 files changed, 6 insertions(+) create mode 100644 lpv-logo.png diff --git a/.gitattributes b/.gitattributes index a37bc09..65da182 100755 --- a/.gitattributes +++ b/.gitattributes @@ -15,6 +15,7 @@ box.json.dist export-ignore CHANGELOG.md export-ignore example/ export-ignore LICENSE.md export-ignore +lpv-logo.png export-ignore phpstan.neon.dist export-ignore phpunit.xml.dist export-ignore README.md export-ignore diff --git a/README.md b/README.md index f821d85..6fc08f5 100755 --- a/README.md +++ b/README.md @@ -6,6 +6,11 @@ [![composer.lock available](https://poser.pugx.org/stolt/lean-package-validator/composerlock)](https://packagist.org/packages/stolt/lean-package-validator) [![PDS Skeleton](https://img.shields.io/badge/pds-skeleton-blue.svg?style=flat)](https://github.com/php-pds/skeleton) +

+ Lean package validator logo +

+ The lean package validator is a utility tool that validates a project/micro-package for its `leanness`. A project/micro-package is considered `lean` when its common repository artifacts won't be included in release assets. diff --git a/lpv-logo.png b/lpv-logo.png new file mode 100644 index 0000000000000000000000000000000000000000..c04e61b0241397eb77d59ea38fb058aca06bcd4f GIT binary patch literal 10670 zcmeHNcT|(xvPVz^5l}z`qz35_LI}MbI-&O_EhGU#mxQW<(xms^q$40DND)MO(L?VD zQl*MCr77(N&bgW{kHhk{RiRvcbdinsU;fz8wI% zd3;F4(8}*GsL8okeh+gZKDi!S+YpZ6y%n|KCB@{rVWm5WtkG4IeQsFxsS$LuI-Yoc ziE^wex1JoL>T$=2xLuVq($^Q1kY?1w_I?ZH_*zFOVUs6BK3{8eLn^?YkodVQ?ck!R zaY@+(kK^_JO3^{66XWr!_x|Q)__=ZlIg70A?eHu4OxIA(F@j+~!k79EV84Pa-#1H< zw%pr+m{6Z1DH_=DS(lX21vtI9%+YC@o_`y`Dp6HeH`Fo2!M?A4M{I?9DoxN17r4ba&$(E zdr1KV#egQEtF@6x39}MQhY4D-FoiQ*kK4&!R1;lR{3P?2E z4dseKxi~XlV8X0j+%ZxB0B)T5U;a6{YH0ic?~MMP1soszUNBdF0U(Iq$%+537HEv3 z2M*+ShyJYvS|3*v{JKcAi@O^fspx@p#<2bs0s;TS-qqdB@iH6)oFD0kbi%2kakC2i zZAxXRhV~y87Zli{oLn!haAf~Y6N9q(ldQk_b}@1p&R-qDng4ALeyNPp($ElB zaDlsDxCd2`0$j{5j&Oma5aO4YLLh4)q##6$400TjPO0*qe7#o}cZVjNE5iXwSKZo>D zPDnir?1E1L5kUcvFhmdn5*7i82tfW+GDNzeakY4XDgXisie8RfBt{$;4vt#bMWx~Z zF6Fpr#O2+PFpP_vzKe^a6yU-s<_pU|hBa^t3IW5w6kr%64iv|fxPX8-NK{_{EPnA8 z-~r)o|Dx}LK-qZzU)mSThgtHsq^qFNxcR*=MZc{nJ>X6DOfAr6E8 z76KaPfka&TiNpGB2yO>+wngIl$L|IEFFESp6oW8AOiV;r7{(_c0=C8#gMba6wHQc{ zPXr-g4T1{`*??@s{*I1zvB7x4+>o-iI396a;R^JUD`w8$Q^oaneNQ{&MILaJ@d*g< z{XrQR1mOQYSpJKS@vmql`TrLml9vj9X)!pv-(%T_VjXw`lNN3y*$P;%|3U<67 zjXP!$TB|85;GJLmWWOtl$4RbZpc;zT*GPy+Zc<5STCm{Z(V9UOWc9r)HZzH1=xyD* zEe|s!-cFfAOA|dN;$9Ja&j4zR+Z*aE!Vrc?o&_F zyj3yaG^01@K+-dNv^;$y&^lQatO}vwuIX(N?uzHKgpZUM{cI~oS6X%_5aHfV$GZm%BZ!#$#joVwRhpj@inplo*%I`KIBLB#Md8GWlz@KXPrPllGIYOU zue+!$_a3>|!W!ENkJEQC-wK7cf2tUYOoYGYPxtQi_mF=7V_mklbAZ+X_`Dh2W0{bR ziAJTRS6{6~O4%y(lD}%+izj#BvKw4`ncA)1i@Xw2e0x-desn)P9a=he5UI?V9ZC*z=G76jf~IS*!00q)5#8go-|t|Vk+s?t)LyPtdC zyGcLk?$(cWm>1Ei&sM1kXF$#?PvixXuQ9JIu10{8ZJUnQNo_v7nTGUEpiuqBNvH8d zEq69%F`Ke{V+5O)MUchJd;m2#*@mIcXM$(7=()BNFW|b%70H81DJ=4|{Vm^g6EXiY z(;71oYGadjVd?a~6_;6$k6Av_J&Rv0OYZGDQ$+d>Zlrm9`eI&@@q$sV1{*@(=>6@h z{EH?U-T>!G=aFImR-NAXp_iv;?#UL1YJ7dyY?(wBjpMM2Sjfhkv9}gtGE#wjsY~-? zA99qXN3IAKXqf~*NhD@J<(bnCD~Nltw*JhLew*odc4%PE?|W8#q>7yk4q&A+rXI4< z6rR$9e+#|)`epC(V1P)|kZ>eFoz<&xUHK0Px61R~JdkwkwGj}WvLZYQY5uVD?$&wI zmK&H33EZR2ph>cs@htYtyeNzZ;18|o1jvsn#l&$!35P(6&w}77& zFcxAvu(;xkxy;D+{gd5hnSI?#fMwTR*PJ9eRbpk%=UGzESd(Ck^`ritjL~L;{9fRp z)vr4DRJWVlwkMhgGR=XQ+v)JIpVA{c^P^M;owKUTW_;S35$r# z**mQ(ecZ2OsyU90Uafh}1&df7hioYgp0Vp?%N=U2F{(-pBK0Z4Q`GQ?FIQ{KDpLaz zHB==H|2WRoL|zRdBxIkT*Xw3UPM<5(MY+mYcFmk(E_24e)h*?fSu$+xtq1+0X>1KPN9e|MkVI?PV4diY764)Sei zygg!T9DI3v{0kcYIaPObbbBkosh607<;P+s0%aa^^Ri0!2Tb?l6Sj-G2sgS59M?kuRUJx4CjEX3kEP$!5kQhl#fG$tr5nk5YQd!|o*yWYc`_+{XPU;WXVphosT{|LodGbFe(xOV}I~eZg%kzATryy zdVZcMs@28U+itdtB2*!}u7VQShjHL@5`I&11_rK~L1XoXQPo0bMrcbff>0@H z|Fc8?aO7Rb%y?`V_9~S?@>98bAwj3sTT#~R-Gc}>Mb3p~($!DA%L?aLPaNlD*NV2U z_7TvPVKB9=*Y1`FXrvqE3|O6wA4!n#VeRN~PlZ-?K?a(@VywX9Cw81ifcmV{&4*%s z1QGNZPxZL*)g!22cFY8+7&2vnYd<$l8BO%%m}dM=&ZAnknf$VpCEVdDxAMr_os5Yk zJhMp4oG=yDyMw3cR2KN1y`t*Tn%UTlr+_Bl3#@k8@eBMZVz3)Ar!|n}X&mp18kiR| zd7ivzSZhy)Zq6Dz6Z>MgvhqUFan`feRv($A5)iA7aqVMb3w)*tAOACaf+Z~5=$M&C$L&lki$k1xzI4(Qq79{6Chc9JF8Wq>mvs` zk}+ei4|;$?3abt?Iii^z2C>-Zw;T0;{%DeEYYBzE*Swn@vI2Gx_W`jA7}u9j0viyl zd;5H2_V9&)uKN#|Y1QO_QUrOY0Wm!`gTJ_{4gF$&k7Nw(!v?k|23Z4P*U0Q7dq6@;?GCdxO~{qvL}q~ifa}o_d6sSn6Zv` zlyK=8QuA>Ob~zD$5uMW$UmGPniG}ky&Ww}9+I^Pc(@M<>sryB(ku=P^W$4#i2=?uV{|ThkBNf9B2=YJH!p=E+WK2e4%3)0z}0XL{Kjh4bZxDphw588 zVY1zQvSNJ+g$Nq;NX;adNp6Cn!e^|vn_EZ03{JdM17~7)1(NVsS11fIfN_6i0W~8x zbr)tQDcd_4uM3{bkWSmJooRp*7jLUE@^^O;2D7~ATP&<+Ul56|rzM&28FjybSh`H* zb4|G@&8)|<3M5h1{lNul(=4eG@=e+u&z@>765fvH$QBwSwBf>Ek0n-#)>>35Zq{kW zYHtcqzuNT{?l8tRK(&oe{1nB40spe|hc9H|w4z|L zJdWX*fx9{SX-__y4r&4N<2J39HBxBk0vyw%UoX-H&(WW(EF3(nQHAdwP_{*;sAUg9 zyJN!`B6%M7o;6d8^%QFzY2HNUobS-&b5yxMnHHyu{LH3(y#oMEVbp40S`+mHym7o* zok?@-FpSM)Of)qxmml#vrh1Rm!R3jVJHrYx6dzX8Qj^!5&qJnWy=VE%wH@jjm-cf~ zJB4cjIV^gUG5sm8MSnuGlQ}^HEM2Ac+g(zUdO$=bO;GBqpU^-tS~Y|8Zpp__N`xv` zcijnDK)4+ckvhlY-265K&pm(V-Sq}0Io9McHOk7`k>EEvr{|>Wot%qM{)itA@;xDE-XiF zKJQMU?Hp6Tu;gEqL!zp94reRpOeO*iA!9J_e6<@fZsH0t;4$wM-&r%w6YgN{%N6#k zI(8VdQ2RWEhAx#CRe22R zhSGI6ndsqyKlJsFtDa)loiTI*%$}W1nUBvECg)U;3_kiSXNRkGss#N6TW%KbEV!Zj zuvo*e*SGzG6q{n1>!zO8X`RB#Mx^xL>Bo~~Lp7jVP!IF?!m!f%8s{SAAVU+0%`vB} zeX(iwKnj6m=GOX`lwt7^1mg*>gfhKey`Hx#0dC}DUs)R&ozlE0uZf$Wd07s@H!1}u zmDHMcEgl?B_|W=P778m9aaaSN$+IzzB{r-bw#+EhA|aXn0=t&q zcxDQFX8tEx)Tb9b6`DcpY054OS1VLJq76-w;TEAIE0(oME93n>jdU(yw{&sax?ojM zl)l^UO_XtlqaMSXKm9M`ni=y-V$?L#bmg8!c>WYsTA-1u3Dy#=?`d#K+(1wC2)H~S z4s^veX6ChXqP(TWj>V;1g*n2P zG4qmn`MJhy459g4iI5`p%m;~u$J{!HMhs?|c{d{6Yk)=3&%S>N2Ch3-O+fG>-qqNb zLdcs#M~6>pqE>(CWypbW=URDNv|!KIwLrA>9s4r+5d}diQ6U4<<)$cHW=xZfy2A|O z=r!(uslh2Fh>DU^rG-t)I;lF@K zHu|iJ1jOU1lF2ax86^i*&zkWjbPl{{gC)*R@3h{$W;fuc&rfs^`I&R<8FQw{$5Mxx z{tdSp)51Je@;A3Pgknw89+Y}KK0pmA;3pk89}OKGZa;~f$_;+z$E+Rb4ACXWZ3$^AeiTVq zB$^H#d_z2VoC4GsRS?Ue&?2EP#kH86(6}TB!OeC&LArpbNI$X}i8%tS$ItWp%%;)j z++PN6JM1-IbsgT2E|-1dE@tr(>m`)`?)VjEd&Mak(rO$y5)omh$?v|o{bKe9*2T8S zW;RX3_Mv7oMpgCBn@92->~*4agyyT}grWTw5xWB=q0@o{*R8&;Gs$sjH7`~u4!D*2 zOtnVLBd4HBKxxwB32>~bDbhS@H&&%a)^_`+i}UfZ#B4!r9@jk6O)6MVa|6+IILXup z9sd2T?MP4G9hY2*y3Et|*t~Wrwx7{6(1Lsfr}{YQcYJS9plO#IcOhnl&7v`QqfS?)W4TXzO`EtJ$rlm33R(j0sP@0Coa#l)%y0$`ITUj&^msVSTK0yyDZR znTbsH_H2dKwnDi(QpHoiJKX9)VQFy1boFW{Z*PW1dNQ`7V@2w|N0Ewk@vTH{ytuto z40^6^H8ou3@pRl+x{u7<_{Ty=St;~4v@AQ>DZT2C>Tdn&K0CdInD8*~gj{?daw4%% ztTr#vYvvUS>;7r??_(A35Q>d1Pqtf)GtL75;~xO;Z@R&i7mlL0gNj+BcadZdpasR1 zLxZ`aT;{z| zm4#INc1`MJ{sVV^%i1&L`N@GZ0=M{6gTmaENps1bA%Fcb#`+lVzU$y5es@d4G9@#f zHfyC`WbDqj=IQS(r82c5wLTkDE=5ziUvKZ_OST4|D9F&y9p0hw{sOC16?4=pY$Ko* zrtOyGyic%uFPyvFkbm2y`HdrQbBY+g%X+g`9Z~olfn>$5A8(y~A5EA%;qe(iBuizl zCrrI!@GDgp`6)%z**q{s+BaL$EvKz-%If7yHNb>EeLUCP^Icb+Z;lLOE91*9ff5a~ zy242l49#jdL|TDlS6O*NKbr}w?mLfy`F{?sHVn)*oUvxkWG>xA<}rtTB&Ipq7qOZ* zvh4Pvcy)5KWc0bI)S(%Mi+_XWCW@|M)H~l()$#ze6E?8r8IfxKGWpI{eitzF}-gTOW?Y+Fwp*8=Ez^U=!Qn1vS3YQrvR6AHiUS@ zBP((l2BEEJ4Z&u745`n!^0o2XxKWu!-EP~Kkd#S7cN=34X%~<>J23CAkQz7bb?UQJ zwSxL!T`4z~kvDET=>~+XU4R_}&yZ|E$=;I>hllXPCy%#xVq3{IBO90wZQ~bArQF?% zS|Ge39d;*+wAev{4TOV)+0IXoFJ@iGnuD&mumEMR28N8!C~N2Tr5QxxvomEbdO}QW z4{cYJdEMFP6;cP&pS7>V=p(x(MH7k!U;ipaK-!V(9o~D@!HL(VBi{wc*f4%R=jfJ2^FDVz1p7+SxfE66j(%IR*`T4h&`B=D1zj~o} zlY=*YoxV9Wn`vB(>FoD_&2!gdOSimsXfHA=q@Gu9sfsfLvX}p<{`j?v$@i+rdp^SD znIH{HLG5L$>9E8R9z$od2S{Fj(De&HQKM&t`w*n1q{pGq3r>Vmc~otk-|k6|%wdIT zxsnnv(n=@VtOM7TpNS-keLp5Yp}P5*LQ2HXQ6lp5sz|Hawy!=%H^#5 F{|EfJWZM7$ literal 0 HcmV?d00001 From db646921ab31b813e2082ec1a5ece26992ee67b5 Mon Sep 17 00:00:00 2001 From: Raphael Stolt Date: Thu, 7 Nov 2024 21:45:24 +0100 Subject: [PATCH 117/152] Adds modified project logo --- lpv-logo.png | Bin 10670 -> 10650 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/lpv-logo.png b/lpv-logo.png index c04e61b0241397eb77d59ea38fb058aca06bcd4f..5e3929abd7ea745daadfbb0931b176fde639fa92 100644 GIT binary patch delta 6477 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 From 4e55b7b0993bcfa7f755381b22ca769af68a472a Mon Sep 17 00:00:00 2001 From: Raphael Stolt Date: Thu, 7 Nov 2024 22:23:50 +0100 Subject: [PATCH 118/152] Adds final project logo --- lpv-logo.png | Bin 10650 -> 7279 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/lpv-logo.png b/lpv-logo.png index 5e3929abd7ea745daadfbb0931b176fde639fa92..2e6d9f0928dc1fdbbd1e2a134de2c744adc73357 100644 GIT binary patch delta 3171 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 delta 6569 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 Date: Thu, 7 Nov 2024 12:39:48 +0000 Subject: [PATCH 119/152] Update phlak/semver requirement Updates the requirements on [phlak/semver](https://github.com/PHLAK/SemVer) to permit the latest version. - [Release notes](https://github.com/PHLAK/SemVer/releases) - [Commits](https://github.com/PHLAK/SemVer/compare/4.1.0...6.0.0) --- updated-dependencies: - dependency-name: phlak/semver dependency-type: direct:development ... Signed-off-by: dependabot[bot] --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) mode change 100755 => 100644 composer.json diff --git a/composer.json b/composer.json old mode 100755 new mode 100644 index 08b6eec..fc9ece9 --- a/composer.json +++ b/composer.json @@ -57,7 +57,7 @@ "require-dev": { "friendsofphp/php-cs-fixer": "^3.0", "mockery/mockery": "^1.0", - "phlak/semver": "^4.1", + "phlak/semver": "^4.1 || ^6.0", "php-mock/php-mock-phpunit": "^2.7||^1.1", "phpstan/phpstan": "^1.11", "phpunit/phpunit": "^11.2.6||^10.5.25", From 8aaf67121ef7e5d5ab3314ee17365c6e170821a1 Mon Sep 17 00:00:00 2001 From: Raphael Stolt Date: Mon, 11 Nov 2024 10:33:21 +0100 Subject: [PATCH 120/152] Adds the --keep-readme and --keep-glob-pattern options --- README.md | 12 ++++ src/Analyser.php | 96 ++++++++++++++++++++++++-- src/Commands/ValidateCommand.php | 45 +++++++++++- src/Glob.php | 28 ++++++++ tests/AnalyserTest.php | 71 +++++++++++++++++++ tests/Commands/ValidateCommandTest.php | 86 +++++++++++++++++++++++ 6 files changed, 330 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 6fc08f5..c091e5c 100755 --- a/README.md +++ b/README.md @@ -123,6 +123,18 @@ The `--keep-license` option will allow a license file in the release/dist archiv lean-package-validator validate [] --keep-license ``` +The `--keep-readme` option will allow a README file in the release/dist archive file which is per default ommitted. + +``` bash +lean-package-validator validate [] --keep-readme +``` + +The `--keep-glob-pattern` option allows to keep matching files in the release/dist archive file which are per default ommitted. + +``` bash +lean-package-validator validate [] --keep-glob-pattern '{LICENSE.*,README.*,docs*}' +``` + The `--align-export-ignores|-a` option will align the created or overwritten export-ignores for a better readability. ``` bash diff --git a/src/Analyser.php b/src/Analyser.php index 23dc9c2..7df0764 100755 --- a/src/Analyser.php +++ b/src/Analyser.php @@ -102,6 +102,22 @@ class Analyser */ private bool $keepLicense = false; + /** + * Whether to exclude a README file from the export-ignores + * or not. + * + * @var boolean + */ + private bool $keepReadme = false; + + + /** + * Pattern to exclude from the export-ignores. + * + * @var string + */ + private string $keepGlobPattern = ''; + /** * Whether to align the export-ignores on create or overwrite * or not. @@ -205,21 +221,22 @@ public function setGlobPatternFromFile(string $file): Analyser } /** - * Guard the set glob pattern. + * Guard the given glob pattern. * - * @throws \Stolt\LeanPackage\Exceptions\InvalidGlobPattern + * @param string $pattern + * @throws InvalidGlobPattern * @return void */ - private function guardGlobPattern(): void + private function guardGlobPattern(string $pattern): void { $invalidGlobPattern = false; - if (\substr($this->globPattern, 0) !== '{' - && (\substr($this->globPattern, -1) !== '}' && \substr($this->globPattern, -2) !== '}*')) { + if (\substr($pattern, 0) !== '{' + && (\substr($pattern, -1) !== '}' && \substr($pattern, -2) !== '}*')) { $invalidGlobPattern = true; } - $bracesContent = \trim(\substr($this->globPattern, 1, -1)); + $bracesContent = \trim(\substr($pattern, 1, -1)); if (empty($bracesContent)) { $invalidGlobPattern = true; @@ -250,7 +267,7 @@ private function guardGlobPattern(): void public function setGlobPattern($pattern): Analyser { $this->globPattern = \trim($pattern); - $this->guardGlobPattern(); + $this->guardGlobPattern($this->globPattern); return $this; } @@ -376,6 +393,53 @@ public function isKeepLicenseEnabled(): bool return $this->keepLicense === true; } + /** + * Keep README file in releases. + * + * @return Analyser + */ + public function keepReadme(): Analyser + { + $this->keepReadme = true; + + return $this; + } + + /** + * Guard for not export-ignoring README file. + * + * @return boolean + */ + public function isKeepReadmeEnabled(): bool + { + return $this->keepReadme === true; + } + + /** + * Sets the glob pattern for not export-ignoring license files. + * + * @param string $globPattern + * @throws InvalidGlobPattern + * @return Analyser + */ + public function setKeepGlobPattern(string $globPattern): Analyser + { + $this->guardGlobPattern($globPattern); + $this->keepGlobPattern = $globPattern; + + return $this; + } + + /** + * Guard for not export-ignoring glob pattern. + * + * @return boolean + */ + public function isKeepGlobPatternSet(): bool + { + return $this->keepGlobPattern !== ''; + } + /** * Align export-ignores. * @@ -635,6 +699,24 @@ public function collectExpectedExportIgnores(): array $expectedExportIgnores = $licenseLessExpectedExportIgnores; } + if ($this->isKeepReadmeEnabled()) { + $readmeLessExpectedExportIgnores = []; + \array_filter($expectedExportIgnores, function ($exportIgnore) use ( + &$readmeLessExpectedExportIgnores + ) { + if (!\preg_match('/(Readme.*)/i', $exportIgnore)) { + $readmeLessExpectedExportIgnores[] = $exportIgnore; + } + }); + + $expectedExportIgnores = $readmeLessExpectedExportIgnores; + } + + if ($this->isKeepGlobPatternSet()) { + $excludes = Glob::globArray($this->keepGlobPattern, $expectedExportIgnores); + $expectedExportIgnores = \array_diff($expectedExportIgnores, $excludes); + } + return \array_unique($expectedExportIgnores); } diff --git a/src/Commands/ValidateCommand.php b/src/Commands/ValidateCommand.php index fc0c009..9d2a28f 100755 --- a/src/Commands/ValidateCommand.php +++ b/src/Commands/ValidateCommand.php @@ -99,7 +99,9 @@ protected function configure(): void $globPatternFileDescription = 'Use this file with glob patterns ' . 'to match artifacts which should be export-ignored'; - $keepLicenseDescription = 'Do not export-ignore license file'; + $keepLicenseDescription = 'Do not export-ignore the license file'; + $keepReadmeDescription = 'Do not export-ignore the README file'; + $keepGlobPatternDescription = 'Do not export-ignore matching glob pattern e.g. {LICENSE.*,README.*,docs*}'; $alignExportIgnoresDescription = 'Align export-ignores on create or overwrite'; @@ -143,6 +145,18 @@ protected function configure(): void InputOption::VALUE_NONE, $keepLicenseDescription ); + $this->addOption( + 'keep-readme', + null, + InputOption::VALUE_NONE, + $keepReadmeDescription + ); + $this->addOption( + 'keep-glob-pattern', + null, + InputOption::VALUE_NONE, + $keepGlobPatternDescription + ); $this->addOption( 'align-export-ignores', 'a', @@ -245,6 +259,35 @@ protected function execute(InputInterface $input, OutputInterface $output): int $this->analyser->keepLicense(); } + $keepReadme = (boolean) $input->getOption('keep-readme'); + + if ($keepReadme) { + $verboseOutput = '+ Keeping the README file.'; + $output->writeln($verboseOutput, OutputInterface::VERBOSITY_VERBOSE); + + $this->analyser->keepReadme(); + } + + $keepGlobPattern = (string) $input->getOption('keep-glob-pattern'); + + if ($keepGlobPattern !== '') { + $verboseOutput = \sprintf('+ Keeping files matching the glob pattern %s.', $keepGlobPattern); + $output->writeln($verboseOutput, OutputInterface::VERBOSITY_VERBOSE); + try { + $this->analyser->setKeepGlobPattern($keepGlobPattern); + } catch (InvalidGlobPattern $e) { + $warning = "Warning: The provided glob pattern " + . "'$keepGlobPattern' is considered invalid."; + $outputContent = '' . $warning . ''; + $output->writeln($outputContent); + + $output->writeln($e->getMessage(), OutputInterface::VERBOSITY_DEBUG); + + return Command::FAILURE; + } + } + + $alignExportIgnores = $input->getOption('align-export-ignores'); if ($alignExportIgnores) { diff --git a/src/Glob.php b/src/Glob.php index 2379fcd..5023722 100644 --- a/src/Glob.php +++ b/src/Glob.php @@ -56,6 +56,34 @@ public static function glob($pattern, $flags = 0, $forceFallback = false) return static::systemGlob($pattern, $flags); } + /** + * Find array elements matching a pattern. + * + * @param string $pattern + * @param array $array + * @param int $flags + * @return array + */ + public static function globArray(string $pattern, array $array, int $flags = FNM_CASEFOLD) + { + $pattern = \str_replace(['{', '}'], '', $pattern); + + $patternParts = \explode(',', $pattern); + + foreach ($patternParts as $index => $patternPart) { + $matches[] = \array_filter($array, function ($val) use ($patternPart, $flags) { + return \fnmatch($patternPart, $val, $flags); + }); + } + + $excludes = []; + foreach ($matches as $index => $value) { + $excludes[] = \array_values($value)[0]; + } + + return $excludes; + } + /** * Use the glob function provided by the system. * diff --git a/tests/AnalyserTest.php b/tests/AnalyserTest.php index 7df6323..43ee499 100755 --- a/tests/AnalyserTest.php +++ b/tests/AnalyserTest.php @@ -1085,6 +1085,77 @@ public function licenseFileIsNotExportIgnored(): void ); } + #[Test] + #[Ticket('https://github.com/raphaelstolt/lean-package-validator/issues/47')] + public function readmeFileIsNotExportIgnored(): void + { + $artifactFilenames = [ + 'LICENSE.txt', + 'README.md', + 'phpspec.yml.dist', + ]; + + $this->createTemporaryFiles( + $artifactFilenames, + ['specs'] + ); + + $expectedGitattributesContent = <<setDirectory($this->temporaryDirectory)->keepReadme(); + $actualGitattributesContent = $analyser->getExpectedGitattributesContent(); + + $this->assertTrue($analyser->isKeepReadmeEnabled()); + $this->assertEquals( + $expectedGitattributesContent, + $actualGitattributesContent + ); + } + + /** + * @throws InvalidGlobPattern + */ + #[Test] + public function filesMatchingKeepGlobPatternAreNotExportIgnored(): void + { + $artifactFilenames = [ + 'LICENSE.txt', + 'README.rst', + 'phpspec.yml.dist', + ]; + + $this->createTemporaryFiles( + $artifactFilenames, + ['specs', 'docs'] + ); + + $expectedGitattributesContent = <<setDirectory($this->temporaryDirectory)->setKeepGlobPattern('{LICENSE.*,README.*,docs*}'); + $actualGitattributesContent = $analyser->getExpectedGitattributesContent(); + + $this->assertTrue($analyser->isKeepGlobPatternSet()); + $this->assertEquals( + $expectedGitattributesContent, + $actualGitattributesContent + ); + } + #[Test] #[Ticket('https://github.com/raphaelstolt/lean-package-validator/issues/24')] public function directoriesOnlyExportIgnoredOnce(): void diff --git a/tests/Commands/ValidateCommandTest.php b/tests/Commands/ValidateCommandTest.php index a6108b4..31ea654 100644 --- a/tests/Commands/ValidateCommandTest.php +++ b/tests/Commands/ValidateCommandTest.php @@ -455,6 +455,92 @@ public function licenseIsNotInSuggestedFileContent(): void Use the --create|-c option to create a .gitattributes file with the shown content. +CONTENT; + + $this->assertSame($expectedDisplay, $commandTester->getDisplay()); + $this->assertTrue($commandTester->getStatusCode() > Command::SUCCESS); + } + + #[Test] + #[Ticket('https://github.com/raphaelstolt/lean-package-validator/issues/47')] + public function readmeIsNotInSuggestedFileContent(): void + { + $artifactFilenames = [ + 'CONDUCT.md', + 'phpspec.yml.dist', + 'License.md', + 'README.md' + ]; + + $this->createTemporaryFiles( + $artifactFilenames, + ['specs'] + ); + + $command = $this->application->find('validate'); + $commandTester = new CommandTester($command); + $commandTester->execute([ + 'command' => $command->getName(), + 'directory' => WORKING_DIRECTORY, + '--keep-readme' => true, + ]); + + $expectedDisplay = <<temporaryDirectory}. + +Would expect the following .gitattributes file content: +* text=auto eol=lf + +.gitattributes export-ignore +CONDUCT.md export-ignore +License.md export-ignore +phpspec.yml.dist export-ignore +specs/ export-ignore + +Use the --create|-c option to create a .gitattributes file with the shown content. + +CONTENT; + + $this->assertSame($expectedDisplay, $commandTester->getDisplay()); + $this->assertTrue($commandTester->getStatusCode() > Command::SUCCESS); + } + + #[Test] + public function keepGlobPatternMatchesAreNotInSuggestedFileContent(): void + { + $artifactFilenames = [ + 'CONDUCT.md', + 'phpspec.yml.dist', + 'License.md', + 'README.md' + ]; + + $this->createTemporaryFiles( + $artifactFilenames, + ['specs', 'docs'] + ); + + $command = $this->application->find('validate'); + $commandTester = new CommandTester($command); + $commandTester->execute([ + 'command' => $command->getName(), + 'directory' => WORKING_DIRECTORY, + '--keep-glob-pattern' => '{README.*,License.*,docs*}', + ]); + + $expectedDisplay = <<temporaryDirectory}. + +Would expect the following .gitattributes file content: +* text=auto eol=lf + +.gitattributes export-ignore +CONDUCT.md export-ignore +phpspec.yml.dist export-ignore +specs/ export-ignore + +Use the --create|-c option to create a .gitattributes file with the shown content. + CONTENT; $this->assertSame($expectedDisplay, $commandTester->getDisplay()); From c1fe1b595b3bc60e264ef7df8af85a00fbb3daa3 Mon Sep 17 00:00:00 2001 From: Raphael Stolt Date: Mon, 11 Nov 2024 10:40:23 +0100 Subject: [PATCH 121/152] Release version 4.1.0 --- CHANGELOG.md | 9 ++++++++- bin/lean-package-validator | 2 +- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 73b02be..57bd9eb 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,12 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/) and this p ## [Unreleased] +## [v4.1.0] - 2024-11-11 + +### Added + +- New `--keep-readme` and `--keep-glob-pattern` options. Closes [#47](https://github.com/raphaelstolt/lean-package-validator/issues/47). + ## [v4.0.5] - 2024-11-06 ### Added @@ -288,7 +294,8 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/) and this p - Initial release. -[Unreleased]: https://github.com/raphaelstolt/lean-package-validator/compare/v4.0.5...HEAD +[Unreleased]: https://github.com/raphaelstolt/lean-package-validator/compare/v4.1.0...HEAD +[v4.1.0]: https://github.com/raphaelstolt/lean-package-validator/compare/v4.0.5...v4.1.0 [v4.0.5]: https://github.com/raphaelstolt/lean-package-validator/compare/v4.0.4...v4.0.5 [v4.0.4]: https://github.com/raphaelstolt/lean-package-validator/compare/v4.0.3...v4.0.4 [v4.0.3]: https://github.com/raphaelstolt/lean-package-validator/compare/v4.0.2...v4.0.3 diff --git a/bin/lean-package-validator b/bin/lean-package-validator index 912729e..8f56305 100755 --- a/bin/lean-package-validator +++ b/bin/lean-package-validator @@ -22,7 +22,7 @@ if (false === $autoloaded) { } \define('WORKING_DIRECTORY', \getcwd()); -\define('VERSION', '4.0.5'); +\define('VERSION', '4.1.0'); use Stolt\LeanPackage\Commands\InitCommand; use Stolt\LeanPackage\Commands\ValidateCommand; From ee3fbc394714e3c21afcac41a5a1008e8583bb91 Mon Sep 17 00:00:00 2001 From: Raphael Stolt Date: Mon, 11 Nov 2024 11:50:58 +0100 Subject: [PATCH 122/152] Adds a new Composer script --- composer.json | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/composer.json b/composer.json index fc9ece9..9350194 100644 --- a/composer.json +++ b/composer.json @@ -36,7 +36,8 @@ "lpv:application-version-guard": "Checks that the application version matches the given Git tag.", "lpv:application-phar-version-guard": "Checks that the PHAR version matches the given Git tag.", "lpv:static-analyse": "Runs a static code analysis via PHPStan.", - "lpv:validate-gitattributes": "Checks the leanness of this package." + "lpv:validate-gitattributes": "Checks the leanness of this package.", + "lpv:pre-commit-check": "Does a final (aggregated) check before committing." }, "scripts": { "lpv:test": "phpunit", @@ -47,7 +48,12 @@ "lpv:application-version-guard": "php bin/application-version --verify-tag-match=bin", "lpv:application-phar-version-guard": "php bin/application-version --verify-tag-match=phar", "lpv:static-analyse": "phpstan analyse --configuration phpstan.neon.dist", - "lpv:validate-gitattributes": "bin/lean-package-validator validate" + "lpv:validate-gitattributes": "bin/lean-package-validator validate", + "lpv:pre-commit-check": [ + "@lpv:test", + "@lpv:cs-lint", + "@lpv:static-analyse" + ] }, "config": { "preferred-install": "dist", From eb796720314a52d168c1e31dfe0e1e0aef16dded Mon Sep 17 00:00:00 2001 From: Raphael Stolt Date: Mon, 11 Nov 2024 12:30:31 +0100 Subject: [PATCH 123/152] Adds missing test --- src/Glob.php | 17 ++++++++++------- tests/GlobTest.php | 29 +++++++++++++++++++++++++++++ 2 files changed, 39 insertions(+), 7 deletions(-) create mode 100644 tests/GlobTest.php diff --git a/src/Glob.php b/src/Glob.php index 5023722..f44da96 100644 --- a/src/Glob.php +++ b/src/Glob.php @@ -57,28 +57,31 @@ public static function glob($pattern, $flags = 0, $forceFallback = false) } /** - * Find array elements matching a pattern. + * Find array elements matching a glob pattern. * * @param string $pattern * @param array $array * @param int $flags * @return array */ - public static function globArray(string $pattern, array $array, int $flags = FNM_CASEFOLD) + public static function globArray(string $pattern, array $array, int $flags = FNM_CASEFOLD): array { $pattern = \str_replace(['{', '}'], '', $pattern); $patternParts = \explode(',', $pattern); - foreach ($patternParts as $index => $patternPart) { - $matches[] = \array_filter($array, function ($val) use ($patternPart, $flags) { - return \fnmatch($patternPart, $val, $flags); + $matches = []; + foreach ($patternParts as $patternPart) { + $matches[] = \array_filter($array, function ($value) use ($patternPart, $flags) { + return \fnmatch($patternPart, $value, $flags); }); } $excludes = []; - foreach ($matches as $index => $value) { - $excludes[] = \array_values($value)[0]; + foreach ($matches as $match) { + if (\count(\array_values($match)) > 0) { + $excludes[] = \array_values($match)[0]; + } } return $excludes; diff --git a/tests/GlobTest.php b/tests/GlobTest.php new file mode 100644 index 0000000..e6781b4 --- /dev/null +++ b/tests/GlobTest.php @@ -0,0 +1,29 @@ +assertEquals($expectedResult, $actualResult); + + $actualResult = Glob::globArray( + '{composer.lock}', + ['spec.dist.yml', 'phpunit.dist.xml', 'README.md', 'LICENSE.md', 'docs/'] + ); + $this->assertEquals([], $actualResult); + } +} From d0da68f2aa81fdb85f63592d2e244e87abacb386 Mon Sep 17 00:00:00 2001 From: Raphael Stolt Date: Mon, 11 Nov 2024 13:05:37 +0100 Subject: [PATCH 124/152] Adds combining options test --- tests/Commands/ValidateCommandTest.php | 44 ++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/tests/Commands/ValidateCommandTest.php b/tests/Commands/ValidateCommandTest.php index 31ea654..d6b8d9e 100644 --- a/tests/Commands/ValidateCommandTest.php +++ b/tests/Commands/ValidateCommandTest.php @@ -499,6 +499,50 @@ public function readmeIsNotInSuggestedFileContent(): void Use the --create|-c option to create a .gitattributes file with the shown content. +CONTENT; + + $this->assertSame($expectedDisplay, $commandTester->getDisplay()); + $this->assertTrue($commandTester->getStatusCode() > Command::SUCCESS); + } + + #[Test] + public function licenseAndReadmeAreNotInSuggestedFileContent(): void + { + $artifactFilenames = [ + 'CONDUCT.md', + 'phpspec.yml.dist', + 'License.md', + 'README.md' + ]; + + $this->createTemporaryFiles( + $artifactFilenames, + ['specs', 'docs'] + ); + + $command = $this->application->find('validate'); + $commandTester = new CommandTester($command); + $commandTester->execute([ + 'command' => $command->getName(), + 'directory' => WORKING_DIRECTORY, + '--keep-readme' => true, + '--keep-license' => true, + ]); + + $expectedDisplay = <<temporaryDirectory}. + +Would expect the following .gitattributes file content: +* text=auto eol=lf + +.gitattributes export-ignore +CONDUCT.md export-ignore +docs/ export-ignore +phpspec.yml.dist export-ignore +specs/ export-ignore + +Use the --create|-c option to create a .gitattributes file with the shown content. + CONTENT; $this->assertSame($expectedDisplay, $commandTester->getDisplay()); From 7e1281d2d90504216f9d84f626da713f35e1eda6 Mon Sep 17 00:00:00 2001 From: Raphael Stolt Date: Mon, 11 Nov 2024 18:29:37 +0100 Subject: [PATCH 125/152] Updates phpstan/phpstan --- composer.json | 2 +- phpstan.neon.dist | 4 ++++ src/Commands/InitCommand.php | 3 +++ tests/Commands/ValidateCommandTest.php | 2 +- tests/Presets/FinderTest.php | 3 ++- tests/TestCase.php | 2 +- 6 files changed, 12 insertions(+), 4 deletions(-) diff --git a/composer.json b/composer.json index 9350194..818ba26 100644 --- a/composer.json +++ b/composer.json @@ -65,7 +65,7 @@ "mockery/mockery": "^1.0", "phlak/semver": "^4.1 || ^6.0", "php-mock/php-mock-phpunit": "^2.7||^1.1", - "phpstan/phpstan": "^1.11", + "phpstan/phpstan": "^2.0", "phpunit/phpunit": "^11.2.6||^10.5.25", "zenstruck/console-test": "^1.6" } diff --git a/phpstan.neon.dist b/phpstan.neon.dist index 192071a..cd547dd 100644 --- a/phpstan.neon.dist +++ b/phpstan.neon.dist @@ -3,9 +3,13 @@ parameters: paths: - src - tests + treatPhpDocTypesAsCertain: false reportUnmatchedIgnoredErrors: false ignoreErrors: - identifier: missingType.iterableValue + - identifier: argument.type + - identifier: identical.alwaysTrue + - identifier: method.alreadyNarrowedType - '#Constant WORKING_DIRECTORY not found.#' - '#Mockery\\MockInterface#' - '#Mockery\\LegacyMockInterface#' diff --git a/src/Commands/InitCommand.php b/src/Commands/InitCommand.php index adfbb0e..d50f4a9 100644 --- a/src/Commands/InitCommand.php +++ b/src/Commands/InitCommand.php @@ -109,6 +109,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int $directory = (string) $input->getArgument('directory'); $overwriteDefaultLpvFile = $input->getOption('overwrite'); $chosenPreset = (string) $input->getOption('preset'); + $globPatternFromPreset = false; if ($directory !== WORKING_DIRECTORY) { try { @@ -159,9 +160,11 @@ protected function execute(InputInterface $input, OutputInterface $output): int ); $verboseOutput = '+ Writing default glob pattern to .lpv file in ' . WORKING_DIRECTORY . '.'; + if ($globPatternFromPreset === true) { $verboseOutput = '+ Writing glob pattern for preset ' . $chosenPreset . ' to .lpv file in ' . WORKING_DIRECTORY . '.'; } + $output->writeln($verboseOutput, OutputInterface::VERBOSITY_VERBOSE); if ($bytesWritten === false) { diff --git a/tests/Commands/ValidateCommandTest.php b/tests/Commands/ValidateCommandTest.php index d6b8d9e..cfeb89b 100644 --- a/tests/Commands/ValidateCommandTest.php +++ b/tests/Commands/ValidateCommandTest.php @@ -179,7 +179,7 @@ public function showsDifferenceBetweenActualAndExpectedGitattributesContent(): v '--diff' => true, ]); - $actualDisplayRows = \array_values(\explode(PHP_EOL, $commandTester->getDisplay())); + $actualDisplayRows = \explode(PHP_EOL, $commandTester->getDisplay()); $expectedDiffRows = ['--- Original', '+++ Expected', '@@ -1 +1,2 @@']; foreach ($expectedDiffRows as $expectedDiffRow) { diff --git a/tests/Presets/FinderTest.php b/tests/Presets/FinderTest.php index 76cd28b..c21228f 100644 --- a/tests/Presets/FinderTest.php +++ b/tests/Presets/FinderTest.php @@ -33,7 +33,8 @@ public function findsExpectedPresetGlobByLanguageNames(string $languageName): vo { $finder = new Finder(new PhpPreset()); $presetGlob = $finder->getPresetGlobByLanguageName($languageName); - $this->assertTrue(\is_array($presetGlob)); + + $this->assertIsArray($presetGlob); } #[Test] diff --git a/tests/TestCase.php b/tests/TestCase.php index a394281..844b297 100755 --- a/tests/TestCase.php +++ b/tests/TestCase.php @@ -74,7 +74,7 @@ protected function createTemporaryFiles(array $files, array $directories = []) \touch($artifactFile); } - if (\is_array($directories) && \count($directories) > 0) { + if (\count($directories) > 0) { foreach ($directories as $directory) { $artifactDirectory = $this->temporaryDirectory . DIRECTORY_SEPARATOR From cb96f45481b674d96b42c42e8436ff9c91a77d19 Mon Sep 17 00:00:00 2001 From: Raphael Stolt Date: Thu, 28 Nov 2024 09:02:58 +0100 Subject: [PATCH 126/152] Moves cpx part --- README.md | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index c091e5c..47a561b 100755 --- a/README.md +++ b/README.md @@ -43,12 +43,6 @@ further utilisation via [Composer scripts](https://getcomposer.org/doc/articles/ composer require --dev stolt/lean-package-validator ``` -A third option to use the lean package validator is via [cpx](https://cpx.dev/). - -``` bash -cpx stolt/lean-package-validator validate -``` - > [!TIP] > As of release `v1.9.0` it's also possible to install and use the lean package validator > via a PHAR [file](https://github.com/raphaelstolt/lean-package-validator/releases/tag/v1.9.0). @@ -192,11 +186,10 @@ The `--overwrite|-o` option overwrites an existing `.lpv` file. The `--preset` option allows to choose from a predefined set of glob pattern. Available presets are `PHP`, `Python`, and `Go`. With `PHP` being the default. -## Utilisation via Composer scripts or it's dedicated GitHub Action +## Utilisation via Composer scripts, cpx, or it's dedicated GitHub Action To avoid that changes coming from contributions or own modifications slip into release/dist archives it -might be helpful to use a guarding [Composer script](https://getcomposer.org/doc/articles/scripts.md), -which will be available at everyone's fingertips. +might be helpful to use a guarding [Composer script](https://getcomposer.org/doc/articles/scripts.md), which will be available at everyone's fingertips. By adding the following to the project/micro-package its `composer.json` the `.gitattributes` file can now be easily validated via `composer validate-gitattributes`. @@ -208,6 +201,11 @@ now be easily validated via `composer validate-gitattributes`. }, } ``` +Another option to utilise the lean package validator is via [cpx](https://cpx.dev/). + +``` bash +cpx stolt/lean-package-validator validate +``` For utilising a dedicated GitHub Action have a look at the documentation over [here](https://github.com/raphaelstolt/lean-package-validator-action). From d22c858275f0bf5cd89cccdc35604f9d60eec33b Mon Sep 17 00:00:00 2001 From: Raphael Stolt Date: Thu, 28 Nov 2024 09:19:07 +0100 Subject: [PATCH 127/152] Fixes broken test --- composer.json | 2 +- tests/ApplicationTest.php | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/composer.json b/composer.json index 818ba26..9a3d4c1 100644 --- a/composer.json +++ b/composer.json @@ -66,7 +66,7 @@ "phlak/semver": "^4.1 || ^6.0", "php-mock/php-mock-phpunit": "^2.7||^1.1", "phpstan/phpstan": "^2.0", - "phpunit/phpunit": "^11.2.6||^10.5.25", + "phpunit/phpunit": "^11.4.4||^10.5.25", "zenstruck/console-test": "^1.6" } } diff --git a/tests/ApplicationTest.php b/tests/ApplicationTest.php index f47e306..b6f6a12 100644 --- a/tests/ApplicationTest.php +++ b/tests/ApplicationTest.php @@ -37,12 +37,12 @@ public function expectedCommandsAreListed(): void $this->assertStringContainsString( 'init', - $output[17], + \implode('', $output), 'Expected init command not listed.' ); $this->assertStringContainsString( 'validate', - $output[19], + \implode('', $output), 'Expected validate command not listed.' ); $this->assertEquals(Command::SUCCESS, $returnValue); From 1a96f62d607b0d7878203831b34276d76e3045be Mon Sep 17 00:00:00 2001 From: Raphael Stolt Date: Fri, 6 Dec 2024 09:40:03 +0100 Subject: [PATCH 128/152] Updates runner image --- .github/workflows/test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 033e454..db09f9c 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -5,7 +5,7 @@ on: push jobs: build: name: "PHPUnit (PHP ${{ matrix.php }})" - runs-on: "ubuntu-20.04" + runs-on: ubuntu-latest strategy: matrix: From c46061aa6fcd763c1159b73819d31194883b76f6 Mon Sep 17 00:00:00 2001 From: Raphael Stolt Date: Wed, 11 Dec 2024 14:42:32 +0100 Subject: [PATCH 129/152] Expands the PHP preset --- CHANGELOG.md | 4 ++++ src/Presets/PhpPreset.php | 2 ++ tests/AnalyserTest.php | 2 ++ tests/Commands/InitCommandTest.php | 2 ++ 4 files changed, 10 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 57bd9eb..d095d65 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,10 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/) and this p ## [Unreleased] +### Added + +- Further PHP preset expansion. + ## [v4.1.0] - 2024-11-11 ### Added diff --git a/src/Presets/PhpPreset.php b/src/Presets/PhpPreset.php index 5aa493e..cdfe1ce 100644 --- a/src/Presets/PhpPreset.php +++ b/src/Presets/PhpPreset.php @@ -25,12 +25,14 @@ public function getPresetGlob(): array 'composer-dependency-analyser*', 'collision-detector*', 'captainhook.json', + 'peck.json', 'infection*', 'phpstan*', 'sonar*', 'rector*', 'package*', 'pint.json', + '*debugbar.json', 'ecs*', '*.dist.*', '*.dist', diff --git a/tests/AnalyserTest.php b/tests/AnalyserTest.php index 43ee499..35d1c2f 100755 --- a/tests/AnalyserTest.php +++ b/tests/AnalyserTest.php @@ -1505,12 +1505,14 @@ public function returnsExpectedDefaultGlobPatterns(): void 'composer-dependency-analyser*', 'collision-detector*', 'captainhook.json', + 'peck.json', 'infection*', 'phpstan*', 'sonar*', 'rector*', 'package*', 'pint.json', + '*debugbar.json', 'ecs*', '*.dist.*', '*.dist', diff --git a/tests/Commands/InitCommandTest.php b/tests/Commands/InitCommandTest.php index 901d169..29ac6ac 100644 --- a/tests/Commands/InitCommandTest.php +++ b/tests/Commands/InitCommandTest.php @@ -82,12 +82,14 @@ public function createsExpectedDefaultLpvFile(): void composer-dependency-analyser* collision-detector* captainhook.json +peck.json infection* phpstan* sonar* rector* package* pint.json +*debugbar.json ecs* *.dist.* *.dist From 0f57c0cb8f530275cf38f67ed345f45ad319cb75 Mon Sep 17 00:00:00 2001 From: Raphael Stolt Date: Tue, 14 Jan 2025 09:06:16 +0100 Subject: [PATCH 130/152] Release version 4.1.1 --- CHANGELOG.md | 5 ++++- bin/lean-package-validator | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d095d65..ea7f619 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,8 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/) and this p ## [Unreleased] +## [v4.1.1] - 2025-01-14 + ### Added - Further PHP preset expansion. @@ -298,7 +300,8 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/) and this p - Initial release. -[Unreleased]: https://github.com/raphaelstolt/lean-package-validator/compare/v4.1.0...HEAD +[Unreleased]: https://github.com/raphaelstolt/lean-package-validator/compare/v4.1.1...HEAD +[v4.1.1]: https://github.com/raphaelstolt/lean-package-validator/compare/v4.1.0...v4.1.1 [v4.1.0]: https://github.com/raphaelstolt/lean-package-validator/compare/v4.0.5...v4.1.0 [v4.0.5]: https://github.com/raphaelstolt/lean-package-validator/compare/v4.0.4...v4.0.5 [v4.0.4]: https://github.com/raphaelstolt/lean-package-validator/compare/v4.0.3...v4.0.4 diff --git a/bin/lean-package-validator b/bin/lean-package-validator index 8f56305..85478cb 100755 --- a/bin/lean-package-validator +++ b/bin/lean-package-validator @@ -22,7 +22,7 @@ if (false === $autoloaded) { } \define('WORKING_DIRECTORY', \getcwd()); -\define('VERSION', '4.1.0'); +\define('VERSION', '4.1.1'); use Stolt\LeanPackage\Commands\InitCommand; use Stolt\LeanPackage\Commands\ValidateCommand; From 94775e32b0246849b0dcefdce680c4091ffa0c0c Mon Sep 17 00:00:00 2001 From: Raphael Stolt Date: Wed, 29 Jan 2025 13:06:10 +0100 Subject: [PATCH 131/152] Expands the pre-commit-check Composer script --- composer.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 9a3d4c1..4023782 100644 --- a/composer.json +++ b/composer.json @@ -52,7 +52,8 @@ "lpv:pre-commit-check": [ "@lpv:test", "@lpv:cs-lint", - "@lpv:static-analyse" + "@lpv:static-analyse", + "@lpv:application-version-guard" ] }, "config": { From 47872f8af061ea85ea2ed0f33bce953b656da404 Mon Sep 17 00:00:00 2001 From: Raphael Stolt Date: Mon, 3 Feb 2025 22:52:43 +0100 Subject: [PATCH 132/152] Expands the PHP preset --- CHANGELOG.md | 4 ++++ src/Presets/PhpPreset.php | 1 + tests/AnalyserTest.php | 1 + tests/Commands/InitCommandTest.php | 1 + 4 files changed, 7 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index ea7f619..09c74b7 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,10 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/) and this p ## [Unreleased] +### Added + +- Further PHP preset expansion. + ## [v4.1.1] - 2025-01-14 ### Added diff --git a/src/Presets/PhpPreset.php b/src/Presets/PhpPreset.php index cdfe1ce..c9a1f90 100644 --- a/src/Presets/PhpPreset.php +++ b/src/Presets/PhpPreset.php @@ -32,6 +32,7 @@ public function getPresetGlob(): array 'rector*', 'package*', 'pint.json', + 'renovate.json', '*debugbar.json', 'ecs*', '*.dist.*', diff --git a/tests/AnalyserTest.php b/tests/AnalyserTest.php index 35d1c2f..7e78d1a 100755 --- a/tests/AnalyserTest.php +++ b/tests/AnalyserTest.php @@ -1512,6 +1512,7 @@ public function returnsExpectedDefaultGlobPatterns(): void 'rector*', 'package*', 'pint.json', + 'renovate.json', '*debugbar.json', 'ecs*', '*.dist.*', diff --git a/tests/Commands/InitCommandTest.php b/tests/Commands/InitCommandTest.php index 29ac6ac..ae2633e 100644 --- a/tests/Commands/InitCommandTest.php +++ b/tests/Commands/InitCommandTest.php @@ -89,6 +89,7 @@ public function createsExpectedDefaultLpvFile(): void rector* package* pint.json +renovate.json *debugbar.json ecs* *.dist.* From b4e28b3dfa133591f651ff2df1f5ca1e896d5c68 Mon Sep 17 00:00:00 2001 From: Raphael Stolt Date: Tue, 4 Feb 2025 17:31:40 +0100 Subject: [PATCH 133/152] Adds sort-from-directories-to-files option --- .gitattributes | 1 + CHANGELOG.md | 1 + README.md | 6 +++++ src/Analyser.php | 42 ++++++++++++++++++++++++++++++-- src/Commands/ValidateCommand.php | 17 ++++++++++++- tests/AnalyserTest.php | 35 ++++++++++++++++++++++++++ 6 files changed, 99 insertions(+), 3 deletions(-) diff --git a/.gitattributes b/.gitattributes index 65da182..8f18d1c 100755 --- a/.gitattributes +++ b/.gitattributes @@ -13,6 +13,7 @@ bin/release-version export-ignore bin/start-watchman export-ignore box.json.dist export-ignore CHANGELOG.md export-ignore +composer.json export-ignore example/ export-ignore LICENSE.md export-ignore lpv-logo.png export-ignore diff --git a/CHANGELOG.md b/CHANGELOG.md index 09c74b7..726d8b7 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/) and this p ### Added +- Option to sort ignored artifacts from directories to files. Closes [#30](https://github.com/raphaelstolt/lean-package-validator/issues/30). - Further PHP preset expansion. ## [v4.1.1] - 2025-01-14 diff --git a/README.md b/README.md index 47a561b..f6d9d52 100755 --- a/README.md +++ b/README.md @@ -135,6 +135,12 @@ The `--align-export-ignores|-a` option will align the created or overwritten exp lean-package-validator validate [] --align-export-ignores --create ``` +The `--sort-from-directories-to-files|-s` option will order the export-ignores from directories to files for a better readability. + +``` bash +lean-package-validator validate [] --sort-from-directories-to-files --create +``` + The `--enforce-alignment` option will enforce a strict alignment of export-ignores in the `.gitattributes` file and fail validation if they aren't aligned. Per __default__ no alignment is enforced. diff --git a/src/Analyser.php b/src/Analyser.php index 7df0764..94f31ce 100755 --- a/src/Analyser.php +++ b/src/Analyser.php @@ -2,6 +2,7 @@ namespace Stolt\LeanPackage; +use PHPStan\Type\Php\DateIntervalDynamicReturnTypeExtension; use Stolt\LeanPackage\Exceptions\InvalidGlobPattern; use Stolt\LeanPackage\Exceptions\InvalidGlobPatternFile; use Stolt\LeanPackage\Exceptions\NonExistentGlobPatternFile; @@ -71,7 +72,7 @@ class Analyser private bool $staleExportIgnoresComparison = false; /** - * Whether to do a strict alignment comparsion of the export-ignores + * Whether to do a strict alignment comparison of the export-ignores * in the .gitattributes files against the expected ones * or not. * @@ -79,6 +80,14 @@ class Analyser */ private bool $strictAlignmentComparison = false; + /** + * Whether to sort the export-ignores + * in the .gitattributes from directories to files or not. + * + * @var boolean + */ + private bool $sortFromDirectoriesToFiles = false; + /** * Whether at least one export-ignore pattern has * a preceding slash or not. @@ -317,6 +326,13 @@ public function enableStrictOrderComparison(): Analyser return $this; } + public function sortFromDirectoriesToFiles(): Analyser + { + $this->sortFromDirectoriesToFiles = true; + + return $this; + } + /** * Guard for strict order comparison. * @@ -550,12 +566,18 @@ public function getExpectedGitattributesContent(array $postfixlessExportIgnores \sort($postfixlessExportIgnores, SORT_STRING | SORT_FLAG_CASE); if (\count($postfixlessExportIgnores) > 0) { - if ($this->isAlignExportIgnoresEnabled() || $this->isStrictAlignmentComparisonEnabled()) { + if ($this->sortFromDirectoriesToFiles === false && ($this->isAlignExportIgnoresEnabled() || $this->isStrictAlignmentComparisonEnabled())) { $postfixlessExportIgnores = $this->getAlignedExportIgnoreArtifacts( $postfixlessExportIgnores ); } + if ($this->sortFromDirectoriesToFiles) { + $postfixlessExportIgnores = $this->getByDirectoriesToFilesExportIgnoreArtifacts( + $postfixlessExportIgnores + ); + } + $content = \implode(" export-ignore" . $this->preferredEol, $postfixlessExportIgnores) . " export-ignore" . $this->preferredEol; @@ -898,6 +920,22 @@ private function getAlignedExportIgnoreArtifacts(array $artifacts): array }, $artifacts); } + private function getByDirectoriesToFilesExportIgnoreArtifacts(array $artifacts): array + { + $directories = \array_filter($artifacts, function ($artifact) { + if (\strpos($artifact, '/')) { + return $artifact; + } + }); + $files = \array_filter($artifacts, function ($artifact) { + if (\strpos($artifact, '/') === false) { + return $artifact; + } + }); + + return \array_merge($directories, $files); + } + /** * Is existing .gitattributes file having all export-ignore(s). * diff --git a/src/Commands/ValidateCommand.php b/src/Commands/ValidateCommand.php index 9d2a28f..acb3e28 100755 --- a/src/Commands/ValidateCommand.php +++ b/src/Commands/ValidateCommand.php @@ -102,6 +102,7 @@ protected function configure(): void $keepLicenseDescription = 'Do not export-ignore the license file'; $keepReadmeDescription = 'Do not export-ignore the README file'; $keepGlobPatternDescription = 'Do not export-ignore matching glob pattern e.g. {LICENSE.*,README.*,docs*}'; + $sortDescription = 'Sort from directories to files'; $alignExportIgnoresDescription = 'Align export-ignores on create or overwrite'; @@ -163,6 +164,12 @@ protected function configure(): void InputOption::VALUE_NONE, $alignExportIgnoresDescription ); + $this->addOption( + 'sort-from-directories-to-files', + 's', + InputOption::VALUE_NONE, + $sortDescription + ); $this->addOption( 'omit-header', null, @@ -226,14 +233,22 @@ protected function execute(InputInterface $input, OutputInterface $output): int $reportStaleExportIgnores = $input->getOption('report-stale-export-ignores'); $enforceStrictOrderComparison = $input->getOption('enforce-strict-order'); + $sortFromDirectoriesToFiles = $input->getOption('sort-from-directories-to-files'); - if ($enforceStrictOrderComparison) { + if ($enforceStrictOrderComparison && $sortFromDirectoriesToFiles === false) { $verboseOutput = '+ Enforcing strict order comparison.'; $output->writeln($verboseOutput, OutputInterface::VERBOSITY_VERBOSE); $this->analyser->enableStrictOrderComparison(); } + if ($sortFromDirectoriesToFiles) { + $verboseOutput = '+ Sorting from files to directories.'; + $output->writeln($verboseOutput, OutputInterface::VERBOSITY_VERBOSE); + + $this->analyser->sortFromDirectoriesToFiles(); + } + if ($reportStaleExportIgnores) { $verboseOutput = '+ Enforcing stale export ignores comparison.'; $output->writeln($verboseOutput, OutputInterface::VERBOSITY_VERBOSE); diff --git a/tests/AnalyserTest.php b/tests/AnalyserTest.php index 7e78d1a..80df6e2 100755 --- a/tests/AnalyserTest.php +++ b/tests/AnalyserTest.php @@ -1238,6 +1238,41 @@ public function exportIgnoresAreAligned(): void ); } + #[Test] + public function exportIgnoresAreSortedFromDirectoriesToFiles(): void + { + $artifactFilenames = [ + 'LICENSE.txt', + 'README.md', + 'phpspec.yml.dist', + ]; + + $this->createTemporaryFiles( + $artifactFilenames, + ['specs', 'docs'] + ); + + $expectedGitattributesContent = <<setDirectory($this->temporaryDirectory)->sortFromDirectoriesToFiles(); + $actualGitattributesContent = $analyser->getExpectedGitattributesContent(); + + $this->assertEquals( + $expectedGitattributesContent, + $actualGitattributesContent + ); + } + #[Test] #[Ticket('https://github.com/raphaelstolt/lean-package-validator/issues/4')] public function precedingSlashesAreDetected(): void From f11fd8b6a3eaa03dc26399ce5c4eb20fc0c49741 Mon Sep 17 00:00:00 2001 From: Raphael Stolt Date: Tue, 4 Feb 2025 18:34:13 +0100 Subject: [PATCH 134/152] Keeps composer.json in release --- .gitattributes | 1 - 1 file changed, 1 deletion(-) diff --git a/.gitattributes b/.gitattributes index 8f18d1c..65da182 100755 --- a/.gitattributes +++ b/.gitattributes @@ -13,7 +13,6 @@ bin/release-version export-ignore bin/start-watchman export-ignore box.json.dist export-ignore CHANGELOG.md export-ignore -composer.json export-ignore example/ export-ignore LICENSE.md export-ignore lpv-logo.png export-ignore From ac3e1368a17b3e77b28aa4e59c60db432bcae0a6 Mon Sep 17 00:00:00 2001 From: Raphael Stolt Date: Tue, 4 Feb 2025 17:44:17 +0100 Subject: [PATCH 135/152] Release version 4.2.0 --- CHANGELOG.md | 5 ++++- bin/lean-package-validator | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 726d8b7..6fb7633 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,8 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/) and this p ## [Unreleased] +## [v4.2.0] - 2025-02-06 + ### Added - Option to sort ignored artifacts from directories to files. Closes [#30](https://github.com/raphaelstolt/lean-package-validator/issues/30). @@ -305,7 +307,8 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/) and this p - Initial release. -[Unreleased]: https://github.com/raphaelstolt/lean-package-validator/compare/v4.1.1...HEAD +[Unreleased]: https://github.com/raphaelstolt/lean-package-validator/compare/v4.2.0...HEAD +[v4.2.0]: https://github.com/raphaelstolt/lean-package-validator/compare/v4.1.1...v4.2.0 [v4.1.1]: https://github.com/raphaelstolt/lean-package-validator/compare/v4.1.0...v4.1.1 [v4.1.0]: https://github.com/raphaelstolt/lean-package-validator/compare/v4.0.5...v4.1.0 [v4.0.5]: https://github.com/raphaelstolt/lean-package-validator/compare/v4.0.4...v4.0.5 diff --git a/bin/lean-package-validator b/bin/lean-package-validator index 85478cb..6f57096 100755 --- a/bin/lean-package-validator +++ b/bin/lean-package-validator @@ -22,7 +22,7 @@ if (false === $autoloaded) { } \define('WORKING_DIRECTORY', \getcwd()); -\define('VERSION', '4.1.1'); +\define('VERSION', '4.2.0'); use Stolt\LeanPackage\Commands\InitCommand; use Stolt\LeanPackage\Commands\ValidateCommand; From ac217a493cd574dce3a3be6d8fb72ac4f8019325 Mon Sep 17 00:00:00 2001 From: Raphael Stolt Date: Tue, 4 Feb 2025 18:51:21 +0100 Subject: [PATCH 136/152] Fixes spelling mistakes --- src/Analyser.php | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/src/Analyser.php b/src/Analyser.php index 94f31ce..832c29b 100755 --- a/src/Analyser.php +++ b/src/Analyser.php @@ -54,7 +54,7 @@ class Analyser private string $preferredEol = "\n"; /** - * Whether to do a strict comparsion of the export-ignores + * Whether to do a strict comparison of the export-ignores * in the .gitattributes files against the expected ones * or not. * @@ -63,7 +63,7 @@ class Analyser private bool $strictOrderComparison = false; /** - * Whether to do a strict comparsion for stale export-ignores + * Whether to do a strict comparison for stale export-ignores * in the .gitattributes files against the expected ones * or not. * @@ -550,35 +550,35 @@ public function getGitignoredPatterns(): array /** * Return the expected .gitattributes content. * - * @param array $postfixlessExportIgnores Expected patterns without an export-ignore postfix. + * @param array $postfixLessExportIgnores Expected patterns without an export-ignore postfix. * @return string */ - public function getExpectedGitattributesContent(array $postfixlessExportIgnores = []): string + public function getExpectedGitattributesContent(array $postfixLessExportIgnores = []): string { - if ($postfixlessExportIgnores === []) { - $postfixlessExportIgnores = $this->collectExpectedExportIgnores(); + if ($postfixLessExportIgnores === []) { + $postfixLessExportIgnores = $this->collectExpectedExportIgnores(); } - if (!$this->hasGitattributesFile() && \count($postfixlessExportIgnores) > 0) { - $postfixlessExportIgnores[] = '.gitattributes'; + if (!$this->hasGitattributesFile() && \count($postfixLessExportIgnores) > 0) { + $postfixLessExportIgnores[] = '.gitattributes'; } - \sort($postfixlessExportIgnores, SORT_STRING | SORT_FLAG_CASE); + \sort($postfixLessExportIgnores, SORT_STRING | SORT_FLAG_CASE); - if (\count($postfixlessExportIgnores) > 0) { + if (\count($postfixLessExportIgnores) > 0) { if ($this->sortFromDirectoriesToFiles === false && ($this->isAlignExportIgnoresEnabled() || $this->isStrictAlignmentComparisonEnabled())) { - $postfixlessExportIgnores = $this->getAlignedExportIgnoreArtifacts( - $postfixlessExportIgnores + $postfixLessExportIgnores = $this->getAlignedExportIgnoreArtifacts( + $postfixLessExportIgnores ); } if ($this->sortFromDirectoriesToFiles) { - $postfixlessExportIgnores = $this->getByDirectoriesToFilesExportIgnoreArtifacts( - $postfixlessExportIgnores + $postfixLessExportIgnores = $this->getByDirectoriesToFilesExportIgnoreArtifacts( + $postfixLessExportIgnores ); } - $content = \implode(" export-ignore" . $this->preferredEol, $postfixlessExportIgnores) + $content = \implode(" export-ignore" . $this->preferredEol, $postfixLessExportIgnores) . " export-ignore" . $this->preferredEol; if ($this->hasGitattributesFile()) { From 668f3529be02f9d69fcdca89df53d56049bd8f95 Mon Sep 17 00:00:00 2001 From: Raphael Stolt Date: Tue, 4 Feb 2025 22:40:42 +0100 Subject: [PATCH 137/152] Adds spelling mistakes check --- .gitattributes | 1 + .github/workflows/distribute.yml | 2 +- .github/workflows/lint.yml | 5 ++++- .github/workflows/static-analyse.yml | 2 +- .github/workflows/test-windows.yml | 2 +- .github/workflows/test.yml | 2 -- composer.json | 5 ++++- peck.json | 32 ++++++++++++++++++++++++++++ 8 files changed, 44 insertions(+), 7 deletions(-) create mode 100644 peck.json diff --git a/.gitattributes b/.gitattributes index 65da182..050de8e 100755 --- a/.gitattributes +++ b/.gitattributes @@ -16,6 +16,7 @@ CHANGELOG.md export-ignore example/ export-ignore LICENSE.md export-ignore lpv-logo.png export-ignore +peck.json export-ignore phpstan.neon.dist export-ignore phpunit.xml.dist export-ignore README.md export-ignore diff --git a/.github/workflows/distribute.yml b/.github/workflows/distribute.yml index 9ceefba..910b0c5 100644 --- a/.github/workflows/distribute.yml +++ b/.github/workflows/distribute.yml @@ -19,7 +19,7 @@ jobs: fail-fast: true matrix: php: - - "8.2" + - "8.3" steps: - name: Checkout diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 0768f1b..30632a4 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -11,7 +11,7 @@ jobs: fail-fast: true matrix: php: - - "8.1" + - "8.3" steps: - name: Checkout @@ -30,3 +30,6 @@ jobs: - name: Check leanness of package run: composer run-script lpv:validate-gitattributes + + - name: Check for spelling mistakes of package + run: sudo apt-get install aspell aspell-en && composer run-script lpv:spell-check diff --git a/.github/workflows/static-analyse.yml b/.github/workflows/static-analyse.yml index d8a84f8..c5cc83c 100644 --- a/.github/workflows/static-analyse.yml +++ b/.github/workflows/static-analyse.yml @@ -11,7 +11,7 @@ jobs: fail-fast: true matrix: php: - - "8.1" + - "8.3" steps: - name: Checkout diff --git a/.github/workflows/test-windows.yml b/.github/workflows/test-windows.yml index 59d5c7c..dde0143 100644 --- a/.github/workflows/test-windows.yml +++ b/.github/workflows/test-windows.yml @@ -10,7 +10,7 @@ jobs: strategy: matrix: php: - - "8.1" + - "8.3" steps: - name: Checkout diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index db09f9c..f162cab 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -10,8 +10,6 @@ jobs: strategy: matrix: php: - - "8.1" - - "8.2" - "8.3" - "8.4" diff --git a/composer.json b/composer.json index 4023782..c46a0aa 100644 --- a/composer.json +++ b/composer.json @@ -49,11 +49,13 @@ "lpv:application-phar-version-guard": "php bin/application-version --verify-tag-match=phar", "lpv:static-analyse": "phpstan analyse --configuration phpstan.neon.dist", "lpv:validate-gitattributes": "bin/lean-package-validator validate", + "lpv:spell-check": "./vendor/bin/peck", "lpv:pre-commit-check": [ "@lpv:test", "@lpv:cs-lint", "@lpv:static-analyse", - "@lpv:application-version-guard" + "@lpv:application-version-guard", + "@lpv:spell-check" ] }, "config": { @@ -64,6 +66,7 @@ "require-dev": { "friendsofphp/php-cs-fixer": "^3.0", "mockery/mockery": "^1.0", + "peckphp/peck": "^0.1.2", "phlak/semver": "^4.1 || ^6.0", "php-mock/php-mock-phpunit": "^2.7||^1.1", "phpstan/phpstan": "^2.0", diff --git a/peck.json b/peck.json new file mode 100644 index 0000000..d0e66df --- /dev/null +++ b/peck.json @@ -0,0 +1,32 @@ +{ + "preset": "base", + "ignore": { + "words": [ + "php", + "gitattributes", + "analyser", + "analyse", + "windowsish", + "lpv", + "readme", + "pathnames", + "gitignore", + "eol", + "nosort", + "nocheck", + "onlydir", + "noescape", + "errline", + "errfile", + "errno", + "initialise", + "errstr", + "delegator", + "gitignored", + "str", + "postfix", + "autoconfiguration" + ], + "paths": [] + } +} From 9a5700541086c553308b0f18874eb9347b03a2e8 Mon Sep 17 00:00:00 2001 From: Raphael Stolt Date: Fri, 7 Feb 2025 08:52:29 +0100 Subject: [PATCH 138/152] Adds new tree command --- CHANGELOG.md | 5 ++ README.md | 48 +++++++++++++ bin/lean-package-validator | 5 +- src/Commands/TreeCommand.php | 104 ++++++++++++++++++++++++++++ src/Exceptions/TreeNotAvailable.php | 6 ++ src/Tree.php | 65 +++++++++++++++++ 6 files changed, 232 insertions(+), 1 deletion(-) create mode 100644 src/Commands/TreeCommand.php create mode 100644 src/Exceptions/TreeNotAvailable.php create mode 100644 src/Tree.php diff --git a/CHANGELOG.md b/CHANGELOG.md index 6fb7633..ed30abd 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,11 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/) and this p ## [Unreleased] +## [v4.3.0] - 2025-02-07 + +### Added +- New `tree` command, that displays the source and dist package structure. Closes [#48](https://github.com/raphaelstolt/lean-package-validator/issues/48). + ## [v4.2.0] - 2025-02-06 ### Added diff --git a/README.md b/README.md index f6d9d52..f71ee29 100755 --- a/README.md +++ b/README.md @@ -192,6 +192,54 @@ The `--overwrite|-o` option overwrites an existing `.lpv` file. The `--preset` option allows to choose from a predefined set of glob pattern. Available presets are `PHP`, `Python`, and `Go`. With `PHP` being the default. +The `tree` command allows you to inspect the __flat__ `source` and `dist package` structure of the given project. + +``` bash +lean-package-validator tree [] --src + +Package: stolt/lean-package-validator +. +├── bin +├── coverage-reports +├── example +├── .git +├── .github +├── .idea +├── .phpunit.cache +├── src +├── tests +├── vendor +├── box.json.dist +├── CHANGELOG.md +├── composer.json +├── composer.lock +├── .editorconfig +├── .gitattributes +├── .gitignore +├── .gitmessage +├── LICENSE.md +├── lpv-logo.png +├── peck.json +├── .php-cs-fixer.php +├── phpstan.neon.dist +├── phpunit.xml.dist +└── README.md + +10 directories, 15 files +``` + +``` bash +lean-package-validator tree [] --dist-package + +Package: stolt/lean-package-validator +. +├── bin +├── composer.json +└── src + +2 directories, 1 file +``` + ## Utilisation via Composer scripts, cpx, or it's dedicated GitHub Action To avoid that changes coming from contributions or own modifications slip into release/dist archives it diff --git a/bin/lean-package-validator b/bin/lean-package-validator index 6f57096..dbdefc5 100755 --- a/bin/lean-package-validator +++ b/bin/lean-package-validator @@ -25,12 +25,14 @@ if (false === $autoloaded) { \define('VERSION', '4.2.0'); use Stolt\LeanPackage\Commands\InitCommand; +use Stolt\LeanPackage\Commands\TreeCommand; use Stolt\LeanPackage\Commands\ValidateCommand; use Stolt\LeanPackage\Analyser; use Stolt\LeanPackage\Archive; use Stolt\LeanPackage\Archive\Validator; use Stolt\LeanPackage\Presets\Finder; use Stolt\LeanPackage\Presets\PhpPreset; +use Stolt\LeanPackage\Tree; use Symfony\Component\Console\Application; $finder = new Finder(new PhpPreset()); @@ -44,9 +46,10 @@ $validateCommand = new ValidateCommand( $analyser, new Validator($archive) ); +$treeCommand = new TreeCommand(new Tree($archive)); $application = new Application('Lean package validator', VERSION); $application->addCommands( - [$initCommand, $validateCommand] + [$initCommand, $validateCommand, $treeCommand] ); $application->run(); diff --git a/src/Commands/TreeCommand.php b/src/Commands/TreeCommand.php new file mode 100644 index 0000000..5a3d0de --- /dev/null +++ b/src/Commands/TreeCommand.php @@ -0,0 +1,104 @@ +tree = $tree; + parent::__construct(); + } + + /** + * Command configuration. + * + * @return void + */ + protected function configure(): void + { + $this->directoryToOperateOn = WORKING_DIRECTORY; + $this->setName('tree'); + $description = 'Displays the source structure of a given ' + . "project/micro-package repository or it's dist package"; + $this->setDescription($description); + + $directoryDescription = 'The directory of a project/micro-package repository'; + + $this->addArgument( + 'directory', + InputArgument::OPTIONAL, + $directoryDescription, + $this->directoryToOperateOn + ); + + $srcDescription = 'Show the flat src structure of the project/micro-package repository'; + $distPackageDescription = 'Show the flat dist package structure of the project/micro-package'; + + $this->addOption('src', null, InputOption::VALUE_NONE, $srcDescription); + $this->addOption('dist-package', null, InputOption::VALUE_NONE, $distPackageDescription); + } + + protected function execute(InputInterface $input, OutputInterface $output): int + { + $directory = (string) $input->getArgument('directory'); + + if ($directory !== $this->directoryToOperateOn) { + if (!\file_get_contents($directory) || !\is_dir($directory)) { + $warning = "Warning: The provided directory " + . "'$directory' does not exist or is not a directory."; + $outputContent = '' . $warning . ''; + $output->writeln($outputContent); + + return Command::FAILURE; + } + } + + $showSrcTree = $input->getOption('src'); + $showDistPackageTree = $input->getOption('dist-package'); + + if ($showSrcTree) { + $verboseOutput = '+ Showing flat structure of package source.'; + $output->writeln($verboseOutput, OutputInterface::VERBOSITY_VERBOSE); + + $output->writeln('Package: ' . $this->getPackageName() . ''); + $output->write($this->tree->getTreeForSrc($this->directoryToOperateOn)); + + return Command::SUCCESS; + } + + if ($showDistPackageTree) { + $verboseOutput = '+ Showing flat structure of dist package.'; + $output->writeln($verboseOutput, OutputInterface::VERBOSITY_VERBOSE); + + $output->writeln('Package: ' . $this->getPackageName() . ''); + $output->write($this->tree->getTreeForDistPackage($this->directoryToOperateOn)); + + return Command::SUCCESS; + } + + return Command::FAILURE; + } + + protected function getPackageName(): string + { + $composerContentAsJson = \json_decode(\file_get_contents('composer.json'), true); + return \trim($composerContentAsJson['name']); + } +} diff --git a/src/Exceptions/TreeNotAvailable.php b/src/Exceptions/TreeNotAvailable.php new file mode 100644 index 0000000..f416d55 --- /dev/null +++ b/src/Exceptions/TreeNotAvailable.php @@ -0,0 +1,6 @@ +detectTreeCommand()) { + throw new TreeNotAvailable(); + } + + $this->archive = $archive; + + if (!$this->archive->isGitCommandAvailable()) { + throw new GitNotAvailable(); + } + } + + public function getTreeForSrc(string $directory): string + { + \exec( + 'tree -aL 1 --dirsfirst ' . \escapeshellarg($directory) . ' 2>&1', + $output + ); + + $output[0] = '.'; + + return \implode(PHP_EOL, $output) . PHP_EOL; + } + + public function getTreeForDistPackage(string $directory): string + { + $this->archive->createArchive(); + + \exec( + 'tar --list --exclude="*/*" --file ' . \escapeshellarg($this->archive->getFilename()) . ' | tree -aL 1 --dirsfirst --fromfile . 2>&1', + $output + ); + + $this->archive->removeArchive(); + + return \implode(PHP_EOL, $output) . PHP_EOL; + } + + protected function detectTreeCommand(string $command = 'tree'): bool + { + \exec('where ' . $command . ' 2>&1', $output, $returnValue); + if ((new OsHelper())->isWindows() === false) { + \exec('which ' . $command . ' 2>&1', $output, $returnValue); + } + + return $returnValue === 0; + } +} From 01c100db1eb2901ac436825d907923f4c8b87498 Mon Sep 17 00:00:00 2001 From: Raphael Stolt Date: Fri, 7 Feb 2025 09:39:23 +0100 Subject: [PATCH 139/152] Release 4.3.0 --- CHANGELOG.md | 3 ++- bin/lean-package-validator | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ed30abd..00f294f 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -312,7 +312,8 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/) and this p - Initial release. -[Unreleased]: https://github.com/raphaelstolt/lean-package-validator/compare/v4.2.0...HEAD +[Unreleased]: https://github.com/raphaelstolt/lean-package-validator/compare/v4.3.0...HEAD +[v4.3.0]: https://github.com/raphaelstolt/lean-package-validator/compare/v4.2.0...v4.3.0 [v4.2.0]: https://github.com/raphaelstolt/lean-package-validator/compare/v4.1.1...v4.2.0 [v4.1.1]: https://github.com/raphaelstolt/lean-package-validator/compare/v4.1.0...v4.1.1 [v4.1.0]: https://github.com/raphaelstolt/lean-package-validator/compare/v4.0.5...v4.1.0 diff --git a/bin/lean-package-validator b/bin/lean-package-validator index dbdefc5..7013cef 100755 --- a/bin/lean-package-validator +++ b/bin/lean-package-validator @@ -22,7 +22,7 @@ if (false === $autoloaded) { } \define('WORKING_DIRECTORY', \getcwd()); -\define('VERSION', '4.2.0'); +\define('VERSION', '4.3.0'); use Stolt\LeanPackage\Commands\InitCommand; use Stolt\LeanPackage\Commands\TreeCommand; From acbc37525a7a1bfe3d5e96aae82ac3f85531af1c Mon Sep 17 00:00:00 2001 From: Raphael Stolt Date: Fri, 7 Feb 2025 12:52:20 +0100 Subject: [PATCH 140/152] Improves documentation --- README.md | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index f71ee29..71e6341 100755 --- a/README.md +++ b/README.md @@ -179,7 +179,9 @@ Would expect the following .gitattributes file content: The `--report-stale-export-ignores` option extends the validation to look for export-ignore statements referencing non-existent repository artifacts. In combination with the `--diff` option these will be shown in the output. -#### Additional commands +### Additional commands + +#### Init command The `init` command will create an initial `.lpv` file with the default patterns used to match common repository artifacts. @@ -192,7 +194,10 @@ The `--overwrite|-o` option overwrites an existing `.lpv` file. The `--preset` option allows to choose from a predefined set of glob pattern. Available presets are `PHP`, `Python`, and `Go`. With `PHP` being the default. -The `tree` command allows you to inspect the __flat__ `source` and `dist package` structure of the given project. +#### Tree command + +The `tree` command of the lean package validator allows you to inspect the __flat__ `source` and `dist package` structure +of the given project/micro-package. It requires the [tree](https://en.wikipedia.org/wiki/Tree_(command)) command to be installed. ``` bash lean-package-validator tree [] --src From 6d5f03f760d4b6b3c221eefe8848909989793119 Mon Sep 17 00:00:00 2001 From: Raphael Stolt Date: Fri, 7 Feb 2025 14:09:10 +0100 Subject: [PATCH 141/152] Defaults the tree command to show the structure of the dist package --- src/Commands/TreeCommand.php | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/src/Commands/TreeCommand.php b/src/Commands/TreeCommand.php index 5a3d0de..9e405d1 100644 --- a/src/Commands/TreeCommand.php +++ b/src/Commands/TreeCommand.php @@ -83,17 +83,13 @@ protected function execute(InputInterface $input, OutputInterface $output): int return Command::SUCCESS; } - if ($showDistPackageTree) { - $verboseOutput = '+ Showing flat structure of dist package.'; - $output->writeln($verboseOutput, OutputInterface::VERBOSITY_VERBOSE); - - $output->writeln('Package: ' . $this->getPackageName() . ''); - $output->write($this->tree->getTreeForDistPackage($this->directoryToOperateOn)); + $verboseOutput = '+ Showing flat structure of dist package.'; + $output->writeln($verboseOutput, OutputInterface::VERBOSITY_VERBOSE); - return Command::SUCCESS; - } + $output->writeln('Package: ' . $this->getPackageName() . ''); + $output->write($this->tree->getTreeForDistPackage($this->directoryToOperateOn)); - return Command::FAILURE; + return Command::SUCCESS; } protected function getPackageName(): string From 0183856f8ae0d4aaecd814736b6102d54149f987 Mon Sep 17 00:00:00 2001 From: Raphael Stolt Date: Fri, 7 Feb 2025 15:33:45 +0100 Subject: [PATCH 142/152] Tree command operates on correct directory --- src/Commands/TreeCommand.php | 25 +++++++++++-------------- 1 file changed, 11 insertions(+), 14 deletions(-) diff --git a/src/Commands/TreeCommand.php b/src/Commands/TreeCommand.php index 9e405d1..c99653d 100644 --- a/src/Commands/TreeCommand.php +++ b/src/Commands/TreeCommand.php @@ -4,9 +4,6 @@ namespace Stolt\LeanPackage\Commands; -use Stolt\LeanPackage\Exceptions\GitNotAvailable; -use Stolt\LeanPackage\Exceptions\TreeNotAvailable; -use Stolt\LeanPackage\Helpers\Str as OsHelper; use Stolt\LeanPackage\Tree; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Input\InputArgument; @@ -57,21 +54,18 @@ protected function configure(): void protected function execute(InputInterface $input, OutputInterface $output): int { - $directory = (string) $input->getArgument('directory'); + $this->directoryToOperateOn = (string) $input->getArgument('directory'); - if ($directory !== $this->directoryToOperateOn) { - if (!\file_get_contents($directory) || !\is_dir($directory)) { - $warning = "Warning: The provided directory " - . "'$directory' does not exist or is not a directory."; - $outputContent = '' . $warning . ''; - $output->writeln($outputContent); + if (!\is_dir($this->directoryToOperateOn)) { + $warning = "Warning: The provided directory " + . "'$this->directoryToOperateOn' does not exist or is not a directory."; + $outputContent = '' . $warning . ''; + $output->writeln($outputContent); - return Command::FAILURE; - } + return Command::FAILURE; } $showSrcTree = $input->getOption('src'); - $showDistPackageTree = $input->getOption('dist-package'); if ($showSrcTree) { $verboseOutput = '+ Showing flat structure of package source.'; @@ -94,7 +88,10 @@ protected function execute(InputInterface $input, OutputInterface $output): int protected function getPackageName(): string { - $composerContentAsJson = \json_decode(\file_get_contents('composer.json'), true); + $composerContentAsJson = \json_decode( + \file_get_contents($this->directoryToOperateOn . DIRECTORY_SEPARATOR . 'composer.json'), + true + ); return \trim($composerContentAsJson['name']); } } From 5d6189b9bf4f89810594a39570ec4c5c422fa75d Mon Sep 17 00:00:00 2001 From: Raphael Stolt Date: Fri, 7 Feb 2025 15:36:04 +0100 Subject: [PATCH 143/152] Release 4.3.1 --- CHANGELOG.md | 11 ++++++++++- bin/lean-package-validator | 2 +- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 00f294f..e9a4bd5 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,14 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/) and this p ## [Unreleased] +## [v4.3.1] - 2025-02-07 + +### Added +- The tree command defaults to the `--dist-package` option. + +### Fixed +- A bug where the directory to operate on was incorrect. + ## [v4.3.0] - 2025-02-07 ### Added @@ -312,7 +320,8 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/) and this p - Initial release. -[Unreleased]: https://github.com/raphaelstolt/lean-package-validator/compare/v4.3.0...HEAD +[Unreleased]: https://github.com/raphaelstolt/lean-package-validator/compare/v4.3.1...HEAD +[v4.3.1]: https://github.com/raphaelstolt/lean-package-validator/compare/v4.3.0...v4.3.1 [v4.3.0]: https://github.com/raphaelstolt/lean-package-validator/compare/v4.2.0...v4.3.0 [v4.2.0]: https://github.com/raphaelstolt/lean-package-validator/compare/v4.1.1...v4.2.0 [v4.1.1]: https://github.com/raphaelstolt/lean-package-validator/compare/v4.1.0...v4.1.1 diff --git a/bin/lean-package-validator b/bin/lean-package-validator index 7013cef..716a200 100755 --- a/bin/lean-package-validator +++ b/bin/lean-package-validator @@ -22,7 +22,7 @@ if (false === $autoloaded) { } \define('WORKING_DIRECTORY', \getcwd()); -\define('VERSION', '4.3.0'); +\define('VERSION', '4.3.1'); use Stolt\LeanPackage\Commands\InitCommand; use Stolt\LeanPackage\Commands\TreeCommand; From 5e073c62bd78684f0c6911cb46674b0055e3202f Mon Sep 17 00:00:00 2001 From: Raphael Stolt Date: Sun, 9 Feb 2025 12:38:48 +0100 Subject: [PATCH 144/152] Excludes files for src option --- CHANGELOG.md | 5 +++++ src/Tree.php | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e9a4bd5..1f8696c 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,11 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/) and this p ## [Unreleased] +## [v4.3.2] - 2025-02-10 + +### Added +- The tree command with the `--src` option now exludes files from `.gitignore` and the `.git` directory. + ## [v4.3.1] - 2025-02-07 ### Added diff --git a/src/Tree.php b/src/Tree.php index 6a48be2..b404078 100644 --- a/src/Tree.php +++ b/src/Tree.php @@ -30,7 +30,7 @@ public function __construct(Archive $archive) public function getTreeForSrc(string $directory): string { \exec( - 'tree -aL 1 --dirsfirst ' . \escapeshellarg($directory) . ' 2>&1', + 'tree -aL 1 --dirsfirst ' . \escapeshellarg($directory) . ' --gitignore -I .git 2>&1', $output ); From f1a37f778232d03289aa86cad75bfce81c2510ea Mon Sep 17 00:00:00 2001 From: Raphael Stolt Date: Sun, 9 Feb 2025 12:57:22 +0100 Subject: [PATCH 145/152] Handles differing Unix tree command behaviour --- peck.json | 1 + src/Helpers/Str.php | 18 +++++++++++++++++- src/Tree.php | 22 ++++++++++++++-------- 3 files changed, 32 insertions(+), 9 deletions(-) diff --git a/peck.json b/peck.json index d0e66df..647b4ca 100644 --- a/peck.json +++ b/peck.json @@ -7,6 +7,7 @@ "analyser", "analyse", "windowsish", + "macish", "lpv", "readme", "pathnames", diff --git a/src/Helpers/Str.php b/src/Helpers/Str.php index 0a5f219..c1a9619 100644 --- a/src/Helpers/Str.php +++ b/src/Helpers/Str.php @@ -11,7 +11,7 @@ class Str * * @return boolean */ - public function isWindows($os = PHP_OS): bool + public function isWindows(string $os = PHP_OS): bool { if (\strtoupper(\substr($os, 0, 3)) !== 'WIN') { return false; @@ -19,4 +19,20 @@ public function isWindows($os = PHP_OS): bool return true; } + + /** + * Check if the operating system is macish. + * + * @param string $os + * + * @return boolean + */ + public function isMacOs(string $os = PHP_OS): bool + { + if (\strtoupper(\substr($os, 0, 3)) !== 'DAR') { + return false; + } + + return true; + } } diff --git a/src/Tree.php b/src/Tree.php index b404078..b5ca412 100644 --- a/src/Tree.php +++ b/src/Tree.php @@ -29,10 +29,13 @@ public function __construct(Archive $archive) public function getTreeForSrc(string $directory): string { - \exec( - 'tree -aL 1 --dirsfirst ' . \escapeshellarg($directory) . ' --gitignore -I .git 2>&1', - $output - ); + $command = 'tree -aL 1 --dirsfirst ' . \escapeshellarg($directory) . ' -I .git 2>&1'; + + if ((new OsHelper())->isMacOs()) { + $command = 'tree -aL 1 --dirsfirst ' . \escapeshellarg($directory) . ' --gitignore -I .git 2>&1'; + } + + \exec($command, $output); $output[0] = '.'; @@ -43,10 +46,13 @@ public function getTreeForDistPackage(string $directory): string { $this->archive->createArchive(); - \exec( - 'tar --list --exclude="*/*" --file ' . \escapeshellarg($this->archive->getFilename()) . ' | tree -aL 1 --dirsfirst --fromfile . 2>&1', - $output - ); + $command = 'tar --list --exclude="*/*" --file ' . \escapeshellarg($this->archive->getFilename()) . ' | tree -aL 1 --dirsfirst --fromfile . 2>&1'; + + if ((new OsHelper())->isMacOs()) { + $command = 'tar --list --file ' . \escapeshellarg($this->archive->getFilename()) . ' | tree -aL 1 --dirsfirst --fromfile . 2>&1'; + } + + \exec($command, $output); $this->archive->removeArchive(); From 889d35c5a0d1f29a42bdd4a5fc73d72086749797 Mon Sep 17 00:00:00 2001 From: Raphael Stolt Date: Fri, 7 Feb 2025 20:29:15 +0100 Subject: [PATCH 146/152] Adds integration tests --- tests/Commands/TreeCommandTest.php | 172 +++++++++++++++++++++++++++++ 1 file changed, 172 insertions(+) create mode 100644 tests/Commands/TreeCommandTest.php diff --git a/tests/Commands/TreeCommandTest.php b/tests/Commands/TreeCommandTest.php new file mode 100644 index 0000000..376c07d --- /dev/null +++ b/tests/Commands/TreeCommandTest.php @@ -0,0 +1,172 @@ +setUpTemporaryDirectory(); + if (!\defined('WORKING_DIRECTORY')) { + \define('WORKING_DIRECTORY', $this->temporaryDirectory); + } + $this->application = $this->getApplication(); + } + + /** + * Tear down test environment. + * + * @return void + */ + protected function tearDown(): void + { + if (\is_dir($this->temporaryDirectory)) { + $this->removeDirectory($this->temporaryDirectory); + } + } + + #[Test] + public function displayExpectedSrcTree(): void + { + $command = $this->application->find('tree'); + $commandTester = new CommandTester($command); + + $artifactFilenames = [ + '.gitattributes', + 'composer.json', + ]; + + $this->createTemporaryFiles( + $artifactFilenames, + ['src', 'tests', '.github', 'docs', 'bin'] + ); + + file_put_contents(WORKING_DIRECTORY . '/composer.json', \json_encode(['name' => 'test-src/package'])); + + $expectedDisplay = <<execute([ + 'command' => $command->getName(), + 'directory' => WORKING_DIRECTORY, + '--src' => true + ]); + + $this->assertSame($expectedDisplay, $commandTester->getDisplay()); + $commandTester->assertCommandIsSuccessful(); + } + + #[Test] + public function displayExpectedDistPackageTree(): void + { + $command = $this->application->find('tree'); + $commandTester = new CommandTester($command); + + $artifactFilenames = [ + '.gitattributes', + '.gitignore', + 'captainhook.json', + 'CODE_OF_CONDUCT.md', + 'CONTRIBUTING.md', + 'infection.json5', + 'LICENSE.txt', + 'phpstan.neon', + 'phpunit.xml', + 'README.md', + 'sonar-project.properties', + 'package.json', + 'package-lock.json', + 'composer.json', + ]; + + $this->createTemporaryFiles( + $artifactFilenames, + ['src', 'tests', '.github', 'docs', 'bin'] + ); + + file_put_contents(WORKING_DIRECTORY . '/composer.json', \json_encode(['name' => 'test-dist/package'])); + + $gitattributesContent = <<createTemporaryGitattributesFile($gitattributesContent); + + + $expectedDisplay = <<execute([ + 'command' => $command->getName(), + 'directory' => WORKING_DIRECTORY, + ]); + + $this->assertSame($expectedDisplay, $commandTester->getDisplay()); + $commandTester->assertCommandIsSuccessful(); + } + + /** + * @return Application + */ + protected function getApplication(): Application + { + $application = new Application(); + $application->add(new TreeCommand(new Tree(new Archive(WORKING_DIRECTORY)))); + + return $application; + } +} From fdc37eb4e8c8b8edf6131d650ec1a29210933600 Mon Sep 17 00:00:00 2001 From: Raphael Stolt Date: Mon, 10 Feb 2025 08:54:20 +0100 Subject: [PATCH 147/152] Release 4.3.2 --- CHANGELOG.md | 2 +- bin/lean-package-validator | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1f8696c..72e70ac 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,7 +10,7 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/) and this p ## [v4.3.2] - 2025-02-10 ### Added -- The tree command with the `--src` option now exludes files from `.gitignore` and the `.git` directory. +- The tree command with the `--src` option now excludes files from `.gitignore` and the `.git` directory. ## [v4.3.1] - 2025-02-07 diff --git a/bin/lean-package-validator b/bin/lean-package-validator index 716a200..2ea63c7 100755 --- a/bin/lean-package-validator +++ b/bin/lean-package-validator @@ -22,7 +22,7 @@ if (false === $autoloaded) { } \define('WORKING_DIRECTORY', \getcwd()); -\define('VERSION', '4.3.1'); +\define('VERSION', '4.3.2'); use Stolt\LeanPackage\Commands\InitCommand; use Stolt\LeanPackage\Commands\TreeCommand; From 84acf77d3b74e1c52d387936296c0ae225c57fcc Mon Sep 17 00:00:00 2001 From: Raphael Stolt Date: Mon, 10 Feb 2025 11:20:58 +0100 Subject: [PATCH 148/152] Adds a check for the Unix tree command >=v2.* --- README.md | 10 +++----- src/Commands/TreeCommand.php | 2 +- src/Tree.php | 50 +++++++++++++++++++++++++++--------- 3 files changed, 42 insertions(+), 20 deletions(-) diff --git a/README.md b/README.md index 71e6341..8a257a2 100755 --- a/README.md +++ b/README.md @@ -197,7 +197,8 @@ Available presets are `PHP`, `Python`, and `Go`. With `PHP` being the default. #### Tree command The `tree` command of the lean package validator allows you to inspect the __flat__ `source` and `dist package` structure -of the given project/micro-package. It requires the [tree](https://en.wikipedia.org/wiki/Tree_(command)) command to be installed. +of the given project/micro-package. It requires the [tree](https://en.wikipedia.org/wiki/Tree_(command)) Unix command to +be installed in version `>=2.0`. ``` bash lean-package-validator tree [] --src @@ -205,15 +206,10 @@ lean-package-validator tree [] --src Package: stolt/lean-package-validator . ├── bin -├── coverage-reports ├── example -├── .git ├── .github -├── .idea -├── .phpunit.cache ├── src ├── tests -├── vendor ├── box.json.dist ├── CHANGELOG.md ├── composer.json @@ -230,7 +226,7 @@ Package: stolt/lean-package-validator ├── phpunit.xml.dist └── README.md -10 directories, 15 files +5 directories, 15 files ``` ``` bash diff --git a/src/Commands/TreeCommand.php b/src/Commands/TreeCommand.php index c99653d..00e0b24 100644 --- a/src/Commands/TreeCommand.php +++ b/src/Commands/TreeCommand.php @@ -81,7 +81,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int $output->writeln($verboseOutput, OutputInterface::VERBOSITY_VERBOSE); $output->writeln('Package: ' . $this->getPackageName() . ''); - $output->write($this->tree->getTreeForDistPackage($this->directoryToOperateOn)); + $output->write($this->tree->getTreeForDistPackage()); return Command::SUCCESS; } diff --git a/src/Tree.php b/src/Tree.php index b5ca412..cd36828 100644 --- a/src/Tree.php +++ b/src/Tree.php @@ -2,6 +2,7 @@ namespace Stolt\LeanPackage; +use Stolt\LeanPackage\Exceptions\GitHeadNotAvailable; use Stolt\LeanPackage\Exceptions\GitNotAvailable; use Stolt\LeanPackage\Exceptions\TreeNotAvailable; use Stolt\LeanPackage\Helpers\Str as OsHelper; @@ -11,15 +12,10 @@ final class Tree private Archive $archive; /** - * @throws TreeNotAvailable * @throws GitNotAvailable */ public function __construct(Archive $archive) { - if (!$this->detectTreeCommand()) { - throw new TreeNotAvailable(); - } - $this->archive = $archive; if (!$this->archive->isGitCommandAvailable()) { @@ -27,14 +23,21 @@ public function __construct(Archive $archive) } } + /** + * @throws TreeNotAvailable + */ public function getTreeForSrc(string $directory): string { - $command = 'tree -aL 1 --dirsfirst ' . \escapeshellarg($directory) . ' -I .git 2>&1'; + if (!$this->detectTreeCommand()) { + throw new TreeNotAvailable('Unix tree command is not available.'); + } - if ((new OsHelper())->isMacOs()) { - $command = 'tree -aL 1 --dirsfirst ' . \escapeshellarg($directory) . ' --gitignore -I .git 2>&1'; + if (!$this->detectTreeCommandVersion()) { + throw new TreeNotAvailable('Required tree command version >=2.0 is not available.'); } + $command = 'tree -aL 1 --dirsfirst ' . \escapeshellarg($directory) . ' --gitignore -I .git 2>&1'; + \exec($command, $output); $output[0] = '.'; @@ -42,8 +45,17 @@ public function getTreeForSrc(string $directory): string return \implode(PHP_EOL, $output) . PHP_EOL; } - public function getTreeForDistPackage(string $directory): string + /** + * @throws TreeNotAvailable + * @throws GitHeadNotAvailable + * @throws GitNotAvailable + */ + public function getTreeForDistPackage(): string { + if (!$this->detectTreeCommand()) { + throw new TreeNotAvailable('Unix tree command is not available.'); + } + $this->archive->createArchive(); $command = 'tar --list --exclude="*/*" --file ' . \escapeshellarg($this->archive->getFilename()) . ' | tree -aL 1 --dirsfirst --fromfile . 2>&1'; @@ -59,13 +71,27 @@ public function getTreeForDistPackage(string $directory): string return \implode(PHP_EOL, $output) . PHP_EOL; } - protected function detectTreeCommand(string $command = 'tree'): bool + protected function detectTreeCommand(): bool { - \exec('where ' . $command . ' 2>&1', $output, $returnValue); + $command = 'where tree 2>&1'; + if ((new OsHelper())->isWindows() === false) { - \exec('which ' . $command . ' 2>&1', $output, $returnValue); + $command = 'which tree 2>&1'; } + \exec($command, $output, $returnValue); + return $returnValue === 0; } + + protected function detectTreeCommandVersion(): bool + { + \exec('tree --version 2>&1', $output); + + if (\strpos($output[0], 'v2')) { + return true; + } + + return false; + } } From 7907b8a0cae5693beffd12d45ac097d9cde327fe Mon Sep 17 00:00:00 2001 From: Raphael Stolt Date: Mon, 10 Feb 2025 13:03:04 +0100 Subject: [PATCH 149/152] Replaces dependency on Unix tree command --- README.md | 3 +- bin/lean-package-validator | 2 +- src/Tree.php | 110 +++++++++++++++++------------ tests/Commands/TreeCommandTest.php | 100 ++------------------------ 4 files changed, 75 insertions(+), 140 deletions(-) diff --git a/README.md b/README.md index 8a257a2..fc6d1c9 100755 --- a/README.md +++ b/README.md @@ -197,8 +197,7 @@ Available presets are `PHP`, `Python`, and `Go`. With `PHP` being the default. #### Tree command The `tree` command of the lean package validator allows you to inspect the __flat__ `source` and `dist package` structure -of the given project/micro-package. It requires the [tree](https://en.wikipedia.org/wiki/Tree_(command)) Unix command to -be installed in version `>=2.0`. +of the given project/micro-package. ``` bash lean-package-validator tree [] --src diff --git a/bin/lean-package-validator b/bin/lean-package-validator index 2ea63c7..35d7c59 100755 --- a/bin/lean-package-validator +++ b/bin/lean-package-validator @@ -46,7 +46,7 @@ $validateCommand = new ValidateCommand( $analyser, new Validator($archive) ); -$treeCommand = new TreeCommand(new Tree($archive)); +$treeCommand = new TreeCommand(new Tree(new Archive(WORKING_DIRECTORY,'tree-temp'))); $application = new Application('Lean package validator', VERSION); $application->addCommands( diff --git a/src/Tree.php b/src/Tree.php index cd36828..b0d9f61 100644 --- a/src/Tree.php +++ b/src/Tree.php @@ -2,10 +2,10 @@ namespace Stolt\LeanPackage; +use FilesystemIterator; use Stolt\LeanPackage\Exceptions\GitHeadNotAvailable; use Stolt\LeanPackage\Exceptions\GitNotAvailable; -use Stolt\LeanPackage\Exceptions\TreeNotAvailable; -use Stolt\LeanPackage\Helpers\Str as OsHelper; +use Symfony\Component\Finder\Finder; final class Tree { @@ -23,75 +23,97 @@ public function __construct(Archive $archive) } } - /** - * @throws TreeNotAvailable - */ public function getTreeForSrc(string $directory): string { - if (!$this->detectTreeCommand()) { - throw new TreeNotAvailable('Unix tree command is not available.'); - } - - if (!$this->detectTreeCommandVersion()) { - throw new TreeNotAvailable('Required tree command version >=2.0 is not available.'); - } - - $command = 'tree -aL 1 --dirsfirst ' . \escapeshellarg($directory) . ' --gitignore -I .git 2>&1'; - - \exec($command, $output); - - $output[0] = '.'; - - return \implode(PHP_EOL, $output) . PHP_EOL; + return $this->getTree($directory); } /** - * @throws TreeNotAvailable * @throws GitHeadNotAvailable * @throws GitNotAvailable */ public function getTreeForDistPackage(): string { - if (!$this->detectTreeCommand()) { - throw new TreeNotAvailable('Unix tree command is not available.'); + $this->archive->createArchive(); + $temporaryDirectory = \sys_get_temp_dir() . '/dist-release'; + + if (!\file_exists($temporaryDirectory)) { + \mkdir($temporaryDirectory); } - $this->archive->createArchive(); + $command = 'tar -xf ' . \escapeshellarg($this->archive->getFilename()) . ' --directory ' . $temporaryDirectory . ' 2>&1'; - $command = 'tar --list --exclude="*/*" --file ' . \escapeshellarg($this->archive->getFilename()) . ' | tree -aL 1 --dirsfirst --fromfile . 2>&1'; + \exec($command); - if ((new OsHelper())->isMacOs()) { - $command = 'tar --list --file ' . \escapeshellarg($this->archive->getFilename()) . ' | tree -aL 1 --dirsfirst --fromfile . 2>&1'; - } + $distReleaseTree = $this->getTree($temporaryDirectory); - \exec($command, $output); $this->archive->removeArchive(); + $this->removeDirectory($temporaryDirectory); - return \implode(PHP_EOL, $output) . PHP_EOL; + return $distReleaseTree; } - protected function detectTreeCommand(): bool + private function getTree(string $directory): string { - $command = 'where tree 2>&1'; - - if ((new OsHelper())->isWindows() === false) { - $command = 'which tree 2>&1'; + $finder = new Finder(); + $finder->in($directory)->ignoreVCSIgnored(true) + ->ignoreDotFiles(false)->depth(0)->sortByName()->sortByType(); + + $tree[] = '.'; + + $index = 0; + $directoryCount = 0; + $fileCount = 0; + + foreach ($finder as $file) { + $index++; + $filename = $file->getFilename(); + if ($file->isDir()) { + $filename = $file->getFilename() . '/'; + $directoryCount++; + } + + if ($file->isFile()) { + $fileCount++; + } + + if ($index < $finder->count()) { + $tree[] = '├── ' . $filename; + } else { + $tree[] = '└── ' . $filename; + } } - \exec($command, $output, $returnValue); - - return $returnValue === 0; + $tree[] = PHP_EOL; + $tree[] = \sprintf( + '%d %s, %d %s', + $directoryCount, + $directoryCount > 1 ? 'directories' : 'directory', + $fileCount, + $fileCount > 1 ? 'files': 'file' + ); + $tree[] = PHP_EOL; + + return \implode(PHP_EOL, $tree); } - protected function detectTreeCommandVersion(): bool + protected function removeDirectory(string $directory): void { - \exec('tree --version 2>&1', $output); - - if (\strpos($output[0], 'v2')) { - return true; + $files = new \RecursiveIteratorIterator( + new \RecursiveDirectoryIterator($directory, FilesystemIterator::SKIP_DOTS), + \RecursiveIteratorIterator::CHILD_FIRST + ); + + /** @var \SplFileInfo $fileinfo */ + foreach ($files as $fileinfo) { + if ($fileinfo->isDir()) { + @\rmdir($fileinfo->getRealPath()); + continue; + } + @\unlink($fileinfo->getRealPath()); } - return false; + @\rmdir($directory); } } diff --git a/tests/Commands/TreeCommandTest.php b/tests/Commands/TreeCommandTest.php index 376c07d..f962831 100644 --- a/tests/Commands/TreeCommandTest.php +++ b/tests/Commands/TreeCommandTest.php @@ -7,6 +7,7 @@ use PHPUnit\Framework\Attributes\Test; use Stolt\LeanPackage\Archive; use Stolt\LeanPackage\Commands\TreeCommand; +use Stolt\LeanPackage\Exceptions\GitNotAvailable; use Stolt\LeanPackage\Tests\CommandTester; use Stolt\LeanPackage\Tests\TestCase; use Stolt\LeanPackage\Tree; @@ -17,7 +18,7 @@ class TreeCommandTest extends TestCase /** * @var Application */ - private $application; + private Application $application; /** * Set up test environment. @@ -44,7 +45,7 @@ protected function tearDown(): void } #[Test] - public function displayExpectedSrcTree(): void + public function displaysExpectedSrcTree(): void { $command = $this->application->find('tree'); $commandTester = new CommandTester($command); @@ -59,107 +60,20 @@ public function displayExpectedSrcTree(): void ['src', 'tests', '.github', 'docs', 'bin'] ); - file_put_contents(WORKING_DIRECTORY . '/composer.json', \json_encode(['name' => 'test-src/package'])); - - $expectedDisplay = <<temporaryDirectory . '/composer.json', \json_encode(['name' => 'test-src/package'])); $commandTester->execute([ 'command' => $command->getName(), - 'directory' => WORKING_DIRECTORY, + 'directory' => $this->temporaryDirectory, '--src' => true ]); - $this->assertSame($expectedDisplay, $commandTester->getDisplay()); - $commandTester->assertCommandIsSuccessful(); - } - - #[Test] - public function displayExpectedDistPackageTree(): void - { - $command = $this->application->find('tree'); - $commandTester = new CommandTester($command); - - $artifactFilenames = [ - '.gitattributes', - '.gitignore', - 'captainhook.json', - 'CODE_OF_CONDUCT.md', - 'CONTRIBUTING.md', - 'infection.json5', - 'LICENSE.txt', - 'phpstan.neon', - 'phpunit.xml', - 'README.md', - 'sonar-project.properties', - 'package.json', - 'package-lock.json', - 'composer.json', - ]; - - $this->createTemporaryFiles( - $artifactFilenames, - ['src', 'tests', '.github', 'docs', 'bin'] - ); - - file_put_contents(WORKING_DIRECTORY . '/composer.json', \json_encode(['name' => 'test-dist/package'])); - - $gitattributesContent = <<createTemporaryGitattributesFile($gitattributesContent); - - - $expectedDisplay = <<execute([ - 'command' => $command->getName(), - 'directory' => WORKING_DIRECTORY, - ]); - - $this->assertSame($expectedDisplay, $commandTester->getDisplay()); + $this->assertStringContainsString('5 directories, 2 files', $commandTester->getDisplay()); $commandTester->assertCommandIsSuccessful(); } /** + * @throws GitNotAvailable * @return Application */ protected function getApplication(): Application From 8988c427f51093f6185757548f0857b9365e569f Mon Sep 17 00:00:00 2001 From: Raphael Stolt Date: Mon, 10 Feb 2025 13:06:30 +0100 Subject: [PATCH 150/152] Release 4.3.3 --- CHANGELOG.md | 9 ++++++++- bin/lean-package-validator | 2 +- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 72e70ac..bbdc01a 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,11 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/) and this p ## [Unreleased] +## [v4.3.3] - 2025-02-10 + +### Fixed +- Replace the dependency on the Unix `tree` command. Closes [#49](https://github.com/raphaelstolt/lean-package-validator/issues/49). + ## [v4.3.2] - 2025-02-10 ### Added @@ -325,7 +330,9 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/) and this p - Initial release. -[Unreleased]: https://github.com/raphaelstolt/lean-package-validator/compare/v4.3.1...HEAD +[Unreleased]: https://github.com/raphaelstolt/lean-package-validator/compare/v4.3.3...HEAD +[v4.3.3]: https://github.com/raphaelstolt/lean-package-validator/compare/v4.3.2...v4.3.3 +[v4.3.2]: https://github.com/raphaelstolt/lean-package-validator/compare/v4.3.1...v4.3.2 [v4.3.1]: https://github.com/raphaelstolt/lean-package-validator/compare/v4.3.0...v4.3.1 [v4.3.0]: https://github.com/raphaelstolt/lean-package-validator/compare/v4.2.0...v4.3.0 [v4.2.0]: https://github.com/raphaelstolt/lean-package-validator/compare/v4.1.1...v4.2.0 diff --git a/bin/lean-package-validator b/bin/lean-package-validator index 35d7c59..3a3da03 100755 --- a/bin/lean-package-validator +++ b/bin/lean-package-validator @@ -22,7 +22,7 @@ if (false === $autoloaded) { } \define('WORKING_DIRECTORY', \getcwd()); -\define('VERSION', '4.3.2'); +\define('VERSION', '4.3.3'); use Stolt\LeanPackage\Commands\InitCommand; use Stolt\LeanPackage\Commands\TreeCommand; From 0a4557af4617a665e67c95409a24f916fb3fd63a Mon Sep 17 00:00:00 2001 From: Raphael Stolt Date: Mon, 10 Feb 2025 13:10:06 +0100 Subject: [PATCH 151/152] Improves documentation --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index fc6d1c9..1661513 100755 --- a/README.md +++ b/README.md @@ -197,7 +197,7 @@ Available presets are `PHP`, `Python`, and `Go`. With `PHP` being the default. #### Tree command The `tree` command of the lean package validator allows you to inspect the __flat__ `source` and `dist package` structure -of the given project/micro-package. +of the given project/micro-package. It is __not__ intended for validation use. ``` bash lean-package-validator tree [] --src From fb474a6902c93fe317c46e573ad194ff88820934 Mon Sep 17 00:00:00 2001 From: Raphael Stolt Date: Mon, 10 Feb 2025 14:21:19 +0100 Subject: [PATCH 152/152] Improves contribution guideline --- .github/CONTRIBUTING.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md index d73be63..1644ec3 100755 --- a/.github/CONTRIBUTING.md +++ b/.github/CONTRIBUTING.md @@ -9,3 +9,5 @@ Thanks for considering to contribute to the `lean package validator`. Please fol - Commits __MUST__ use the provided [commit message template](../.gitmessage), which follows the [rules](http://chris.beams.io/posts/git-commit/) described by Chris Beams. It can be configured via `composer lpv:configure-commit-template` prior to committing. - All upstreamed contributions __MUST__ use [feature / topic branches](https://git-scm.com/book/en/v2/Git-Branching-Branching-Workflows) to ease merging. + +- Please run `composer lpv:pre-commit-check` before opening a pull request.