From 1497772ebf3eb1597502a4fd4d613ab809dd4162 Mon Sep 17 00:00:00 2001 From: Tan Nguyen Date: Tue, 12 Dec 2023 16:29:37 +0700 Subject: [PATCH] Updated project structure. (#16) --- .circleci/config.yml | 14 +++--- .github/PULL_REQUEST_TEMPLATE.md | 19 +++++++ .github/release-drafter.yml | 12 +++++ .github/workflows/auto-assign-pr-author.yml | 16 ++++++ .github/workflows/release.yml | 41 +++++++++++++++ README.md | 46 +++++++++++------ composer.json | 30 ++++++++++- docker-compose.yml | 2 +- phpmd.xml | 24 +++++++++ phpstan.neon | 16 ++++++ renovate.json | 7 +++ .../FormatExtension.php | 8 +-- .../Printer/PrinterProgressFail.php | 50 +++++++++++++------ 13 files changed, 240 insertions(+), 45 deletions(-) create mode 100644 .github/PULL_REQUEST_TEMPLATE.md create mode 100644 .github/release-drafter.yml create mode 100644 .github/workflows/auto-assign-pr-author.yml create mode 100644 .github/workflows/release.yml create mode 100644 phpmd.xml create mode 100644 phpstan.neon create mode 100644 renovate.json diff --git a/.circleci/config.yml b/.circleci/config.yml index ec0249f..d254b34 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -14,26 +14,26 @@ jobs: command: composer validate --ansi --strict - run: name: Start containers. - command: docker-compose up -d --build + command: docker compose up -d --build - run: name: Copy codebase into container. - command: docker cp -L /app/. $(docker-compose ps -q phpserver):/app/ + command: docker cp -L /app/. $(docker compose ps -q phpserver):/app/ - run: name: Install dev dependencies. - command: docker-compose exec phpserver composer install --ansi --no-suggest + command: docker compose exec phpserver composer install --ansi --no-suggest - run: name: Lint code. - command: docker-compose exec phpserver vendor/bin/phpcs + command: docker compose exec phpserver vendor/bin/phpcs - run: name: Run tests. command: | - docker-compose exec phpserver mkdir -p /app/screenshots - docker-compose exec phpserver vendor/bin/behat + docker compose exec phpserver mkdir -p /app/screenshots + docker compose exec phpserver vendor/bin/behat - run: name: Copy artifacts. command: | mkdir -p /tmp/artifacts/behat - docker cp $(docker-compose ps -q phpserver):/app/screenshots /tmp/artifacts/behat + docker cp $(docker compose ps -q phpserver):/app/screenshots /tmp/artifacts/behat when: always - store_artifacts: path: /tmp/artifacts diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md new file mode 100644 index 0000000..813aa2e --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -0,0 +1,19 @@ +## Checklist before requesting a review + +- [ ] I have formatted the subject to include ticket number + as `[PRJ-123] Verb in past tense with dot at the end.` +- [ ] I have added a link to the issue tracker +- [ ] I have provided information in `Changed` section about WHY something was + done if this was not a normal implementation +- [ ] I have performed a self-review of my code +- [ ] I have commented my code, particularly in hard-to-understand areas +- [ ] I have added tests that prove my fix is effective or that my feature works +- [ ] I have run new and existing relevant tests locally with my changes, and + they passed +- [ ] I have provided screenshots, where applicable + +## Changed + +1. + +## Screenshots diff --git a/.github/release-drafter.yml b/.github/release-drafter.yml new file mode 100644 index 0000000..699ff47 --- /dev/null +++ b/.github/release-drafter.yml @@ -0,0 +1,12 @@ +name-template: '$NEXT_MINOR_VERSION' +tag-template: '$NEXT_MINOR_VERSION' +change-template: '- $TITLE @$AUTHOR (#$NUMBER)' +change-title-escapes: '\<*_&' # You can add # and @ to disable mentions, and add ` to disable code blocks. +template: | + ## What's new since $PREVIOUS_TAG + + $CHANGES + + **Full Changelog**: https://github.com/$OWNER/$REPOSITORY/compare/$PREVIOUS_TAG...$NEXT_MINOR_VERSION + + $CONTRIBUTORS diff --git a/.github/workflows/auto-assign-pr-author.yml b/.github/workflows/auto-assign-pr-author.yml new file mode 100644 index 0000000..d80454a --- /dev/null +++ b/.github/workflows/auto-assign-pr-author.yml @@ -0,0 +1,16 @@ +name: 'Auto Author Assign' + +on: + pull_request_target: + types: + - opened + - reopened + +permissions: + pull-requests: write + +jobs: + assign-author: + runs-on: ubuntu-latest + steps: + - uses: toshimaru/auto-author-assign@v2.0.1 diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..8800904 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,41 @@ +name: Release + +on: + push: + tags: + - '*' + branches: + - master + +permissions: + contents: write + +jobs: + release-drafter: + permissions: + contents: write + pull-requests: write + runs-on: ubuntu-latest + steps: + - uses: release-drafter/release-drafter@v5 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + release-php: + if: startsWith(github.ref, 'refs/tags/') + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: actions/cache@v3 + with: + path: /tmp/composer-cache + key: ${{ runner.os }}-${{ hashFiles('**/composer.lock') }} + - uses: php-actions/composer@v6 + - name: Build and test + run: composer build + - name: Get Tag Name + id: get-version + run: echo "version=${GITHUB_REF#refs/tags/}" >> $GITHUB_OUTPUT + - name: Create Release + uses: softprops/action-gh-release@v1 + with: + files: | diff --git a/README.md b/README.md index ea33397..32560c6 100644 --- a/README.md +++ b/README.md @@ -1,13 +1,25 @@ -# Behat Progress Fail Output Extension -Behat output formatter to show progress as TAP and fails inline. +

+ + Yourproject logo +

+

Behat Progress Fail Output Extension

+ +
+ +[![GitHub Issues](https://img.shields.io/github/issues/drevops/behat-format-progress-fail.svg)](https://github.com/drevops/behat-format-progress-fail/issues) +[![GitHub Pull Requests](https://img.shields.io/github/issues-pr/drevops/behat-format-progress-fail.svg)](https://github.com/drevops/behat-format-progress-fail/pulls) [![CircleCI](https://circleci.com/gh/drevops/behat-format-progress-fail.svg?style=shield)](https://circleci.com/gh/drevops/behat-format-progress-fail) ![GitHub release (latest by date)](https://img.shields.io/github/v/release/drevops/behat-format-progress-fail) -[![Total Downloads](https://poser.pugx.org/drevops/behat-format-progress-fail/downloads)](https://packagist.org/packages/drevops/behat-format-progress-fail) ![LICENSE](https://img.shields.io/github/license/drevops/behat-format-progress-fail) +![Renovate](https://img.shields.io/badge/renovate-enabled-green?logo=renovatebot) + +
+ +## Features +- Behat output formatter to show progress as TAP and fails inline. -## Output ``` .. --- FAIL --- @@ -24,13 +36,19 @@ Behat output formatter to show progress as TAP and fails inline. ![Output in CI](https://cloud.githubusercontent.com/assets/378794/26039517/1765b812-395f-11e7-9932-dd1aa43a97d4.png) -## Installing +## Installation ```bash composer require --dev drevops/behat-format-progress-fail ``` -## Configure +## Usage + +```bash +vendor/bin/behat --format=progress_fail +``` + +### Configure >behat.yml ```yaml @@ -38,30 +56,26 @@ default: extensions: DrevOps\BehatFormatProgressFail\FormatExtension: ~ ``` -## Usage - -```bash -vendor/bin/behat --format=progress_fail -``` ## Maintenance ### Local development setup 1. Install Docker. -2. Start environment: `docker-compose up -d --build`. -3. Install dependencies: `docker-compose exec phpserver composer install --ansi --no-suggest`. +2. Start environment: `docker compose up -d --build`. +3. Install dependencies: `docker compose exec phpserver composer install --ansi --no-suggest`. ### Lint code ```bash -docker-compose exec phpserver vendor/bin/phpcs +docker compose exec phpserver composer lint +docker compose exec phpserver composer lint:fix ``` ### Run tests ```bash -docker-compose exec phpserver vendor/bin/behat +docker compose exec phpserver vendor/bin/behat ``` ### Enable Xdebug @@ -73,5 +87,5 @@ XDEBUG_ENABLE=true docker-compose up -d phpserver To disable, run ```bash -docker-compose up -d phpserver +docker compose up -d phpserver ``` diff --git a/composer.json b/composer.json index b1ad247..45d3da4 100644 --- a/composer.json +++ b/composer.json @@ -1,7 +1,7 @@ { "name": "drevops/behat-format-progress-fail", - "description": "Behat output formatter to show progress as TAP and fails inline.", "type": "library", + "description": "Behat output formatter to show progress as TAP and fails inline.", "license": "GPL-2.0-or-later", "authors": [ { @@ -9,6 +9,11 @@ "email": "alex@drevops.com" } ], + "homepage": "https://github.com/drevops/behat-format-progress-fail", + "support": { + "issues": "https://github.com/drevops/behat-format-progress-fail/issues", + "source": "https://github.com/drevops/behat-format-progress-fail" + }, "require": { "behat/behat": "^3.3" }, @@ -19,11 +24,32 @@ "squizlabs/php_codesniffer": "^3", "escapestudios/symfony2-coding-standard": "^3", "phpunit/phpunit": "^9.5", - "symfony/process": "^5.3" + "symfony/process": "^5.3", + "phpstan/phpstan": "^1.10", + "phpmd/phpmd": "^2.14" }, "autoload": { "psr-0": { "DrevOps\\BehatFormatProgressFail": "src/" } + }, + "config": { + "allow-plugins": { + "dealerdirect/phpcodesniffer-composer-installer": true + } + }, + "scripts": { + "lint": [ + "phpcs", + "phpmd --exclude vendor,vendor-bin,node_modules . text phpmd.xml", + "phpstan" + ], + "lint:fix": "phpcbf", + "test": "vendor/bin/behat", + "build": [ + "@composer bin box require --dev humbug/box", + "box validate", + "box compile" + ] } } diff --git a/docker-compose.yml b/docker-compose.yml index 032c91c..f946ef8 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,7 +1,7 @@ version: '2' services: phpserver: - image: amazeeio/php:7.4-cli-drupal + image: amazeeio/php:8.1-cli-drupal volumes: - .:/app:delegated environment: diff --git a/phpmd.xml b/phpmd.xml new file mode 100644 index 0000000..03a0648 --- /dev/null +++ b/phpmd.xml @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + + + + */tests/*Test.php + diff --git a/phpstan.neon b/phpstan.neon new file mode 100644 index 0000000..39a423d --- /dev/null +++ b/phpstan.neon @@ -0,0 +1,16 @@ +## +# Configuration file for PHPStan static code checking, see https://phpstan.org . +# + +parameters: + + level: 9 + + paths: + - src + - tests + + excludePaths: + - vendor/* + - node_modules/* + - tests/behat/features/bootstrap diff --git a/renovate.json b/renovate.json new file mode 100644 index 0000000..decdefd --- /dev/null +++ b/renovate.json @@ -0,0 +1,7 @@ +{ + "$schema": "https://docs.renovatebot.com/renovate-schema.json", + "dependencyDashboard": true, + "extends": [ + "config:base" + ] +} diff --git a/src/DrevOps/BehatFormatProgressFail/FormatExtension.php b/src/DrevOps/BehatFormatProgressFail/FormatExtension.php index 0457971..6dc5065 100644 --- a/src/DrevOps/BehatFormatProgressFail/FormatExtension.php +++ b/src/DrevOps/BehatFormatProgressFail/FormatExtension.php @@ -42,7 +42,7 @@ class FormatExtension implements ExtensionInterface /** * {@inheritdoc} */ - public function process(ContainerBuilder $container) + public function process(ContainerBuilder $container): void { } @@ -57,14 +57,14 @@ public function getConfigKey() /** * {@inheritdoc} */ - public function initialize(ExtensionManager $extensionManager) + public function initialize(ExtensionManager $extensionManager): void { } /** * {@inheritdoc} */ - public function configure(ArrayNodeDefinition $builder) + public function configure(ArrayNodeDefinition $builder): void { $builder->children()->scalarNode('name')->defaultValue(self::MOD_ID); $builder->children()->scalarNode('base_path')->defaultValue(self::BASE_PATH); @@ -73,7 +73,7 @@ public function configure(ArrayNodeDefinition $builder) /** * {@inheritdoc} */ - public function load(ContainerBuilder $container, array $config) + public function load(ContainerBuilder $container, array $config): void { $definition = new Definition( 'Behat\Behat\Output\Node\EventListener\AST\StepListener', [ diff --git a/src/DrevOps/BehatFormatProgressFail/Printer/PrinterProgressFail.php b/src/DrevOps/BehatFormatProgressFail/Printer/PrinterProgressFail.php index 0ee2465..ca29751 100644 --- a/src/DrevOps/BehatFormatProgressFail/Printer/PrinterProgressFail.php +++ b/src/DrevOps/BehatFormatProgressFail/Printer/PrinterProgressFail.php @@ -7,6 +7,7 @@ namespace DrevOps\BehatFormatProgressFail\Printer; +use Behat\Behat\Definition\Call\DefinitionCall; use Behat\Behat\Output\Node\Printer\Helper\ResultToStringConverter; use Behat\Behat\Output\Node\Printer\StepPrinter; use Behat\Behat\Tester\Result\ExecutedStepResult; @@ -25,17 +26,17 @@ class PrinterProgressFail implements StepPrinter /** * @var ResultToStringConverter $resultConverter */ - private $resultConverter; + private ResultToStringConverter $resultConverter; /** * @var int $stepsPrinted */ - private $stepsPrinted = 0; + private int $stepsPrinted = 0; /** * @var string $basePath */ - private $basePath; + private string $basePath; /** * Initializes printer. @@ -43,7 +44,7 @@ class PrinterProgressFail implements StepPrinter * @param ResultToStringConverter $resultConverter * @param string $basePath */ - public function __construct(ResultToStringConverter $resultConverter, $basePath = '') + public function __construct(ResultToStringConverter $resultConverter, string $basePath = '') { $this->resultConverter = $resultConverter; $this->basePath = $basePath; @@ -52,7 +53,7 @@ public function __construct(ResultToStringConverter $resultConverter, $basePath /** * {@inheritdoc} */ - public function printStep(Formatter $formatter, Scenario $scenario, StepNode $step, StepResult $result) + public function printStep(Formatter $formatter, Scenario $scenario, StepNode $step, StepResult $result): void { $lineWidth = 70; $printer = $formatter->getOutputPrinter(); @@ -72,7 +73,7 @@ public function printStep(Formatter $formatter, Scenario $scenario, StepNode $st $printer->write("{+$style}U{-$style}"); break; case TestResult::FAILED: - $printer->write($this->printFailure($result, $scenario, $step)); + $printer->write($this->printFailure($result, $step)); break; } @@ -85,12 +86,11 @@ public function printStep(Formatter $formatter, Scenario $scenario, StepNode $st * Creates information about fail step. * * @param StepResult $result - * @param Scenario $scenario * @param StepNode $step * * @return string */ - protected function printFailure($result, $scenario, $step) + protected function printFailure(StepResult $result, StepNode $step): string { $style = $this->resultConverter->convertResultToString($result); @@ -101,22 +101,42 @@ protected function printFailure($result, $scenario, $step) $output = ''; - $fileName = $this->relativizePaths($result->getCallResult()->getCall()->getFeature()->getFile()); + $fileName = ''; + $callResult = $result->getCallResult(); + $call = $callResult->getCall(); + if ($call instanceof DefinitionCall) { + $feature = $call->getFeature(); + $fileName = $this->relativizePaths($feature->getFile() ?? ''); + } $fileLine = $step->getLine(); $output .= PHP_EOL; $output .= "{+$style}--- FAIL ---{-$style}"; $output .= PHP_EOL; - $output .= sprintf(" {+$style}%s %s{-$style} {+comment}# (%s):%s{-comment}", $step->getKeyword(), $step->getText(), $fileName, $fileLine, implode(PHP_EOL, array_filter($step->getArguments()))); + + $output .= sprintf(" {+$style}%s %s{-$style} {+comment}# (%s):%s{-comment}", $step->getKeyword(), $step->getText(), $fileName, $fileLine); $output .= PHP_EOL; - if (count(array_filter($step->getArguments())) > 0) { - $output .= sprintf(" {+$style}%s{-$style}", implode(PHP_EOL, array_filter($step->getArguments()))); + $stepArguments = $step->getArguments(); + $stepArguments = array_map(function ($item) { + if (method_exists($item, '__toString')) { + return $item->__toString(); + } + + return ''; + }, $stepArguments); + $stepArguments = array_filter($stepArguments); + if (count($stepArguments) > 0) { + $output .= sprintf(" {+$style}%s{-$style}", implode(PHP_EOL, array_filter($stepArguments))); + $output .= PHP_EOL; + } + + $exception = $result->getException(); + if ($exception) { + $output .= sprintf(" {+$style}%s{-$style}", $exception->getMessage()); $output .= PHP_EOL; } - $output .= sprintf(" {+$style}%s{-$style}", $result->getException()->getMessage()); - $output .= PHP_EOL; $output .= "{+$style}------------{-$style}"; $output .= PHP_EOL; @@ -130,7 +150,7 @@ protected function printFailure($result, $scenario, $step) * * @return string */ - protected function relativizePaths($path) + protected function relativizePaths(string $path): string { return !$this->basePath ? $path : str_replace( $this->basePath.DIRECTORY_SEPARATOR, '', $path