diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md new file mode 100644 index 0000000..e5ca37b --- /dev/null +++ b/.github/CONTRIBUTING.md @@ -0,0 +1,34 @@ +# CONTRIBUTING + +## Code Contributions + +## Installation + +Install project dependencies and test tools by running the following commands. + +```bash +$ composer install +``` + +## Running tests + +```bash +$ composer test +``` +```bash +$ composer coverage // xdebug +$ composer pcov // pcov +``` + +Add tests for your new code ensuring that you have 100% code coverage. +In rare cases, code may be excluded from test coverage using `@codeCoverageIgnore`. + +## Sending a pull request + +To ensure your PHP code changes pass the CI checks, make sure to run all the same checks before submitting a PR. + +```bash +$ composer tests +``` + +When you make a pull request, the tests will automatically be run again by GH action on multiple php versions. diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md new file mode 100644 index 0000000..55e8c3e --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -0,0 +1,14 @@ +--- +name: Bug Report +about: Create a bug report +labels: Bug +--- + +### Bug Report + + + +### How to reproduce + + + diff --git a/.github/ISSUE_TEMPLATE/feature.md b/.github/ISSUE_TEMPLATE/feature.md new file mode 100644 index 0000000..5a19855 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature.md @@ -0,0 +1,7 @@ +--- +name: Feature +about: Suggest a new feature or enhancement +labels: Feature +--- + + diff --git a/.github/ISSUE_TEMPLATE/question.md b/.github/ISSUE_TEMPLATE/question.md new file mode 100644 index 0000000..747f85f --- /dev/null +++ b/.github/ISSUE_TEMPLATE/question.md @@ -0,0 +1,7 @@ +--- +name: Question +about: Ask a question regarding software usage +labels: Support +--- + + diff --git a/.github/SECURITY.md b/.github/SECURITY.md new file mode 100644 index 0000000..7d68164 --- /dev/null +++ b/.github/SECURITY.md @@ -0,0 +1,6 @@ +# Reporting a vulnerability + +If you have found any issues that might have security implications, +please send a report privately to akihito.koriyama@gmail.com + +Do not report security reports publicly. diff --git a/.github/workflows/coding-standards.yml b/.github/workflows/coding-standards.yml new file mode 100644 index 0000000..7ba88b1 --- /dev/null +++ b/.github/workflows/coding-standards.yml @@ -0,0 +1,41 @@ +name: Coding Standards + +on: + push: + pull_request: + workflow_dispatch: + +jobs: + coding-standards: + name: Coding Standards + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v2 + + - name: Setup PHP + uses: shivammathur/setup-php@v2 + with: + php-version: 8.0 + tools: cs2pr + coverage: none + + - name: Get composer cache directory + id: composer-cache + run: echo "::set-output name=dir::$(composer config cache-files-dir)" + + - name: Cache dependencies + uses: actions/cache@v2 + with: + path: ${{ steps.composer-cache.outputs.dir }} + key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }} + restore-keys: ${{ runner.os }}-composer- + + - name: Install dependencies + run: composer install --no-interaction --no-progress --prefer-dist + + - name: Validate composer.json + run: composer validate --strict + + - name: Run PHP_CodeSniffer + run: ./vendor/bin/phpcs -q --no-colors --report=checkstyle src tests | cs2pr diff --git a/.github/workflows/continuous-integration.yml b/.github/workflows/continuous-integration.yml new file mode 100644 index 0000000..20e8b14 --- /dev/null +++ b/.github/workflows/continuous-integration.yml @@ -0,0 +1,61 @@ +name: Continuous Integration + +on: + push: + pull_request: + workflow_dispatch: + schedule: + - cron: '42 15 * * *' + +jobs: + phpunit: + name: PHPUnit + runs-on: ubuntu-latest + strategy: + matrix: + operating-system: + - ubuntu-latest + php-version: + - '7.3' + - '7.4' + - '8.0' + dependencies: + - lowest + - highest + steps: + - name: Checkout + uses: actions/checkout@v1 + + - name: Setup PHP ${{ matrix.php-version }} + uses: shivammathur/setup-php@v2 + with: + php-version: ${{ matrix.php-version }} + coverage: pcov + ini-values: zend.assertions=1 + + - name: Get composer cache directory + id: composer-cache + run: echo "::set-output name=dir::$(composer config cache-files-dir)" + + - name: Cache dependencies + uses: actions/cache@v2 + with: + path: ${{ steps.composer-cache.outputs.dir }} + key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }} + restore-keys: ${{ runner.os }}-composer- + + - name: Install lowest dependencies + if: ${{ matrix.dependencies == 'lowest' }} + run: composer update --prefer-lowest --no-interaction --no-progress --no-suggest + + - name: Install highest dependencies + if: ${{ matrix.dependencies == 'highest' }} + run: composer update --no-interaction --no-progress --no-suggest + + - name: Run test suite + run: ./vendor/bin/phpunit --coverage-clover=coverage.xml + + - name: Upload coverage report + uses: codecov/codecov-action@v1 + with: + file: ./coverage.xml diff --git a/.github/workflows/static-analysis.yml b/.github/workflows/static-analysis.yml new file mode 100644 index 0000000..b14f27c --- /dev/null +++ b/.github/workflows/static-analysis.yml @@ -0,0 +1,113 @@ +name: Static Analysis + +on: + push: + pull_request: + workflow_dispatch: + +jobs: + static-analysis-phpstan: + name: Static Analysis with PHPStan + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v2 + + - name: Setup PHP + uses: shivammathur/setup-php@v2 + with: + php-version: 8.0 + tools: cs2pr + coverage: none + + - name: Get composer cache directory + id: composer-cache + run: echo "::set-output name=dir::$(composer config cache-files-dir)" + + - name: Cache dependencies + uses: actions/cache@v2 + with: + path: ${{ steps.composer-cache.outputs.dir }} + key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }} + restore-keys: ${{ runner.os }}-composer- + + - name: Install dependencies + run: composer install --no-interaction --no-progress --prefer-dist + + - name: Run PHPStan + run: ./vendor/bin/phpstan analyse -c phpstan.neon --no-progress --no-interaction --error-format=checkstyle | cs2pr + + static-analysis-psalm: + name: Static Analysis with Psalm + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v2 + + - name: Setup PHP + uses: shivammathur/setup-php@v2 + with: + php-version: 8.0 + tools: cs2pr + coverage: none + + - name: Get composer cache directory + id: composer-cache + run: echo "::set-output name=dir::$(composer config cache-files-dir)" + + - name: Install dependencies + run: composer install --no-interaction --no-progress --prefer-dist + + - name: Run Psalm + run: ./vendor/bin/psalm --show-info=false --output-format=checkstyle --shepherd | cs2pr + + static-analysis-phpmd: + name: Static Analysis with PHPMD + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v2 + + - name: Setup PHP + uses: shivammathur/setup-php@v2 + with: + php-version: 7.4 + + - name: Get composer cache directory + id: composer-cache + run: echo "::set-output name=dir::$(composer config cache-files-dir)" + + - name: Cache dependencies + uses: actions/cache@v2 + with: + path: ${{ steps.composer-cache.outputs.dir }} + key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }} + restore-keys: ${{ runner.os }}-composer- + + - name: Install dependencies + run: composer install --no-interaction --no-progress --prefer-dist + + static-analysis-composer-require-checker: + name: Static Analysis with ComposerRequireChecker + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v2 + + - name: Setup PHP + uses: shivammathur/setup-php@v2 + with: + php-version: 8.0 + coverage: none + + - name: Get composer cache directory + id: composer-cache + run: echo "::set-output name=dir::$(composer config cache-files-dir)" + + - name: Install dependencies + run: | + composer install --no-interaction --no-progress --prefer-dist + composer require --dev maglnet/composer-require-checker ^3.0 + + - name: Run composer-require-checker + run: ./vendor/bin/composer-require-checker check ./composer.json diff --git a/.gitignore b/.gitignore index 6a5f138..59904aa 100644 --- a/.gitignore +++ b/.gitignore @@ -1,9 +1,7 @@ +/.phpunit.result.cache +/.phpcs-cache /vendor/ +/vendor-bin/tools/vendor/ /build/ -/.idea/ - -/composer.lock /phpunit.xml -/.phpunit.result.cache -/.php_cs.cache -.phpcs-cache +composer.lock diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 547a552..0000000 --- a/.travis.yml +++ /dev/null @@ -1,55 +0,0 @@ -language: php - -php: - - 7.2 - - 7.3 - - 7.4 - -cache: - directories: - - ./vendor - - $HOME/.composer/cache - -before_install: - - mv ~/.phpenv/versions/$(phpenv version-name)/etc/conf.d/xdebug.ini{,.disabled} || echo "xdebug not available" - - composer validate - - composer self-update - -install: - - composer update - -script: - - ./vendor/bin/phpunit; - -jobs: - fast_finish: true - include: - - stage: Test - name: Lowest dependencies - php: 7.4 - install: composer update --prefer-dist --prefer-lowest - - - stage: Code Quality - name: Code coverage - php: 7.4 - before_script: - - mv ~/.phpenv/versions/$(phpenv version-name)/etc/conf.d/xdebug.ini{.disabled,} - - if [[ ! $(php -m | grep -si xdebug) ]]; then echo "xdebug required for coverage"; exit 1; fi - script: - - ./vendor/bin/phpunit -v --coverage-clover ./build/logs/clover.xml - after_script: - - wget https://scrutinizer-ci.com/ocular.phar && php ocular.phar code-coverage:upload --format=php-clover coverage.clover; - - - stage: Code Quality - name: Static analysis - php: 7.4 - script: - - ./vendor/bin/phpstan analyse -c phpstan.neon --no-progress --no-interaction; - - ./vendor/bin/psalm --show-info=false - - ./vendor/bin/phpmetrics --exclude=Exception src - - - stage: Code Quality - name: Coding standards - php: 7.4 - script: - - ./vendor/bin/phpcs diff --git a/composer.json b/composer.json index f6e60de..19a4611 100644 --- a/composer.json +++ b/composer.json @@ -9,18 +9,18 @@ } ], "require": { - "php": ">=7.2.0", + "php": "^7.3 || ^8.0", "vlucas/phpdotenv": "^5.1" }, "require-dev": { - "phpunit/phpunit": "^8.5", - "squizlabs/php_codesniffer": "^3.5", - "friendsofphp/php-cs-fixer": "^2.16", - "phpmd/phpmd": "^2.8", + "phpunit/phpunit": "^9.5", + "doctrine/coding-standard": "^9.0", + "phpmd/phpmd": "^2.10", "phpstan/phpstan": "^0.12", - "vimeo/psalm": "^3.8", - "phpmetrics/phpmetrics": "^2.6", - "doctrine/coding-standard": "^8.1" + "psalm/plugin-phpunit": "^0.15", + "slevomat/coding-standard": "^7.0", + "squizlabs/php_codesniffer": "^3.6", + "vimeo/psalm": "^4.7" }, "autoload": { "psr-4": { @@ -41,13 +41,12 @@ ], "tests": [ "@cs", - "./vendor/bin/phpmd src,tests text ./phpmd.xml", "./vendor/bin/phpstan analyse -c phpstan.neon --no-progress", "./vendor/bin/psalm", "@test" ], "coverage": [ - "php -dzend_extension=xdebug.so ./vendor/bin/phpunit --coverage-text --coverage-html=build/coverage" + "php -dzend_extension=xdebug.so -dxdebug.mode=coverage ./vendor/bin/phpunit --coverage-text --coverage-html=build/coverage" ], "cs": "./vendor/bin/phpcs", "cs-fix": "./vendor/bin/phpcbf", diff --git a/phpcs.xml b/phpcs.xml index d9826f8..ec9dbb5 100755 --- a/phpcs.xml +++ b/phpcs.xml @@ -2,14 +2,16 @@ BEAR.Skeleton Coding Standard - + + + @@ -23,19 +25,24 @@ - + + + + + - - - - - - + */tests/Fake/* + */tmp/* - + + + + + + diff --git a/phpmd.xml b/phpmd.xml index eacbfc4..a705e52 100644 --- a/phpmd.xml +++ b/phpmd.xml @@ -1,38 +1,23 @@ - - - - - - - - - - - - - - + PHPMD rule sets + + + + + + + - - - - + - - + + + - - - - - - - - - + diff --git a/phpstan.neon b/phpstan.neon index 9175a61..13ec8a3 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -3,5 +3,3 @@ parameters: paths: - src - tests - ignoreErrors: - checkMissingIterableValueType: false diff --git a/phpunit.xml.dist b/phpunit.xml.dist index b07d809..fb27b69 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -1,24 +1,13 @@ - - - - tests/Resource - - - tests/Hypermedia - - - tests/Http - - - - - src - - src/Bootstrap.php - - - + + + + src + + + + + tests + + diff --git a/tests/DotenvTest.php b/tests/DotenvTest.php index a6059e2..d522358 100644 --- a/tests/DotenvTest.php +++ b/tests/DotenvTest.php @@ -6,9 +6,12 @@ use PHPUnit\Framework\TestCase; +use function getenv; + class DotenvTest extends TestCase { - protected Dotenv $dotenv; + /** @var Dotenv */ + protected $dotenv; protected function setUp(): void { @@ -39,4 +42,10 @@ public function testLoadGetEnv(): void $this->assertSame(getenv('FOO'), 'BAR'); } + public function testLoadNothing(): void + { + $_ENV = []; + $this->dotenv->load(__DIR__ . '/Fake/none'); + $this->assertArrayNotHasKey('FOO', $_ENV); + } } diff --git a/tests/Fake/none/.placeholder b/tests/Fake/none/.placeholder new file mode 100644 index 0000000..e69de29