diff --git a/.codecov.yml b/.codecov.yml index 506169ac7..3385f9577 100644 --- a/.codecov.yml +++ b/.codecov.yml @@ -1,4 +1,50 @@ coverage: - range: 95..100 + range: 70..80 round: nearest precision: 2 + +ignore: + - "app" + - "assets" + - "bin" + - "build" + - "config" + - "db" + - "docs" + - "frontend" + - "infrastructure" + - "public" + - "Sniffs" + - "translations" + - "var" + - "vendor" + - "src/Core/Application/Dependency" + - "src/Core/Application/DependencyInjection" + - "src/Core/Application/Dto" + - "src/Core/Application/Exception" + - "src/Core/Application/Resources" + - "src/Core/Domain" + - "src/Core/SprykerSdkCoreBundle.php" + - "src/Extension/DependencyInjection" + - "src/Extension/Resources" + - "src/Extension/SprykerSdkExtensionBundle.php" + - "src/Infrastructure/DependencyInjection" + - "src/Infrastructure/Dto" + - "src/Infrastructure/Entity" + - "src/Infrastructure/Event" + - "src/Infrastructure/Exception" + - "src/Infrastructure/Resources" + - "src/Infrastructure/SprykerSdkInfrastructureBundle.php" + - "src/Presentation/Console/DependencyInjection" + - "src/Presentation/Console/Resources" + - "src/Presentation/Ide/Dto" + - "src/Presentation/RestApi/Enum" + - "src/Presentation/RestApi/Exception" + - "src/Presentation/RestApi/Resources" + - "src/Presentation/RestApi/SprykerSdkRestApiBundle.php" + - "**/*.md" + - "**/*.yml" + - "**/*.yaml" + - "**/*.json" + - "**/*.xml" + - "**/*.lock" diff --git a/.env.prod b/.env.prod index 9ddc98b88..2b375e51d 100644 --- a/.env.prod +++ b/.env.prod @@ -1,5 +1,5 @@ ###> telemetry TELEMETRY_ENABLED=true TELEMETRY_TRANSPORT=data_lake -TELEMETRY_SERVER_URL=https://uvg36eyk46.execute-api.eu-central-1.amazonaws.com/sdk +TELEMETRY_SERVER_URL=https://data.prod.spryker-dwh.net/sdk ###< telemetry diff --git a/.env.sprykerci b/.env.sprykerci new file mode 100644 index 000000000..2b375e51d --- /dev/null +++ b/.env.sprykerci @@ -0,0 +1,5 @@ +###> telemetry +TELEMETRY_ENABLED=true +TELEMETRY_TRANSPORT=data_lake +TELEMETRY_SERVER_URL=https://data.prod.spryker-dwh.net/sdk +###< telemetry diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index ccf96f5f2..f00ec9166 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -1,94 +1,93 @@ name: CI on: - pull_request: - push: - branches: - - master - - develop - - feature/[a-z]+-[0-9]+/dev-* - workflow_dispatch: + pull_request: + push: + branches: + - master + - develop + - feature/[a-z]+-[0-9]+/dev-* + workflow_dispatch: env: APP_ENV: test # Symfony application environment + CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} jobs: - validation: - name: "CS, PHPStan, Security" - runs-on: ubuntu-22.04 - strategy: - fail-fast: false - matrix: - php-version: [ - '7.4', - '8.0', - '8.1' - ] - - steps: - - uses: actions/checkout@v2 - - - name: Setup PHP - uses: shivammathur/setup-php@v2 - with: - php-version: ${{ matrix.php-version }} - extensions: mbstring, ctype, iconv - tools: composer:v2 - - uses: actions/setup-node@v3 - with: - node-version: 14 - - uses: bahmutov/npm-install@v1 - with: - useLockFile: false - - - name: Composer get cache directory - id: composer-cache - run: | - echo "::set-output name=dir::$(composer config cache-files-dir)" - - - name: Composer cache - uses: actions/cache@v2 - with: - path: ${{ steps.composer-cache.outputs.dir }} - key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }} - restore-keys: | - ${{ runner.os }}-composer- - - - name: Composer validate - run: composer validate - - - name: Composer version - run: composer --version - - - name: Composer install - run: composer install - - - name: Run PHPStan - run: composer stan - - - name: Run CodeStyle checks - run: composer cs-check - - - name: Codecept unit tests - run: composer test - - - name: Codecept unit tests - run: composer test-extension - - - name: Install SDK - run: bin/console sdk:init:hidden-sdk -n - - - name: Codecept acceptance tests - run: composer test-qa - - - name: Codecept tests with coverage - if: ${{ matrix.php-version == '8.0' }} - run: composer test-cover - - - name: Upload coverage results to Coveralls - if: ${{ matrix.php-version == '8.0' }} - env: - COVERALLS_REPO_TOKEN: ${{ secrets.GITHUB_TOKEN }} - run: | - composer global require "php-coveralls/php-coveralls" "symfony/console: ^5.4" - php-coveralls --coverage_clover=tests/_output/coverage.xml --json_path=tests/_output/coveralls-upload.json -vvv + validation: + name: "CS, PHPStan, Security" + runs-on: ubuntu-22.04 + strategy: + fail-fast: false + matrix: + php-version: [ + '7.4', + '8.1' + ] + + steps: + - uses: actions/checkout@v2 + + - name: Setup PHP + uses: shivammathur/setup-php@v2 + with: + php-version: ${{ matrix.php-version }} + extensions: mbstring, ctype, iconv + tools: composer:v2 + - uses: actions/setup-node@v3 + with: + node-version: 14 + - uses: bahmutov/npm-install@v1 + with: + useLockFile: false + + - name: Composer get cache directory + id: composer-cache + run: | + echo "::set-output name=dir::$(composer config cache-files-dir)" + + - name: Composer cache + uses: actions/cache@v2 + with: + path: ${{ steps.composer-cache.outputs.dir }} + key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }} + restore-keys: | + ${{ runner.os }}-composer- + + - name: Composer validate + run: composer validate + + - name: Composer version + run: composer --version + + - name: Composer install + run: composer install + + - name: Run PHPStan + run: composer stan + + - name: Run CodeStyle checks + run: composer cs-check + + - name: Codecept unit tests + run: composer test + + - name: Codecept unit tests + run: composer test-vcs-connector-extension + + - name: Codecept unit tests + run: composer test-inspection-doc-extension + + - name: Install SDK + run: bin/console sdk:init:hidden-sdk -n + + - name: Codecept acceptance tests + run: composer test-qa + + - name: Codecept tests with coverage + if: ${{ matrix.php-version == '8.1' }} + run: composer test-cover + + - name: Code Coverage Report + if: success() && matrix.php-version == '8.1' + uses: codecov/codecov-action@v1 diff --git a/.github/workflows/integrator-dependency-update-pr.yml b/.github/workflows/integrator-dependency-update-pr.yml new file mode 100644 index 000000000..83b1d0ea0 --- /dev/null +++ b/.github/workflows/integrator-dependency-update-pr.yml @@ -0,0 +1,45 @@ +name: Update Integrator dependencies + +env: + TARGET_BRANCH: rc + DEPENDENCY: spryker-sdk/integrator + PR_BRANCH: update-dependencies + PR_LABELS: composer dependencies + PR_ASSIGNEES: pavelmaksimov25,DmytroKlymanSpryker + PR_REVIEWERS: pavelmaksimov25,DmytroKlymanSpryker + +on: + repository_dispatch: + types: [ integrator_dependency_updated ] + +jobs: + update-dependencies: + runs-on: ubuntu-latest + steps: + - id: commit + uses: pr-mpt/actions-commit-hash@v2 + + - name: Checkout project + uses: actions/checkout@v3 + with: + ref: ${{ env.TARGET_BRANCH }} + + - name: Update dependencies + run: composer update ${{ env.DEPENDENCY }} --no-scripts --no-progress --no-install + + - name: Commit, push and create pull request + uses: peter-evans/create-pull-request@v5 + with: + title: Updated ${{ env.DEPENDENCY }} + body: | + This pull request updates ${{ env.DEPENDENCY }} dependency to the latest version. + commit-message: Updated ${{ env.DEPENDENCY }} dependency + committer: SprykerReleaseBot + author: ${{ github.actor }} <${{ github.actor }}@example.test> + base: ${{ env.TARGET_BRANCH }} + branch: ${{ env.PR_BRANCH }} + branch-suffix: timestamp + labels: ${{ env.PR_LABELS }} + delete-branch: true + assignees: ${{ env.PR_ASSIGNEES }} + reviewers: ${{ env.PR_REVIEWERS }} diff --git a/.github/workflows/post-release.yml b/.github/workflows/post-release.yml index 318f1f97c..69189a0ec 100644 --- a/.github/workflows/post-release.yml +++ b/.github/workflows/post-release.yml @@ -6,7 +6,7 @@ on: jobs: docker: - name: docker build and push + name: Build and push SDK semver release docker images runs-on: ubuntu-22.04 steps: # https://github.com/actions/checkout @@ -14,11 +14,11 @@ jobs: uses: actions/checkout@v2 # Multi-platform set up. - - name: Set up QEMU - uses: docker/setup-qemu-action@v1 + - name: Set up QEMU + uses: docker/setup-qemu-action@v1 - - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v1 + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v1 # https://github.com/docker/login-action - name: Login to DockerHub @@ -39,9 +39,94 @@ jobs: tags: spryker/php-sdk:${{ github.event.release.tag_name }} labels: Release ${{ github.event.release.tag_name }} + docker-sprykerci-74: + name: Build and push docker image for SprykerCI PHP 7.4 + runs-on: ubuntu-22.04 + needs: docker + steps: + # https://github.com/actions/checkout + - name: Checkout codebase + uses: actions/checkout@v2 + + # https://github.com/docker/login-action + - name: Login to DockerHub + uses: docker/login-action@v2 + with: + username: ${{ secrets.DOCKER_USERNAME }} + password: ${{ secrets.DOCKER_PASSWORD }} + + # https://github.com/docker/build-push-action + - name: Build and push + id: docker_build + uses: docker/build-push-action@v3 + with: + context: . + file: ./infrastructure/sdk.sprykerci74.Dockerfile + platforms: linux/amd64 + push: true + tags: spryker/php-sdk:sprykerci-7.4 + labels: SprykerCI + + docker-sprykerci-80: + name: Build and push docker image for SprykerCI PHP 8.0 + runs-on: ubuntu-22.04 + needs: docker + steps: + # https://github.com/actions/checkout + - name: Checkout codebase + uses: actions/checkout@v2 + + # https://github.com/docker/login-action + - name: Login to DockerHub + uses: docker/login-action@v2 + with: + username: ${{ secrets.DOCKER_USERNAME }} + password: ${{ secrets.DOCKER_PASSWORD }} + + # https://github.com/docker/build-push-action + - name: Build and push + id: docker_build + uses: docker/build-push-action@v3 + with: + context: . + file: ./infrastructure/sdk.sprykerci80.Dockerfile + platforms: linux/amd64 + push: true + tags: spryker/php-sdk:sprykerci-8.0,spryker/php-sdk:sprykerci + labels: SprykerCI + + docker-sprykerci-81: + name: Build and push docker image for SprykerCI PHP 8.1 + runs-on: ubuntu-22.04 + needs: docker + steps: + # https://github.com/actions/checkout + - name: Checkout codebase + uses: actions/checkout@v2 + + # https://github.com/docker/login-action + - name: Login to DockerHub + uses: docker/login-action@v2 + with: + username: ${{ secrets.DOCKER_USERNAME }} + password: ${{ secrets.DOCKER_PASSWORD }} + + # https://github.com/docker/build-push-action + - name: Build and push + id: docker_build + uses: docker/build-push-action@v3 + with: + context: . + file: ./infrastructure/sdk.sprykerci81.Dockerfile + platforms: linux/amd64 + push: true + tags: spryker/php-sdk:sprykerci-8.1 + labels: SprykerCI + installer: - name: Create and publish installer + name: Create and publish Spryker SDK installer runs-on: ubuntu-22.04 + needs: docker steps: # https://github.com/actions/checkout - name: Checkout codebase @@ -71,3 +156,13 @@ jobs: asset_path: ./build/installer.sh asset_name: installer.sh asset_content_type: text/x-shellscript + + trigger-sprykerci: + name: Triggers SprykerCI post-release pipeline + runs-on: ubuntu-22.04 + needs: [ docker-sprykerci-74, docker-sprykerci-80, docker-sprykerci-81, installer ] + steps: + - name: Trigger CI pipeline + shell: bash + run: | + curl -X POST https://eu.buddy.works/paas-demo/sdk/pipelines/pipeline/181690/trigger-webhook?token=${{ secrets.EXTERNAL_CI_HOOK_TOKEN }} diff --git a/.github/workflows/upgrader-dependency-update-pr.yml b/.github/workflows/upgrader-dependency-update-pr.yml new file mode 100644 index 000000000..1af34dd5c --- /dev/null +++ b/.github/workflows/upgrader-dependency-update-pr.yml @@ -0,0 +1,45 @@ +name: Update Upgrader dependencies + +env: + TARGET_BRANCH: rc + DEPENDENCY: spryker-sdk/upgrader + PR_BRANCH: update-dependencies + PR_LABELS: composer dependencies + PR_ASSIGNEES: pavelmaksimov25,DmytroKlymanSpryker + PR_REVIEWERS: pavelmaksimov25,DmytroKlymanSpryker + +on: + repository_dispatch: + types: [ upgrader_dependency_updated ] + +jobs: + update-dependencies: + runs-on: ubuntu-latest + steps: + - id: commit + uses: pr-mpt/actions-commit-hash@v2 + + - name: Checkout project + uses: actions/checkout@v3 + with: + ref: ${{ env.TARGET_BRANCH }} + + - name: Update dependencies + run: composer require ${{ env.DEPENDENCY }} --no-scripts --no-progress --no-install + + - name: Commit, push and create pull request + uses: peter-evans/create-pull-request@v5 + with: + title: Updated ${{ env.DEPENDENCY }} + body: | + This pull request updates ${{ env.DEPENDENCY }} dependency to the latest version. + commit-message: Updated ${{ env.DEPENDENCY }} dependency + committer: SprykerReleaseBot + author: ${{ github.actor }} <${{ github.actor }}@example.test> + base: ${{ env.TARGET_BRANCH }} + branch: ${{ env.PR_BRANCH }} + branch-suffix: timestamp + labels: ${{ env.PR_LABELS }} + delete-branch: true + assignees: ${{ env.PR_ASSIGNEES }} + reviewers: ${{ env.PR_REVIEWERS }} diff --git a/README.md b/README.md index 38758937d..75275ee9a 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,7 @@ # Spryker SDK [![Build Status](https://github.com/spryker-sdk/sdk/workflows/CI/badge.svg?branch=master)](https://github.com/spryker-sdk/sdk/actions?query=workflow%3ACI+branch%3Amaster) +[![codecov](https://codecov.io/gh/spryker-sdk/sdk/branch/master/graph/badge.svg?token=Ff8EDd0kgG)](https://codecov.io/gh/spryker-sdk/sdk) [![Latest Stable Version](https://poser.pugx.org/spryker-sdk/sdk/v/stable.svg)](https://packagist.org/packages/spryker-sdk/sdk) [![Minimum PHP Version](https://img.shields.io/badge/php-%3E%3D%207.4-8892BF.svg)](https://php.net/) [![PHPStan](https://img.shields.io/badge/PHPStan-level%208-brightgreen.svg?style=flat)](https://phpstan.org/) @@ -16,8 +17,8 @@ so you can focus developing exciting features for your business case. - ensure docker & docker-compose is installed - Download the `installer.sh` from the latest release at https://github.com/spryker-sdk/sdk/releases - run `installer.sh ` -- run `source ~/.zshrc` or `source ~/.bashrc` or re-open terminal -- alias `apryker-sdk` should be set and `SPRYKER_SDK_PATH` env variable should be exported +- follow the installer's instructions. +- alias `spryker-sdk` should be set and `SPRYKER_SDK_PATH` env variable should be exported. If not check our troubleshooting doc. Installation into the current dir: ```shell diff --git a/app/Migrations/Version20221130100606.php b/app/Migrations/Version20221130100606.php new file mode 100644 index 000000000..af66d0ad4 --- /dev/null +++ b/app/Migrations/Version20221130100606.php @@ -0,0 +1,42 @@ +addSql('CREATE TABLE sdk_task_set_task_relation (id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, task_set_id VARCHAR(255) NOT NULL, sub_task_id VARCHAR(255) NOT NULL, CONSTRAINT FK_407867162B5289CB FOREIGN KEY (task_set_id) REFERENCES sdk_task (id) ON DELETE CASCADE NOT DEFERRABLE INITIALLY IMMEDIATE, CONSTRAINT FK_40786716F26E5D72 FOREIGN KEY (sub_task_id) REFERENCES sdk_task (id) ON DELETE CASCADE NOT DEFERRABLE INITIALLY IMMEDIATE)'); + $this->addSql('CREATE INDEX IDX_407867162B5289CB ON sdk_task_set_task_relation (task_set_id)'); + $this->addSql('CREATE INDEX IDX_40786716F26E5D72 ON sdk_task_set_task_relation (sub_task_id)'); + $this->addSql('CREATE UNIQUE INDEX task_set_sub_task ON sdk_task_set_task_relation (task_set_id, sub_task_id)'); + } + + /** + * @param \Doctrine\DBAL\Schema\Schema $schema + * + * @return void + */ + public function down(Schema $schema): void + { + $this->addSql('DROP TABLE sdk_task_set_task_relation'); + } +} diff --git a/bin/spryker-sdk.sh b/bin/spryker-sdk.sh index 5b7e7d2df..6df4ed0b9 100755 --- a/bin/spryker-sdk.sh +++ b/bin/spryker-sdk.sh @@ -5,10 +5,14 @@ if ! docker info > /dev/null 2>&1; then exit 1 fi -SDK_DIR="$(dirname $(dirname $0))" +LOCAL_SDK_DIR="$(realpath $(dirname $(dirname $0)))" + +if [[ ! -f $LOCAL_SDK_DIR/VERSION ]]; then + git --git-dir=$LOCAL_SDK_DIR/.git describe --abbrev=0 --tags > $LOCAL_SDK_DIR/VERSION +fi if [[ $# == 1 && ($@ == "--version" || $@ == "-V") ]]; then - cat $SDK_DIR/VERSION + cat $LOCAL_SDK_DIR/VERSION exit 0 fi @@ -40,10 +44,10 @@ fi export DOCKER_BUILDKIT=1 export COMPOSE_DOCKER_CLI_BUILD=1 -export EXECUTABLE_FILE_PATH="$(cd "$(dirname "$0")";pwd)/spryker-sdk.sh" export USER_UID="$(id -u)" -export SDK_DIR="$SDK_DIR" -export SDK_VERSION="$(cat "$SDK_DIR/VERSION")" +export LOCAL_SDK_DIR="$LOCAL_SDK_DIR" +export EXECUTABLE_FILE_PATH="$(cd "$(dirname "$0")";pwd)/spryker-sdk.sh" +export SDK_VERSION="$(cat "$LOCAL_SDK_DIR/VERSION")" export UNAME_INFO="$(uname -a)" ### rest api server @@ -66,30 +70,25 @@ rest-api-start*) export SPRYKER_XDEBUG_HOST_IP=${myIp} export PHP_IDE_CONFIG=serverName=spryker-sdk export SDK_XDEBUG_MODE="$ARG_XDEBUG_MODE" - docker-compose -f "${SDK_DIR}/docker-compose.rest-api.dev.yaml" up -d + + docker-compose -f "${LOCAL_SDK_DIR}/docker-compose.rest-api.dev.yaml" up -d exit 0 ;; "rest-api-stop") - docker-compose -f "${SDK_DIR}/docker-compose.rest-api.dev.yaml" stop + docker-compose -f "${LOCAL_SDK_DIR}/docker-compose.rest-api.dev.yaml" stop exit 0 ;; "rest-api-status") - docker-compose -f "${SDK_DIR}/docker-compose.rest-api.dev.yaml" ps + docker-compose -f "${LOCAL_SDK_DIR}/docker-compose.rest-api.dev.yaml" ps exit 0 ;; "rest-api-rm") - docker-compose -f "${SDK_DIR}/docker-compose.rest-api.dev.yaml" rm -s + docker-compose -f "${LOCAL_SDK_DIR}/docker-compose.rest-api.dev.yaml" rm -s exit 0 ;; esac -install_composer () { - if [[ ! -d "$SDK_DIR/vendor" ]]; then - composer install --no-scripts --no-interaction --optimize-autoloader --ignore-platform-reqs; - fi; -} - ### cli case $MODE in "debug") @@ -98,8 +97,7 @@ case $MODE in exit 1 fi echo "Ensure mutagen is running by executing: mutagen compose -f docker-compose.yml -f docker-compose.dev.yml up -d" - install_composer - docker-compose -f "${SDK_DIR}/docker-compose.dev.yml" run --rm \ + docker-compose -f "${LOCAL_SDK_DIR}/docker-compose.dev.yml" run --rm \ -e SPRYKER_XDEBUG_HOST_IP="${myIp}" \ -e PHP_IDE_CONFIG="serverName=spryker-sdk" \ spryker-sdk "$ARGUMENTS" @@ -109,18 +107,31 @@ case $MODE in ARGUMENTS='/bin/bash' fi if [[ -z "$SPRYKER_SDK_ENV" || $SPRYKER_SDK_ENV == 'prod' ]]; then - docker-compose -f "${SDK_DIR}/docker-compose.yml" run --entrypoint="/bin/bash -c" --rm spryker-sdk "$ARGUMENTS" + docker-compose -f "${LOCAL_SDK_DIR}/docker-compose.yml" run --entrypoint="/bin/bash -c" --rm spryker-sdk "$ARGUMENTS" + else + docker-compose -f "${LOCAL_SDK_DIR}/docker-compose.dev.yml" run --entrypoint="/bin/bash -c" --rm -e XDEBUG_MODE=off spryker-sdk "$ARGUMENTS" + fi + ;; +"docker-debug" | "dd") + if [[ $ARGUMENTS_EMPTY == 1 ]]; then + ARGUMENTS='/bin/bash' + fi + if [[ -z "$SPRYKER_SDK_ENV" || $SPRYKER_SDK_ENV == 'prod' ]]; then + echo "This mode is not available for production." + exit 1 else - install_composer - docker-compose -f "${SDK_DIR}/docker-compose.dev.yml" run --entrypoint="/bin/bash -c" --rm -e XDEBUG_MODE=off -w /data spryker-sdk "$ARGUMENTS" + docker-compose -f "${LOCAL_SDK_DIR}/docker-compose.dev.yml" run --entrypoint="/bin/bash -c" --rm \ + -e SPRYKER_XDEBUG_HOST_IP="${myIp}" -e PHP_IDE_CONFIG="serverName=spryker-sdk" spryker-sdk "$ARGUMENTS" fi ;; *) if [[ -z "$SPRYKER_SDK_ENV" || $SPRYKER_SDK_ENV == 'prod' ]]; then - docker-compose -f "${SDK_DIR}/docker-compose.yml" run --rm spryker-sdk "$ARGUMENTS" + docker-compose -f "${LOCAL_SDK_DIR}/docker-compose.yml" run --rm spryker-sdk "$ARGUMENTS" + elif [[ ! -f "${LOCAL_SDK_DIR}/docker-compose.dev.yml" ]]; then + echo "The development environment is not available. Please run \`unset SPRYKER_SDK_ENV\` or \`export SPRYKER_SDK_ENV=prod\` to enable \`production\` mode." + exit 1 else - install_composer - docker-compose -f "${SDK_DIR}/docker-compose.dev.yml" run --rm -e XDEBUG_MODE=off spryker-sdk "$ARGUMENTS" + docker-compose -f "${LOCAL_SDK_DIR}/docker-compose.dev.yml" run --rm -e XDEBUG_MODE=off spryker-sdk "$ARGUMENTS" fi ;; esac diff --git a/codeception.yml b/codeception.yml index f1c4ca30b..7af7b82e0 100644 --- a/codeception.yml +++ b/codeception.yml @@ -20,12 +20,13 @@ suites: - Cli - Filesystem - \SprykerSdk\Sdk\Tests\Helper\Core\Application\Service\TelemetryEventHelper + - \SprykerSdk\Sdk\Tests\Helper\Presentation\RestApi\RestApiHelper - SprykerSdk\Sdk\Tests\Helper\RestApiServerHelper: port: 8000 - Symfony: app_path: app environment: test - - REST: + - SprykerSdk\Sdk\Tests\Helper\RestApiHelper: url: http://localhost:8000/api/v1 depends: PhpBrowser part: Json diff --git a/composer.json b/composer.json index 36750d77c..57645e45f 100644 --- a/composer.json +++ b/composer.json @@ -21,41 +21,53 @@ "composer/semver": "^3.2", "doctrine/doctrine-bundle": "^2.5", "doctrine/doctrine-migrations-bundle": "^3.2", - "doctrine/migrations": "^3.4", + "doctrine/migrations": "^3.5", "doctrine/orm": "^2.11", + "ergebnis/json-printer": "*", "guzzlehttp/guzzle": "^7.4", + "laminas/laminas-filter": "^2.15", + "laminas/laminas-stdlib": "^3.13.0", + "m4tthumphrey/php-gitlab-api": "*", "monolog/monolog": "^2.3", - "nelmio/api-doc-bundle": "^4.10", + "nelmio/api-doc-bundle": "*", "ondrejmirtes/better-reflection": "4.3.*", "phpbench/phpbench": "^1.2", "phpstan/phpstan": "^1.2", + "psr/cache": "^1.0 || ^2.0 || ^3.0", + "psr/log": "^1.0 || ^2.0 || ^3.0", "ramsey/uuid": "^3.9", "rector/rector": "^0.13.0", "spryker-sdk/acp": "^0.2.0", "spryker-sdk/async-api": "^0.2.3", + "spryker-sdk/brancho": "1.0.x-dev", "spryker-sdk/composer-replace": "dev-master", - "spryker-sdk/sdk-contracts": "^0.4.6", - "spryker-sdk/spryk": "dev-master as 0.4.6", + "spryker-sdk/evaluator": "^0.1.1", + "spryker-sdk/sdk-contracts": "^0.4.7", + "spryker-sdk/security-checker": "^0.2.0", + "spryker-sdk/spryk": "^0.4.7", "spryker-sdk/sync-api": "^0.1.1", "spryker-sdk/upgrader": "dev-master", - "spryker/architecture-sniffer": "^0.5.2", + "spryker/architecture-sniffer": "^0.5.7", "spryker/code-sniffer": "^0.17.6", "symfony/asset": "^5.0", "symfony/config": "^5.4.0", "symfony/console": "^5.0", + "symfony/deprecation-contracts": "^2.5 || ^3.0", "symfony/dotenv": "^5.0", "symfony/event-dispatcher": "^5.0", + "symfony/event-dispatcher-contracts": "^2.5 || ^3.0", "symfony/expression-language": "^5.0", "symfony/filesystem": "^5.0", "symfony/flex": "^1.18.0", - "symfony/framework-bundle": "^5.3", - "symfony/lock": "^5.4", + "symfony/framework-bundle": "^5.4", + "symfony/lock": "^5.0", "symfony/monolog-bundle": "^3.8", "symfony/process": "^5.0", "symfony/runtime": "^5.0", "symfony/serializer": "^5.0", "symfony/twig-bundle": "^5.0", "symfony/validator": "^5.0", + "symfony/var-exporter": "^5.0 || ^6.0", "symfony/workflow": "^5.0", "symfony/yaml": "^5.0", "vimeo/psalm": "^4.24" @@ -66,15 +78,13 @@ "codeception/module-cli": "*", "codeception/module-filesystem": "^2.0", "codeception/module-phpbrowser": "^2.0", - "codeception/module-rest": "^2.0.2", + "codeception/module-rest": "^2.0", "codeception/module-symfony": "*", "codeception/module-webdriver": "^2.0", "mikey179/vfsstream": "^1.6", + "pavelmaksimov25/jsonpath": "^0.2.0", "phpunit/php-code-coverage": "^9.2", "phpunit/php-timer": "^5.0", - "sllh/composer-versions-check": "^2.0", - "spryker-sdk/brancho": "1.0.x-dev", - "spryker-sdk/security-checker": "^0.1.0", "symfony/var-dumper": "^5.0" }, "config": { @@ -86,9 +96,9 @@ "allow-plugins": { "composer/package-versions-deprecated": true, "dealerdirect/phpcodesniffer-composer-installer": true, - "sllh/composer-versions-check": true, "symfony/flex": true, - "symfony/runtime": true + "symfony/runtime": true, + "php-http/discovery": true } }, "autoload": { @@ -98,23 +108,20 @@ "psr-4": { "App\\": "app/", "SprykerSdk\\Sdk\\": "src/", - "SprykerSdk\\Sniffs\\": "Sniffs/" + "SprykerSdk\\Sniffs\\": "Sniffs/", + "VcsConnector\\": "extension/VcsConnector/src/", + "VcsConnector\\Tests\\": "extension/VcsConnector/tests/", + "Hello\\": "extension/Hello/src/", + "Custom\\": "extension/Custom/src/", + "InspectionDoc\\": "extension/InspectionDoc/src/" } }, "autoload-dev": { "psr-4": { "SprykerSdk\\Sdk\\": "tests/Sdk/", - "Hello\\": "extension/Hello/src/", - "Custom\\": "extension/Custom/src/", - "VcsConnector\\": "extension/VcsConnector/src/", - "VcsConnector\\Tests\\": "extension/VcsConnector/tests/" + "InspectionDoc\\Tests\\": "extension/InspectionDoc/tests/" } }, - "replace": { - "symfony/polyfill-ctype": "*", - "symfony/polyfill-iconv": "*", - "symfony/polyfill-php72": "*" - }, "scripts": { "cs-check": "phpcs", "cs-fix": "phpcbf", @@ -125,7 +132,8 @@ "@stan" ], "test": "codecept build && codecept run unit", - "test-extension": "codecept build -c extension/VcsConnector/codeception.yml && codecept run unit -c extension/VcsConnector/codeception.yml", + "test-vcs-connector-extension": "codecept build -c extension/VcsConnector/codeception.yml && codecept run unit -c extension/VcsConnector/codeception.yml", + "test-inspection-doc-extension": "codecept build -c extension/InspectionDoc/codeception.yml && codecept run unit -c extension/InspectionDoc/codeception.yml", "test-qa": "codecept build && codecept run acceptance", "test-cover": "codecept build && codecept run unit --coverage-xml", "test-cover-html": "codecept build && codecept run unit --coverage-html", diff --git a/composer.lock b/composer.lock index 56d1f9fb9..469515ba3 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "2862c2a692b39dae5d019c99b2ea050c", + "content-hash": "32eccf76e1f1cb1547860b42d816f531", "packages": [ { "name": "amphp/amp", @@ -172,6 +172,155 @@ ], "time": "2021-03-30T17:13:30+00:00" }, + { + "name": "aws/aws-crt-php", + "version": "v1.2.1", + "source": { + "type": "git", + "url": "https://github.com/awslabs/aws-crt-php.git", + "reference": "1926277fc71d253dfa820271ac5987bdb193ccf5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/awslabs/aws-crt-php/zipball/1926277fc71d253dfa820271ac5987bdb193ccf5", + "reference": "1926277fc71d253dfa820271ac5987bdb193ccf5", + "shasum": "" + }, + "require": { + "php": ">=5.5" + }, + "require-dev": { + "phpunit/phpunit": "^4.8.35||^5.6.3||^9.5", + "yoast/phpunit-polyfills": "^1.0" + }, + "suggest": { + "ext-awscrt": "Make sure you install awscrt native extension to use any of the functionality." + }, + "type": "library", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "Apache-2.0" + ], + "authors": [ + { + "name": "AWS SDK Common Runtime Team", + "email": "aws-sdk-common-runtime@amazon.com" + } + ], + "description": "AWS Common Runtime for PHP", + "homepage": "https://github.com/awslabs/aws-crt-php", + "keywords": [ + "amazon", + "aws", + "crt", + "sdk" + ], + "support": { + "issues": "https://github.com/awslabs/aws-crt-php/issues", + "source": "https://github.com/awslabs/aws-crt-php/tree/v1.2.1" + }, + "time": "2023-03-24T20:22:19+00:00" + }, + { + "name": "aws/aws-sdk-php", + "version": "3.272.2", + "source": { + "type": "git", + "url": "https://github.com/aws/aws-sdk-php.git", + "reference": "0c4cba74c79f9b44393c27721fa1fa9138c95387" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/0c4cba74c79f9b44393c27721fa1fa9138c95387", + "reference": "0c4cba74c79f9b44393c27721fa1fa9138c95387", + "shasum": "" + }, + "require": { + "aws/aws-crt-php": "^1.0.4", + "ext-json": "*", + "ext-pcre": "*", + "ext-simplexml": "*", + "guzzlehttp/guzzle": "^6.5.8 || ^7.4.5", + "guzzlehttp/promises": "^1.4.0", + "guzzlehttp/psr7": "^1.9.1 || ^2.4.5", + "mtdowling/jmespath.php": "^2.6", + "php": ">=5.5", + "psr/http-message": "^1.0" + }, + "require-dev": { + "andrewsville/php-token-reflection": "^1.4", + "aws/aws-php-sns-message-validator": "~1.0", + "behat/behat": "~3.0", + "composer/composer": "^1.10.22", + "dms/phpunit-arraysubset-asserts": "^0.4.0", + "doctrine/cache": "~1.4", + "ext-dom": "*", + "ext-openssl": "*", + "ext-pcntl": "*", + "ext-sockets": "*", + "nette/neon": "^2.3", + "paragonie/random_compat": ">= 2", + "phpunit/phpunit": "^4.8.35 || ^5.6.3 || ^9.5", + "psr/cache": "^1.0", + "psr/simple-cache": "^1.0", + "sebastian/comparator": "^1.2.3 || ^4.0", + "yoast/phpunit-polyfills": "^1.0" + }, + "suggest": { + "aws/aws-php-sns-message-validator": "To validate incoming SNS notifications", + "doctrine/cache": "To use the DoctrineCacheAdapter", + "ext-curl": "To send requests using cURL", + "ext-openssl": "Allows working with CloudFront private distributions and verifying received SNS messages", + "ext-sockets": "To use client-side monitoring" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0-dev" + } + }, + "autoload": { + "files": [ + "src/functions.php" + ], + "psr-4": { + "Aws\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "Apache-2.0" + ], + "authors": [ + { + "name": "Amazon Web Services", + "homepage": "http://aws.amazon.com" + } + ], + "description": "AWS SDK for PHP - Use Amazon Web Services in your PHP project", + "homepage": "http://aws.amazon.com/sdkforphp", + "keywords": [ + "amazon", + "aws", + "cloud", + "dynamodb", + "ec2", + "glacier", + "s3", + "sdk" + ], + "support": { + "forum": "https://forums.aws.amazon.com/forum.jspa?forumID=80", + "issues": "https://github.com/aws/aws-sdk-php/issues", + "source": "https://github.com/aws/aws-sdk-php/tree/3.272.2" + }, + "time": "2023-06-12T18:21:59+00:00" + }, { "name": "cebe/php-openapi", "version": "1.7.0", @@ -241,6 +390,64 @@ }, "time": "2022-04-20T14:46:44+00:00" }, + { + "name": "chobie/jira-api-restclient", + "version": "dev-master", + "source": { + "type": "git", + "url": "https://github.com/chobie/jira-api-restclient.git", + "reference": "141f494c43ce254f951825fc6702af9f685d4ddb" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/chobie/jira-api-restclient/zipball/141f494c43ce254f951825fc6702af9f685d4ddb", + "reference": "141f494c43ce254f951825fc6702af9f685d4ddb", + "shasum": "" + }, + "require": { + "php": ">=5.4.0" + }, + "require-dev": { + "aik099/coding-standard": "dev-master", + "phpspec/prophecy": "^1.10", + "squizlabs/php_codesniffer": "^2.6", + "yoast/phpunit-polyfills": "^1.0" + }, + "default-branch": true, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0-dev" + } + }, + "autoload": { + "psr-4": { + "chobie\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Shuhei Tanuma", + "email": "chobieeee@php.net", + "homepage": "http://chobie.github.io/" + } + ], + "description": "JIRA REST API Client", + "keywords": [ + "api", + "jira", + "rest" + ], + "support": { + "issues": "https://github.com/chobie/jira-api-restclient/issues", + "source": "https://github.com/chobie/jira-api-restclient/tree/master" + }, + "time": "2022-10-06T10:19:38+00:00" + }, { "name": "clue/stream-filter", "version": "v1.6.0", @@ -307,18 +514,92 @@ ], "time": "2022-02-21T13:15:14+00:00" }, + { + "name": "cocur/slugify", + "version": "v4.3.0", + "source": { + "type": "git", + "url": "https://github.com/cocur/slugify.git", + "reference": "652234ef5f1be844a2ae1c36ad1b4c88b05160f9" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/cocur/slugify/zipball/652234ef5f1be844a2ae1c36ad1b4c88b05160f9", + "reference": "652234ef5f1be844a2ae1c36ad1b4c88b05160f9", + "shasum": "" + }, + "require": { + "ext-mbstring": "*", + "php": "^7.1 || ~8.0.0 || ~8.1.0 || ~8.2.0" + }, + "conflict": { + "symfony/config": "<3.4 || >=4,<4.3", + "symfony/dependency-injection": "<3.4 || >=4,<4.3", + "symfony/http-kernel": "<3.4 || >=4,<4.3", + "twig/twig": "<2.12.1" + }, + "require-dev": { + "laravel/framework": "^5.0|^6.0|^7.0|^8.0", + "latte/latte": "~2.2", + "league/container": "^2.2.0", + "mikey179/vfsstream": "~1.6.8", + "mockery/mockery": "^1.3", + "nette/di": "~2.4", + "pimple/pimple": "~1.1", + "plumphp/plum": "~0.1", + "symfony/config": "^3.4 || ^4.3 || ^5.0 || ^6.0", + "symfony/dependency-injection": "^3.4 || ^4.3 || ^5.0 || ^6.0", + "symfony/http-kernel": "^3.4 || ^4.3 || ^5.0 || ^6.0", + "symfony/phpunit-bridge": "^5.4 || ^6.0", + "twig/twig": "^2.12.1 || ~3.0", + "zendframework/zend-modulemanager": "~2.2", + "zendframework/zend-servicemanager": "~2.2", + "zendframework/zend-view": "~2.2" + }, + "type": "library", + "autoload": { + "psr-4": { + "Cocur\\Slugify\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Florian Eckerstorfer", + "email": "florian@eckerstorfer.co", + "homepage": "https://florian.ec" + }, + { + "name": "Ivo Bathke", + "email": "ivo.bathke@gmail.com" + } + ], + "description": "Converts a string into a slug.", + "keywords": [ + "slug", + "slugify" + ], + "support": { + "issues": "https://github.com/cocur/slugify/issues", + "source": "https://github.com/cocur/slugify/tree/v4.3.0" + }, + "time": "2022-12-07T19:48:48+00:00" + }, { "name": "composer/ca-bundle", - "version": "1.3.4", + "version": "1.3.6", "source": { "type": "git", "url": "https://github.com/composer/ca-bundle.git", - "reference": "69098eca243998b53eed7a48d82dedd28b447cd5" + "reference": "90d087e988ff194065333d16bc5cf649872d9cdb" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/composer/ca-bundle/zipball/69098eca243998b53eed7a48d82dedd28b447cd5", - "reference": "69098eca243998b53eed7a48d82dedd28b447cd5", + "url": "https://api.github.com/repos/composer/ca-bundle/zipball/90d087e988ff194065333d16bc5cf649872d9cdb", + "reference": "90d087e988ff194065333d16bc5cf649872d9cdb", "shasum": "" }, "require": { @@ -365,7 +646,7 @@ "support": { "irc": "irc://irc.freenode.org/composer", "issues": "https://github.com/composer/ca-bundle/issues", - "source": "https://github.com/composer/ca-bundle/tree/1.3.4" + "source": "https://github.com/composer/ca-bundle/tree/1.3.6" }, "funding": [ { @@ -381,7 +662,7 @@ "type": "tidelift" } ], - "time": "2022-10-12T12:08:29+00:00" + "time": "2023-06-06T12:02:59+00:00" }, { "name": "composer/class-map-generator", @@ -458,23 +739,23 @@ }, { "name": "composer/composer", - "version": "2.4.3", + "version": "2.5.8", "source": { "type": "git", "url": "https://github.com/composer/composer.git", - "reference": "b34c0e9a93f2cd688c62ce4dfcc69e13b6ce7aa4" + "reference": "4c516146167d1392c8b9b269bb7c24115d262164" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/composer/composer/zipball/b34c0e9a93f2cd688c62ce4dfcc69e13b6ce7aa4", - "reference": "b34c0e9a93f2cd688c62ce4dfcc69e13b6ce7aa4", + "url": "https://api.github.com/repos/composer/composer/zipball/4c516146167d1392c8b9b269bb7c24115d262164", + "reference": "4c516146167d1392c8b9b269bb7c24115d262164", "shasum": "" }, "require": { "composer/ca-bundle": "^1.0", "composer/class-map-generator": "^1.0", "composer/metadata-minifier": "^1.0", - "composer/pcre": "^2 || ^3", + "composer/pcre": "^2.1 || ^3.1", "composer/semver": "^3.0", "composer/spdx-licenses": "^1.5.7", "composer/xdebug-handler": "^2.0.2 || ^3.0.3", @@ -490,10 +771,11 @@ "symfony/finder": "^5.4 || ^6.0", "symfony/polyfill-php73": "^1.24", "symfony/polyfill-php80": "^1.24", + "symfony/polyfill-php81": "^1.24", "symfony/process": "^5.4 || ^6.0" }, "require-dev": { - "phpstan/phpstan": "^1.4.1", + "phpstan/phpstan": "^1.9.3", "phpstan/phpstan-deprecation-rules": "^1", "phpstan/phpstan-phpunit": "^1.0", "phpstan/phpstan-strict-rules": "^1", @@ -511,7 +793,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "2.4-dev" + "dev-main": "2.5-dev" }, "phpstan": { "includes": [ @@ -550,7 +832,7 @@ "support": { "irc": "ircs://irc.libera.chat:6697/composer", "issues": "https://github.com/composer/composer/issues", - "source": "https://github.com/composer/composer/tree/2.4.3" + "source": "https://github.com/composer/composer/tree/2.5.8" }, "funding": [ { @@ -566,7 +848,7 @@ "type": "tidelift" } ], - "time": "2022-10-14T14:56:41+00:00" + "time": "2023-06-09T15:13:21+00:00" }, { "name": "composer/metadata-minifier", @@ -712,16 +994,16 @@ }, { "name": "composer/pcre", - "version": "3.0.0", + "version": "3.1.0", "source": { "type": "git", "url": "https://github.com/composer/pcre.git", - "reference": "e300eb6c535192decd27a85bc72a9290f0d6b3bd" + "reference": "4bff79ddd77851fe3cdd11616ed3f92841ba5bd2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/composer/pcre/zipball/e300eb6c535192decd27a85bc72a9290f0d6b3bd", - "reference": "e300eb6c535192decd27a85bc72a9290f0d6b3bd", + "url": "https://api.github.com/repos/composer/pcre/zipball/4bff79ddd77851fe3cdd11616ed3f92841ba5bd2", + "reference": "4bff79ddd77851fe3cdd11616ed3f92841ba5bd2", "shasum": "" }, "require": { @@ -763,7 +1045,7 @@ ], "support": { "issues": "https://github.com/composer/pcre/issues", - "source": "https://github.com/composer/pcre/tree/3.0.0" + "source": "https://github.com/composer/pcre/tree/3.1.0" }, "funding": [ { @@ -779,7 +1061,7 @@ "type": "tidelift" } ], - "time": "2022-02-25T20:21:48+00:00" + "time": "2022-11-17T09:50:14+00:00" }, { "name": "composer/semver", @@ -1008,6 +1290,58 @@ ], "time": "2022-02-25T21:32:43+00:00" }, + { + "name": "czproject/git-php", + "version": "v4.1.0", + "source": { + "type": "git", + "url": "https://github.com/czproject/git-php.git", + "reference": "bb195e30442bc5206b30fa9a304e20ea8e96458f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/czproject/git-php/zipball/bb195e30442bc5206b30fa9a304e20ea8e96458f", + "reference": "bb195e30442bc5206b30fa9a304e20ea8e96458f", + "shasum": "" + }, + "require": { + "php": ">=5.6.0" + }, + "require-dev": { + "nette/tester": "^2.0" + }, + "type": "library", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Jan Pecha", + "email": "janpecha@email.cz" + } + ], + "description": "Library for work with Git repository in PHP.", + "keywords": [ + "git" + ], + "support": { + "issues": "https://github.com/czproject/git-php/issues", + "source": "https://github.com/czproject/git-php/tree/v4.1.0" + }, + "funding": [ + { + "url": "https://www.paypal.com/donate?hosted_button_id=EPSKR7MGVV7KC", + "type": "custom" + } + ], + "time": "2022-12-10T18:23:32+00:00" + }, { "name": "davidrjonas/composer-lock-diff", "version": "1.7.0", @@ -1162,32 +1496,35 @@ }, { "name": "doctrine/annotations", - "version": "1.13.3", + "version": "2.0.1", "source": { "type": "git", "url": "https://github.com/doctrine/annotations.git", - "reference": "648b0343343565c4a056bfc8392201385e8d89f0" + "reference": "e157ef3f3124bbf6fe7ce0ffd109e8a8ef284e7f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/annotations/zipball/648b0343343565c4a056bfc8392201385e8d89f0", - "reference": "648b0343343565c4a056bfc8392201385e8d89f0", + "url": "https://api.github.com/repos/doctrine/annotations/zipball/e157ef3f3124bbf6fe7ce0ffd109e8a8ef284e7f", + "reference": "e157ef3f3124bbf6fe7ce0ffd109e8a8ef284e7f", "shasum": "" }, "require": { - "doctrine/lexer": "1.*", + "doctrine/lexer": "^2 || ^3", "ext-tokenizer": "*", - "php": "^7.1 || ^8.0", + "php": "^7.2 || ^8.0", "psr/cache": "^1 || ^2 || ^3" }, "require-dev": { - "doctrine/cache": "^1.11 || ^2.0", - "doctrine/coding-standard": "^6.0 || ^8.1", - "phpstan/phpstan": "^1.4.10 || ^1.8.0", - "phpunit/phpunit": "^7.5 || ^8.0 || ^9.1.5", - "symfony/cache": "^4.4 || ^5.2", + "doctrine/cache": "^2.0", + "doctrine/coding-standard": "^10", + "phpstan/phpstan": "^1.8.0", + "phpunit/phpunit": "^7.5 || ^8.5 || ^9.5", + "symfony/cache": "^5.4 || ^6", "vimeo/psalm": "^4.10" }, + "suggest": { + "php": "PHP 8.0 or higher comes with attributes, a native replacement for annotations" + }, "type": "library", "autoload": { "psr-4": { @@ -1229,9 +1566,9 @@ ], "support": { "issues": "https://github.com/doctrine/annotations/issues", - "source": "https://github.com/doctrine/annotations/tree/1.13.3" + "source": "https://github.com/doctrine/annotations/tree/2.0.1" }, - "time": "2022-07-02T10:48:51+00:00" + "time": "2023-02-02T22:02:53+00:00" }, { "name": "doctrine/cache", @@ -1489,38 +1826,39 @@ }, { "name": "doctrine/dbal", - "version": "3.4.5", + "version": "3.6.2", "source": { "type": "git", "url": "https://github.com/doctrine/dbal.git", - "reference": "a5a58773109c0abb13e658c8ccd92aeec8d07f9e" + "reference": "b4bd1cfbd2b916951696d82e57d054394d84864c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/dbal/zipball/a5a58773109c0abb13e658c8ccd92aeec8d07f9e", - "reference": "a5a58773109c0abb13e658c8ccd92aeec8d07f9e", + "url": "https://api.github.com/repos/doctrine/dbal/zipball/b4bd1cfbd2b916951696d82e57d054394d84864c", + "reference": "b4bd1cfbd2b916951696d82e57d054394d84864c", "shasum": "" }, "require": { "composer-runtime-api": "^2", "doctrine/cache": "^1.11|^2.0", "doctrine/deprecations": "^0.5.3|^1", - "doctrine/event-manager": "^1.0", + "doctrine/event-manager": "^1|^2", "php": "^7.4 || ^8.0", "psr/cache": "^1|^2|^3", "psr/log": "^1|^2|^3" }, "require-dev": { - "doctrine/coding-standard": "10.0.0", - "jetbrains/phpstorm-stubs": "2022.2", - "phpstan/phpstan": "1.8.3", - "phpstan/phpstan-strict-rules": "^1.3", - "phpunit/phpunit": "9.5.24", - "psalm/plugin-phpunit": "0.17.0", - "squizlabs/php_codesniffer": "3.7.1", + "doctrine/coding-standard": "11.1.0", + "fig/log-test": "^1", + "jetbrains/phpstorm-stubs": "2022.3", + "phpstan/phpstan": "1.10.9", + "phpstan/phpstan-strict-rules": "^1.5", + "phpunit/phpunit": "9.6.6", + "psalm/plugin-phpunit": "0.18.4", + "squizlabs/php_codesniffer": "3.7.2", "symfony/cache": "^5.4|^6.0", "symfony/console": "^4.4|^5.4|^6.0", - "vimeo/psalm": "4.27.0" + "vimeo/psalm": "4.30.0" }, "suggest": { "symfony/console": "For helpful console commands such as SQL execution and import of files." @@ -1580,7 +1918,7 @@ ], "support": { "issues": "https://github.com/doctrine/dbal/issues", - "source": "https://github.com/doctrine/dbal/tree/3.4.5" + "source": "https://github.com/doctrine/dbal/tree/3.6.2" }, "funding": [ { @@ -1596,7 +1934,7 @@ "type": "tidelift" } ], - "time": "2022-09-23T17:48:57+00:00" + "time": "2023-04-14T07:25:38+00:00" }, { "name": "doctrine/deprecations", @@ -1643,56 +1981,58 @@ }, { "name": "doctrine/doctrine-bundle", - "version": "2.7.0", + "version": "2.9.1", "source": { "type": "git", "url": "https://github.com/doctrine/DoctrineBundle.git", - "reference": "d2088fc50494e4e7441fecca54732245a613eeb6" + "reference": "7539b3c8bd620f7df6c2c6d510204bd2ce0064e3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/DoctrineBundle/zipball/d2088fc50494e4e7441fecca54732245a613eeb6", - "reference": "d2088fc50494e4e7441fecca54732245a613eeb6", + "url": "https://api.github.com/repos/doctrine/DoctrineBundle/zipball/7539b3c8bd620f7df6c2c6d510204bd2ce0064e3", + "reference": "7539b3c8bd620f7df6c2c6d510204bd2ce0064e3", "shasum": "" }, "require": { - "doctrine/annotations": "^1", "doctrine/cache": "^1.11 || ^2.0", - "doctrine/dbal": "^2.13.1|^3.3.2", - "doctrine/persistence": "^2.2|^3", + "doctrine/dbal": "^3.6.0", + "doctrine/persistence": "^2.2 || ^3", "doctrine/sql-formatter": "^1.0.1", - "php": "^7.1 || ^8.0", - "symfony/cache": "^4.3.3|^5.0|^6.0", - "symfony/config": "^4.4.3|^5.0|^6.0", - "symfony/console": "^3.4.30|^4.3.3|^5.0|^6.0", - "symfony/dependency-injection": "^4.4.18|^5.0|^6.0", - "symfony/deprecation-contracts": "^2.1|^3", - "symfony/doctrine-bridge": "^4.4.22|^5.2.7|^6.0", - "symfony/framework-bundle": "^3.4.30|^4.3.3|^5.0|^6.0", - "symfony/service-contracts": "^1.1.1|^2.0|^3" + "php": "^7.4 || ^8.0", + "symfony/cache": "^5.4 || ^6.0", + "symfony/config": "^5.4 || ^6.0", + "symfony/console": "^5.4 || ^6.0", + "symfony/dependency-injection": "^5.4 || ^6.0", + "symfony/deprecation-contracts": "^2.1 || ^3", + "symfony/doctrine-bridge": "^5.4.19 || ^6.0.7", + "symfony/framework-bundle": "^5.4 || ^6.0", + "symfony/service-contracts": "^1.1.1 || ^2.0 || ^3" }, "conflict": { - "doctrine/orm": "<2.10|>=3.0", - "twig/twig": "<1.34|>=2.0,<2.4" + "doctrine/annotations": ">=3.0", + "doctrine/orm": "<2.11 || >=3.0", + "twig/twig": "<1.34 || >=2.0 <2.4" }, "require-dev": { + "doctrine/annotations": "^1 || ^2", "doctrine/coding-standard": "^9.0", + "doctrine/deprecations": "^1.0", "doctrine/orm": "^2.11 || ^3.0", "friendsofphp/proxy-manager-lts": "^1.0", - "phpunit/phpunit": "^7.5 || ^8.0 || ^9.3 || ^10.0", - "psalm/plugin-phpunit": "^0.16.1", - "psalm/plugin-symfony": "^3", - "psr/log": "^1.1.4|^2.0|^3.0", - "symfony/phpunit-bridge": "^5.2|^6.0", - "symfony/property-info": "^4.3.3|^5.0|^6.0", - "symfony/proxy-manager-bridge": "^3.4|^4.3.3|^5.0|^6.0", - "symfony/security-bundle": "^4.4|^5.0|^6.0", - "symfony/twig-bridge": "^3.4.30|^4.3.3|^5.0|^6.0", - "symfony/validator": "^3.4.30|^4.3.3|^5.0|^6.0", - "symfony/web-profiler-bundle": "^3.4.30|^4.3.3|^5.0|^6.0", - "symfony/yaml": "^3.4.30|^4.3.3|^5.0|^6.0", - "twig/twig": "^1.34|^2.12|^3.0", - "vimeo/psalm": "^4.7" + "phpunit/phpunit": "^9.5.26 || ^10.0", + "psalm/plugin-phpunit": "^0.18.4", + "psalm/plugin-symfony": "^4", + "psr/log": "^1.1.4 || ^2.0 || ^3.0", + "symfony/phpunit-bridge": "^6.1", + "symfony/property-info": "^5.4 || ^6.0", + "symfony/proxy-manager-bridge": "^5.4 || ^6.0", + "symfony/security-bundle": "^5.4 || ^6.0", + "symfony/twig-bridge": "^5.4 || ^6.0", + "symfony/validator": "^5.4 || ^6.0", + "symfony/web-profiler-bundle": "^5.4 || ^6.0", + "symfony/yaml": "^5.4 || ^6.0", + "twig/twig": "^1.34 || ^2.12 || ^3.0", + "vimeo/psalm": "^4.30" }, "suggest": { "doctrine/orm": "The Doctrine ORM integration is optional in the bundle.", @@ -1737,7 +2077,7 @@ ], "support": { "issues": "https://github.com/doctrine/DoctrineBundle/issues", - "source": "https://github.com/doctrine/DoctrineBundle/tree/2.7.0" + "source": "https://github.com/doctrine/DoctrineBundle/tree/2.9.1" }, "funding": [ { @@ -1753,7 +2093,7 @@ "type": "tidelift" } ], - "time": "2022-06-10T10:55:26+00:00" + "time": "2023-04-14T05:39:34+00:00" }, { "name": "doctrine/doctrine-migrations-bundle", @@ -2025,30 +2365,30 @@ }, { "name": "doctrine/instantiator", - "version": "1.4.1", + "version": "1.5.0", "source": { "type": "git", "url": "https://github.com/doctrine/instantiator.git", - "reference": "10dcfce151b967d20fde1b34ae6640712c3891bc" + "reference": "0a0fa9780f5d4e507415a065172d26a98d02047b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/instantiator/zipball/10dcfce151b967d20fde1b34ae6640712c3891bc", - "reference": "10dcfce151b967d20fde1b34ae6640712c3891bc", + "url": "https://api.github.com/repos/doctrine/instantiator/zipball/0a0fa9780f5d4e507415a065172d26a98d02047b", + "reference": "0a0fa9780f5d4e507415a065172d26a98d02047b", "shasum": "" }, "require": { "php": "^7.1 || ^8.0" }, "require-dev": { - "doctrine/coding-standard": "^9", + "doctrine/coding-standard": "^9 || ^11", "ext-pdo": "*", "ext-phar": "*", "phpbench/phpbench": "^0.16 || ^1", "phpstan/phpstan": "^1.4", "phpstan/phpstan-phpunit": "^1", "phpunit/phpunit": "^7.5 || ^8.5 || ^9.5", - "vimeo/psalm": "^4.22" + "vimeo/psalm": "^4.30 || ^5.4" }, "type": "library", "autoload": { @@ -2075,7 +2415,7 @@ ], "support": { "issues": "https://github.com/doctrine/instantiator/issues", - "source": "https://github.com/doctrine/instantiator/tree/1.4.1" + "source": "https://github.com/doctrine/instantiator/tree/1.5.0" }, "funding": [ { @@ -2091,35 +2431,37 @@ "type": "tidelift" } ], - "time": "2022-03-03T08:28:38+00:00" + "time": "2022-12-30T00:15:36+00:00" }, { "name": "doctrine/lexer", - "version": "1.2.3", + "version": "2.1.0", "source": { "type": "git", "url": "https://github.com/doctrine/lexer.git", - "reference": "c268e882d4dbdd85e36e4ad69e02dc284f89d229" + "reference": "39ab8fcf5a51ce4b85ca97c7a7d033eb12831124" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/lexer/zipball/c268e882d4dbdd85e36e4ad69e02dc284f89d229", - "reference": "c268e882d4dbdd85e36e4ad69e02dc284f89d229", + "url": "https://api.github.com/repos/doctrine/lexer/zipball/39ab8fcf5a51ce4b85ca97c7a7d033eb12831124", + "reference": "39ab8fcf5a51ce4b85ca97c7a7d033eb12831124", "shasum": "" }, "require": { + "doctrine/deprecations": "^1.0", "php": "^7.1 || ^8.0" }, "require-dev": { - "doctrine/coding-standard": "^9.0", + "doctrine/coding-standard": "^9 || ^10", "phpstan/phpstan": "^1.3", "phpunit/phpunit": "^7.5 || ^8.5 || ^9.5", - "vimeo/psalm": "^4.11" + "psalm/plugin-phpunit": "^0.18.3", + "vimeo/psalm": "^4.11 || ^5.0" }, "type": "library", "autoload": { "psr-4": { - "Doctrine\\Common\\Lexer\\": "lib/Doctrine/Common/Lexer" + "Doctrine\\Common\\Lexer\\": "src" } }, "notification-url": "https://packagist.org/downloads/", @@ -2151,7 +2493,7 @@ ], "support": { "issues": "https://github.com/doctrine/lexer/issues", - "source": "https://github.com/doctrine/lexer/tree/1.2.3" + "source": "https://github.com/doctrine/lexer/tree/2.1.0" }, "funding": [ { @@ -2167,27 +2509,27 @@ "type": "tidelift" } ], - "time": "2022-02-28T11:07:21+00:00" + "time": "2022-12-14T08:49:07+00:00" }, { "name": "doctrine/migrations", - "version": "3.5.2", + "version": "3.5.5", "source": { "type": "git", "url": "https://github.com/doctrine/migrations.git", - "reference": "61c6ef3a10b7df43c3b6388a184754f26e58700a" + "reference": "4b1e2b6ba71d21d0c5be22ed03b6fc954d20b204" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/migrations/zipball/61c6ef3a10b7df43c3b6388a184754f26e58700a", - "reference": "61c6ef3a10b7df43c3b6388a184754f26e58700a", + "url": "https://api.github.com/repos/doctrine/migrations/zipball/4b1e2b6ba71d21d0c5be22ed03b6fc954d20b204", + "reference": "4b1e2b6ba71d21d0c5be22ed03b6fc954d20b204", "shasum": "" }, "require": { "composer-runtime-api": "^2", - "doctrine/dbal": "^3.3", + "doctrine/dbal": "^3.5.1", "doctrine/deprecations": "^0.5.3 || ^1", - "doctrine/event-manager": "^1.0", + "doctrine/event-manager": "^1.2 || ^2.0", "friendsofphp/proxy-manager-lts": "^1.0", "php": "^7.4 || ^8.0", "psr/log": "^1.1.3 || ^2 || ^3", @@ -2199,10 +2541,9 @@ }, "require-dev": { "doctrine/coding-standard": "^9", - "doctrine/orm": "^2.12", + "doctrine/orm": "^2.13", "doctrine/persistence": "^2 || ^3", "doctrine/sql-formatter": "^1.0", - "ergebnis/composer-normalize": "^2.9", "ext-pdo_sqlite": "*", "phpstan/phpstan": "^1.5", "phpstan/phpstan-deprecation-rules": "^1", @@ -2222,12 +2563,6 @@ "bin/doctrine-migrations" ], "type": "library", - "extra": { - "composer-normalize": { - "indent-size": 4, - "indent-style": "space" - } - }, "autoload": { "psr-4": { "Doctrine\\Migrations\\": "lib/Doctrine/Migrations" @@ -2260,7 +2595,7 @@ ], "support": { "issues": "https://github.com/doctrine/migrations/issues", - "source": "https://github.com/doctrine/migrations/tree/3.5.2" + "source": "https://github.com/doctrine/migrations/tree/3.5.5" }, "funding": [ { @@ -2276,55 +2611,56 @@ "type": "tidelift" } ], - "time": "2022-08-04T14:29:49+00:00" + "time": "2023-01-18T12:44:30+00:00" }, { "name": "doctrine/orm", - "version": "2.13.3", + "version": "2.15.1", "source": { "type": "git", "url": "https://github.com/doctrine/orm.git", - "reference": "e750360bd52b080c4cbaaee1b48b80f7dc873b36" + "reference": "9bc6f5b4ac6f1e7d4248b2efbd01a748782075bc" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/orm/zipball/e750360bd52b080c4cbaaee1b48b80f7dc873b36", - "reference": "e750360bd52b080c4cbaaee1b48b80f7dc873b36", + "url": "https://api.github.com/repos/doctrine/orm/zipball/9bc6f5b4ac6f1e7d4248b2efbd01a748782075bc", + "reference": "9bc6f5b4ac6f1e7d4248b2efbd01a748782075bc", "shasum": "" }, "require": { "composer-runtime-api": "^2", "doctrine/cache": "^1.12.1 || ^2.1.1", - "doctrine/collections": "^1.5", + "doctrine/collections": "^1.5 || ^2.1", "doctrine/common": "^3.0.3", "doctrine/dbal": "^2.13.1 || ^3.2", "doctrine/deprecations": "^0.5.3 || ^1", - "doctrine/event-manager": "^1.1", + "doctrine/event-manager": "^1.2 || ^2", "doctrine/inflector": "^1.4 || ^2.0", - "doctrine/instantiator": "^1.3", - "doctrine/lexer": "^1.2.3", + "doctrine/instantiator": "^1.3 || ^2", + "doctrine/lexer": "^2", "doctrine/persistence": "^2.4 || ^3", "ext-ctype": "*", "php": "^7.1 || ^8.0", "psr/cache": "^1 || ^2 || ^3", - "symfony/console": "^3.0 || ^4.0 || ^5.0 || ^6.0", + "symfony/console": "^4.2 || ^5.0 || ^6.0", "symfony/polyfill-php72": "^1.23", "symfony/polyfill-php80": "^1.16" }, "conflict": { - "doctrine/annotations": "<1.13 || >= 2.0" + "doctrine/annotations": "<1.13 || >= 3.0" }, "require-dev": { - "doctrine/annotations": "^1.13", - "doctrine/coding-standard": "^9.0.2 || ^10.0", + "doctrine/annotations": "^1.13 || ^2", + "doctrine/coding-standard": "^9.0.2 || ^12.0", "phpbench/phpbench": "^0.16.10 || ^1.0", - "phpstan/phpstan": "~1.4.10 || 1.8.5", - "phpunit/phpunit": "^7.5 || ^8.5 || ^9.5", + "phpstan/phpstan": "~1.4.10 || 1.10.14", + "phpunit/phpunit": "^7.5 || ^8.5 || ^9.6", "psr/log": "^1 || ^2 || ^3", - "squizlabs/php_codesniffer": "3.7.1", + "squizlabs/php_codesniffer": "3.7.2", "symfony/cache": "^4.4 || ^5.4 || ^6.0", + "symfony/var-exporter": "^4.4 || ^5.4 || ^6.2", "symfony/yaml": "^3.4 || ^4.0 || ^5.0 || ^6.0", - "vimeo/psalm": "4.27.0" + "vimeo/psalm": "4.30.0 || 5.11.0" }, "suggest": { "ext-dom": "Provides support for XSD validation for XML mapping files", @@ -2374,22 +2710,22 @@ ], "support": { "issues": "https://github.com/doctrine/orm/issues", - "source": "https://github.com/doctrine/orm/tree/2.13.3" + "source": "https://github.com/doctrine/orm/tree/2.15.1" }, - "time": "2022-10-07T06:37:17+00:00" + "time": "2023-05-07T18:56:25+00:00" }, { "name": "doctrine/persistence", - "version": "3.0.4", + "version": "3.2.0", "source": { "type": "git", "url": "https://github.com/doctrine/persistence.git", - "reference": "05612da375f8a3931161f435f91d6704926e6ec5" + "reference": "63fee8c33bef740db6730eb2a750cd3da6495603" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/persistence/zipball/05612da375f8a3931161f435f91d6704926e6ec5", - "reference": "05612da375f8a3931161f435f91d6704926e6ec5", + "url": "https://api.github.com/repos/doctrine/persistence/zipball/63fee8c33bef740db6730eb2a750cd3da6495603", + "reference": "63fee8c33bef740db6730eb2a750cd3da6495603", "shasum": "" }, "require": { @@ -2398,20 +2734,18 @@ "psr/cache": "^1.0 || ^2.0 || ^3.0" }, "conflict": { - "doctrine/annotations": "<1.7 || >=2.0", "doctrine/common": "<2.10" }, "require-dev": { "composer/package-versions-deprecated": "^1.11", - "doctrine/annotations": "^1.7", - "doctrine/coding-standard": "^10", + "doctrine/coding-standard": "^11", "doctrine/common": "^3.0", - "phpstan/phpstan": "1.8.8", + "phpstan/phpstan": "1.9.4", "phpstan/phpstan-phpunit": "^1", "phpstan/phpstan-strict-rules": "^1.1", "phpunit/phpunit": "^8.5 || ^9.5", "symfony/cache": "^4.4 || ^5.4 || ^6.0", - "vimeo/psalm": "4.29.0" + "vimeo/psalm": "4.30.0 || 5.3.0" }, "type": "library", "autoload": { @@ -2460,7 +2794,7 @@ ], "support": { "issues": "https://github.com/doctrine/persistence/issues", - "source": "https://github.com/doctrine/persistence/tree/3.0.4" + "source": "https://github.com/doctrine/persistence/tree/3.2.0" }, "funding": [ { @@ -2476,7 +2810,7 @@ "type": "tidelift" } ], - "time": "2022-10-13T07:34:14+00:00" + "time": "2023-05-17T18:32:04+00:00" }, { "name": "doctrine/sql-formatter", @@ -2696,22 +3030,22 @@ }, { "name": "friendsofphp/proxy-manager-lts", - "version": "v1.0.13", + "version": "v1.0.16", "source": { "type": "git", "url": "https://github.com/FriendsOfPHP/proxy-manager-lts.git", - "reference": "88354616f4cf4f6620910fd035e282173ba453e8" + "reference": "ecadbdc9052e4ad08c60c8a02268712e50427f7c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/FriendsOfPHP/proxy-manager-lts/zipball/88354616f4cf4f6620910fd035e282173ba453e8", - "reference": "88354616f4cf4f6620910fd035e282173ba453e8", + "url": "https://api.github.com/repos/FriendsOfPHP/proxy-manager-lts/zipball/ecadbdc9052e4ad08c60c8a02268712e50427f7c", + "reference": "ecadbdc9052e4ad08c60c8a02268712e50427f7c", "shasum": "" }, "require": { "laminas/laminas-code": "~3.4.1|^4.0", "php": ">=7.1", - "symfony/filesystem": "^4.4.17|^5.0|^6.0" + "symfony/filesystem": "^4.4.17|^5.0|^6.0|^7.0" }, "conflict": { "laminas/laminas-stdlib": "<3.2.1", @@ -2722,7 +3056,7 @@ }, "require-dev": { "ext-phar": "*", - "symfony/phpunit-bridge": "^5.4|^6.0" + "symfony/phpunit-bridge": "^5.4|^6.0|^7.0" }, "type": "library", "extra": { @@ -2762,7 +3096,7 @@ ], "support": { "issues": "https://github.com/FriendsOfPHP/proxy-manager-lts/issues", - "source": "https://github.com/FriendsOfPHP/proxy-manager-lts/tree/v1.0.13" + "source": "https://github.com/FriendsOfPHP/proxy-manager-lts/tree/v1.0.16" }, "funding": [ { @@ -2774,26 +3108,26 @@ "type": "tidelift" } ], - "time": "2022-10-17T19:48:16+00:00" + "time": "2023-05-24T07:17:17+00:00" }, { "name": "guzzlehttp/guzzle", - "version": "7.5.0", + "version": "7.7.0", "source": { "type": "git", "url": "https://github.com/guzzle/guzzle.git", - "reference": "b50a2a1251152e43f6a37f0fa053e730a67d25ba" + "reference": "fb7566caccf22d74d1ab270de3551f72a58399f5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/guzzle/guzzle/zipball/b50a2a1251152e43f6a37f0fa053e730a67d25ba", - "reference": "b50a2a1251152e43f6a37f0fa053e730a67d25ba", + "url": "https://api.github.com/repos/guzzle/guzzle/zipball/fb7566caccf22d74d1ab270de3551f72a58399f5", + "reference": "fb7566caccf22d74d1ab270de3551f72a58399f5", "shasum": "" }, "require": { "ext-json": "*", - "guzzlehttp/promises": "^1.5", - "guzzlehttp/psr7": "^1.9 || ^2.4", + "guzzlehttp/promises": "^1.5.3 || ^2.0", + "guzzlehttp/psr7": "^1.9.1 || ^2.4.5", "php": "^7.2.5 || ^8.0", "psr/http-client": "^1.0", "symfony/deprecation-contracts": "^2.2 || ^3.0" @@ -2804,7 +3138,8 @@ "require-dev": { "bamarni/composer-bin-plugin": "^1.8.1", "ext-curl": "*", - "php-http/client-integration-tests": "^3.0", + "php-http/client-integration-tests": "dev-master#2c025848417c1135031fdf9c728ee53d0a7ceaee as 3.0.999", + "php-http/message-factory": "^1.1", "phpunit/phpunit": "^8.5.29 || ^9.5.23", "psr/log": "^1.1 || ^2.0 || ^3.0" }, @@ -2818,9 +3153,6 @@ "bamarni-bin": { "bin-links": true, "forward-command": false - }, - "branch-alias": { - "dev-master": "7.5-dev" } }, "autoload": { @@ -2886,7 +3218,7 @@ ], "support": { "issues": "https://github.com/guzzle/guzzle/issues", - "source": "https://github.com/guzzle/guzzle/tree/7.5.0" + "source": "https://github.com/guzzle/guzzle/tree/7.7.0" }, "funding": [ { @@ -2902,20 +3234,20 @@ "type": "tidelift" } ], - "time": "2022-08-28T15:39:27+00:00" + "time": "2023-05-21T14:04:53+00:00" }, { "name": "guzzlehttp/promises", - "version": "1.5.2", + "version": "1.5.3", "source": { "type": "git", "url": "https://github.com/guzzle/promises.git", - "reference": "b94b2807d85443f9719887892882d0329d1e2598" + "reference": "67ab6e18aaa14d753cc148911d273f6e6cb6721e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/guzzle/promises/zipball/b94b2807d85443f9719887892882d0329d1e2598", - "reference": "b94b2807d85443f9719887892882d0329d1e2598", + "url": "https://api.github.com/repos/guzzle/promises/zipball/67ab6e18aaa14d753cc148911d273f6e6cb6721e", + "reference": "67ab6e18aaa14d753cc148911d273f6e6cb6721e", "shasum": "" }, "require": { @@ -2925,11 +3257,6 @@ "symfony/phpunit-bridge": "^4.4 || ^5.1" }, "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.5-dev" - } - }, "autoload": { "files": [ "src/functions_include.php" @@ -2970,7 +3297,7 @@ ], "support": { "issues": "https://github.com/guzzle/promises/issues", - "source": "https://github.com/guzzle/promises/tree/1.5.2" + "source": "https://github.com/guzzle/promises/tree/1.5.3" }, "funding": [ { @@ -2986,26 +3313,26 @@ "type": "tidelift" } ], - "time": "2022-08-28T14:55:35+00:00" + "time": "2023-05-21T12:31:43+00:00" }, { "name": "guzzlehttp/psr7", - "version": "2.4.1", + "version": "2.5.0", "source": { "type": "git", "url": "https://github.com/guzzle/psr7.git", - "reference": "69568e4293f4fa993f3b0e51c9723e1e17c41379" + "reference": "b635f279edd83fc275f822a1188157ffea568ff6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/guzzle/psr7/zipball/69568e4293f4fa993f3b0e51c9723e1e17c41379", - "reference": "69568e4293f4fa993f3b0e51c9723e1e17c41379", + "url": "https://api.github.com/repos/guzzle/psr7/zipball/b635f279edd83fc275f822a1188157ffea568ff6", + "reference": "b635f279edd83fc275f822a1188157ffea568ff6", "shasum": "" }, "require": { "php": "^7.2.5 || ^8.0", "psr/http-factory": "^1.0", - "psr/http-message": "^1.0", + "psr/http-message": "^1.1 || ^2.0", "ralouphie/getallheaders": "^3.0" }, "provide": { @@ -3025,9 +3352,6 @@ "bamarni-bin": { "bin-links": true, "forward-command": false - }, - "branch-alias": { - "dev-master": "2.4-dev" } }, "autoload": { @@ -3089,7 +3413,7 @@ ], "support": { "issues": "https://github.com/guzzle/psr7/issues", - "source": "https://github.com/guzzle/psr7/tree/2.4.1" + "source": "https://github.com/guzzle/psr7/tree/2.5.0" }, "funding": [ { @@ -3105,7 +3429,7 @@ "type": "tidelift" } ], - "time": "2022-08-28T14:45:39+00:00" + "time": "2023-04-17T16:11:26+00:00" }, { "name": "http-interop/http-factory-guzzle", @@ -3171,12 +3495,12 @@ "source": { "type": "git", "url": "https://github.com/JetBrains/phpstorm-stubs.git", - "reference": "ded8d118bab0870bf61027bf4fbdfbe6dcc0afd4" + "reference": "077d371b23d38d7f6f039994bfb03732d7965fbc" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/JetBrains/phpstorm-stubs/zipball/ded8d118bab0870bf61027bf4fbdfbe6dcc0afd4", - "reference": "ded8d118bab0870bf61027bf4fbdfbe6dcc0afd4", + "url": "https://api.github.com/repos/JetBrains/phpstorm-stubs/zipball/077d371b23d38d7f6f039994bfb03732d7965fbc", + "reference": "077d371b23d38d7f6f039994bfb03732d7965fbc", "shasum": "" }, "require-dev": { @@ -3184,7 +3508,7 @@ "nikic/php-parser": "@stable", "php": "^8.0", "phpdocumentor/reflection-docblock": "@stable", - "phpunit/phpunit": "@stable" + "phpunit/phpunit": "^9.6" }, "default-branch": true, "type": "library", @@ -3212,7 +3536,7 @@ "support": { "source": "https://github.com/JetBrains/phpstorm-stubs/tree/master" }, - "time": "2022-10-20T14:24:05+00:00" + "time": "2023-04-18T09:13:06+00:00" }, { "name": "justinrainbow/json-schema", @@ -3286,16 +3610,16 @@ }, { "name": "knplabs/github-api", - "version": "v3.9.0", + "version": "v3.11.0", "source": { "type": "git", "url": "https://github.com/KnpLabs/php-github-api.git", - "reference": "665ba275dbf36f9e9ef78876f27ca87796e3599c" + "reference": "c68b874ac3267c3cc0544b726dbb4e49a72a9920" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/KnpLabs/php-github-api/zipball/665ba275dbf36f9e9ef78876f27ca87796e3599c", - "reference": "665ba275dbf36f9e9ef78876f27ca87796e3599c", + "url": "https://api.github.com/repos/KnpLabs/php-github-api/zipball/c68b874ac3267c3cc0544b726dbb4e49a72a9920", + "reference": "c68b874ac3267c3cc0544b726dbb4e49a72a9920", "shasum": "" }, "require": { @@ -3329,7 +3653,7 @@ "extra": { "branch-alias": { "dev-2.x": "2.20.x-dev", - "dev-master": "3.9.x-dev" + "dev-master": "3.10.x-dev" } }, "autoload": { @@ -3362,7 +3686,7 @@ ], "support": { "issues": "https://github.com/KnpLabs/php-github-api/issues", - "source": "https://github.com/KnpLabs/php-github-api/tree/v3.9.0" + "source": "https://github.com/KnpLabs/php-github-api/tree/v3.11.0" }, "funding": [ { @@ -3370,20 +3694,20 @@ "type": "github" } ], - "time": "2022-10-24T12:42:09+00:00" + "time": "2023-03-10T11:40:14+00:00" }, { "name": "laminas/laminas-code", - "version": "4.7.0", + "version": "4.7.1", "source": { "type": "git", "url": "https://github.com/laminas/laminas-code.git", - "reference": "0337d9265bc2e6376babad8c511500821620cb30" + "reference": "91aabc066d5620428120800c0eafc0411e441a62" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laminas/laminas-code/zipball/0337d9265bc2e6376babad8c511500821620cb30", - "reference": "0337d9265bc2e6376babad8c511500821620cb30", + "url": "https://api.github.com/repos/laminas/laminas-code/zipball/91aabc066d5620428120800c0eafc0411e441a62", + "reference": "91aabc066d5620428120800c0eafc0411e441a62", "shasum": "" }, "require": { @@ -3436,7 +3760,7 @@ "type": "community_bridge" } ], - "time": "2022-09-13T10:33:30+00:00" + "time": "2022-11-21T01:32:31+00:00" }, { "name": "laminas/laminas-config", @@ -3738,22 +4062,22 @@ }, { "name": "m4tthumphrey/php-gitlab-api", - "version": "11.8.0", + "version": "11.6.0", "source": { "type": "git", "url": "https://github.com/GitLabPHP/Client.git", - "reference": "38380c933ada8fd2099bc611f0de23c339cdb04a" + "reference": "0f38333b31499d3bd850bbb2267eb719df2e279b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/GitLabPHP/Client/zipball/38380c933ada8fd2099bc611f0de23c339cdb04a", - "reference": "38380c933ada8fd2099bc611f0de23c339cdb04a", + "url": "https://api.github.com/repos/GitLabPHP/Client/zipball/0f38333b31499d3bd850bbb2267eb719df2e279b", + "reference": "0f38333b31499d3bd850bbb2267eb719df2e279b", "shasum": "" }, "require": { "ext-json": "*", "ext-xml": "*", - "php": "^7.4.15 || ^8.0.2", + "php": "^7.2.5 || ^8.0", "php-http/cache-plugin": "^1.7.5", "php-http/client-common": "^2.5", "php-http/discovery": "^1.14", @@ -3763,7 +4087,7 @@ "psr/http-client-implementation": "^1.0", "psr/http-factory-implementation": "^1.0", "psr/http-message": "^1.0", - "symfony/options-resolver": "^4.4 || ^5.0 || ^6.0", + "symfony/options-resolver": "^3.4 || ^4.0 || ^5.0 || ^6.0", "symfony/polyfill-php80": "^1.17" }, "require-dev": { @@ -3810,7 +4134,7 @@ ], "support": { "issues": "https://github.com/GitLabPHP/Client/issues", - "source": "https://github.com/GitLabPHP/Client/tree/11.8.0" + "source": "https://github.com/GitLabPHP/Client/tree/11.6.0" }, "funding": [ { @@ -3818,20 +4142,20 @@ "type": "github" } ], - "time": "2022-04-24T19:04:02+00:00" + "time": "2022-01-23T19:13:35+00:00" }, { "name": "monolog/monolog", - "version": "2.8.0", + "version": "2.9.1", "source": { "type": "git", "url": "https://github.com/Seldaek/monolog.git", - "reference": "720488632c590286b88b80e62aa3d3d551ad4a50" + "reference": "f259e2b15fb95494c83f52d3caad003bbf5ffaa1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Seldaek/monolog/zipball/720488632c590286b88b80e62aa3d3d551ad4a50", - "reference": "720488632c590286b88b80e62aa3d3d551ad4a50", + "url": "https://api.github.com/repos/Seldaek/monolog/zipball/f259e2b15fb95494c83f52d3caad003bbf5ffaa1", + "reference": "f259e2b15fb95494c83f52d3caad003bbf5ffaa1", "shasum": "" }, "require": { @@ -3846,7 +4170,7 @@ "doctrine/couchdb": "~1.0@dev", "elasticsearch/elasticsearch": "^7 || ^8", "ext-json": "*", - "graylog2/gelf-php": "^1.4.2", + "graylog2/gelf-php": "^1.4.2 || ^2@dev", "guzzlehttp/guzzle": "^7.4", "guzzlehttp/psr7": "^2.2", "mongodb/mongodb": "^1.8", @@ -3908,7 +4232,7 @@ ], "support": { "issues": "https://github.com/Seldaek/monolog/issues", - "source": "https://github.com/Seldaek/monolog/tree/2.8.0" + "source": "https://github.com/Seldaek/monolog/tree/2.9.1" }, "funding": [ { @@ -3920,24 +4244,85 @@ "type": "tidelift" } ], - "time": "2022-07-24T11:55:47+00:00" + "time": "2023-02-06T13:44:46+00:00" + }, + { + "name": "mtdowling/jmespath.php", + "version": "2.6.1", + "source": { + "type": "git", + "url": "https://github.com/jmespath/jmespath.php.git", + "reference": "9b87907a81b87bc76d19a7fb2d61e61486ee9edb" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/jmespath/jmespath.php/zipball/9b87907a81b87bc76d19a7fb2d61e61486ee9edb", + "reference": "9b87907a81b87bc76d19a7fb2d61e61486ee9edb", + "shasum": "" + }, + "require": { + "php": "^5.4 || ^7.0 || ^8.0", + "symfony/polyfill-mbstring": "^1.17" + }, + "require-dev": { + "composer/xdebug-handler": "^1.4 || ^2.0", + "phpunit/phpunit": "^4.8.36 || ^7.5.15" + }, + "bin": [ + "bin/jp.php" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.6-dev" + } + }, + "autoload": { + "files": [ + "src/JmesPath.php" + ], + "psr-4": { + "JmesPath\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + } + ], + "description": "Declaratively specify how to extract elements from a JSON document", + "keywords": [ + "json", + "jsonpath" + ], + "support": { + "issues": "https://github.com/jmespath/jmespath.php/issues", + "source": "https://github.com/jmespath/jmespath.php/tree/2.6.1" + }, + "time": "2021-06-14T00:11:39+00:00" }, { "name": "nelmio/api-doc-bundle", - "version": "v4.10.2", + "version": "v4.11.1", "source": { "type": "git", "url": "https://github.com/nelmio/NelmioApiDocBundle.git", - "reference": "52921ac56e49b20ad3ee00bca0ee04870f21b7af" + "reference": "d40c4eb0c090675f3685f75712af331f02924462" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nelmio/NelmioApiDocBundle/zipball/52921ac56e49b20ad3ee00bca0ee04870f21b7af", - "reference": "52921ac56e49b20ad3ee00bca0ee04870f21b7af", + "url": "https://api.github.com/repos/nelmio/NelmioApiDocBundle/zipball/d40c4eb0c090675f3685f75712af331f02924462", + "reference": "d40c4eb0c090675f3685f75712af331f02924462", "shasum": "" }, "require": { - "doctrine/annotations": "^1.11", + "doctrine/annotations": "^1.11|^2.0", "ext-json": "*", "php": ">=7.2", "phpdocumentor/reflection-docblock": "^3.1|^4.0|^5.0", @@ -4030,22 +4415,22 @@ ], "support": { "issues": "https://github.com/nelmio/NelmioApiDocBundle/issues", - "source": "https://github.com/nelmio/NelmioApiDocBundle/tree/v4.10.2" + "source": "https://github.com/nelmio/NelmioApiDocBundle/tree/v4.11.1" }, - "time": "2022-10-18T19:55:47+00:00" + "time": "2023-02-01T07:18:39+00:00" }, { "name": "netresearch/jsonmapper", - "version": "v4.0.0", + "version": "v4.2.0", "source": { "type": "git", "url": "https://github.com/cweiske/jsonmapper.git", - "reference": "8bbc021a8edb2e4a7ea2f8ad4fa9ec9dce2fcb8d" + "reference": "f60565f8c0566a31acf06884cdaa591867ecc956" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/cweiske/jsonmapper/zipball/8bbc021a8edb2e4a7ea2f8ad4fa9ec9dce2fcb8d", - "reference": "8bbc021a8edb2e4a7ea2f8ad4fa9ec9dce2fcb8d", + "url": "https://api.github.com/repos/cweiske/jsonmapper/zipball/f60565f8c0566a31acf06884cdaa591867ecc956", + "reference": "f60565f8c0566a31acf06884cdaa591867ecc956", "shasum": "" }, "require": { @@ -4081,22 +4466,22 @@ "support": { "email": "cweiske@cweiske.de", "issues": "https://github.com/cweiske/jsonmapper/issues", - "source": "https://github.com/cweiske/jsonmapper/tree/v4.0.0" + "source": "https://github.com/cweiske/jsonmapper/tree/v4.2.0" }, - "time": "2020-12-01T19:48:11+00:00" + "time": "2023-04-09T17:37:40+00:00" }, { "name": "nikic/php-parser", - "version": "v4.15.1", + "version": "v4.15.5", "source": { "type": "git", "url": "https://github.com/nikic/PHP-Parser.git", - "reference": "0ef6c55a3f47f89d7a374e6f835197a0b5fcf900" + "reference": "11e2663a5bc9db5d714eedb4277ee300403b4a9e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/0ef6c55a3f47f89d7a374e6f835197a0b5fcf900", - "reference": "0ef6c55a3f47f89d7a374e6f835197a0b5fcf900", + "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/11e2663a5bc9db5d714eedb4277ee300403b4a9e", + "reference": "11e2663a5bc9db5d714eedb4277ee300403b4a9e", "shasum": "" }, "require": { @@ -4137,9 +4522,9 @@ ], "support": { "issues": "https://github.com/nikic/PHP-Parser/issues", - "source": "https://github.com/nikic/PHP-Parser/tree/v4.15.1" + "source": "https://github.com/nikic/PHP-Parser/tree/v4.15.5" }, - "time": "2022-09-04T07:30:47+00:00" + "time": "2023-05-19T20:20:00+00:00" }, { "name": "ondrejmirtes/better-reflection", @@ -4316,16 +4701,16 @@ }, { "name": "pdepend/pdepend", - "version": "2.12.1", + "version": "2.13.0", "source": { "type": "git", "url": "https://github.com/pdepend/pdepend.git", - "reference": "7a892d56ceafd804b4a2ecc85184640937ce9e84" + "reference": "31be7cd4f305f3f7b52af99c1cb13fc938d1cfad" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pdepend/pdepend/zipball/7a892d56ceafd804b4a2ecc85184640937ce9e84", - "reference": "7a892d56ceafd804b4a2ecc85184640937ce9e84", + "url": "https://api.github.com/repos/pdepend/pdepend/zipball/31be7cd4f305f3f7b52af99c1cb13fc938d1cfad", + "reference": "31be7cd4f305f3f7b52af99c1cb13fc938d1cfad", "shasum": "" }, "require": { @@ -4361,7 +4746,7 @@ "description": "Official version of pdepend to be handled with Composer", "support": { "issues": "https://github.com/pdepend/pdepend/issues", - "source": "https://github.com/pdepend/pdepend/tree/2.12.1" + "source": "https://github.com/pdepend/pdepend/tree/2.13.0" }, "funding": [ { @@ -4369,20 +4754,20 @@ "type": "tidelift" } ], - "time": "2022-09-08T19:30:37+00:00" + "time": "2023-02-28T20:56:15+00:00" }, { "name": "php-http/cache-plugin", - "version": "1.7.5", + "version": "1.8.0", "source": { "type": "git", "url": "https://github.com/php-http/cache-plugin.git", - "reference": "63bc3f7242825c9a817db8f78e4c9703b0c471e2" + "reference": "6bf9fbf66193f61d90c2381b75eb1fa0202fd314" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-http/cache-plugin/zipball/63bc3f7242825c9a817db8f78e4c9703b0c471e2", - "reference": "63bc3f7242825c9a817db8f78e4c9703b0c471e2", + "url": "https://api.github.com/repos/php-http/cache-plugin/zipball/6bf9fbf66193f61d90c2381b75eb1fa0202fd314", + "reference": "6bf9fbf66193f61d90c2381b75eb1fa0202fd314", "shasum": "" }, "require": { @@ -4393,14 +4778,9 @@ "symfony/options-resolver": "^2.6 || ^3.0 || ^4.0 || ^5.0 || ^6.0" }, "require-dev": { - "phpspec/phpspec": "^5.1 || ^6.0" + "phpspec/phpspec": "^5.1 || ^6.0 || ^7.0" }, "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.6-dev" - } - }, "autoload": { "psr-4": { "Http\\Client\\Common\\Plugin\\": "src/" @@ -4426,32 +4806,31 @@ ], "support": { "issues": "https://github.com/php-http/cache-plugin/issues", - "source": "https://github.com/php-http/cache-plugin/tree/1.7.5" + "source": "https://github.com/php-http/cache-plugin/tree/1.8.0" }, - "time": "2022-01-18T12:24:56+00:00" + "time": "2023-04-28T10:56:55+00:00" }, { "name": "php-http/client-common", - "version": "2.6.0", + "version": "2.7.0", "source": { "type": "git", "url": "https://github.com/php-http/client-common.git", - "reference": "45db684cd4e186dcdc2b9c06b22970fe123796c0" + "reference": "880509727a447474d2a71b7d7fa5d268ddd3db4b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-http/client-common/zipball/45db684cd4e186dcdc2b9c06b22970fe123796c0", - "reference": "45db684cd4e186dcdc2b9c06b22970fe123796c0", + "url": "https://api.github.com/repos/php-http/client-common/zipball/880509727a447474d2a71b7d7fa5d268ddd3db4b", + "reference": "880509727a447474d2a71b7d7fa5d268ddd3db4b", "shasum": "" }, "require": { "php": "^7.1 || ^8.0", "php-http/httplug": "^2.0", "php-http/message": "^1.6", - "php-http/message-factory": "^1.0", "psr/http-client": "^1.0", "psr/http-factory": "^1.0", - "psr/http-message": "^1.0", + "psr/http-message": "^1.0 || ^2.0", "symfony/options-resolver": "~4.0.15 || ~4.1.9 || ^4.2.1 || ^5.0 || ^6.0", "symfony/polyfill-php80": "^1.17" }, @@ -4461,7 +4840,7 @@ "nyholm/psr7": "^1.2", "phpspec/phpspec": "^5.1 || ^6.3 || ^7.1", "phpspec/prophecy": "^1.10.2", - "phpunit/phpunit": "^7.5.15 || ^8.5 || ^9.3" + "phpunit/phpunit": "^7.5.20 || ^8.5.33 || ^9.6.7" }, "suggest": { "ext-json": "To detect JSON responses with the ContentTypePlugin", @@ -4471,11 +4850,6 @@ "php-http/stopwatch-plugin": "Symfony Stopwatch plugin" }, "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.3.x-dev" - } - }, "autoload": { "psr-4": { "Http\\Client\\Common\\": "src/" @@ -4501,49 +4875,59 @@ ], "support": { "issues": "https://github.com/php-http/client-common/issues", - "source": "https://github.com/php-http/client-common/tree/2.6.0" + "source": "https://github.com/php-http/client-common/tree/2.7.0" }, - "time": "2022-09-29T09:59:43+00:00" + "time": "2023-05-17T06:46:59+00:00" }, { "name": "php-http/discovery", - "version": "1.14.3", + "version": "1.18.1", "source": { "type": "git", "url": "https://github.com/php-http/discovery.git", - "reference": "31d8ee46d0215108df16a8527c7438e96a4d7735" + "reference": "f258b3a1d16acb7b21f3b42d7a2494a733365237" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-http/discovery/zipball/31d8ee46d0215108df16a8527c7438e96a4d7735", - "reference": "31d8ee46d0215108df16a8527c7438e96a4d7735", + "url": "https://api.github.com/repos/php-http/discovery/zipball/f258b3a1d16acb7b21f3b42d7a2494a733365237", + "reference": "f258b3a1d16acb7b21f3b42d7a2494a733365237", "shasum": "" }, "require": { + "composer-plugin-api": "^1.0|^2.0", "php": "^7.1 || ^8.0" }, "conflict": { - "nyholm/psr7": "<1.0" + "nyholm/psr7": "<1.0", + "zendframework/zend-diactoros": "*" + }, + "provide": { + "php-http/async-client-implementation": "*", + "php-http/client-implementation": "*", + "psr/http-client-implementation": "*", + "psr/http-factory-implementation": "*", + "psr/http-message-implementation": "*" }, "require-dev": { + "composer/composer": "^1.0.2|^2.0", "graham-campbell/phpspec-skip-example-extension": "^5.0", "php-http/httplug": "^1.0 || ^2.0", "php-http/message-factory": "^1.0", - "phpspec/phpspec": "^5.1 || ^6.1" - }, - "suggest": { - "php-http/message": "Allow to use Guzzle, Diactoros or Slim Framework factories" + "phpspec/phpspec": "^5.1 || ^6.1 || ^7.3", + "symfony/phpunit-bridge": "^6.2" }, - "type": "library", + "type": "composer-plugin", "extra": { - "branch-alias": { - "dev-master": "1.9-dev" - } + "class": "Http\\Discovery\\Composer\\Plugin", + "plugin-optional": true }, "autoload": { "psr-4": { "Http\\Discovery\\": "src/" - } + }, + "exclude-from-classmap": [ + "src/Composer/Plugin.php" + ] }, "notification-url": "https://packagist.org/downloads/", "license": [ @@ -4555,7 +4939,7 @@ "email": "mark.sagikazar@gmail.com" } ], - "description": "Finds installed HTTPlug implementations and PSR-7 message factories", + "description": "Finds and installs PSR-7, PSR-17, PSR-18 and HTTPlug implementations", "homepage": "http://php-http.org", "keywords": [ "adapter", @@ -4564,44 +4948,40 @@ "factory", "http", "message", + "psr17", "psr7" ], "support": { "issues": "https://github.com/php-http/discovery/issues", - "source": "https://github.com/php-http/discovery/tree/1.14.3" + "source": "https://github.com/php-http/discovery/tree/1.18.1" }, - "time": "2022-07-11T14:04:40+00:00" + "time": "2023-05-17T08:53:10+00:00" }, { "name": "php-http/httplug", - "version": "2.3.0", + "version": "2.4.0", "source": { "type": "git", "url": "https://github.com/php-http/httplug.git", - "reference": "f640739f80dfa1152533976e3c112477f69274eb" + "reference": "625ad742c360c8ac580fcc647a1541d29e257f67" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-http/httplug/zipball/f640739f80dfa1152533976e3c112477f69274eb", - "reference": "f640739f80dfa1152533976e3c112477f69274eb", + "url": "https://api.github.com/repos/php-http/httplug/zipball/625ad742c360c8ac580fcc647a1541d29e257f67", + "reference": "625ad742c360c8ac580fcc647a1541d29e257f67", "shasum": "" }, "require": { "php": "^7.1 || ^8.0", "php-http/promise": "^1.1", "psr/http-client": "^1.0", - "psr/http-message": "^1.0" + "psr/http-message": "^1.0 || ^2.0" }, "require-dev": { - "friends-of-phpspec/phpspec-code-coverage": "^4.1", - "phpspec/phpspec": "^5.1 || ^6.0" + "friends-of-phpspec/phpspec-code-coverage": "^4.1 || ^5.0 || ^6.0", + "phpspec/phpspec": "^5.1 || ^6.0 || ^7.0" }, "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.x-dev" - } - }, "autoload": { "psr-4": { "Http\\Client\\": "src/" @@ -4630,29 +5010,28 @@ ], "support": { "issues": "https://github.com/php-http/httplug/issues", - "source": "https://github.com/php-http/httplug/tree/2.3.0" + "source": "https://github.com/php-http/httplug/tree/2.4.0" }, - "time": "2022-02-21T09:52:22+00:00" + "time": "2023-04-14T15:10:03+00:00" }, { "name": "php-http/message", - "version": "1.13.0", + "version": "1.16.0", "source": { "type": "git", "url": "https://github.com/php-http/message.git", - "reference": "7886e647a30a966a1a8d1dad1845b71ca8678361" + "reference": "47a14338bf4ebd67d317bf1144253d7db4ab55fd" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-http/message/zipball/7886e647a30a966a1a8d1dad1845b71ca8678361", - "reference": "7886e647a30a966a1a8d1dad1845b71ca8678361", + "url": "https://api.github.com/repos/php-http/message/zipball/47a14338bf4ebd67d317bf1144253d7db4ab55fd", + "reference": "47a14338bf4ebd67d317bf1144253d7db4ab55fd", "shasum": "" }, "require": { "clue/stream-filter": "^1.5", - "php": "^7.1 || ^8.0", - "php-http/message-factory": "^1.0.2", - "psr/http-message": "^1.0" + "php": "^7.2 || ^8.0", + "psr/http-message": "^1.1 || ^2.0" }, "provide": { "php-http/message-factory-implementation": "1.0" @@ -4660,8 +5039,9 @@ "require-dev": { "ergebnis/composer-normalize": "^2.6", "ext-zlib": "*", - "guzzlehttp/psr7": "^1.0", - "laminas/laminas-diactoros": "^2.0", + "guzzlehttp/psr7": "^1.0 || ^2.0", + "laminas/laminas-diactoros": "^2.0 || ^3.0", + "php-http/message-factory": "^1.0.2", "phpspec/phpspec": "^5.1 || ^6.3 || ^7.1", "slim/slim": "^3.0" }, @@ -4672,11 +5052,6 @@ "slim/slim": "Used with Slim Framework PSR-7 implementation" }, "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.10-dev" - } - }, "autoload": { "files": [ "src/filters.php" @@ -4704,32 +5079,32 @@ ], "support": { "issues": "https://github.com/php-http/message/issues", - "source": "https://github.com/php-http/message/tree/1.13.0" + "source": "https://github.com/php-http/message/tree/1.16.0" }, - "time": "2022-02-11T13:41:14+00:00" + "time": "2023-05-17T06:43:38+00:00" }, { "name": "php-http/message-factory", - "version": "v1.0.2", + "version": "1.1.0", "source": { "type": "git", "url": "https://github.com/php-http/message-factory.git", - "reference": "a478cb11f66a6ac48d8954216cfed9aa06a501a1" + "reference": "4d8778e1c7d405cbb471574821c1ff5b68cc8f57" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-http/message-factory/zipball/a478cb11f66a6ac48d8954216cfed9aa06a501a1", - "reference": "a478cb11f66a6ac48d8954216cfed9aa06a501a1", + "url": "https://api.github.com/repos/php-http/message-factory/zipball/4d8778e1c7d405cbb471574821c1ff5b68cc8f57", + "reference": "4d8778e1c7d405cbb471574821c1ff5b68cc8f57", "shasum": "" }, "require": { "php": ">=5.4", - "psr/http-message": "^1.0" + "psr/http-message": "^1.0 || ^2.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.0-dev" + "dev-master": "1.x-dev" } }, "autoload": { @@ -4758,42 +5133,37 @@ ], "support": { "issues": "https://github.com/php-http/message-factory/issues", - "source": "https://github.com/php-http/message-factory/tree/master" + "source": "https://github.com/php-http/message-factory/tree/1.1.0" }, - "time": "2015-12-19T14:08:53+00:00" + "abandoned": "psr/http-factory", + "time": "2023-04-14T14:16:17+00:00" }, { "name": "php-http/multipart-stream-builder", - "version": "1.2.0", + "version": "1.3.0", "source": { "type": "git", "url": "https://github.com/php-http/multipart-stream-builder.git", - "reference": "11c1d31f72e01c738bbce9e27649a7cca829c30e" + "reference": "f5938fd135d9fa442cc297dc98481805acfe2b6a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-http/multipart-stream-builder/zipball/11c1d31f72e01c738bbce9e27649a7cca829c30e", - "reference": "11c1d31f72e01c738bbce9e27649a7cca829c30e", + "url": "https://api.github.com/repos/php-http/multipart-stream-builder/zipball/f5938fd135d9fa442cc297dc98481805acfe2b6a", + "reference": "f5938fd135d9fa442cc297dc98481805acfe2b6a", "shasum": "" }, "require": { "php": "^7.1 || ^8.0", - "php-http/discovery": "^1.7", - "php-http/message-factory": "^1.0.2", - "psr/http-factory": "^1.0", - "psr/http-message": "^1.0" + "php-http/discovery": "^1.15", + "psr/http-factory-implementation": "^1.0" }, "require-dev": { "nyholm/psr7": "^1.0", "php-http/message": "^1.5", + "php-http/message-factory": "^1.0.2", "phpunit/phpunit": "^7.5.15 || ^8.5 || ^9.3" }, "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.x-dev" - } - }, "autoload": { "psr-4": { "Http\\Message\\MultipartStream\\": "src/" @@ -4820,9 +5190,9 @@ ], "support": { "issues": "https://github.com/php-http/multipart-stream-builder/issues", - "source": "https://github.com/php-http/multipart-stream-builder/tree/1.2.0" + "source": "https://github.com/php-http/multipart-stream-builder/tree/1.3.0" }, - "time": "2021-05-21T08:32:01+00:00" + "time": "2023-04-28T14:10:22+00:00" }, { "name": "php-http/promise", @@ -4934,25 +5304,25 @@ }, { "name": "phpbench/dom", - "version": "0.3.2", + "version": "0.3.3", "source": { "type": "git", "url": "https://github.com/phpbench/dom.git", - "reference": "b013b717832ddbaadf2a40984b04bc66af9a7110" + "reference": "786a96db538d0def931f5b19225233ec42ec7a72" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpbench/dom/zipball/b013b717832ddbaadf2a40984b04bc66af9a7110", - "reference": "b013b717832ddbaadf2a40984b04bc66af9a7110", + "url": "https://api.github.com/repos/phpbench/dom/zipball/786a96db538d0def931f5b19225233ec42ec7a72", + "reference": "786a96db538d0def931f5b19225233ec42ec7a72", "shasum": "" }, "require": { "ext-dom": "*", - "php": "^7.2||^8.0" + "php": "^7.3||^8.0" }, "require-dev": { - "friendsofphp/php-cs-fixer": "^2.18", - "phpstan/phpstan": "^0.12.83", + "friendsofphp/php-cs-fixer": "^3.14", + "phpstan/phpstan": "^1.10", "phpunit/phpunit": "^8.0||^9.0" }, "type": "library", @@ -4979,35 +5349,35 @@ "description": "DOM wrapper to simplify working with the PHP DOM implementation", "support": { "issues": "https://github.com/phpbench/dom/issues", - "source": "https://github.com/phpbench/dom/tree/0.3.2" + "source": "https://github.com/phpbench/dom/tree/0.3.3" }, - "time": "2021-09-24T15:26:07+00:00" + "time": "2023-03-06T23:46:57+00:00" }, { "name": "phpbench/phpbench", - "version": "1.2.7", + "version": "1.2.10", "source": { "type": "git", "url": "https://github.com/phpbench/phpbench.git", - "reference": "dce145304abbb16c8d9af69c19d96f47e9d0e670" + "reference": "95206f92479674599a75e02b74b9933e2d9883aa" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpbench/phpbench/zipball/dce145304abbb16c8d9af69c19d96f47e9d0e670", - "reference": "dce145304abbb16c8d9af69c19d96f47e9d0e670", + "url": "https://api.github.com/repos/phpbench/phpbench/zipball/95206f92479674599a75e02b74b9933e2d9883aa", + "reference": "95206f92479674599a75e02b74b9933e2d9883aa", "shasum": "" }, "require": { - "doctrine/annotations": "^1.13", + "doctrine/annotations": "^1.13 || ^2.0", "ext-dom": "*", "ext-json": "*", "ext-pcre": "*", "ext-reflection": "*", "ext-spl": "*", "ext-tokenizer": "*", - "php": "^7.3 || ^8.0", + "php": "^7.4 || ^8.0", "phpbench/container": "^2.1", - "phpbench/dom": "~0.3.1", + "phpbench/dom": "~0.3.3", "psr/log": "^1.1 || ^2.0 || ^3.0", "seld/jsonlint": "^1.1", "symfony/console": "^4.2 || ^5.0 || ^6.0", @@ -5025,7 +5395,7 @@ "phpstan/extension-installer": "^1.1", "phpstan/phpstan": "^1.0", "phpstan/phpstan-phpunit": "^1.0", - "phpunit/phpunit": "^8.5.8 || ^9.0", + "phpunit/phpunit": "^9.0", "symfony/error-handler": "^5.2 || ^6.0", "symfony/var-dumper": "^4.0 || ^5.0 || ^6.0" }, @@ -5063,7 +5433,7 @@ "description": "PHP Benchmarking Framework", "support": { "issues": "https://github.com/phpbench/phpbench/issues", - "source": "https://github.com/phpbench/phpbench/tree/1.2.7" + "source": "https://github.com/phpbench/phpbench/tree/1.2.10" }, "funding": [ { @@ -5071,7 +5441,7 @@ "type": "github" } ], - "time": "2022-10-15T09:57:51+00:00" + "time": "2023-03-24T08:52:55+00:00" }, { "name": "phpdocumentor/reflection-common", @@ -5185,24 +5555,27 @@ }, { "name": "phpdocumentor/type-resolver", - "version": "1.6.2", + "version": "1.7.1", "source": { "type": "git", "url": "https://github.com/phpDocumentor/TypeResolver.git", - "reference": "48f445a408c131e38cab1c235aa6d2bb7a0bb20d" + "reference": "dfc078e8af9c99210337325ff5aa152872c98714" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/48f445a408c131e38cab1c235aa6d2bb7a0bb20d", - "reference": "48f445a408c131e38cab1c235aa6d2bb7a0bb20d", + "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/dfc078e8af9c99210337325ff5aa152872c98714", + "reference": "dfc078e8af9c99210337325ff5aa152872c98714", "shasum": "" }, "require": { + "doctrine/deprecations": "^1.0", "php": "^7.4 || ^8.0", - "phpdocumentor/reflection-common": "^2.0" + "phpdocumentor/reflection-common": "^2.0", + "phpstan/phpdoc-parser": "^1.13" }, "require-dev": { "ext-tokenizer": "*", + "phpbench/phpbench": "^1.2", "phpstan/extension-installer": "^1.1", "phpstan/phpstan": "^1.8", "phpstan/phpstan-phpunit": "^1.1", @@ -5234,9 +5607,9 @@ "description": "A PSR-5 based resolver of Class names, Types and Structural Element Names", "support": { "issues": "https://github.com/phpDocumentor/TypeResolver/issues", - "source": "https://github.com/phpDocumentor/TypeResolver/tree/1.6.2" + "source": "https://github.com/phpDocumentor/TypeResolver/tree/1.7.1" }, - "time": "2022-10-14T12:47:21+00:00" + "time": "2023-03-27T19:02:04+00:00" }, { "name": "phpmd/phpmd", @@ -5323,22 +5696,23 @@ }, { "name": "phpstan/phpdoc-parser", - "version": "1.11.0", + "version": "1.21.0", "source": { "type": "git", "url": "https://github.com/phpstan/phpdoc-parser.git", - "reference": "7d1e81213b0c7eb8d5a9f524456cbc2778ed5c65" + "reference": "6df62b08faef4f899772bc7c3bbabb93d2b7a21c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/7d1e81213b0c7eb8d5a9f524456cbc2778ed5c65", - "reference": "7d1e81213b0c7eb8d5a9f524456cbc2778ed5c65", + "url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/6df62b08faef4f899772bc7c3bbabb93d2b7a21c", + "reference": "6df62b08faef4f899772bc7c3bbabb93d2b7a21c", "shasum": "" }, "require": { "php": "^7.2 || ^8.0" }, "require-dev": { + "nikic/php-parser": "^4.15", "php-parallel-lint/php-parallel-lint": "^1.2", "phpstan/extension-installer": "^1.0", "phpstan/phpstan": "^1.5", @@ -5362,22 +5736,22 @@ "description": "PHPDoc parser with support for nullable, intersection and generic types", "support": { "issues": "https://github.com/phpstan/phpdoc-parser/issues", - "source": "https://github.com/phpstan/phpdoc-parser/tree/1.11.0" + "source": "https://github.com/phpstan/phpdoc-parser/tree/1.21.0" }, - "time": "2022-10-14T13:32:28+00:00" + "time": "2023-05-17T13:13:44+00:00" }, { "name": "phpstan/phpstan", - "version": "1.8.10", + "version": "1.10.15", "source": { "type": "git", "url": "https://github.com/phpstan/phpstan.git", - "reference": "0c4459dc42c568b818b3f25186589f3acddc1823" + "reference": "762c4dac4da6f8756eebb80e528c3a47855da9bd" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpstan/zipball/0c4459dc42c568b818b3f25186589f3acddc1823", - "reference": "0c4459dc42c568b818b3f25186589f3acddc1823", + "url": "https://api.github.com/repos/phpstan/phpstan/zipball/762c4dac4da6f8756eebb80e528c3a47855da9bd", + "reference": "762c4dac4da6f8756eebb80e528c3a47855da9bd", "shasum": "" }, "require": { @@ -5406,8 +5780,11 @@ "static analysis" ], "support": { + "docs": "https://phpstan.org/user-guide/getting-started", + "forum": "https://github.com/phpstan/phpstan/discussions", "issues": "https://github.com/phpstan/phpstan/issues", - "source": "https://github.com/phpstan/phpstan/tree/1.8.10" + "security": "https://github.com/phpstan/phpstan/security/policy", + "source": "https://github.com/phpstan/phpstan-src" }, "funding": [ { @@ -5423,7 +5800,7 @@ "type": "tidelift" } ], - "time": "2022-10-17T14:23:35+00:00" + "time": "2023-05-09T15:28:01+00:00" }, { "name": "psr/cache", @@ -5574,21 +5951,21 @@ }, { "name": "psr/http-client", - "version": "1.0.1", + "version": "1.0.2", "source": { "type": "git", "url": "https://github.com/php-fig/http-client.git", - "reference": "2dfb5f6c5eff0e91e20e913f8c5452ed95b86621" + "reference": "0955afe48220520692d2d09f7ab7e0f93ffd6a31" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-fig/http-client/zipball/2dfb5f6c5eff0e91e20e913f8c5452ed95b86621", - "reference": "2dfb5f6c5eff0e91e20e913f8c5452ed95b86621", + "url": "https://api.github.com/repos/php-fig/http-client/zipball/0955afe48220520692d2d09f7ab7e0f93ffd6a31", + "reference": "0955afe48220520692d2d09f7ab7e0f93ffd6a31", "shasum": "" }, "require": { "php": "^7.0 || ^8.0", - "psr/http-message": "^1.0" + "psr/http-message": "^1.0 || ^2.0" }, "type": "library", "extra": { @@ -5608,7 +5985,7 @@ "authors": [ { "name": "PHP-FIG", - "homepage": "http://www.php-fig.org/" + "homepage": "https://www.php-fig.org/" } ], "description": "Common interface for HTTP clients", @@ -5620,27 +5997,27 @@ "psr-18" ], "support": { - "source": "https://github.com/php-fig/http-client/tree/master" + "source": "https://github.com/php-fig/http-client/tree/1.0.2" }, - "time": "2020-06-29T06:28:15+00:00" + "time": "2023-04-10T20:12:12+00:00" }, { "name": "psr/http-factory", - "version": "1.0.1", + "version": "1.0.2", "source": { "type": "git", "url": "https://github.com/php-fig/http-factory.git", - "reference": "12ac7fcd07e5b077433f5f2bee95b3a771bf61be" + "reference": "e616d01114759c4c489f93b099585439f795fe35" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-fig/http-factory/zipball/12ac7fcd07e5b077433f5f2bee95b3a771bf61be", - "reference": "12ac7fcd07e5b077433f5f2bee95b3a771bf61be", + "url": "https://api.github.com/repos/php-fig/http-factory/zipball/e616d01114759c4c489f93b099585439f795fe35", + "reference": "e616d01114759c4c489f93b099585439f795fe35", "shasum": "" }, "require": { "php": ">=7.0.0", - "psr/http-message": "^1.0" + "psr/http-message": "^1.0 || ^2.0" }, "type": "library", "extra": { @@ -5660,7 +6037,7 @@ "authors": [ { "name": "PHP-FIG", - "homepage": "http://www.php-fig.org/" + "homepage": "https://www.php-fig.org/" } ], "description": "Common interfaces for PSR-7 HTTP message factories", @@ -5675,31 +6052,31 @@ "response" ], "support": { - "source": "https://github.com/php-fig/http-factory/tree/master" + "source": "https://github.com/php-fig/http-factory/tree/1.0.2" }, - "time": "2019-04-30T12:38:16+00:00" + "time": "2023-04-10T20:10:41+00:00" }, { "name": "psr/http-message", - "version": "1.0.1", + "version": "1.1", "source": { "type": "git", "url": "https://github.com/php-fig/http-message.git", - "reference": "f6561bf28d520154e4b0ec72be95418abe6d9363" + "reference": "cb6ce4845ce34a8ad9e68117c10ee90a29919eba" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-fig/http-message/zipball/f6561bf28d520154e4b0ec72be95418abe6d9363", - "reference": "f6561bf28d520154e4b0ec72be95418abe6d9363", + "url": "https://api.github.com/repos/php-fig/http-message/zipball/cb6ce4845ce34a8ad9e68117c10ee90a29919eba", + "reference": "cb6ce4845ce34a8ad9e68117c10ee90a29919eba", "shasum": "" }, "require": { - "php": ">=5.3.0" + "php": "^7.2 || ^8.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.0.x-dev" + "dev-master": "1.1.x-dev" } }, "autoload": { @@ -5728,9 +6105,9 @@ "response" ], "support": { - "source": "https://github.com/php-fig/http-message/tree/master" + "source": "https://github.com/php-fig/http-message/tree/1.1" }, - "time": "2016-08-06T14:39:51+00:00" + "time": "2023-04-04T09:50:52+00:00" }, { "name": "psr/log", @@ -5828,16 +6205,16 @@ }, { "name": "ramsey/uuid", - "version": "3.9.6", + "version": "3.9.7", "source": { "type": "git", "url": "https://github.com/ramsey/uuid.git", - "reference": "ffa80ab953edd85d5b6c004f96181a538aad35a3" + "reference": "dc75aa439eb4c1b77f5379fd958b3dc0e6014178" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/ramsey/uuid/zipball/ffa80ab953edd85d5b6c004f96181a538aad35a3", - "reference": "ffa80ab953edd85d5b6c004f96181a538aad35a3", + "url": "https://api.github.com/repos/ramsey/uuid/zipball/dc75aa439eb4c1b77f5379fd958b3dc0e6014178", + "reference": "dc75aa439eb4c1b77f5379fd958b3dc0e6014178", "shasum": "" }, "require": { @@ -5874,11 +6251,6 @@ "ramsey/uuid-doctrine": "Allows the use of Ramsey\\Uuid\\Uuid as Doctrine field type." }, "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.x-dev" - } - }, "autoload": { "files": [ "src/functions.php" @@ -5929,27 +6301,27 @@ "type": "tidelift" } ], - "time": "2021-09-25T23:07:42+00:00" + "time": "2022-12-19T21:55:10+00:00" }, { "name": "react/promise", - "version": "v2.9.0", + "version": "v2.10.0", "source": { "type": "git", "url": "https://github.com/reactphp/promise.git", - "reference": "234f8fd1023c9158e2314fa9d7d0e6a83db42910" + "reference": "f913fb8cceba1e6644b7b90c4bfb678ed8a3ef38" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/reactphp/promise/zipball/234f8fd1023c9158e2314fa9d7d0e6a83db42910", - "reference": "234f8fd1023c9158e2314fa9d7d0e6a83db42910", + "url": "https://api.github.com/repos/reactphp/promise/zipball/f913fb8cceba1e6644b7b90c4bfb678ed8a3ef38", + "reference": "f913fb8cceba1e6644b7b90c4bfb678ed8a3ef38", "shasum": "" }, "require": { "php": ">=5.4.0" }, "require-dev": { - "phpunit/phpunit": "^9.3 || ^5.7 || ^4.8.36" + "phpunit/phpunit": "^9.5 || ^5.7 || ^4.8.36" }, "type": "library", "autoload": { @@ -5993,19 +6365,15 @@ ], "support": { "issues": "https://github.com/reactphp/promise/issues", - "source": "https://github.com/reactphp/promise/tree/v2.9.0" + "source": "https://github.com/reactphp/promise/tree/v2.10.0" }, "funding": [ { - "url": "https://github.com/WyriHaximus", - "type": "github" - }, - { - "url": "https://github.com/clue", - "type": "github" + "url": "https://opencollective.com/reactphp", + "type": "open_collective" } ], - "time": "2022-02-11T10:27:51+00:00" + "time": "2023-05-02T15:15:43+00:00" }, { "name": "rector/rector", @@ -6069,16 +6437,16 @@ }, { "name": "sebastian/diff", - "version": "4.0.4", + "version": "4.0.5", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/diff.git", - "reference": "3461e3fccc7cfdfc2720be910d3bd73c69be590d" + "reference": "74be17022044ebaaecfdf0c5cd504fc9cd5a7131" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/3461e3fccc7cfdfc2720be910d3bd73c69be590d", - "reference": "3461e3fccc7cfdfc2720be910d3bd73c69be590d", + "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/74be17022044ebaaecfdf0c5cd504fc9cd5a7131", + "reference": "74be17022044ebaaecfdf0c5cd504fc9cd5a7131", "shasum": "" }, "require": { @@ -6123,7 +6491,7 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/diff/issues", - "source": "https://github.com/sebastianbergmann/diff/tree/4.0.4" + "source": "https://github.com/sebastianbergmann/diff/tree/4.0.5" }, "funding": [ { @@ -6131,20 +6499,20 @@ "type": "github" } ], - "time": "2020-10-26T13:10:38+00:00" + "time": "2023-05-07T05:35:17+00:00" }, { "name": "seld/jsonlint", - "version": "1.9.0", + "version": "1.10.0", "source": { "type": "git", "url": "https://github.com/Seldaek/jsonlint.git", - "reference": "4211420d25eba80712bff236a98960ef68b866b7" + "reference": "594fd6462aad8ecee0b45ca5045acea4776667f1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Seldaek/jsonlint/zipball/4211420d25eba80712bff236a98960ef68b866b7", - "reference": "4211420d25eba80712bff236a98960ef68b866b7", + "url": "https://api.github.com/repos/Seldaek/jsonlint/zipball/594fd6462aad8ecee0b45ca5045acea4776667f1", + "reference": "594fd6462aad8ecee0b45ca5045acea4776667f1", "shasum": "" }, "require": { @@ -6183,7 +6551,7 @@ ], "support": { "issues": "https://github.com/Seldaek/jsonlint/issues", - "source": "https://github.com/Seldaek/jsonlint/tree/1.9.0" + "source": "https://github.com/Seldaek/jsonlint/tree/1.10.0" }, "funding": [ { @@ -6195,7 +6563,7 @@ "type": "tidelift" } ], - "time": "2022-04-01T13:37:23+00:00" + "time": "2023-05-11T13:16:46+00:00" }, { "name": "seld/phar-utils", @@ -6308,37 +6676,37 @@ }, { "name": "slevomat/coding-standard", - "version": "8.6.0", + "version": "8.3.0", "source": { "type": "git", "url": "https://github.com/slevomat/coding-standard.git", - "reference": "d4175d8bf1246f4bf8be04ab688fbdc6fed18ece" + "reference": "a14df437f2efe861ca9118508f304de9655957e4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/slevomat/coding-standard/zipball/d4175d8bf1246f4bf8be04ab688fbdc6fed18ece", - "reference": "d4175d8bf1246f4bf8be04ab688fbdc6fed18ece", + "url": "https://api.github.com/repos/slevomat/coding-standard/zipball/a14df437f2efe861ca9118508f304de9655957e4", + "reference": "a14df437f2efe861ca9118508f304de9655957e4", "shasum": "" }, "require": { "dealerdirect/phpcodesniffer-composer-installer": "^0.6.2 || ^0.7", "php": "^7.2 || ^8.0", - "phpstan/phpdoc-parser": ">=1.11.0 <1.12.0", + "phpstan/phpdoc-parser": "^1.6.2", "squizlabs/php_codesniffer": "^3.7.1" }, "require-dev": { "phing/phing": "2.17.4", "php-parallel-lint/php-parallel-lint": "1.3.2", - "phpstan/phpstan": "1.4.10|1.8.9", + "phpstan/phpstan": "1.4.10|1.8.1", "phpstan/phpstan-deprecation-rules": "1.0.0", "phpstan/phpstan-phpunit": "1.0.0|1.1.1", - "phpstan/phpstan-strict-rules": "1.4.4", - "phpunit/phpunit": "7.5.20|8.5.21|9.5.25" + "phpstan/phpstan-strict-rules": "1.3.0", + "phpunit/phpunit": "7.5.20|8.5.21|9.5.21" }, "type": "phpcodesniffer-standard", "extra": { "branch-alias": { - "dev-master": "8.x-dev" + "dev-master": "7.x-dev" } }, "autoload": { @@ -6351,13 +6719,9 @@ "MIT" ], "description": "Slevomat Coding Standard for PHP_CodeSniffer complements Consistence Coding Standard by providing sniffs with additional checks.", - "keywords": [ - "dev", - "phpcs" - ], "support": { "issues": "https://github.com/slevomat/coding-standard/issues", - "source": "https://github.com/slevomat/coding-standard/tree/8.6.0" + "source": "https://github.com/slevomat/coding-standard/tree/8.3.0" }, "funding": [ { @@ -6369,20 +6733,20 @@ "type": "tidelift" } ], - "time": "2022-10-16T10:31:02+00:00" + "time": "2022-07-16T11:59:39+00:00" }, { "name": "spryker-sdk/acp", - "version": "0.2.2", + "version": "0.2.3", "source": { "type": "git", "url": "https://github.com/spryker-sdk/acp.git", - "reference": "991e7f3aca7c5cb55e0c14157f8075a38f3c28db" + "reference": "4b138f356927e237a953bf9443ee5443fe346fbe" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/spryker-sdk/acp/zipball/991e7f3aca7c5cb55e0c14157f8075a38f3c28db", - "reference": "991e7f3aca7c5cb55e0c14157f8075a38f3c28db", + "url": "https://api.github.com/repos/spryker-sdk/acp/zipball/4b138f356927e237a953bf9443ee5443fe346fbe", + "reference": "4b138f356927e237a953bf9443ee5443fe346fbe", "shasum": "" }, "require": { @@ -6399,6 +6763,7 @@ "codeception/module-asserts": "*", "codeception/module-phpbrowser": "*", "mikey179/vfsstream": "^1.6", + "phpstan/phpdoc-parser": "~1.5.1", "sllh/composer-versions-check": "^2.0", "spryker-sdk/architector": "0.1.x-dev", "spryker/code-sniffer": "*", @@ -6427,22 +6792,22 @@ "description": "SDK for ACP.", "support": { "issues": "https://github.com/spryker-sdk/acp/issues", - "source": "https://github.com/spryker-sdk/acp/tree/0.2.2" + "source": "https://github.com/spryker-sdk/acp/tree/0.2.3" }, - "time": "2022-07-12T10:46:42+00:00" + "time": "2023-02-01T12:06:33+00:00" }, { "name": "spryker-sdk/async-api", - "version": "0.2.6", + "version": "0.2.7", "source": { "type": "git", "url": "https://github.com/spryker-sdk/async-api.git", - "reference": "34c2983b48fecfd3678f8fc4dae6f12bba15b392" + "reference": "c70ca5fedc51578934708c5ea8b1cb6735b2bb80" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/spryker-sdk/async-api/zipball/34c2983b48fecfd3678f8fc4dae6f12bba15b392", - "reference": "34c2983b48fecfd3678f8fc4dae6f12bba15b392", + "url": "https://api.github.com/repos/spryker-sdk/async-api/zipball/c70ca5fedc51578934708c5ea8b1cb6735b2bb80", + "reference": "c70ca5fedc51578934708c5ea8b1cb6735b2bb80", "shasum": "" }, "require": { @@ -6450,8 +6815,8 @@ "spryker-sdk/spryk": "^0.4.0", "symfony/console": "^4.0.0 || ^5.3 || ^6.0", "symfony/finder": "^4.0.0 || ^5.3 || ^6.0", - "symfony/process": "^4.0.0 || ^5.4", - "symfony/property-access": "^4.0.0 || ^5.4" + "symfony/process": "^4.0.0 || ^5.4 || ^6.0", + "symfony/property-access": "^4.0.0 || ^5.4 || ^6.0" }, "require-dev": { "codeception/codeception": "*", @@ -6463,7 +6828,118 @@ "symfony/var-dumper": "*" }, "bin": [ - "bin/asyncapi" + "bin/asyncapi" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Transfer\\": "src/Transfer/", + "SprykerSdk\\AsyncApi\\": "src/SprykerSdk/AsyncApi/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "proprietary" + ], + "description": "SDK for AsyncAPI.", + "support": { + "issues": "https://github.com/spryker-sdk/async-api/issues", + "source": "https://github.com/spryker-sdk/async-api/tree/0.2.7" + }, + "time": "2023-01-24T16:01:31+00:00" + }, + { + "name": "spryker-sdk/azure-php-client", + "version": "dev-master", + "source": { + "type": "git", + "url": "https://github.com/spryker-sdk/azure-php-client.git", + "reference": "14744793587002f1297197c7d9546976343c5f6b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/spryker-sdk/azure-php-client/zipball/14744793587002f1297197c7d9546976343c5f6b", + "reference": "14744793587002f1297197c7d9546976343c5f6b", + "shasum": "" + }, + "require": { + "ext-json": "*", + "ext-simplexml": "*", + "guzzlehttp/guzzle": "^7.5", + "php": ">=7.4", + "psr/http-client": "^1.0", + "psr/http-message": "^1.0" + }, + "require-dev": { + "phpstan/phpstan": "^1.10", + "phpunit/phpunit": "^9.5", + "spryker/code-sniffer": "dev-master" + }, + "default-branch": true, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "SprykerAzure\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "proprietary" + ], + "description": "Azure Repos client for PHP", + "support": { + "issues": "https://github.com/spryker-sdk/azure-php-client/issues", + "source": "https://github.com/spryker-sdk/azure-php-client/tree/master" + }, + "time": "2023-03-15T11:18:56+00:00" + }, + { + "name": "spryker-sdk/brancho", + "version": "dev-master", + "source": { + "type": "git", + "url": "https://github.com/spryker-sdk/brancho.git", + "reference": "960f563ab5435e362e1f52a385b8b8c7cd434b2d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/spryker-sdk/brancho/zipball/960f563ab5435e362e1f52a385b8b8c7cd434b2d", + "reference": "960f563ab5435e362e1f52a385b8b8c7cd434b2d", + "shasum": "" + }, + "require": { + "chobie/jira-api-restclient": "^2.0@dev", + "cocur/slugify": "^4.0", + "laminas/laminas-filter": "^2.9", + "php": ">=7.3", + "symfony-cmf/slugifier-api": "^2.0", + "symfony/console": "^5.0", + "symfony/options-resolver": "^5.0", + "symfony/process": "^5.0", + "symfony/yaml": "^5.0" + }, + "require-dev": { + "codeception/codeception": "^4.1", + "codeception/module-asserts": "^1.1", + "codeception/module-phpbrowser": "^1.0.0", + "mikey179/vfsstream": "^1.6", + "phpstan/phpstan": "^0.12.18", + "spryker/code-sniffer": "*", + "symfony/var-dumper": "^5.0" + }, + "default-branch": true, + "bin": [ + "bin/brancho" ], "type": "library", "extra": { @@ -6473,20 +6949,19 @@ }, "autoload": { "psr-4": { - "Transfer\\": "src/Transfer/", - "SprykerSdk\\AsyncApi\\": "src/SprykerSdk/AsyncApi/" + "Brancho\\": "src/Brancho/" } }, "notification-url": "https://packagist.org/downloads/", "license": [ "proprietary" ], - "description": "SDK for AsyncAPI.", + "description": "Builds nice branch names.", "support": { - "issues": "https://github.com/spryker-sdk/async-api/issues", - "source": "https://github.com/spryker-sdk/async-api/tree/0.2.6" + "issues": "https://github.com/spryker-sdk/brancho/issues", + "source": "https://github.com/spryker-sdk/brancho/tree/master" }, - "time": "2022-07-22T11:15:03+00:00" + "time": "2023-05-30T07:45:24+00:00" }, { "name": "spryker-sdk/composer-replace", @@ -6494,12 +6969,12 @@ "source": { "type": "git", "url": "https://github.com/spryker-sdk/composer-replace.git", - "reference": "517e6a0ba2ddc40ae34a54327f52c01e05f21ff6" + "reference": "67851f6320b0946e1f62262a4f56f1b8ccaf7a55" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/spryker-sdk/composer-replace/zipball/517e6a0ba2ddc40ae34a54327f52c01e05f21ff6", - "reference": "517e6a0ba2ddc40ae34a54327f52c01e05f21ff6", + "url": "https://api.github.com/repos/spryker-sdk/composer-replace/zipball/67851f6320b0946e1f62262a4f56f1b8ccaf7a55", + "reference": "67851f6320b0946e1f62262a4f56f1b8ccaf7a55", "shasum": "" }, "require": { @@ -6526,7 +7001,82 @@ "issues": "https://github.com/spryker-sdk/composer-replace/issues", "source": "https://github.com/spryker-sdk/composer-replace/tree/master" }, - "time": "2022-02-24T08:49:47+00:00" + "time": "2022-12-01T11:27:13+00:00" + }, + { + "name": "spryker-sdk/evaluator", + "version": "0.1.5", + "source": { + "type": "git", + "url": "https://github.com/spryker-sdk/evaluator.git", + "reference": "1acb655209157b309e58e8f79dfd6a2be93e901a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/spryker-sdk/evaluator/zipball/1acb655209157b309e58e8f79dfd6a2be93e901a", + "reference": "1acb655209157b309e58e8f79dfd6a2be93e901a", + "shasum": "" + }, + "require": { + "composer/semver": "^3.3", + "ext-ctype": "*", + "ext-iconv": "*", + "ext-json": "*", + "guzzlehttp/guzzle": "^7.5", + "laminas/laminas-filter": "^2.11.0", + "php": ">=7.4", + "spryker-sdk/security-checker": "^0.2.0", + "symfony/console": "^5.4|^6.0", + "symfony/dotenv": "^5.4|^6.0", + "symfony/filesystem": "^5.4|^6.0", + "symfony/flex": "^1.17|^2", + "symfony/framework-bundle": "^5.4|^6.0", + "symfony/monolog-bundle": "^3.8", + "symfony/process": "^5.4|^6.0", + "symfony/runtime": "^5.4|^6.0", + "symfony/serializer": "^5.4|^6.0", + "symfony/stopwatch": "^5.4|^6.0", + "symfony/uid": "^5.4|^6.0", + "symfony/yaml": "^5.4|^6.0" + }, + "conflict": { + "symfony/symfony": "*" + }, + "replace": { + "symfony/polyfill-ctype": "*", + "symfony/polyfill-iconv": "*", + "symfony/polyfill-php72": "*" + }, + "require-dev": { + "phpstan/phpstan": "^1.10", + "phpunit/phpunit": "^9.6", + "spryker/code-sniffer": "^0.17.18" + }, + "bin": [ + "bin/evaluator" + ], + "type": "project", + "extra": { + "symfony": { + "allow-contrib": false, + "require": "^5.4|^6.0" + } + }, + "autoload": { + "psr-4": { + "SprykerSdk\\Evaluator\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "proprietary" + ], + "description": "The tool for evaluating Spryker shops", + "support": { + "issues": "https://github.com/spryker-sdk/evaluator/issues", + "source": "https://github.com/spryker-sdk/evaluator/tree/0.1.5" + }, + "time": "2023-08-07T12:28:16+00:00" }, { "name": "spryker-sdk/integrator", @@ -6534,29 +7084,36 @@ "source": { "type": "git", "url": "https://github.com/spryker-sdk/integrator.git", - "reference": "dde4e8721ba8b1449f6af8602fb507e88cb6981d" + "reference": "2828f1dbc03af7eac45a49148e2cd97f010e00f1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/spryker-sdk/integrator/zipball/dde4e8721ba8b1449f6af8602fb507e88cb6981d", - "reference": "dde4e8721ba8b1449f6af8602fb507e88cb6981d", + "url": "https://api.github.com/repos/spryker-sdk/integrator/zipball/2828f1dbc03af7eac45a49148e2cd97f010e00f1", + "reference": "2828f1dbc03af7eac45a49148e2cd97f010e00f1", "shasum": "" }, "require": { + "aws/aws-sdk-php": "^3.257", "composer-plugin-api": "^1.0.0 || ^2.0.0", "composer/composer": "^2.1.0", + "czproject/git-php": "^4.1", + "ext-dom": "*", + "ext-simplexml": "*", "laminas/laminas-filter": "^2.11.0", "nikic/php-parser": "^4.3.0", "php": ">=7.4", "sebastian/diff": "^4.0.0", - "symfony/console": "^5.3.0", - "symfony/finder": "^5.3.0" + "symfony/console": "^5.3.0 || ^6.0", + "symfony/finder": "^5.3.0 || ^6.0", + "symfony/process": "^5.4 || ^6.0" }, "require-dev": { + "ext-zip": "*", "phpstan/phpstan": "^1.0.0", "phpunit/phpunit": "^9.5.0", + "spryker-sdk/manifest-test-data-provider": "dev-master", "spryker/code-sniffer": "dev-master", - "symfony/filesystem": "^5.3.0" + "symfony/filesystem": "^5.3.0 || ^6.0" }, "default-branch": true, "bin": [ @@ -6582,20 +7139,20 @@ "issues": "https://github.com/spryker-sdk/integrator/issues", "source": "https://github.com/spryker-sdk/integrator/tree/master" }, - "time": "2022-11-24T10:49:16+00:00" + "time": "2023-08-18T15:05:56+00:00" }, { "name": "spryker-sdk/sdk-contracts", - "version": "0.4.6", + "version": "0.4.7", "source": { "type": "git", "url": "https://github.com/spryker-sdk/sdk-contracts.git", - "reference": "36e5c4777dc230e9671a72006f3e669a09872443" + "reference": "dc004f2fb711c6736c5501af97d90d63a2e0b1c7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/spryker-sdk/sdk-contracts/zipball/36e5c4777dc230e9671a72006f3e669a09872443", - "reference": "36e5c4777dc230e9671a72006f3e669a09872443", + "url": "https://api.github.com/repos/spryker-sdk/sdk-contracts/zipball/dc004f2fb711c6736c5501af97d90d63a2e0b1c7", + "reference": "dc004f2fb711c6736c5501af97d90d63a2e0b1c7", "shasum": "" }, "require": { @@ -6619,28 +7176,75 @@ "description": "Contracts to extend the Spryker SDK", "support": { "issues": "https://github.com/spryker-sdk/sdk-contracts/issues", - "source": "https://github.com/spryker-sdk/sdk-contracts/tree/0.4.6" + "source": "https://github.com/spryker-sdk/sdk-contracts/tree/0.4.7" + }, + "time": "2023-06-27T10:55:21+00:00" + }, + { + "name": "spryker-sdk/security-checker", + "version": "0.2.0", + "source": { + "type": "git", + "url": "https://github.com/spryker-sdk/security-checker.git", + "reference": "619c9c636590e0bef836f1c9ab1203ac9a66c46c" }, - "time": "2022-11-22T16:03:10+00:00" + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/spryker-sdk/security-checker/zipball/619c9c636590e0bef836f1c9ab1203ac9a66c46c", + "reference": "619c9c636590e0bef836f1c9ab1203ac9a66c46c", + "shasum": "" + }, + "require": { + "php": ">=7.3", + "symfony/console": "^4.0.0 || ^5.0.0 || ^6.0.0", + "symfony/options-resolver": "^4.0.0 || ^5.0.0 || ^6.0.0", + "symfony/process": "^4.0.0 || ^5.0.0 || ^6.0.0" + }, + "require-dev": { + "phpstan/phpstan": "^1.2.0", + "slevomat/coding-standard": "^6.2", + "spryker/code-sniffer": "^0.15.6", + "squizlabs/php_codesniffer": "^3.5" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "SecurityChecker\\": "src/SecurityChecker/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "proprietary" + ], + "description": "A security checker for your composer.lock", + "support": { + "issues": "https://github.com/spryker-sdk/security-checker/issues", + "source": "https://github.com/spryker-sdk/security-checker/tree/0.2.0" + }, + "time": "2023-04-24T11:24:18+00:00" }, { "name": "spryker-sdk/spryk", - "version": "dev-master", + "version": "0.4.7", "source": { "type": "git", "url": "https://github.com/spryker-sdk/spryk.git", - "reference": "b007dcacebd2a1e6fd48b61006e3c3ac26226b73" + "reference": "60acb10713edcaec92dea6ad5a715b49987a2d14" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/spryker-sdk/spryk/zipball/b007dcacebd2a1e6fd48b61006e3c3ac26226b73", - "reference": "b007dcacebd2a1e6fd48b61006e3c3ac26226b73", + "url": "https://api.github.com/repos/spryker-sdk/spryk/zipball/60acb10713edcaec92dea6ad5a715b49987a2d14", + "reference": "60acb10713edcaec92dea6ad5a715b49987a2d14", "shasum": "" }, "require": { "php": ">=7.4" }, - "default-branch": true, "bin": [ "bin/spryk-build", "bin/spryk-dump", @@ -6660,22 +7264,22 @@ "description": "Spryk module", "support": { "issues": "https://github.com/spryker-sdk/spryk/issues", - "source": "https://github.com/spryker-sdk/spryk/tree/0.4.6" + "source": "https://github.com/spryker-sdk/spryk/tree/0.4.7" }, - "time": "2022-10-18T14:00:10+00:00" + "time": "2022-12-16T13:28:34+00:00" }, { "name": "spryker-sdk/sync-api", - "version": "0.1.4", + "version": "0.1.5", "source": { "type": "git", "url": "https://github.com/spryker-sdk/sync-api.git", - "reference": "db4a9d6a9282ea0333cec7640b23c7f7c2a06f94" + "reference": "430bcdeff0f5323b83c20a8012eac45ba171bc2a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/spryker-sdk/sync-api/zipball/db4a9d6a9282ea0333cec7640b23c7f7c2a06f94", - "reference": "db4a9d6a9282ea0333cec7640b23c7f7c2a06f94", + "url": "https://api.github.com/repos/spryker-sdk/sync-api/zipball/430bcdeff0f5323b83c20a8012eac45ba171bc2a", + "reference": "430bcdeff0f5323b83c20a8012eac45ba171bc2a", "shasum": "" }, "require": { @@ -6691,6 +7295,7 @@ "codeception/codeception": "*", "codeception/module-asserts": "*", "mikey179/vfsstream": "^1.6", + "phpstan/phpdoc-parser": "~1.5.1", "sllh/composer-versions-check": "^2.0", "spryker-sdk/architector": "0.1.x-dev", "spryker/code-sniffer": "dev-master", @@ -6719,9 +7324,9 @@ "description": "SDK for SyncAPI.", "support": { "issues": "https://github.com/spryker-sdk/sync-api/issues", - "source": "https://github.com/spryker-sdk/sync-api/tree/0.1.4" + "source": "https://github.com/spryker-sdk/sync-api/tree/0.1.5" }, - "time": "2022-07-12T07:57:55+00:00" + "time": "2023-02-08T18:07:21+00:00" }, { "name": "spryker-sdk/upgrader", @@ -6729,15 +7334,16 @@ "source": { "type": "git", "url": "https://github.com/spryker-sdk/upgrader.git", - "reference": "1e2203b3e8e465ab40d0c40d8a940daa6a1177c3" + "reference": "a143281d4951139714c686dc94e0f293b23e3ccc" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/spryker-sdk/upgrader/zipball/1e2203b3e8e465ab40d0c40d8a940daa6a1177c3", - "reference": "1e2203b3e8e465ab40d0c40d8a940daa6a1177c3", + "url": "https://api.github.com/repos/spryker-sdk/upgrader/zipball/a143281d4951139714c686dc94e0f293b23e3ccc", + "reference": "a143281d4951139714c686dc94e0f293b23e3ccc", "shasum": "" }, "require": { + "composer/semver": "^3.3", "davidrjonas/composer-lock-diff": "^1.6", "ergebnis/json-printer": "^3.1", "ext-json": "*", @@ -6749,17 +7355,21 @@ "nikic/php-parser": "4.15.*", "php": ">=7.4", "phpstan/phpstan": "^1.2", - "spryker-sdk/integrator": "dev-master", - "spryker-sdk/sdk-contracts": "^0.4.6", + "spryker-sdk/azure-php-client": "dev-master", + "spryker-sdk/integrator": "^1.0@dev", + "spryker-sdk/sdk-contracts": "^0.4.7", "symfony/config": "^5.0", "symfony/console": "^5.0", "symfony/dependency-injection": "^5.0", "symfony/filesystem": "^5.3", "symfony/finder": "^5.3", - "symfony/framework-bundle": "5.3.*", + "symfony/framework-bundle": "^5.4", "symfony/http-kernel": "^5.0", + "symfony/monolog-bundle": "^3.8", "symfony/process": "^5.0", "symfony/runtime": "^5", + "symfony/serializer": "^5.4", + "symfony/uid": "^5.4", "symfony/yaml": "^5.3" }, "require-dev": { @@ -6779,7 +7389,7 @@ "Evaluate\\": "src/Evaluate/", "Upgrader\\": "src/Upgrader/", "ReleaseApp\\": "src/ReleaseApp/", - "CodeCompliance\\": "src/CodeCompliance/" + "DynamicEvaluator\\": "src/DynamicEvaluator/" } }, "notification-url": "https://packagist.org/downloads/", @@ -6791,28 +7401,29 @@ "issues": "https://github.com/spryker-sdk/upgrader/issues", "source": "https://github.com/spryker-sdk/upgrader/tree/master" }, - "time": "2022-11-24T10:55:10+00:00" + "time": "2023-08-18T15:09:30+00:00" }, { "name": "spryker/architecture-sniffer", - "version": "0.5.6", + "version": "0.5.7", "source": { "type": "git", "url": "https://github.com/spryker/architecture-sniffer.git", - "reference": "671a2a8f002e2d09aef14f85f30498c24a8ccaa6" + "reference": "07fa5a75f481dfd0de2676a4f11c36df6365f652" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/spryker/architecture-sniffer/zipball/671a2a8f002e2d09aef14f85f30498c24a8ccaa6", - "reference": "671a2a8f002e2d09aef14f85f30498c24a8ccaa6", + "url": "https://api.github.com/repos/spryker/architecture-sniffer/zipball/07fa5a75f481dfd0de2676a4f11c36df6365f652", + "reference": "07fa5a75f481dfd0de2676a4f11c36df6365f652", "shasum": "" }, "require": { "laminas/laminas-config": "^2.5.1 || ^3.1.0", "laminas/laminas-filter": "^2.5.1", - "php": ">=7.3", + "php": ">=7.4", + "phpdocumentor/reflection-docblock": "^5.3.0", "phpmd/phpmd": "^2.10.0", - "symfony/finder": "^3.4.0 || ^4.0.0 || ^5.0.0" + "symfony/finder": "^4.0.0 || ^5.0.0 || ^6.0.0" }, "require-dev": { "codeception/codeception": "^4.1", @@ -6852,24 +7463,24 @@ "issues": "https://github.com/spryker/architecture-sniffer/issues", "source": "https://github.com/spryker/architecture-sniffer" }, - "time": "2022-04-28T10:27:06+00:00" + "time": "2023-01-24T16:01:38+00:00" }, { "name": "spryker/code-sniffer", - "version": "0.17.13", + "version": "0.17.18", "source": { "type": "git", "url": "https://github.com/spryker/code-sniffer.git", - "reference": "f6af35c65d53544921749a6d79b483e13487393b" + "reference": "5fb8b573abc4a906d0d364a4a03abd38e565ba29" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/spryker/code-sniffer/zipball/f6af35c65d53544921749a6d79b483e13487393b", - "reference": "f6af35c65d53544921749a6d79b483e13487393b", + "url": "https://api.github.com/repos/spryker/code-sniffer/zipball/5fb8b573abc4a906d0d364a4a03abd38e565ba29", + "reference": "5fb8b573abc4a906d0d364a4a03abd38e565ba29", "shasum": "" }, "require": { - "php": ">=7.3", + "php": ">=7.4", "slevomat/coding-standard": "^7.2.0 || ^8.0.1", "squizlabs/php_codesniffer": "^3.6.2" }, @@ -6910,7 +7521,7 @@ "issues": "https://github.com/spryker/code-sniffer/issues", "source": "https://github.com/spryker/code-sniffer" }, - "time": "2022-09-27T09:21:07+00:00" + "time": "2023-01-03T16:08:22+00:00" }, { "name": "spryker/symfony", @@ -6986,16 +7597,16 @@ }, { "name": "squizlabs/php_codesniffer", - "version": "3.7.1", + "version": "3.7.2", "source": { "type": "git", "url": "https://github.com/squizlabs/PHP_CodeSniffer.git", - "reference": "1359e176e9307e906dc3d890bcc9603ff6d90619" + "reference": "ed8e00df0a83aa96acf703f8c2979ff33341f879" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/squizlabs/PHP_CodeSniffer/zipball/1359e176e9307e906dc3d890bcc9603ff6d90619", - "reference": "1359e176e9307e906dc3d890bcc9603ff6d90619", + "url": "https://api.github.com/repos/squizlabs/PHP_CodeSniffer/zipball/ed8e00df0a83aa96acf703f8c2979ff33341f879", + "reference": "ed8e00df0a83aa96acf703f8c2979ff33341f879", "shasum": "" }, "require": { @@ -7031,14 +7642,15 @@ "homepage": "https://github.com/squizlabs/PHP_CodeSniffer", "keywords": [ "phpcs", - "standards" + "standards", + "static analysis" ], "support": { "issues": "https://github.com/squizlabs/PHP_CodeSniffer/issues", "source": "https://github.com/squizlabs/PHP_CodeSniffer", "wiki": "https://github.com/squizlabs/PHP_CodeSniffer/wiki" }, - "time": "2022-06-18T07:21:10+00:00" + "time": "2023-02-22T23:07:41+00:00" }, { "name": "symfony-cmf/routing", @@ -7103,18 +7715,71 @@ }, "time": "2021-11-08T16:33:10+00:00" }, + { + "name": "symfony-cmf/slugifier-api", + "version": "2.1.0", + "source": { + "type": "git", + "url": "https://github.com/symfony-cmf/slugifier-api.git", + "reference": "64e0b48bce38fb7e6b1bf284d4574fa183d1cc94" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony-cmf/slugifier-api/zipball/64e0b48bce38fb7e6b1bf284d4574fa183d1cc94", + "reference": "64e0b48bce38fb7e6b1bf284d4574fa183d1cc94", + "shasum": "" + }, + "require": { + "php": "^5.6|^7.0|^8.0" + }, + "require-dev": { + "symfony/phpunit-bridge": "^5.2" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Cmf\\Api\\Slugifier\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Symfony CMF Community", + "homepage": "https://github.com/symfony-cmf/slugifier-api/contributors" + } + ], + "description": "Provides a basic slugifier interface to transform text into strings suitable for URLs", + "homepage": "http://cmf.symfony.com", + "keywords": [ + "slugify", + "urlize" + ], + "support": { + "issues": "https://github.com/symfony-cmf/slugifier-api/issues", + "source": "https://github.com/symfony-cmf/slugifier-api/tree/2.1.0" + }, + "time": "2021-01-22T09:05:45+00:00" + }, { "name": "symfony/asset", - "version": "v5.4.13", + "version": "v5.4.21", "source": { "type": "git", "url": "https://github.com/symfony/asset.git", - "reference": "9aa867206711cb6fcca51ef127ba52a018170be9" + "reference": "1504b6773c6b90118f9871e90a67833b5d1dca3c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/asset/zipball/9aa867206711cb6fcca51ef127ba52a018170be9", - "reference": "9aa867206711cb6fcca51ef127ba52a018170be9", + "url": "https://api.github.com/repos/symfony/asset/zipball/1504b6773c6b90118f9871e90a67833b5d1dca3c", + "reference": "1504b6773c6b90118f9871e90a67833b5d1dca3c", "shasum": "" }, "require": { @@ -7159,7 +7824,7 @@ "description": "Manages URL generation and versioning of web assets such as CSS stylesheets, JavaScript files and image files", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/asset/tree/v5.4.13" + "source": "https://github.com/symfony/asset/tree/v5.4.21" }, "funding": [ { @@ -7175,20 +7840,20 @@ "type": "tidelift" } ], - "time": "2022-08-31T08:17:19+00:00" + "time": "2023-02-14T08:03:56+00:00" }, { "name": "symfony/cache", - "version": "v5.4.13", + "version": "v5.4.23", "source": { "type": "git", "url": "https://github.com/symfony/cache.git", - "reference": "89bb6a0fe27205636d80e568ffaf9bbb52f691e3" + "reference": "983c79ff28612cdfd66d8e44e1a06e5afc87e107" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/cache/zipball/89bb6a0fe27205636d80e568ffaf9bbb52f691e3", - "reference": "89bb6a0fe27205636d80e568ffaf9bbb52f691e3", + "url": "https://api.github.com/repos/symfony/cache/zipball/983c79ff28612cdfd66d8e44e1a06e5afc87e107", + "reference": "983c79ff28612cdfd66d8e44e1a06e5afc87e107", "shasum": "" }, "require": { @@ -7256,7 +7921,7 @@ "psr6" ], "support": { - "source": "https://github.com/symfony/cache/tree/v5.4.13" + "source": "https://github.com/symfony/cache/tree/v5.4.23" }, "funding": [ { @@ -7272,7 +7937,7 @@ "type": "tidelift" } ], - "time": "2022-09-06T13:23:31+00:00" + "time": "2023-04-21T15:38:51+00:00" }, { "name": "symfony/cache-contracts", @@ -7355,16 +8020,16 @@ }, { "name": "symfony/config", - "version": "v5.4.11", + "version": "v5.4.21", "source": { "type": "git", "url": "https://github.com/symfony/config.git", - "reference": "ec79e03125c1d2477e43dde8528535d90cc78379" + "reference": "2a6b1111d038adfa15d52c0871e540f3b352d1e4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/config/zipball/ec79e03125c1d2477e43dde8528535d90cc78379", - "reference": "ec79e03125c1d2477e43dde8528535d90cc78379", + "url": "https://api.github.com/repos/symfony/config/zipball/2a6b1111d038adfa15d52c0871e540f3b352d1e4", + "reference": "2a6b1111d038adfa15d52c0871e540f3b352d1e4", "shasum": "" }, "require": { @@ -7414,7 +8079,7 @@ "description": "Helps you find, load, combine, autofill and validate configuration values of any kind", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/config/tree/v5.4.11" + "source": "https://github.com/symfony/config/tree/v5.4.21" }, "funding": [ { @@ -7430,20 +8095,20 @@ "type": "tidelift" } ], - "time": "2022-07-20T13:00:38+00:00" + "time": "2023-02-14T08:03:56+00:00" }, { "name": "symfony/console", - "version": "v5.4.14", + "version": "v5.4.23", "source": { "type": "git", "url": "https://github.com/symfony/console.git", - "reference": "984ea2c0f45f42dfed01d2f3987b187467c4b16d" + "reference": "90f21e27d0d88ce38720556dd164d4a1e4c3934c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/984ea2c0f45f42dfed01d2f3987b187467c4b16d", - "reference": "984ea2c0f45f42dfed01d2f3987b187467c4b16d", + "url": "https://api.github.com/repos/symfony/console/zipball/90f21e27d0d88ce38720556dd164d4a1e4c3934c", + "reference": "90f21e27d0d88ce38720556dd164d4a1e4c3934c", "shasum": "" }, "require": { @@ -7508,12 +8173,12 @@ "homepage": "https://symfony.com", "keywords": [ "cli", - "command line", + "command-line", "console", "terminal" ], "support": { - "source": "https://github.com/symfony/console/tree/v5.4.14" + "source": "https://github.com/symfony/console/tree/v5.4.23" }, "funding": [ { @@ -7529,7 +8194,7 @@ "type": "tidelift" } ], - "time": "2022-10-07T08:01:20+00:00" + "time": "2023-04-24T18:47:29+00:00" }, { "name": "symfony/debug", @@ -7602,16 +8267,16 @@ }, { "name": "symfony/dependency-injection", - "version": "v5.4.13", + "version": "v5.4.23", "source": { "type": "git", "url": "https://github.com/symfony/dependency-injection.git", - "reference": "24cf522668845391c0542bc1de496366072a6d0e" + "reference": "bb7b7988c898c94f5338e16403c52b5a3cae1d93" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/24cf522668845391c0542bc1de496366072a6d0e", - "reference": "24cf522668845391c0542bc1de496366072a6d0e", + "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/bb7b7988c898c94f5338e16403c52b5a3cae1d93", + "reference": "bb7b7988c898c94f5338e16403c52b5a3cae1d93", "shasum": "" }, "require": { @@ -7671,7 +8336,7 @@ "description": "Allows you to standardize and centralize the way objects are constructed in your application", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/dependency-injection/tree/v5.4.13" + "source": "https://github.com/symfony/dependency-injection/tree/v5.4.23" }, "funding": [ { @@ -7687,7 +8352,7 @@ "type": "tidelift" } ], - "time": "2022-08-30T19:10:13+00:00" + "time": "2023-04-21T15:04:16+00:00" }, { "name": "symfony/deprecation-contracts", @@ -7758,16 +8423,16 @@ }, { "name": "symfony/doctrine-bridge", - "version": "v5.4.14", + "version": "v5.4.23", "source": { "type": "git", "url": "https://github.com/symfony/doctrine-bridge.git", - "reference": "3e1e56af2174c205d60a73f5acd7eff89cef65b2" + "reference": "32cddf41cf6abfc4c3db68568c785e48eebf3d71" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/doctrine-bridge/zipball/3e1e56af2174c205d60a73f5acd7eff89cef65b2", - "reference": "3e1e56af2174c205d60a73f5acd7eff89cef65b2", + "url": "https://api.github.com/repos/symfony/doctrine-bridge/zipball/32cddf41cf6abfc4c3db68568c785e48eebf3d71", + "reference": "32cddf41cf6abfc4c3db68568c785e48eebf3d71", "shasum": "" }, "require": { @@ -7787,7 +8452,7 @@ "phpunit/phpunit": "<5.4.3", "symfony/cache": "<5.4", "symfony/dependency-injection": "<4.4", - "symfony/form": "<5.1", + "symfony/form": "<5.4.21|>=6,<6.2.7", "symfony/http-kernel": "<5", "symfony/messenger": "<4.4", "symfony/property-info": "<5", @@ -7797,8 +8462,8 @@ "symfony/validator": "<5.2" }, "require-dev": { - "doctrine/annotations": "^1.10.4", - "doctrine/collections": "~1.0", + "doctrine/annotations": "^1.10.4|^2", + "doctrine/collections": "^1.0|^2.0", "doctrine/data-fixtures": "^1.1", "doctrine/dbal": "^2.13.1|^3.0", "doctrine/orm": "^2.7.4", @@ -7808,7 +8473,7 @@ "symfony/dependency-injection": "^4.4|^5.0|^6.0", "symfony/doctrine-messenger": "^5.1|^6.0", "symfony/expression-language": "^4.4|^5.0|^6.0", - "symfony/form": "^5.4.9|^6.0.9", + "symfony/form": "^5.4.21|^6.2.7", "symfony/http-kernel": "^5.0|^6.0", "symfony/messenger": "^4.4|^5.0|^6.0", "symfony/property-access": "^4.4|^5.0|^6.0", @@ -7855,7 +8520,7 @@ "description": "Provides integration for Doctrine with various Symfony components", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/doctrine-bridge/tree/v5.4.14" + "source": "https://github.com/symfony/doctrine-bridge/tree/v5.4.23" }, "funding": [ { @@ -7871,20 +8536,20 @@ "type": "tidelift" } ], - "time": "2022-10-09T21:15:07+00:00" + "time": "2023-04-05T05:19:44+00:00" }, { "name": "symfony/dotenv", - "version": "v5.4.5", + "version": "v5.4.22", "source": { "type": "git", "url": "https://github.com/symfony/dotenv.git", - "reference": "83a2310904a4f5d4f42526227b5a578ac82232a9" + "reference": "77b7660bfcb85e8f28287d557d7af0046bcd2ca3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/dotenv/zipball/83a2310904a4f5d4f42526227b5a578ac82232a9", - "reference": "83a2310904a4f5d4f42526227b5a578ac82232a9", + "url": "https://api.github.com/repos/symfony/dotenv/zipball/77b7660bfcb85e8f28287d557d7af0046bcd2ca3", + "reference": "77b7660bfcb85e8f28287d557d7af0046bcd2ca3", "shasum": "" }, "require": { @@ -7926,7 +8591,7 @@ "environment" ], "support": { - "source": "https://github.com/symfony/dotenv/tree/v5.4.5" + "source": "https://github.com/symfony/dotenv/tree/v5.4.22" }, "funding": [ { @@ -7942,20 +8607,20 @@ "type": "tidelift" } ], - "time": "2022-02-15T17:04:12+00:00" + "time": "2023-03-09T20:36:58+00:00" }, { "name": "symfony/error-handler", - "version": "v5.4.14", + "version": "v5.4.23", "source": { "type": "git", "url": "https://github.com/symfony/error-handler.git", - "reference": "5fe6d42ffeb68b094df8fdbf3acf23f391cc6be0" + "reference": "218206b4772d9f412d7d277980c020d06e9d8a4e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/error-handler/zipball/5fe6d42ffeb68b094df8fdbf3acf23f391cc6be0", - "reference": "5fe6d42ffeb68b094df8fdbf3acf23f391cc6be0", + "url": "https://api.github.com/repos/symfony/error-handler/zipball/218206b4772d9f412d7d277980c020d06e9d8a4e", + "reference": "218206b4772d9f412d7d277980c020d06e9d8a4e", "shasum": "" }, "require": { @@ -7997,7 +8662,7 @@ "description": "Provides tools to manage errors and ease debugging PHP code", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/error-handler/tree/v5.4.14" + "source": "https://github.com/symfony/error-handler/tree/v5.4.23" }, "funding": [ { @@ -8013,20 +8678,20 @@ "type": "tidelift" } ], - "time": "2022-10-03T15:15:50+00:00" + "time": "2023-04-17T10:03:27+00:00" }, { "name": "symfony/event-dispatcher", - "version": "v5.4.9", + "version": "v5.4.22", "source": { "type": "git", "url": "https://github.com/symfony/event-dispatcher.git", - "reference": "8e6ce1cc0279e3ff3c8ff0f43813bc88d21ca1bc" + "reference": "1df20e45d56da29a4b1d8259dd6e950acbf1b13f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/8e6ce1cc0279e3ff3c8ff0f43813bc88d21ca1bc", - "reference": "8e6ce1cc0279e3ff3c8ff0f43813bc88d21ca1bc", + "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/1df20e45d56da29a4b1d8259dd6e950acbf1b13f", + "reference": "1df20e45d56da29a4b1d8259dd6e950acbf1b13f", "shasum": "" }, "require": { @@ -8082,7 +8747,7 @@ "description": "Provides tools that allow your application components to communicate with each other by dispatching events and listening to them", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/event-dispatcher/tree/v5.4.9" + "source": "https://github.com/symfony/event-dispatcher/tree/v5.4.22" }, "funding": [ { @@ -8098,7 +8763,7 @@ "type": "tidelift" } ], - "time": "2022-05-05T16:45:39+00:00" + "time": "2023-03-17T11:31:58+00:00" }, { "name": "symfony/event-dispatcher-contracts", @@ -8181,16 +8846,16 @@ }, { "name": "symfony/expression-language", - "version": "v5.4.14", + "version": "v5.4.21", "source": { "type": "git", "url": "https://github.com/symfony/expression-language.git", - "reference": "2f27d5b1e7926bba18e87719af75f696977cd58b" + "reference": "501589522b844b8eecf012c133f0404f0eef77ac" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/expression-language/zipball/2f27d5b1e7926bba18e87719af75f696977cd58b", - "reference": "2f27d5b1e7926bba18e87719af75f696977cd58b", + "url": "https://api.github.com/repos/symfony/expression-language/zipball/501589522b844b8eecf012c133f0404f0eef77ac", + "reference": "501589522b844b8eecf012c133f0404f0eef77ac", "shasum": "" }, "require": { @@ -8224,7 +8889,7 @@ "description": "Provides an engine that can compile and evaluate expressions", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/expression-language/tree/v5.4.14" + "source": "https://github.com/symfony/expression-language/tree/v5.4.21" }, "funding": [ { @@ -8240,20 +8905,20 @@ "type": "tidelift" } ], - "time": "2022-10-07T08:01:20+00:00" + "time": "2023-02-14T08:03:56+00:00" }, { "name": "symfony/filesystem", - "version": "v5.4.13", + "version": "v5.4.23", "source": { "type": "git", "url": "https://github.com/symfony/filesystem.git", - "reference": "ac09569844a9109a5966b9438fc29113ce77cf51" + "reference": "b2f79d86cd9e7de0fff6d03baa80eaed7a5f38b5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/filesystem/zipball/ac09569844a9109a5966b9438fc29113ce77cf51", - "reference": "ac09569844a9109a5966b9438fc29113ce77cf51", + "url": "https://api.github.com/repos/symfony/filesystem/zipball/b2f79d86cd9e7de0fff6d03baa80eaed7a5f38b5", + "reference": "b2f79d86cd9e7de0fff6d03baa80eaed7a5f38b5", "shasum": "" }, "require": { @@ -8288,7 +8953,7 @@ "description": "Provides basic utilities for the filesystem", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/filesystem/tree/v5.4.13" + "source": "https://github.com/symfony/filesystem/tree/v5.4.23" }, "funding": [ { @@ -8304,20 +8969,20 @@ "type": "tidelift" } ], - "time": "2022-09-21T19:53:16+00:00" + "time": "2023-03-02T11:38:35+00:00" }, { "name": "symfony/finder", - "version": "v5.4.11", + "version": "v5.4.21", "source": { "type": "git", "url": "https://github.com/symfony/finder.git", - "reference": "7872a66f57caffa2916a584db1aa7f12adc76f8c" + "reference": "078e9a5e1871fcfe6a5ce421b539344c21afef19" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/finder/zipball/7872a66f57caffa2916a584db1aa7f12adc76f8c", - "reference": "7872a66f57caffa2916a584db1aa7f12adc76f8c", + "url": "https://api.github.com/repos/symfony/finder/zipball/078e9a5e1871fcfe6a5ce421b539344c21afef19", + "reference": "078e9a5e1871fcfe6a5ce421b539344c21afef19", "shasum": "" }, "require": { @@ -8351,7 +9016,7 @@ "description": "Finds files and directories via an intuitive fluent interface", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/finder/tree/v5.4.11" + "source": "https://github.com/symfony/finder/tree/v5.4.21" }, "funding": [ { @@ -8367,20 +9032,20 @@ "type": "tidelift" } ], - "time": "2022-07-29T07:37:50+00:00" + "time": "2023-02-16T09:33:00+00:00" }, { "name": "symfony/flex", - "version": "v1.19.3", + "version": "v1.19.5", "source": { "type": "git", "url": "https://github.com/symfony/flex.git", - "reference": "ab0453b16029e131c112df1a76e59eb2a47e1f67" + "reference": "51077ed0f6dc2c94cd0b670167eee3747c31b2c1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/flex/zipball/ab0453b16029e131c112df1a76e59eb2a47e1f67", - "reference": "ab0453b16029e131c112df1a76e59eb2a47e1f67", + "url": "https://api.github.com/repos/symfony/flex/zipball/51077ed0f6dc2c94cd0b670167eee3747c31b2c1", + "reference": "51077ed0f6dc2c94cd0b670167eee3747c31b2c1", "shasum": "" }, "require": { @@ -8416,7 +9081,7 @@ "description": "Composer plugin for Symfony", "support": { "issues": "https://github.com/symfony/flex/issues", - "source": "https://github.com/symfony/flex/tree/v1.19.3" + "source": "https://github.com/symfony/flex/tree/v1.19.5" }, "funding": [ { @@ -8432,20 +9097,20 @@ "type": "tidelift" } ], - "time": "2022-08-07T09:39:08+00:00" + "time": "2023-01-30T17:02:31+00:00" }, { "name": "symfony/form", - "version": "v5.4.13", + "version": "v5.4.23", "source": { "type": "git", "url": "https://github.com/symfony/form.git", - "reference": "d9d661776636ce689bc879b66fb06c6a6895f1a7" + "reference": "ebdc48d54d82b74230a8aed6458c238ec5788e38" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/form/zipball/d9d661776636ce689bc879b66fb06c6a6895f1a7", - "reference": "d9d661776636ce689bc879b66fb06c6a6895f1a7", + "url": "https://api.github.com/repos/symfony/form/zipball/ebdc48d54d82b74230a8aed6458c238ec5788e38", + "reference": "ebdc48d54d82b74230a8aed6458c238ec5788e38", "shasum": "" }, "require": { @@ -8465,16 +9130,16 @@ "phpunit/phpunit": "<5.4.3", "symfony/console": "<4.4", "symfony/dependency-injection": "<4.4", - "symfony/doctrine-bridge": "<4.4", + "symfony/doctrine-bridge": "<5.4.21|>=6,<6.2.7", "symfony/error-handler": "<4.4.5", "symfony/framework-bundle": "<4.4", "symfony/http-kernel": "<4.4", "symfony/translation": "<4.4", "symfony/translation-contracts": "<1.1.7", - "symfony/twig-bridge": "<4.4" + "symfony/twig-bridge": "<5.4.21|>=6,<6.2.7" }, "require-dev": { - "doctrine/collections": "~1.0", + "doctrine/collections": "^1.0|^2.0", "symfony/config": "^4.4|^5.0|^6.0", "symfony/console": "^5.4|^6.0", "symfony/dependency-injection": "^4.4|^5.0|^6.0", @@ -8519,7 +9184,7 @@ "description": "Allows to easily create, process and reuse HTML forms", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/form/tree/v5.4.13" + "source": "https://github.com/symfony/form/tree/v5.4.23" }, "funding": [ { @@ -8535,46 +9200,48 @@ "type": "tidelift" } ], - "time": "2022-09-28T15:33:58+00:00" + "time": "2023-04-17T15:04:56+00:00" }, { "name": "symfony/framework-bundle", - "version": "v5.3.15", + "version": "v5.4.22", "source": { "type": "git", "url": "https://github.com/symfony/framework-bundle.git", - "reference": "fef224d1904da67120fdfe9de3d070f8ba607742" + "reference": "6cb4f6aed4bd7fbf7b2ee74c231184a07f3d00c1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/framework-bundle/zipball/fef224d1904da67120fdfe9de3d070f8ba607742", - "reference": "fef224d1904da67120fdfe9de3d070f8ba607742", + "url": "https://api.github.com/repos/symfony/framework-bundle/zipball/6cb4f6aed4bd7fbf7b2ee74c231184a07f3d00c1", + "reference": "6cb4f6aed4bd7fbf7b2ee74c231184a07f3d00c1", "shasum": "" }, "require": { "ext-xml": "*", "php": ">=7.2.5", - "symfony/cache": "^5.2", - "symfony/config": "^5.3", - "symfony/dependency-injection": "^5.3", - "symfony/deprecation-contracts": "^2.1", - "symfony/error-handler": "^4.4.1|^5.0.1", - "symfony/event-dispatcher": "^5.1", - "symfony/filesystem": "^4.4|^5.0", - "symfony/finder": "^4.4|^5.0", - "symfony/http-foundation": "^5.3", - "symfony/http-kernel": "^5.3", + "symfony/cache": "^5.2|^6.0", + "symfony/config": "^5.3|^6.0", + "symfony/dependency-injection": "^5.4.5|^6.0.5", + "symfony/deprecation-contracts": "^2.1|^3", + "symfony/error-handler": "^4.4.1|^5.0.1|^6.0", + "symfony/event-dispatcher": "^5.1|^6.0", + "symfony/filesystem": "^4.4|^5.0|^6.0", + "symfony/finder": "^4.4|^5.0|^6.0", + "symfony/http-foundation": "^5.3|^6.0", + "symfony/http-kernel": "^5.4|^6.0", "symfony/polyfill-mbstring": "~1.0", "symfony/polyfill-php80": "^1.16", - "symfony/routing": "^5.3" + "symfony/polyfill-php81": "^1.22", + "symfony/routing": "^5.3|^6.0" }, "conflict": { + "doctrine/annotations": "<1.13.1", + "doctrine/cache": "<1.11", "doctrine/persistence": "<1.3", "phpdocumentor/reflection-docblock": "<3.2.2", "phpdocumentor/type-resolver": "<1.4.0", "phpunit/phpunit": "<5.4.3", "symfony/asset": "<5.3", - "symfony/browser-kit": "<4.4", "symfony/console": "<5.2.5", "symfony/dom-crawler": "<4.4", "symfony/dotenv": "<5.1", @@ -8582,13 +9249,13 @@ "symfony/http-client": "<4.4", "symfony/lock": "<4.4", "symfony/mailer": "<5.2", - "symfony/messenger": "<4.4", + "symfony/messenger": "<5.4", "symfony/mime": "<4.4", "symfony/property-access": "<5.3", "symfony/property-info": "<4.4", - "symfony/security-core": "<5.3", "symfony/security-csrf": "<5.3", "symfony/serializer": "<5.2", + "symfony/service-contracts": ">=3.0", "symfony/stopwatch": "<4.4", "symfony/translation": "<5.3", "symfony/twig-bridge": "<4.4", @@ -8598,40 +9265,38 @@ "symfony/workflow": "<5.2" }, "require-dev": { - "doctrine/annotations": "^1.10.4", - "doctrine/cache": "^1.0|^2.0", - "doctrine/persistence": "^1.3|^2.0", - "paragonie/sodium_compat": "^1.8", + "doctrine/annotations": "^1.13.1|^2", + "doctrine/cache": "^1.11|^2.0", + "doctrine/persistence": "^1.3|^2|^3", "phpdocumentor/reflection-docblock": "^3.0|^4.0|^5.0", - "symfony/asset": "^5.3", - "symfony/browser-kit": "^4.4|^5.0", - "symfony/console": "^5.2", - "symfony/css-selector": "^4.4|^5.0", - "symfony/dom-crawler": "^4.4.30|^5.3.7", - "symfony/dotenv": "^5.1", - "symfony/expression-language": "^4.4|^5.0", - "symfony/form": "^5.2", - "symfony/http-client": "^4.4|^5.0", - "symfony/lock": "^4.4|^5.0", - "symfony/mailer": "^5.2", - "symfony/messenger": "^5.2", - "symfony/mime": "^4.4|^5.0", - "symfony/notifier": "^5.3", - "symfony/phpunit-bridge": "^5.3", + "symfony/asset": "^5.3|^6.0", + "symfony/browser-kit": "^5.4|^6.0", + "symfony/console": "^5.4.9|^6.0.9", + "symfony/css-selector": "^4.4|^5.0|^6.0", + "symfony/dom-crawler": "^4.4.30|^5.3.7|^6.0", + "symfony/dotenv": "^5.1|^6.0", + "symfony/expression-language": "^4.4|^5.0|^6.0", + "symfony/form": "^5.2|^6.0", + "symfony/http-client": "^4.4|^5.0|^6.0", + "symfony/lock": "^4.4|^5.0|^6.0", + "symfony/mailer": "^5.2|^6.0", + "symfony/messenger": "^5.4|^6.0", + "symfony/mime": "^4.4|^5.0|^6.0", + "symfony/notifier": "^5.4|^6.0", "symfony/polyfill-intl-icu": "~1.0", - "symfony/process": "^4.4|^5.0", - "symfony/property-info": "^4.4|^5.0", - "symfony/rate-limiter": "^5.2", - "symfony/security-bundle": "^5.3", - "symfony/serializer": "^5.2", - "symfony/stopwatch": "^4.4|^5.0", - "symfony/string": "^5.0", - "symfony/translation": "^5.3", - "symfony/twig-bundle": "^4.4|^5.0", - "symfony/validator": "^5.2", - "symfony/web-link": "^4.4|^5.0", - "symfony/workflow": "^5.2", - "symfony/yaml": "^4.4|^5.0", + "symfony/process": "^4.4|^5.0|^6.0", + "symfony/property-info": "^4.4|^5.0|^6.0", + "symfony/rate-limiter": "^5.2|^6.0", + "symfony/security-bundle": "^5.4|^6.0", + "symfony/serializer": "^5.4|^6.0", + "symfony/stopwatch": "^4.4|^5.0|^6.0", + "symfony/string": "^5.0|^6.0", + "symfony/translation": "^5.3|^6.0", + "symfony/twig-bundle": "^4.4|^5.0|^6.0", + "symfony/validator": "^5.2|^6.0", + "symfony/web-link": "^4.4|^5.0|^6.0", + "symfony/workflow": "^5.2|^6.0", + "symfony/yaml": "^4.4|^5.0|^6.0", "twig/twig": "^2.10|^3.0" }, "suggest": { @@ -8670,7 +9335,7 @@ "description": "Provides a tight integration between Symfony components and the Symfony full-stack framework", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/framework-bundle/tree/v5.3.15" + "source": "https://github.com/symfony/framework-bundle/tree/v5.4.22" }, "funding": [ { @@ -8686,20 +9351,20 @@ "type": "tidelift" } ], - "time": "2022-01-28T17:48:02+00:00" + "time": "2023-03-31T08:25:44+00:00" }, { "name": "symfony/http-client", - "version": "v5.4.14", + "version": "v5.4.23", "source": { "type": "git", "url": "https://github.com/symfony/http-client.git", - "reference": "8a3929c814cba77db93de61c22759e0dbeaa4c87" + "reference": "617c98e46b54e43ca76945a908b1749bb82f4478" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-client/zipball/8a3929c814cba77db93de61c22759e0dbeaa4c87", - "reference": "8a3929c814cba77db93de61c22759e0dbeaa4c87", + "url": "https://api.github.com/repos/symfony/http-client/zipball/617c98e46b54e43ca76945a908b1749bb82f4478", + "reference": "617c98e46b54e43ca76945a908b1749bb82f4478", "shasum": "" }, "require": { @@ -8756,8 +9421,11 @@ ], "description": "Provides powerful methods to fetch HTTP resources synchronously or asynchronously", "homepage": "https://symfony.com", + "keywords": [ + "http" + ], "support": { - "source": "https://github.com/symfony/http-client/tree/v5.4.14" + "source": "https://github.com/symfony/http-client/tree/v5.4.23" }, "funding": [ { @@ -8773,7 +9441,7 @@ "type": "tidelift" } ], - "time": "2022-10-11T15:16:01+00:00" + "time": "2023-04-20T13:04:04+00:00" }, { "name": "symfony/http-client-contracts", @@ -8855,16 +9523,16 @@ }, { "name": "symfony/http-foundation", - "version": "v5.4.14", + "version": "v5.4.23", "source": { "type": "git", "url": "https://github.com/symfony/http-foundation.git", - "reference": "e7c7b395c3a61d746919c21e915f51f0039c3f75" + "reference": "af9fbb378f5f956c8f29d4886644c84c193780ac" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-foundation/zipball/e7c7b395c3a61d746919c21e915f51f0039c3f75", - "reference": "e7c7b395c3a61d746919c21e915f51f0039c3f75", + "url": "https://api.github.com/repos/symfony/http-foundation/zipball/af9fbb378f5f956c8f29d4886644c84c193780ac", + "reference": "af9fbb378f5f956c8f29d4886644c84c193780ac", "shasum": "" }, "require": { @@ -8911,7 +9579,7 @@ "description": "Defines an object-oriented layer for the HTTP specification", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/http-foundation/tree/v5.4.14" + "source": "https://github.com/symfony/http-foundation/tree/v5.4.23" }, "funding": [ { @@ -8927,20 +9595,20 @@ "type": "tidelift" } ], - "time": "2022-10-01T21:59:28+00:00" + "time": "2023-04-18T06:30:11+00:00" }, { "name": "symfony/http-kernel", - "version": "v5.4.14", + "version": "v5.4.23", "source": { "type": "git", "url": "https://github.com/symfony/http-kernel.git", - "reference": "6f77fabc1a37c2dceecc6f78cca44772705dc52f" + "reference": "48ea17a7c65ef1ede0c3b2dbc35adace99071810" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-kernel/zipball/6f77fabc1a37c2dceecc6f78cca44772705dc52f", - "reference": "6f77fabc1a37c2dceecc6f78cca44772705dc52f", + "url": "https://api.github.com/repos/symfony/http-kernel/zipball/48ea17a7c65ef1ede0c3b2dbc35adace99071810", + "reference": "48ea17a7c65ef1ede0c3b2dbc35adace99071810", "shasum": "" }, "require": { @@ -8949,7 +9617,7 @@ "symfony/deprecation-contracts": "^2.1|^3", "symfony/error-handler": "^4.4|^5.0|^6.0", "symfony/event-dispatcher": "^5.0|^6.0", - "symfony/http-foundation": "^5.3.7|^6.0", + "symfony/http-foundation": "^5.4.21|^6.2.7", "symfony/polyfill-ctype": "^1.8", "symfony/polyfill-php73": "^1.9", "symfony/polyfill-php80": "^1.16" @@ -9023,7 +9691,7 @@ "description": "Provides a structured process for converting a Request into a Response", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/http-kernel/tree/v5.4.14" + "source": "https://github.com/symfony/http-kernel/tree/v5.4.23" }, "funding": [ { @@ -9039,20 +9707,20 @@ "type": "tidelift" } ], - "time": "2022-10-12T07:12:21+00:00" + "time": "2023-04-28T13:29:52+00:00" }, { "name": "symfony/intl", - "version": "v5.4.14", + "version": "v5.4.23", "source": { "type": "git", "url": "https://github.com/symfony/intl.git", - "reference": "dd26864d69c11e0e077ffc6b89f66c5772ac456e" + "reference": "962789bbc76c82c266623321ffc24416f574b636" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/intl/zipball/dd26864d69c11e0e077ffc6b89f66c5772ac456e", - "reference": "dd26864d69c11e0e077ffc6b89f66c5772ac456e", + "url": "https://api.github.com/repos/symfony/intl/zipball/962789bbc76c82c266623321ffc24416f574b636", + "reference": "962789bbc76c82c266623321ffc24416f574b636", "shasum": "" }, "require": { @@ -9111,7 +9779,7 @@ "localization" ], "support": { - "source": "https://github.com/symfony/intl/tree/v5.4.14" + "source": "https://github.com/symfony/intl/tree/v5.4.23" }, "funding": [ { @@ -9127,20 +9795,20 @@ "type": "tidelift" } ], - "time": "2022-10-07T08:01:20+00:00" + "time": "2023-04-13T10:36:25+00:00" }, { "name": "symfony/lock", - "version": "v5.4.10", + "version": "v5.4.22", "source": { "type": "git", "url": "https://github.com/symfony/lock.git", - "reference": "41a308008d92d30cae5615d903c4d46d95932eea" + "reference": "cc0565235e16ef403097fbd30eba59690bee6b3c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/lock/zipball/41a308008d92d30cae5615d903c4d46d95932eea", - "reference": "41a308008d92d30cae5615d903c4d46d95932eea", + "url": "https://api.github.com/repos/symfony/lock/zipball/cc0565235e16ef403097fbd30eba59690bee6b3c", + "reference": "cc0565235e16ef403097fbd30eba59690bee6b3c", "shasum": "" }, "require": { @@ -9190,7 +9858,7 @@ "semaphore" ], "support": { - "source": "https://github.com/symfony/lock/tree/v5.4.10" + "source": "https://github.com/symfony/lock/tree/v5.4.22" }, "funding": [ { @@ -9206,20 +9874,20 @@ "type": "tidelift" } ], - "time": "2022-06-09T13:29:56+00:00" + "time": "2023-03-10T16:52:09+00:00" }, { "name": "symfony/mime", - "version": "v5.4.14", + "version": "v5.4.23", "source": { "type": "git", "url": "https://github.com/symfony/mime.git", - "reference": "1c118b253bb3495d81e95a6e3ec6c2766a98a0c4" + "reference": "ae0a1032a450a3abf305ee44fc55ed423fbf16e3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/mime/zipball/1c118b253bb3495d81e95a6e3ec6c2766a98a0c4", - "reference": "1c118b253bb3495d81e95a6e3ec6c2766a98a0c4", + "url": "https://api.github.com/repos/symfony/mime/zipball/ae0a1032a450a3abf305ee44fc55ed423fbf16e3", + "reference": "ae0a1032a450a3abf305ee44fc55ed423fbf16e3", "shasum": "" }, "require": { @@ -9237,7 +9905,7 @@ "symfony/serializer": "<5.4.14|>=6.0,<6.0.14|>=6.1,<6.1.6" }, "require-dev": { - "egulias/email-validator": "^2.1.10|^3.1", + "egulias/email-validator": "^2.1.10|^3.1|^4", "phpdocumentor/reflection-docblock": "^3.0|^4.0|^5.0", "symfony/dependency-injection": "^4.4|^5.0|^6.0", "symfony/property-access": "^4.4|^5.1|^6.0", @@ -9274,7 +9942,7 @@ "mime-type" ], "support": { - "source": "https://github.com/symfony/mime/tree/v5.4.14" + "source": "https://github.com/symfony/mime/tree/v5.4.23" }, "funding": [ { @@ -9290,20 +9958,20 @@ "type": "tidelift" } ], - "time": "2022-10-07T08:01:20+00:00" + "time": "2023-04-19T09:49:13+00:00" }, { "name": "symfony/monolog-bridge", - "version": "v5.4.10", + "version": "v5.4.22", "source": { "type": "git", "url": "https://github.com/symfony/monolog-bridge.git", - "reference": "b3b0890e76e7eb626f27b165a5c501f2754dfbbd" + "reference": "34be6f0695e4187dbb832a05905fb4c6581ac39a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/monolog-bridge/zipball/b3b0890e76e7eb626f27b165a5c501f2754dfbbd", - "reference": "b3b0890e76e7eb626f27b165a5c501f2754dfbbd", + "url": "https://api.github.com/repos/symfony/monolog-bridge/zipball/34be6f0695e4187dbb832a05905fb4c6581ac39a", + "reference": "34be6f0695e4187dbb832a05905fb4c6581ac39a", "shasum": "" }, "require": { @@ -9358,7 +10026,7 @@ "description": "Provides integration for Monolog with various Symfony components", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/monolog-bridge/tree/v5.4.10" + "source": "https://github.com/symfony/monolog-bridge/tree/v5.4.22" }, "funding": [ { @@ -9374,7 +10042,7 @@ "type": "tidelift" } ], - "time": "2022-06-19T12:03:50+00:00" + "time": "2023-03-06T21:29:33+00:00" }, { "name": "symfony/monolog-bundle", @@ -9459,16 +10127,16 @@ }, { "name": "symfony/options-resolver", - "version": "v5.4.11", + "version": "v5.4.21", "source": { "type": "git", "url": "https://github.com/symfony/options-resolver.git", - "reference": "54f14e36aa73cb8f7261d7686691fd4d75ea2690" + "reference": "4fe5cf6ede71096839f0e4b4444d65dd3a7c1eb9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/options-resolver/zipball/54f14e36aa73cb8f7261d7686691fd4d75ea2690", - "reference": "54f14e36aa73cb8f7261d7686691fd4d75ea2690", + "url": "https://api.github.com/repos/symfony/options-resolver/zipball/4fe5cf6ede71096839f0e4b4444d65dd3a7c1eb9", + "reference": "4fe5cf6ede71096839f0e4b4444d65dd3a7c1eb9", "shasum": "" }, "require": { @@ -9508,7 +10176,7 @@ "options" ], "support": { - "source": "https://github.com/symfony/options-resolver/tree/v5.4.11" + "source": "https://github.com/symfony/options-resolver/tree/v5.4.21" }, "funding": [ { @@ -9524,20 +10192,20 @@ "type": "tidelift" } ], - "time": "2022-07-20T13:00:38+00:00" + "time": "2023-02-14T08:03:56+00:00" }, { "name": "symfony/password-hasher", - "version": "v5.4.11", + "version": "v5.4.21", "source": { "type": "git", "url": "https://github.com/symfony/password-hasher.git", - "reference": "b0169ed8f09a4ae39eb119218ea1685079a9b179" + "reference": "7ce4529b2b2ea7de3b6f344a1a41f58201999180" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/password-hasher/zipball/b0169ed8f09a4ae39eb119218ea1685079a9b179", - "reference": "b0169ed8f09a4ae39eb119218ea1685079a9b179", + "url": "https://api.github.com/repos/symfony/password-hasher/zipball/7ce4529b2b2ea7de3b6f344a1a41f58201999180", + "reference": "7ce4529b2b2ea7de3b6f344a1a41f58201999180", "shasum": "" }, "require": { @@ -9581,7 +10249,7 @@ "password" ], "support": { - "source": "https://github.com/symfony/password-hasher/tree/v5.4.11" + "source": "https://github.com/symfony/password-hasher/tree/v5.4.21" }, "funding": [ { @@ -9597,20 +10265,20 @@ "type": "tidelift" } ], - "time": "2022-07-20T13:00:38+00:00" + "time": "2023-02-14T08:03:56+00:00" }, { "name": "symfony/polyfill-intl-grapheme", - "version": "v1.26.0", + "version": "v1.27.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-intl-grapheme.git", - "reference": "433d05519ce6990bf3530fba6957499d327395c2" + "reference": "511a08c03c1960e08a883f4cffcacd219b758354" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/433d05519ce6990bf3530fba6957499d327395c2", - "reference": "433d05519ce6990bf3530fba6957499d327395c2", + "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/511a08c03c1960e08a883f4cffcacd219b758354", + "reference": "511a08c03c1960e08a883f4cffcacd219b758354", "shasum": "" }, "require": { @@ -9622,7 +10290,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "1.26-dev" + "dev-main": "1.27-dev" }, "thanks": { "name": "symfony/polyfill", @@ -9662,7 +10330,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.26.0" + "source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.27.0" }, "funding": [ { @@ -9678,20 +10346,20 @@ "type": "tidelift" } ], - "time": "2022-05-24T11:49:31+00:00" + "time": "2022-11-03T14:55:06+00:00" }, { "name": "symfony/polyfill-intl-icu", - "version": "v1.26.0", + "version": "v1.27.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-intl-icu.git", - "reference": "e407643d610e5f2c8a4b14189150f68934bf5e48" + "reference": "a3d9148e2c363588e05abbdd4ee4f971f0a5330c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-intl-icu/zipball/e407643d610e5f2c8a4b14189150f68934bf5e48", - "reference": "e407643d610e5f2c8a4b14189150f68934bf5e48", + "url": "https://api.github.com/repos/symfony/polyfill-intl-icu/zipball/a3d9148e2c363588e05abbdd4ee4f971f0a5330c", + "reference": "a3d9148e2c363588e05abbdd4ee4f971f0a5330c", "shasum": "" }, "require": { @@ -9703,7 +10371,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "1.26-dev" + "dev-main": "1.27-dev" }, "thanks": { "name": "symfony/polyfill", @@ -9749,7 +10417,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-intl-icu/tree/v1.26.0" + "source": "https://github.com/symfony/polyfill-intl-icu/tree/v1.27.0" }, "funding": [ { @@ -9765,20 +10433,20 @@ "type": "tidelift" } ], - "time": "2022-05-24T11:49:31+00:00" + "time": "2022-11-03T14:55:06+00:00" }, { "name": "symfony/polyfill-intl-idn", - "version": "v1.26.0", + "version": "v1.27.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-intl-idn.git", - "reference": "59a8d271f00dd0e4c2e518104cc7963f655a1aa8" + "reference": "639084e360537a19f9ee352433b84ce831f3d2da" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-intl-idn/zipball/59a8d271f00dd0e4c2e518104cc7963f655a1aa8", - "reference": "59a8d271f00dd0e4c2e518104cc7963f655a1aa8", + "url": "https://api.github.com/repos/symfony/polyfill-intl-idn/zipball/639084e360537a19f9ee352433b84ce831f3d2da", + "reference": "639084e360537a19f9ee352433b84ce831f3d2da", "shasum": "" }, "require": { @@ -9792,7 +10460,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "1.26-dev" + "dev-main": "1.27-dev" }, "thanks": { "name": "symfony/polyfill", @@ -9836,7 +10504,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-intl-idn/tree/v1.26.0" + "source": "https://github.com/symfony/polyfill-intl-idn/tree/v1.27.0" }, "funding": [ { @@ -9852,20 +10520,20 @@ "type": "tidelift" } ], - "time": "2022-05-24T11:49:31+00:00" + "time": "2022-11-03T14:55:06+00:00" }, { "name": "symfony/polyfill-intl-normalizer", - "version": "v1.26.0", + "version": "v1.27.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-intl-normalizer.git", - "reference": "219aa369ceff116e673852dce47c3a41794c14bd" + "reference": "19bd1e4fcd5b91116f14d8533c57831ed00571b6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/219aa369ceff116e673852dce47c3a41794c14bd", - "reference": "219aa369ceff116e673852dce47c3a41794c14bd", + "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/19bd1e4fcd5b91116f14d8533c57831ed00571b6", + "reference": "19bd1e4fcd5b91116f14d8533c57831ed00571b6", "shasum": "" }, "require": { @@ -9877,7 +10545,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "1.26-dev" + "dev-main": "1.27-dev" }, "thanks": { "name": "symfony/polyfill", @@ -9920,7 +10588,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.26.0" + "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.27.0" }, "funding": [ { @@ -9936,20 +10604,20 @@ "type": "tidelift" } ], - "time": "2022-05-24T11:49:31+00:00" + "time": "2022-11-03T14:55:06+00:00" }, { "name": "symfony/polyfill-mbstring", - "version": "v1.26.0", + "version": "v1.27.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-mbstring.git", - "reference": "9344f9cb97f3b19424af1a21a3b0e75b0a7d8d7e" + "reference": "8ad114f6b39e2c98a8b0e3bd907732c207c2b534" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/9344f9cb97f3b19424af1a21a3b0e75b0a7d8d7e", - "reference": "9344f9cb97f3b19424af1a21a3b0e75b0a7d8d7e", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/8ad114f6b39e2c98a8b0e3bd907732c207c2b534", + "reference": "8ad114f6b39e2c98a8b0e3bd907732c207c2b534", "shasum": "" }, "require": { @@ -9964,7 +10632,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "1.26-dev" + "dev-main": "1.27-dev" }, "thanks": { "name": "symfony/polyfill", @@ -10003,7 +10671,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.26.0" + "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.27.0" }, "funding": [ { @@ -10019,20 +10687,20 @@ "type": "tidelift" } ], - "time": "2022-05-24T11:49:31+00:00" + "time": "2022-11-03T14:55:06+00:00" }, { "name": "symfony/polyfill-php73", - "version": "v1.26.0", + "version": "v1.27.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php73.git", - "reference": "e440d35fa0286f77fb45b79a03fedbeda9307e85" + "reference": "9e8ecb5f92152187c4799efd3c96b78ccab18ff9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php73/zipball/e440d35fa0286f77fb45b79a03fedbeda9307e85", - "reference": "e440d35fa0286f77fb45b79a03fedbeda9307e85", + "url": "https://api.github.com/repos/symfony/polyfill-php73/zipball/9e8ecb5f92152187c4799efd3c96b78ccab18ff9", + "reference": "9e8ecb5f92152187c4799efd3c96b78ccab18ff9", "shasum": "" }, "require": { @@ -10041,7 +10709,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "1.26-dev" + "dev-main": "1.27-dev" }, "thanks": { "name": "symfony/polyfill", @@ -10082,7 +10750,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-php73/tree/v1.26.0" + "source": "https://github.com/symfony/polyfill-php73/tree/v1.27.0" }, "funding": [ { @@ -10098,20 +10766,20 @@ "type": "tidelift" } ], - "time": "2022-05-24T11:49:31+00:00" + "time": "2022-11-03T14:55:06+00:00" }, { "name": "symfony/polyfill-php80", - "version": "v1.26.0", + "version": "v1.27.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php80.git", - "reference": "cfa0ae98841b9e461207c13ab093d76b0fa7bace" + "reference": "7a6ff3f1959bb01aefccb463a0f2cd3d3d2fd936" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/cfa0ae98841b9e461207c13ab093d76b0fa7bace", - "reference": "cfa0ae98841b9e461207c13ab093d76b0fa7bace", + "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/7a6ff3f1959bb01aefccb463a0f2cd3d3d2fd936", + "reference": "7a6ff3f1959bb01aefccb463a0f2cd3d3d2fd936", "shasum": "" }, "require": { @@ -10120,7 +10788,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "1.26-dev" + "dev-main": "1.27-dev" }, "thanks": { "name": "symfony/polyfill", @@ -10165,7 +10833,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-php80/tree/v1.26.0" + "source": "https://github.com/symfony/polyfill-php80/tree/v1.27.0" }, "funding": [ { @@ -10181,20 +10849,20 @@ "type": "tidelift" } ], - "time": "2022-05-10T07:21:04+00:00" + "time": "2022-11-03T14:55:06+00:00" }, { "name": "symfony/polyfill-php81", - "version": "v1.26.0", + "version": "v1.27.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php81.git", - "reference": "13f6d1271c663dc5ae9fb843a8f16521db7687a1" + "reference": "707403074c8ea6e2edaf8794b0157a0bfa52157a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php81/zipball/13f6d1271c663dc5ae9fb843a8f16521db7687a1", - "reference": "13f6d1271c663dc5ae9fb843a8f16521db7687a1", + "url": "https://api.github.com/repos/symfony/polyfill-php81/zipball/707403074c8ea6e2edaf8794b0157a0bfa52157a", + "reference": "707403074c8ea6e2edaf8794b0157a0bfa52157a", "shasum": "" }, "require": { @@ -10203,7 +10871,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "1.26-dev" + "dev-main": "1.27-dev" }, "thanks": { "name": "symfony/polyfill", @@ -10244,7 +10912,89 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-php81/tree/v1.26.0" + "source": "https://github.com/symfony/polyfill-php81/tree/v1.27.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2022-11-03T14:55:06+00:00" + }, + { + "name": "symfony/polyfill-uuid", + "version": "v1.27.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-uuid.git", + "reference": "f3cf1a645c2734236ed1e2e671e273eeb3586166" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-uuid/zipball/f3cf1a645c2734236ed1e2e671e273eeb3586166", + "reference": "f3cf1a645c2734236ed1e2e671e273eeb3586166", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "provide": { + "ext-uuid": "*" + }, + "suggest": { + "ext-uuid": "For best performance" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.27-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Uuid\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Grégoire Pineau", + "email": "lyrixx@lyrixx.info" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for uuid functions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "polyfill", + "portable", + "uuid" + ], + "support": { + "source": "https://github.com/symfony/polyfill-uuid/tree/v1.27.0" }, "funding": [ { @@ -10260,20 +11010,20 @@ "type": "tidelift" } ], - "time": "2022-05-24T11:49:31+00:00" + "time": "2022-11-03T14:55:06+00:00" }, { "name": "symfony/process", - "version": "v5.4.11", + "version": "v5.4.23", "source": { "type": "git", "url": "https://github.com/symfony/process.git", - "reference": "6e75fe6874cbc7e4773d049616ab450eff537bf1" + "reference": "4b842fc4b61609e0a155a114082bd94e31e98287" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/process/zipball/6e75fe6874cbc7e4773d049616ab450eff537bf1", - "reference": "6e75fe6874cbc7e4773d049616ab450eff537bf1", + "url": "https://api.github.com/repos/symfony/process/zipball/4b842fc4b61609e0a155a114082bd94e31e98287", + "reference": "4b842fc4b61609e0a155a114082bd94e31e98287", "shasum": "" }, "require": { @@ -10306,7 +11056,7 @@ "description": "Executes commands in sub-processes", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/process/tree/v5.4.11" + "source": "https://github.com/symfony/process/tree/v5.4.23" }, "funding": [ { @@ -10322,20 +11072,20 @@ "type": "tidelift" } ], - "time": "2022-06-27T16:58:25+00:00" + "time": "2023-04-18T13:50:24+00:00" }, { "name": "symfony/property-access", - "version": "v5.4.11", + "version": "v5.4.22", "source": { "type": "git", "url": "https://github.com/symfony/property-access.git", - "reference": "c641d63e943ed31981bad4b4dcf29fe7da2ffa8c" + "reference": "ffee082889586b5718347b291e04071f4d07b38f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/property-access/zipball/c641d63e943ed31981bad4b4dcf29fe7da2ffa8c", - "reference": "c641d63e943ed31981bad4b4dcf29fe7da2ffa8c", + "url": "https://api.github.com/repos/symfony/property-access/zipball/ffee082889586b5718347b291e04071f4d07b38f", + "reference": "ffee082889586b5718347b291e04071f4d07b38f", "shasum": "" }, "require": { @@ -10383,11 +11133,11 @@ "injection", "object", "property", - "property path", + "property-path", "reflection" ], "support": { - "source": "https://github.com/symfony/property-access/tree/v5.4.11" + "source": "https://github.com/symfony/property-access/tree/v5.4.22" }, "funding": [ { @@ -10403,20 +11153,20 @@ "type": "tidelift" } ], - "time": "2022-06-27T16:58:25+00:00" + "time": "2023-03-14T14:59:20+00:00" }, { "name": "symfony/property-info", - "version": "v5.4.14", + "version": "v5.4.23", "source": { "type": "git", "url": "https://github.com/symfony/property-info.git", - "reference": "dc7ac44b5ea36c9f7532051b01ba64b1737932d1" + "reference": "ff45ebbfd781eab2571d9d4412d82a9a733fc2b3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/property-info/zipball/dc7ac44b5ea36c9f7532051b01ba64b1737932d1", - "reference": "dc7ac44b5ea36c9f7532051b01ba64b1737932d1", + "url": "https://api.github.com/repos/symfony/property-info/zipball/ff45ebbfd781eab2571d9d4412d82a9a733fc2b3", + "reference": "ff45ebbfd781eab2571d9d4412d82a9a733fc2b3", "shasum": "" }, "require": { @@ -10431,7 +11181,7 @@ "symfony/dependency-injection": "<4.4" }, "require-dev": { - "doctrine/annotations": "^1.10.4", + "doctrine/annotations": "^1.10.4|^2", "phpdocumentor/reflection-docblock": "^3.0|^4.0|^5.0", "phpstan/phpdoc-parser": "^1.0", "symfony/cache": "^4.4|^5.0|^6.0", @@ -10478,7 +11228,7 @@ "validator" ], "support": { - "source": "https://github.com/symfony/property-info/tree/v5.4.14" + "source": "https://github.com/symfony/property-info/tree/v5.4.23" }, "funding": [ { @@ -10494,20 +11244,20 @@ "type": "tidelift" } ], - "time": "2022-10-07T08:01:20+00:00" + "time": "2023-04-17T14:20:34+00:00" }, { "name": "symfony/routing", - "version": "v5.4.11", + "version": "v5.4.22", "source": { "type": "git", "url": "https://github.com/symfony/routing.git", - "reference": "3e01ccd9b2a3a4167ba2b3c53612762300300226" + "reference": "c2ac11eb34947999b7c38fb4c835a57306907e6d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/routing/zipball/3e01ccd9b2a3a4167ba2b3c53612762300300226", - "reference": "3e01ccd9b2a3a4167ba2b3c53612762300300226", + "url": "https://api.github.com/repos/symfony/routing/zipball/c2ac11eb34947999b7c38fb4c835a57306907e6d", + "reference": "c2ac11eb34947999b7c38fb4c835a57306907e6d", "shasum": "" }, "require": { @@ -10522,7 +11272,7 @@ "symfony/yaml": "<4.4" }, "require-dev": { - "doctrine/annotations": "^1.12", + "doctrine/annotations": "^1.12|^2", "psr/log": "^1|^2|^3", "symfony/config": "^5.3|^6.0", "symfony/dependency-injection": "^4.4|^5.0|^6.0", @@ -10568,7 +11318,7 @@ "url" ], "support": { - "source": "https://github.com/symfony/routing/tree/v5.4.11" + "source": "https://github.com/symfony/routing/tree/v5.4.22" }, "funding": [ { @@ -10584,20 +11334,20 @@ "type": "tidelift" } ], - "time": "2022-07-20T13:00:38+00:00" + "time": "2023-03-14T14:59:20+00:00" }, { "name": "symfony/runtime", - "version": "v5.4.11", + "version": "v5.4.22", "source": { "type": "git", "url": "https://github.com/symfony/runtime.git", - "reference": "c32ac27a8abebe4e6375cd12a4f78ba78e9c742f" + "reference": "4a78e519d40a3845437e29dc514959631badfed4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/runtime/zipball/c32ac27a8abebe4e6375cd12a4f78ba78e9c742f", - "reference": "c32ac27a8abebe4e6375cd12a4f78ba78e9c742f", + "url": "https://api.github.com/repos/symfony/runtime/zipball/4a78e519d40a3845437e29dc514959631badfed4", + "reference": "4a78e519d40a3845437e29dc514959631badfed4", "shasum": "" }, "require": { @@ -10644,8 +11394,11 @@ ], "description": "Enables decoupling PHP applications from global state", "homepage": "https://symfony.com", + "keywords": [ + "runtime" + ], "support": { - "source": "https://github.com/symfony/runtime/tree/v5.4.11" + "source": "https://github.com/symfony/runtime/tree/v5.4.22" }, "funding": [ { @@ -10661,20 +11414,20 @@ "type": "tidelift" } ], - "time": "2022-06-27T16:58:25+00:00" + "time": "2023-03-14T15:48:23+00:00" }, { "name": "symfony/security-core", - "version": "v5.4.14", + "version": "v5.4.22", "source": { "type": "git", "url": "https://github.com/symfony/security-core.git", - "reference": "0f8b4595ce4725f8f02fbb63729036813645fc2c" + "reference": "a801d525c7545332e2ddf7f52c163959354b1650" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/security-core/zipball/0f8b4595ce4725f8f02fbb63729036813645fc2c", - "reference": "0f8b4595ce4725f8f02fbb63729036813645fc2c", + "url": "https://api.github.com/repos/symfony/security-core/zipball/a801d525c7545332e2ddf7f52c163959354b1650", + "reference": "a801d525c7545332e2ddf7f52c163959354b1650", "shasum": "" }, "require": { @@ -10738,7 +11491,7 @@ "description": "Symfony Security Component - Core Library", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/security-core/tree/v5.4.14" + "source": "https://github.com/symfony/security-core/tree/v5.4.22" }, "funding": [ { @@ -10754,20 +11507,20 @@ "type": "tidelift" } ], - "time": "2022-10-01T21:59:28+00:00" + "time": "2023-03-10T10:02:45+00:00" }, { "name": "symfony/security-csrf", - "version": "v5.4.11", + "version": "v5.4.21", "source": { "type": "git", "url": "https://github.com/symfony/security-csrf.git", - "reference": "b97ab244b6dda80abb84a4a236d682871695db4a" + "reference": "776a538e5f20fb560a182f790979c71455694203" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/security-csrf/zipball/b97ab244b6dda80abb84a4a236d682871695db4a", - "reference": "b97ab244b6dda80abb84a4a236d682871695db4a", + "url": "https://api.github.com/repos/symfony/security-csrf/zipball/776a538e5f20fb560a182f790979c71455694203", + "reference": "776a538e5f20fb560a182f790979c71455694203", "shasum": "" }, "require": { @@ -10810,7 +11563,7 @@ "description": "Symfony Security Component - CSRF Library", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/security-csrf/tree/v5.4.11" + "source": "https://github.com/symfony/security-csrf/tree/v5.4.21" }, "funding": [ { @@ -10826,20 +11579,20 @@ "type": "tidelift" } ], - "time": "2022-07-20T13:00:38+00:00" + "time": "2023-02-16T09:33:00+00:00" }, { "name": "symfony/security-guard", - "version": "v5.4.13", + "version": "v5.4.22", "source": { "type": "git", "url": "https://github.com/symfony/security-guard.git", - "reference": "83f647fcdc17aa14908f0e02a302d3d9d0f63fbc" + "reference": "62d064b1ee682e4617f4c5ddc0d31f73e1a7ecaa" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/security-guard/zipball/83f647fcdc17aa14908f0e02a302d3d9d0f63fbc", - "reference": "83f647fcdc17aa14908f0e02a302d3d9d0f63fbc", + "url": "https://api.github.com/repos/symfony/security-guard/zipball/62d064b1ee682e4617f4c5ddc0d31f73e1a7ecaa", + "reference": "62d064b1ee682e4617f4c5ddc0d31f73e1a7ecaa", "shasum": "" }, "require": { @@ -10877,7 +11630,7 @@ "description": "Symfony Security Component - Guard", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/security-guard/tree/v5.4.13" + "source": "https://github.com/symfony/security-guard/tree/v5.4.22" }, "funding": [ { @@ -10893,20 +11646,20 @@ "type": "tidelift" } ], - "time": "2022-09-28T13:19:49+00:00" + "time": "2023-03-06T21:29:33+00:00" }, { "name": "symfony/security-http", - "version": "v5.4.13", + "version": "v5.4.23", "source": { "type": "git", "url": "https://github.com/symfony/security-http.git", - "reference": "64e9926b8ab8e4460e4dfdc53dc098fed2dad837" + "reference": "6791856229cc605834d169091981e4eae77dad45" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/security-http/zipball/64e9926b8ab8e4460e4dfdc53dc098fed2dad837", - "reference": "64e9926b8ab8e4460e4dfdc53dc098fed2dad837", + "url": "https://api.github.com/repos/symfony/security-http/zipball/6791856229cc605834d169091981e4eae77dad45", + "reference": "6791856229cc605834d169091981e4eae77dad45", "shasum": "" }, "require": { @@ -10917,7 +11670,7 @@ "symfony/polyfill-mbstring": "~1.0", "symfony/polyfill-php80": "^1.16", "symfony/property-access": "^4.4|^5.0|^6.0", - "symfony/security-core": "^5.4|^6.0" + "symfony/security-core": "^5.4.19|~6.0.19|~6.1.11|^6.2.5" }, "conflict": { "symfony/event-dispatcher": "<4.3", @@ -10962,7 +11715,7 @@ "description": "Symfony Security Component - HTTP Integration", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/security-http/tree/v5.4.13" + "source": "https://github.com/symfony/security-http/tree/v5.4.23" }, "funding": [ { @@ -10978,20 +11731,20 @@ "type": "tidelift" } ], - "time": "2022-09-29T19:14:22+00:00" + "time": "2023-04-21T11:34:27+00:00" }, { "name": "symfony/serializer", - "version": "v5.4.14", + "version": "v5.4.23", "source": { "type": "git", "url": "https://github.com/symfony/serializer.git", - "reference": "21c329453e3c9345b51bf4b67b187c963a4edc45" + "reference": "545da11697153c24c274b9a68cab550b2c0a9860" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/serializer/zipball/21c329453e3c9345b51bf4b67b187c963a4edc45", - "reference": "21c329453e3c9345b51bf4b67b187c963a4edc45", + "url": "https://api.github.com/repos/symfony/serializer/zipball/545da11697153c24c274b9a68cab550b2c0a9860", + "reference": "545da11697153c24c274b9a68cab550b2c0a9860", "shasum": "" }, "require": { @@ -11011,7 +11764,7 @@ "symfony/yaml": "<4.4" }, "require-dev": { - "doctrine/annotations": "^1.12", + "doctrine/annotations": "^1.12|^2", "phpdocumentor/reflection-docblock": "^3.2|^4.0|^5.0", "symfony/cache": "^4.4|^5.0|^6.0", "symfony/config": "^4.4|^5.0|^6.0", @@ -11065,7 +11818,7 @@ "description": "Handles serializing and deserializing data structures, including object graphs, into array structures or other formats like XML and JSON.", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/serializer/tree/v5.4.14" + "source": "https://github.com/symfony/serializer/tree/v5.4.23" }, "funding": [ { @@ -11081,7 +11834,7 @@ "type": "tidelift" } ], - "time": "2022-10-11T15:16:01+00:00" + "time": "2023-04-17T13:59:16+00:00" }, { "name": "symfony/service-contracts", @@ -11168,16 +11921,16 @@ }, { "name": "symfony/stopwatch", - "version": "v5.4.13", + "version": "v5.4.21", "source": { "type": "git", "url": "https://github.com/symfony/stopwatch.git", - "reference": "6df7a3effde34d81717bbef4591e5ffe32226d69" + "reference": "f83692cd869a6f2391691d40a01e8acb89e76fee" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/stopwatch/zipball/6df7a3effde34d81717bbef4591e5ffe32226d69", - "reference": "6df7a3effde34d81717bbef4591e5ffe32226d69", + "url": "https://api.github.com/repos/symfony/stopwatch/zipball/f83692cd869a6f2391691d40a01e8acb89e76fee", + "reference": "f83692cd869a6f2391691d40a01e8acb89e76fee", "shasum": "" }, "require": { @@ -11210,7 +11963,7 @@ "description": "Provides a way to profile code", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/stopwatch/tree/v5.4.13" + "source": "https://github.com/symfony/stopwatch/tree/v5.4.21" }, "funding": [ { @@ -11226,20 +11979,20 @@ "type": "tidelift" } ], - "time": "2022-09-28T13:19:49+00:00" + "time": "2023-02-14T08:03:56+00:00" }, { "name": "symfony/string", - "version": "v5.4.14", + "version": "v5.4.22", "source": { "type": "git", "url": "https://github.com/symfony/string.git", - "reference": "089e7237497fae7a9c404d0c3aeb8db3254733e4" + "reference": "8036a4c76c0dd29e60b6a7cafcacc50cf088ea62" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/string/zipball/089e7237497fae7a9c404d0c3aeb8db3254733e4", - "reference": "089e7237497fae7a9c404d0c3aeb8db3254733e4", + "url": "https://api.github.com/repos/symfony/string/zipball/8036a4c76c0dd29e60b6a7cafcacc50cf088ea62", + "reference": "8036a4c76c0dd29e60b6a7cafcacc50cf088ea62", "shasum": "" }, "require": { @@ -11296,7 +12049,7 @@ "utf8" ], "support": { - "source": "https://github.com/symfony/string/tree/v5.4.14" + "source": "https://github.com/symfony/string/tree/v5.4.22" }, "funding": [ { @@ -11312,20 +12065,20 @@ "type": "tidelift" } ], - "time": "2022-10-05T15:16:54+00:00" + "time": "2023-03-14T06:11:53+00:00" }, { "name": "symfony/translation", - "version": "v5.4.14", + "version": "v5.4.22", "source": { "type": "git", "url": "https://github.com/symfony/translation.git", - "reference": "f0ed07675863aa6e3939df8b1bc879450b585cab" + "reference": "9a401392f01bc385aa42760eff481d213a0cc2ba" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/translation/zipball/f0ed07675863aa6e3939df8b1bc879450b585cab", - "reference": "f0ed07675863aa6e3939df8b1bc879450b585cab", + "url": "https://api.github.com/repos/symfony/translation/zipball/9a401392f01bc385aa42760eff481d213a0cc2ba", + "reference": "9a401392f01bc385aa42760eff481d213a0cc2ba", "shasum": "" }, "require": { @@ -11393,7 +12146,7 @@ "description": "Provides tools to internationalize your application", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/translation/tree/v5.4.14" + "source": "https://github.com/symfony/translation/tree/v5.4.22" }, "funding": [ { @@ -11409,7 +12162,7 @@ "type": "tidelift" } ], - "time": "2022-10-07T08:01:20+00:00" + "time": "2023-03-27T16:07:23+00:00" }, { "name": "symfony/translation-contracts", @@ -11491,16 +12244,16 @@ }, { "name": "symfony/twig-bridge", - "version": "v5.4.14", + "version": "v5.4.22", "source": { "type": "git", "url": "https://github.com/symfony/twig-bridge.git", - "reference": "60db1cc3f5b098eb194c00a10489148a03861371" + "reference": "e5b174464f68be6876046db3ad6e217d9a7dbbac" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/twig-bridge/zipball/60db1cc3f5b098eb194c00a10489148a03861371", - "reference": "60db1cc3f5b098eb194c00a10489148a03861371", + "url": "https://api.github.com/repos/symfony/twig-bridge/zipball/e5b174464f68be6876046db3ad6e217d9a7dbbac", + "reference": "e5b174464f68be6876046db3ad6e217d9a7dbbac", "shasum": "" }, "require": { @@ -11513,22 +12266,22 @@ "phpdocumentor/reflection-docblock": "<3.2.2", "phpdocumentor/type-resolver": "<1.4.0", "symfony/console": "<5.3", - "symfony/form": "<5.3", + "symfony/form": "<5.4.21|>=6,<6.2.7", "symfony/http-foundation": "<5.3", "symfony/http-kernel": "<4.4", "symfony/translation": "<5.2", "symfony/workflow": "<5.2" }, "require-dev": { - "doctrine/annotations": "^1.12", - "egulias/email-validator": "^2.1.10|^3", + "doctrine/annotations": "^1.12|^2", + "egulias/email-validator": "^2.1.10|^3|^4", "phpdocumentor/reflection-docblock": "^3.0|^4.0|^5.0", "symfony/asset": "^4.4|^5.0|^6.0", "symfony/console": "^5.3|^6.0", "symfony/dependency-injection": "^4.4|^5.0|^6.0", "symfony/expression-language": "^4.4|^5.0|^6.0", "symfony/finder": "^4.4|^5.0|^6.0", - "symfony/form": "^5.3|^6.0", + "symfony/form": "^5.4.21|^6.2.7", "symfony/http-foundation": "^5.3|^6.0", "symfony/http-kernel": "^4.4|^5.0|^6.0", "symfony/intl": "^4.4|^5.0|^6.0", @@ -11592,7 +12345,7 @@ "description": "Provides integration for Twig with various Symfony components", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/twig-bridge/tree/v5.4.14" + "source": "https://github.com/symfony/twig-bridge/tree/v5.4.22" }, "funding": [ { @@ -11608,20 +12361,20 @@ "type": "tidelift" } ], - "time": "2022-10-11T12:49:22+00:00" + "time": "2023-03-31T08:28:44+00:00" }, { "name": "symfony/twig-bundle", - "version": "v5.4.8", + "version": "v5.4.21", "source": { "type": "git", "url": "https://github.com/symfony/twig-bundle.git", - "reference": "c992b4474c3a31f3c40a1ca593d213833f91b818" + "reference": "875d0edfc8df7505c1993419882c4071fc28c477" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/twig-bundle/zipball/c992b4474c3a31f3c40a1ca593d213833f91b818", - "reference": "c992b4474c3a31f3c40a1ca593d213833f91b818", + "url": "https://api.github.com/repos/symfony/twig-bundle/zipball/875d0edfc8df7505c1993419882c4071fc28c477", + "reference": "875d0edfc8df7505c1993419882c4071fc28c477", "shasum": "" }, "require": { @@ -11641,7 +12394,7 @@ "symfony/translation": "<5.0" }, "require-dev": { - "doctrine/annotations": "^1.10.4", + "doctrine/annotations": "^1.10.4|^2", "doctrine/cache": "^1.0|^2.0", "symfony/asset": "^4.4|^5.0|^6.0", "symfony/dependency-injection": "^5.3|^6.0", @@ -11681,7 +12434,81 @@ "description": "Provides a tight integration of Twig into the Symfony full-stack framework", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/twig-bundle/tree/v5.4.8" + "source": "https://github.com/symfony/twig-bundle/tree/v5.4.21" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2023-02-14T08:03:56+00:00" + }, + { + "name": "symfony/uid", + "version": "v5.4.21", + "source": { + "type": "git", + "url": "https://github.com/symfony/uid.git", + "reference": "a30744506976aafc807ccb0d4f95865c0a690d02" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/uid/zipball/a30744506976aafc807ccb0d4f95865c0a690d02", + "reference": "a30744506976aafc807ccb0d4f95865c0a690d02", + "shasum": "" + }, + "require": { + "php": ">=7.2.5", + "symfony/polyfill-uuid": "^1.15" + }, + "require-dev": { + "symfony/console": "^4.4|^5.0|^6.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Uid\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Grégoire Pineau", + "email": "lyrixx@lyrixx.info" + }, + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides an object-oriented API to generate and represent UIDs", + "homepage": "https://symfony.com", + "keywords": [ + "UID", + "ulid", + "uuid" + ], + "support": { + "source": "https://github.com/symfony/uid/tree/v5.4.21" }, "funding": [ { @@ -11697,20 +12524,20 @@ "type": "tidelift" } ], - "time": "2022-04-03T13:03:10+00:00" + "time": "2023-02-14T08:03:56+00:00" }, { "name": "symfony/validator", - "version": "v5.4.14", + "version": "v5.4.23", "source": { "type": "git", "url": "https://github.com/symfony/validator.git", - "reference": "717b1eabbc51795369400697458f7e813fc6c71e" + "reference": "ca71f5562a3876a153250f638124b6b95452985f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/validator/zipball/717b1eabbc51795369400697458f7e813fc6c71e", - "reference": "717b1eabbc51795369400697458f7e813fc6c71e", + "url": "https://api.github.com/repos/symfony/validator/zipball/ca71f5562a3876a153250f638124b6b95452985f", + "reference": "ca71f5562a3876a153250f638124b6b95452985f", "shasum": "" }, "require": { @@ -11737,9 +12564,9 @@ "symfony/yaml": "<4.4" }, "require-dev": { - "doctrine/annotations": "^1.13", + "doctrine/annotations": "^1.13|^2", "doctrine/cache": "^1.11|^2.0", - "egulias/email-validator": "^2.1.10|^3", + "egulias/email-validator": "^2.1.10|^3|^4", "symfony/cache": "^4.4|^5.0|^6.0", "symfony/config": "^4.4|^5.0|^6.0", "symfony/console": "^4.4|^5.0|^6.0", @@ -11794,7 +12621,7 @@ "description": "Provides tools to validate values", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/validator/tree/v5.4.14" + "source": "https://github.com/symfony/validator/tree/v5.4.23" }, "funding": [ { @@ -11810,20 +12637,20 @@ "type": "tidelift" } ], - "time": "2022-10-01T21:59:28+00:00" + "time": "2023-04-19T07:52:21+00:00" }, { "name": "symfony/var-dumper", - "version": "v5.4.14", + "version": "v5.4.23", "source": { "type": "git", "url": "https://github.com/symfony/var-dumper.git", - "reference": "6894d06145fefebd9a4c7272baa026a1c394a430" + "reference": "9a8a5b6d6508928174ded2109e29328a55342a42" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/var-dumper/zipball/6894d06145fefebd9a4c7272baa026a1c394a430", - "reference": "6894d06145fefebd9a4c7272baa026a1c394a430", + "url": "https://api.github.com/repos/symfony/var-dumper/zipball/9a8a5b6d6508928174ded2109e29328a55342a42", + "reference": "9a8a5b6d6508928174ded2109e29328a55342a42", "shasum": "" }, "require": { @@ -11883,7 +12710,7 @@ "dump" ], "support": { - "source": "https://github.com/symfony/var-dumper/tree/v5.4.14" + "source": "https://github.com/symfony/var-dumper/tree/v5.4.23" }, "funding": [ { @@ -11899,20 +12726,20 @@ "type": "tidelift" } ], - "time": "2022-10-07T08:01:20+00:00" + "time": "2023-04-18T09:26:27+00:00" }, { "name": "symfony/var-exporter", - "version": "v5.4.10", + "version": "v5.4.21", "source": { "type": "git", "url": "https://github.com/symfony/var-exporter.git", - "reference": "8fc03ee75eeece3d9be1ef47d26d79bea1afb340" + "reference": "be74908a6942fdd331554b3cec27ff41b45ccad4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/var-exporter/zipball/8fc03ee75eeece3d9be1ef47d26d79bea1afb340", - "reference": "8fc03ee75eeece3d9be1ef47d26d79bea1afb340", + "url": "https://api.github.com/repos/symfony/var-exporter/zipball/be74908a6942fdd331554b3cec27ff41b45ccad4", + "reference": "be74908a6942fdd331554b3cec27ff41b45ccad4", "shasum": "" }, "require": { @@ -11956,7 +12783,7 @@ "serialize" ], "support": { - "source": "https://github.com/symfony/var-exporter/tree/v5.4.10" + "source": "https://github.com/symfony/var-exporter/tree/v5.4.21" }, "funding": [ { @@ -11972,20 +12799,20 @@ "type": "tidelift" } ], - "time": "2022-05-27T12:56:18+00:00" + "time": "2023-02-21T19:46:44+00:00" }, { "name": "symfony/workflow", - "version": "v5.4.11", + "version": "v5.4.21", "source": { "type": "git", "url": "https://github.com/symfony/workflow.git", - "reference": "c70047328e4b3229fb770c09ac6463d5ee88fbfc" + "reference": "96ec1843a27c7d3574bd521b807aa18101e31764" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/workflow/zipball/c70047328e4b3229fb770c09ac6463d5ee88fbfc", - "reference": "c70047328e4b3229fb770c09ac6463d5ee88fbfc", + "url": "https://api.github.com/repos/symfony/workflow/zipball/96ec1843a27c7d3574bd521b807aa18101e31764", + "reference": "96ec1843a27c7d3574bd521b807aa18101e31764", "shasum": "" }, "require": { @@ -12038,7 +12865,7 @@ "workflow" ], "support": { - "source": "https://github.com/symfony/workflow/tree/v5.4.11" + "source": "https://github.com/symfony/workflow/tree/v5.4.21" }, "funding": [ { @@ -12054,20 +12881,20 @@ "type": "tidelift" } ], - "time": "2022-07-11T15:34:21+00:00" + "time": "2023-02-24T08:13:13+00:00" }, { "name": "symfony/yaml", - "version": "v5.4.14", + "version": "v5.4.23", "source": { "type": "git", "url": "https://github.com/symfony/yaml.git", - "reference": "e83fe9a72011f07c662da46a05603d66deeeb487" + "reference": "4cd2e3ea301aadd76a4172756296fe552fb45b0b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/yaml/zipball/e83fe9a72011f07c662da46a05603d66deeeb487", - "reference": "e83fe9a72011f07c662da46a05603d66deeeb487", + "url": "https://api.github.com/repos/symfony/yaml/zipball/4cd2e3ea301aadd76a4172756296fe552fb45b0b", + "reference": "4cd2e3ea301aadd76a4172756296fe552fb45b0b", "shasum": "" }, "require": { @@ -12113,7 +12940,7 @@ "description": "Loads and dumps YAML files", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/yaml/tree/v5.4.14" + "source": "https://github.com/symfony/yaml/tree/v5.4.23" }, "funding": [ { @@ -12129,20 +12956,20 @@ "type": "tidelift" } ], - "time": "2022-10-03T15:15:50+00:00" + "time": "2023-04-23T19:33:36+00:00" }, { "name": "twig/twig", - "version": "v3.4.3", + "version": "v3.6.0", "source": { "type": "git", "url": "https://github.com/twigphp/Twig.git", - "reference": "c38fd6b0b7f370c198db91ffd02e23b517426b58" + "reference": "106c170d08e8415d78be2d16c3d057d0d108262b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/twigphp/Twig/zipball/c38fd6b0b7f370c198db91ffd02e23b517426b58", - "reference": "c38fd6b0b7f370c198db91ffd02e23b517426b58", + "url": "https://api.github.com/repos/twigphp/Twig/zipball/106c170d08e8415d78be2d16c3d057d0d108262b", + "reference": "106c170d08e8415d78be2d16c3d057d0d108262b", "shasum": "" }, "require": { @@ -12151,15 +12978,10 @@ "symfony/polyfill-mbstring": "^1.3" }, "require-dev": { - "psr/container": "^1.0", + "psr/container": "^1.0|^2.0", "symfony/phpunit-bridge": "^4.4.9|^5.0.9|^6.0" }, "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.4-dev" - } - }, "autoload": { "psr-4": { "Twig\\": "src/" @@ -12193,7 +13015,7 @@ ], "support": { "issues": "https://github.com/twigphp/Twig/issues", - "source": "https://github.com/twigphp/Twig/tree/v3.4.3" + "source": "https://github.com/twigphp/Twig/tree/v3.6.0" }, "funding": [ { @@ -12205,20 +13027,20 @@ "type": "tidelift" } ], - "time": "2022-09-28T08:42:51+00:00" + "time": "2023-05-03T19:06:57+00:00" }, { "name": "vimeo/psalm", - "version": "4.29.0", + "version": "4.30.0", "source": { "type": "git", "url": "https://github.com/vimeo/psalm.git", - "reference": "7ec5ffbd5f68ae03782d7fd33fff0c45a69f95b3" + "reference": "d0bc6e25d89f649e4f36a534f330f8bb4643dd69" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/vimeo/psalm/zipball/7ec5ffbd5f68ae03782d7fd33fff0c45a69f95b3", - "reference": "7ec5ffbd5f68ae03782d7fd33fff0c45a69f95b3", + "url": "https://api.github.com/repos/vimeo/psalm/zipball/d0bc6e25d89f649e4f36a534f330f8bb4643dd69", + "reference": "d0bc6e25d89f649e4f36a534f330f8bb4643dd69", "shasum": "" }, "require": { @@ -12311,9 +13133,9 @@ ], "support": { "issues": "https://github.com/vimeo/psalm/issues", - "source": "https://github.com/vimeo/psalm/tree/4.29.0" + "source": "https://github.com/vimeo/psalm/tree/4.30.0" }, - "time": "2022-10-11T17:09:17+00:00" + "time": "2022-11-06T20:37:08+00:00" }, { "name": "webmozart/assert", @@ -12475,23 +13297,24 @@ }, { "name": "zircote/swagger-php", - "version": "4.4.10", + "version": "4.7.10", "source": { "type": "git", "url": "https://github.com/zircote/swagger-php.git", - "reference": "795be27b3b3bacc8353350cacc663ac5cbcd05cc" + "reference": "6d2f0fcc46bf9043877de8656a9ea95331155522" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/zircote/swagger-php/zipball/795be27b3b3bacc8353350cacc663ac5cbcd05cc", - "reference": "795be27b3b3bacc8353350cacc663ac5cbcd05cc", + "url": "https://api.github.com/repos/zircote/swagger-php/zipball/6d2f0fcc46bf9043877de8656a9ea95331155522", + "reference": "6d2f0fcc46bf9043877de8656a9ea95331155522", "shasum": "" }, "require": { - "doctrine/annotations": "^1.7", + "doctrine/annotations": "^1.7 || ^2.0", "ext-json": "*", "php": ">=7.2", "psr/log": "^1.1 || ^2.0 || ^3.0", + "symfony/deprecation-contracts": "^2 || ^3", "symfony/finder": ">=2.2", "symfony/yaml": ">=3.3" }, @@ -12546,9 +13369,9 @@ ], "support": { "issues": "https://github.com/zircote/swagger-php/issues", - "source": "https://github.com/zircote/swagger-php/tree/4.4.10" + "source": "https://github.com/zircote/swagger-php/tree/4.7.10" }, - "time": "2022-10-19T02:28:50+00:00" + "time": "2023-04-28T00:56:39+00:00" } ], "packages-dev": [ @@ -12615,138 +13438,6 @@ }, "time": "2021-10-12T13:05:09+00:00" }, - { - "name": "chobie/jira-api-restclient", - "version": "dev-master", - "source": { - "type": "git", - "url": "https://github.com/chobie/jira-api-restclient.git", - "reference": "141f494c43ce254f951825fc6702af9f685d4ddb" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/chobie/jira-api-restclient/zipball/141f494c43ce254f951825fc6702af9f685d4ddb", - "reference": "141f494c43ce254f951825fc6702af9f685d4ddb", - "shasum": "" - }, - "require": { - "php": ">=5.4.0" - }, - "require-dev": { - "aik099/coding-standard": "dev-master", - "phpspec/prophecy": "^1.10", - "squizlabs/php_codesniffer": "^2.6", - "yoast/phpunit-polyfills": "^1.0" - }, - "default-branch": true, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.0-dev" - } - }, - "autoload": { - "psr-4": { - "chobie\\": "src" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Shuhei Tanuma", - "email": "chobieeee@php.net", - "homepage": "http://chobie.github.io/" - } - ], - "description": "JIRA REST API Client", - "keywords": [ - "api", - "jira", - "rest" - ], - "support": { - "issues": "https://github.com/chobie/jira-api-restclient/issues", - "source": "https://github.com/chobie/jira-api-restclient/tree/master" - }, - "time": "2022-10-06T10:19:38+00:00" - }, - { - "name": "cocur/slugify", - "version": "v4.2.0", - "source": { - "type": "git", - "url": "https://github.com/cocur/slugify.git", - "reference": "7e7d03067d1075b1147090b3e1df672dfffb9dc3" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/cocur/slugify/zipball/7e7d03067d1075b1147090b3e1df672dfffb9dc3", - "reference": "7e7d03067d1075b1147090b3e1df672dfffb9dc3", - "shasum": "" - }, - "require": { - "ext-mbstring": "*", - "php": "^7.1 || ~8.0.0 || ~8.1.0" - }, - "conflict": { - "symfony/config": "<3.4 || >=4,<4.3", - "symfony/dependency-injection": "<3.4 || >=4,<4.3", - "symfony/http-kernel": "<3.4 || >=4,<4.3", - "twig/twig": "<2.12.1" - }, - "require-dev": { - "laravel/framework": "^5.0|^6.0|^7.0|^8.0", - "latte/latte": "~2.2", - "league/container": "^2.2.0", - "mikey179/vfsstream": "~1.6.8", - "mockery/mockery": "^1.3", - "nette/di": "~2.4", - "pimple/pimple": "~1.1", - "plumphp/plum": "~0.1", - "symfony/config": "^3.4 || ^4.3 || ^5.0 || ^6.0", - "symfony/dependency-injection": "^3.4 || ^4.3 || ^5.0 || ^6.0", - "symfony/http-kernel": "^3.4 || ^4.3 || ^5.0 || ^6.0", - "symfony/phpunit-bridge": "^5.4 || ^6.0", - "twig/twig": "^2.12.1 || ~3.0", - "zendframework/zend-modulemanager": "~2.2", - "zendframework/zend-servicemanager": "~2.2", - "zendframework/zend-view": "~2.2" - }, - "type": "library", - "autoload": { - "psr-4": { - "Cocur\\Slugify\\": "src" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Florian Eckerstorfer", - "email": "florian@eckerstorfer.co", - "homepage": "https://florian.ec" - }, - { - "name": "Ivo Bathke", - "email": "ivo.bathke@gmail.com" - } - ], - "description": "Converts a string into a slug.", - "keywords": [ - "slug", - "slugify" - ], - "support": { - "issues": "https://github.com/cocur/slugify/issues", - "source": "https://github.com/cocur/slugify/tree/v4.2.0" - }, - "time": "2022-08-13T15:23:32+00:00" - }, { "name": "codeception/codeception", "version": "4.2.2", @@ -13018,20 +13709,21 @@ }, { "name": "codeception/module-cli", - "version": "2.0.0", + "version": "2.0.1", "source": { "type": "git", "url": "https://github.com/Codeception/module-cli.git", - "reference": "aa9bdd8346983eebc3aa3f21e902399ceefec372" + "reference": "a3a101fae4049fa2f810107f7bd5db3b3266ce63" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Codeception/module-cli/zipball/aa9bdd8346983eebc3aa3f21e902399ceefec372", - "reference": "aa9bdd8346983eebc3aa3f21e902399ceefec372", + "url": "https://api.github.com/repos/Codeception/module-cli/zipball/a3a101fae4049fa2f810107f7bd5db3b3266ce63", + "reference": "a3a101fae4049fa2f810107f7bd5db3b3266ce63", "shasum": "" }, "require": { "codeception/codeception": "*@dev", + "codeception/module-asserts": "*", "php": "^7.4 || ^8.0" }, "conflict": { @@ -13059,9 +13751,9 @@ ], "support": { "issues": "https://github.com/Codeception/module-cli/issues", - "source": "https://github.com/Codeception/module-cli/tree/2.0.0" + "source": "https://github.com/Codeception/module-cli/tree/2.0.1" }, - "time": "2021-12-01T01:21:55+00:00" + "time": "2023-01-13T18:41:03+00:00" }, { "name": "codeception/module-filesystem", @@ -13180,16 +13872,16 @@ }, { "name": "codeception/module-rest", - "version": "2.0.2", + "version": "2.0.3", "source": { "type": "git", "url": "https://github.com/Codeception/module-rest.git", - "reference": "9cbba128b3793779e7f4ede8c6255d72b1ea60a7" + "reference": "ee4ea06cd8a5057f24f37f8bf25b6815ddc77840" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Codeception/module-rest/zipball/9cbba128b3793779e7f4ede8c6255d72b1ea60a7", - "reference": "9cbba128b3793779e7f4ede8c6255d72b1ea60a7", + "url": "https://api.github.com/repos/Codeception/module-rest/zipball/ee4ea06cd8a5057f24f37f8bf25b6815ddc77840", + "reference": "ee4ea06cd8a5057f24f37f8bf25b6815ddc77840", "shasum": "" }, "require": { @@ -13198,7 +13890,7 @@ "ext-json": "*", "justinrainbow/json-schema": "~5.2.9", "php": "^7.4 | ^8.0", - "softcreatr/jsonpath": "^0.5 | ^0.7" + "softcreatr/jsonpath": "^0.5 | ^0.7 | ^0.8" }, "require-dev": { "codeception/lib-innerbrowser": "^2.0", @@ -13231,9 +13923,9 @@ ], "support": { "issues": "https://github.com/Codeception/module-rest/issues", - "source": "https://github.com/Codeception/module-rest/tree/2.0.2" + "source": "https://github.com/Codeception/module-rest/tree/2.0.3" }, - "time": "2022-03-30T05:42:11+00:00" + "time": "2023-03-10T19:23:22+00:00" }, { "name": "codeception/module-symfony", @@ -13501,16 +14193,16 @@ }, { "name": "myclabs/deep-copy", - "version": "1.11.0", + "version": "1.11.1", "source": { "type": "git", "url": "https://github.com/myclabs/DeepCopy.git", - "reference": "14daed4296fae74d9e3201d2c4925d1acb7aa614" + "reference": "7284c22080590fb39f2ffa3e9057f10a4ddd0e0c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/14daed4296fae74d9e3201d2c4925d1acb7aa614", - "reference": "14daed4296fae74d9e3201d2c4925d1acb7aa614", + "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/7284c22080590fb39f2ffa3e9057f10a4ddd0e0c", + "reference": "7284c22080590fb39f2ffa3e9057f10a4ddd0e0c", "shasum": "" }, "require": { @@ -13548,15 +14240,86 @@ ], "support": { "issues": "https://github.com/myclabs/DeepCopy/issues", - "source": "https://github.com/myclabs/DeepCopy/tree/1.11.0" + "source": "https://github.com/myclabs/DeepCopy/tree/1.11.1" + }, + "funding": [ + { + "url": "https://tidelift.com/funding/github/packagist/myclabs/deep-copy", + "type": "tidelift" + } + ], + "time": "2023-03-08T13:26:56+00:00" + }, + { + "name": "pavelmaksimov25/jsonpath", + "version": "0.2.1", + "source": { + "type": "git", + "url": "https://github.com/pavelmaksimov25/JSONPath.git", + "reference": "c25843b9173b01028f96bc766247196dd402298a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/pavelmaksimov25/JSONPath/zipball/c25843b9173b01028f96bc766247196dd402298a", + "reference": "c25843b9173b01028f96bc766247196dd402298a", + "shasum": "" + }, + "require": { + "ext-json": "*", + "php": ">7.4 || >=8.0" + }, + "replace": { + "softcreatr/jsonpath": "*" + }, + "require-dev": { + "phpunit/phpunit": "^9.6", + "roave/security-advisories": "dev-latest" + }, + "type": "library", + "autoload": { + "psr-4": { + "Flow\\JSONPath\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Stephen Frank", + "email": "stephen@flowsa.com", + "homepage": "https://prismaticbytes.com", + "role": "Developer" + }, + { + "name": "Sascha Greuel", + "email": "hello@1-2.dev", + "homepage": "https://1-2.dev", + "role": "Developer" + }, + { + "name": "Pavlo Maksymov", + "email": "hello@1-2.dev", + "homepage": "https://1-2.dev", + "role": "Developer" + } + ], + "description": "Fork of the JSONPath implementation for parsing, searching and flattening arrays", + "support": { + "source": "https://github.com/pavelmaksimov25/JSONPath/tree/0.2.1" }, "funding": [ { - "url": "https://tidelift.com/funding/github/packagist/myclabs/deep-copy", - "type": "tidelift" + "url": "https://ecologi.com/softcreatr?r=61212ab3fc69b8eb8a2014f4", + "type": "custom" + }, + { + "url": "https://github.com/softcreatr", + "type": "github" } ], - "time": "2022-03-03T13:19:32+00:00" + "time": "2023-05-25T13:51:59+00:00" }, { "name": "phar-io/manifest", @@ -13671,37 +14434,38 @@ }, { "name": "php-webdriver/webdriver", - "version": "1.13.1", + "version": "1.14.0", "source": { "type": "git", "url": "https://github.com/php-webdriver/php-webdriver.git", - "reference": "6dfe5f814b796c1b5748850aa19f781b9274c36c" + "reference": "3ea4f924afb43056bf9c630509e657d951608563" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-webdriver/php-webdriver/zipball/6dfe5f814b796c1b5748850aa19f781b9274c36c", - "reference": "6dfe5f814b796c1b5748850aa19f781b9274c36c", + "url": "https://api.github.com/repos/php-webdriver/php-webdriver/zipball/3ea4f924afb43056bf9c630509e657d951608563", + "reference": "3ea4f924afb43056bf9c630509e657d951608563", "shasum": "" }, "require": { "ext-curl": "*", "ext-json": "*", "ext-zip": "*", - "php": "^5.6 || ~7.0 || ^8.0", + "php": "^7.3 || ^8.0", "symfony/polyfill-mbstring": "^1.12", - "symfony/process": "^2.8 || ^3.1 || ^4.0 || ^5.0 || ^6.0" + "symfony/process": "^5.0 || ^6.0" }, "replace": { "facebook/webdriver": "*" }, "require-dev": { - "ondram/ci-detector": "^2.1 || ^3.5 || ^4.0", + "ergebnis/composer-normalize": "^2.20.0", + "ondram/ci-detector": "^4.0", "php-coveralls/php-coveralls": "^2.4", - "php-mock/php-mock-phpunit": "^1.1 || ^2.0", + "php-mock/php-mock-phpunit": "^2.0", "php-parallel-lint/php-parallel-lint": "^1.2", - "phpunit/phpunit": "^5.7 || ^7 || ^8 || ^9", + "phpunit/phpunit": "^9.3", "squizlabs/php_codesniffer": "^3.5", - "symfony/var-dumper": "^3.3 || ^4.0 || ^5.0 || ^6.0" + "symfony/var-dumper": "^5.0 || ^6.0" }, "suggest": { "ext-SimpleXML": "For Firefox profile creation" @@ -13730,29 +14494,29 @@ ], "support": { "issues": "https://github.com/php-webdriver/php-webdriver/issues", - "source": "https://github.com/php-webdriver/php-webdriver/tree/1.13.1" + "source": "https://github.com/php-webdriver/php-webdriver/tree/1.14.0" }, - "time": "2022-10-11T11:49:44+00:00" + "time": "2023-02-09T12:12:19+00:00" }, { "name": "phpunit/php-code-coverage", - "version": "9.2.17", + "version": "9.2.26", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-code-coverage.git", - "reference": "aa94dc41e8661fe90c7316849907cba3007b10d8" + "reference": "443bc6912c9bd5b409254a40f4b0f4ced7c80ea1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/aa94dc41e8661fe90c7316849907cba3007b10d8", - "reference": "aa94dc41e8661fe90c7316849907cba3007b10d8", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/443bc6912c9bd5b409254a40f4b0f4ced7c80ea1", + "reference": "443bc6912c9bd5b409254a40f4b0f4ced7c80ea1", "shasum": "" }, "require": { "ext-dom": "*", "ext-libxml": "*", "ext-xmlwriter": "*", - "nikic/php-parser": "^4.14", + "nikic/php-parser": "^4.15", "php": ">=7.3", "phpunit/php-file-iterator": "^3.0.3", "phpunit/php-text-template": "^2.0.2", @@ -13767,8 +14531,8 @@ "phpunit/phpunit": "^9.3" }, "suggest": { - "ext-pcov": "*", - "ext-xdebug": "*" + "ext-pcov": "PHP extension that provides line coverage", + "ext-xdebug": "PHP extension that provides line coverage as well as branch and path coverage" }, "type": "library", "extra": { @@ -13801,7 +14565,7 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/php-code-coverage/issues", - "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.17" + "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.26" }, "funding": [ { @@ -13809,7 +14573,7 @@ "type": "github" } ], - "time": "2022-08-30T12:24:04+00:00" + "time": "2023-03-06T12:58:08+00:00" }, { "name": "phpunit/php-file-iterator", @@ -14054,20 +14818,20 @@ }, { "name": "phpunit/phpunit", - "version": "9.5.25", + "version": "9.6.8", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "3e6f90ca7e3d02025b1d147bd8d4a89fd4ca8a1d" + "reference": "17d621b3aff84d0c8b62539e269e87d8d5baa76e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/3e6f90ca7e3d02025b1d147bd8d4a89fd4ca8a1d", - "reference": "3e6f90ca7e3d02025b1d147bd8d4a89fd4ca8a1d", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/17d621b3aff84d0c8b62539e269e87d8d5baa76e", + "reference": "17d621b3aff84d0c8b62539e269e87d8d5baa76e", "shasum": "" }, "require": { - "doctrine/instantiator": "^1.3.1", + "doctrine/instantiator": "^1.3.1 || ^2", "ext-dom": "*", "ext-json": "*", "ext-libxml": "*", @@ -14096,8 +14860,8 @@ "sebastian/version": "^3.0.2" }, "suggest": { - "ext-soap": "*", - "ext-xdebug": "*" + "ext-soap": "To be able to generate mocks based on WSDL files", + "ext-xdebug": "PHP extension that provides line coverage as well as branch and path coverage" }, "bin": [ "phpunit" @@ -14105,7 +14869,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "9.5-dev" + "dev-master": "9.6-dev" } }, "autoload": { @@ -14136,7 +14900,8 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/phpunit/issues", - "source": "https://github.com/sebastianbergmann/phpunit/tree/9.5.25" + "security": "https://github.com/sebastianbergmann/phpunit/security/policy", + "source": "https://github.com/sebastianbergmann/phpunit/tree/9.6.8" }, "funding": [ { @@ -14152,7 +14917,7 @@ "type": "tidelift" } ], - "time": "2022-09-25T03:44:45+00:00" + "time": "2023-05-11T05:14:45+00:00" }, { "name": "sebastian/cli-parser", @@ -14454,16 +15219,16 @@ }, { "name": "sebastian/environment", - "version": "5.1.4", + "version": "5.1.5", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/environment.git", - "reference": "1b5dff7bb151a4db11d49d90e5408e4e938270f7" + "reference": "830c43a844f1f8d5b7a1f6d6076b784454d8b7ed" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/1b5dff7bb151a4db11d49d90e5408e4e938270f7", - "reference": "1b5dff7bb151a4db11d49d90e5408e4e938270f7", + "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/830c43a844f1f8d5b7a1f6d6076b784454d8b7ed", + "reference": "830c43a844f1f8d5b7a1f6d6076b784454d8b7ed", "shasum": "" }, "require": { @@ -14505,7 +15270,7 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/environment/issues", - "source": "https://github.com/sebastianbergmann/environment/tree/5.1.4" + "source": "https://github.com/sebastianbergmann/environment/tree/5.1.5" }, "funding": [ { @@ -14513,7 +15278,7 @@ "type": "github" } ], - "time": "2022-04-03T09:37:03+00:00" + "time": "2023-02-03T06:03:51+00:00" }, { "name": "sebastian/exporter", @@ -14827,16 +15592,16 @@ }, { "name": "sebastian/recursion-context", - "version": "4.0.4", + "version": "4.0.5", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/recursion-context.git", - "reference": "cd9d8cf3c5804de4341c283ed787f099f5506172" + "reference": "e75bd0f07204fec2a0af9b0f3cfe97d05f92efc1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/cd9d8cf3c5804de4341c283ed787f099f5506172", - "reference": "cd9d8cf3c5804de4341c283ed787f099f5506172", + "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/e75bd0f07204fec2a0af9b0f3cfe97d05f92efc1", + "reference": "e75bd0f07204fec2a0af9b0f3cfe97d05f92efc1", "shasum": "" }, "require": { @@ -14875,10 +15640,10 @@ } ], "description": "Provides functionality to recursively process PHP variables", - "homepage": "http://www.github.com/sebastianbergmann/recursion-context", + "homepage": "https://github.com/sebastianbergmann/recursion-context", "support": { "issues": "https://github.com/sebastianbergmann/recursion-context/issues", - "source": "https://github.com/sebastianbergmann/recursion-context/tree/4.0.4" + "source": "https://github.com/sebastianbergmann/recursion-context/tree/4.0.5" }, "funding": [ { @@ -14886,7 +15651,7 @@ "type": "github" } ], - "time": "2020-10-26T13:17:30+00:00" + "time": "2023-02-03T06:07:39+00:00" }, { "name": "sebastian/resource-operations", @@ -14945,16 +15710,16 @@ }, { "name": "sebastian/type", - "version": "3.2.0", + "version": "3.2.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/type.git", - "reference": "fb3fe09c5f0bae6bc27ef3ce933a1e0ed9464b6e" + "reference": "75e2c2a32f5e0b3aef905b9ed0b179b953b3d7c7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/fb3fe09c5f0bae6bc27ef3ce933a1e0ed9464b6e", - "reference": "fb3fe09c5f0bae6bc27ef3ce933a1e0ed9464b6e", + "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/75e2c2a32f5e0b3aef905b9ed0b179b953b3d7c7", + "reference": "75e2c2a32f5e0b3aef905b9ed0b179b953b3d7c7", "shasum": "" }, "require": { @@ -14989,7 +15754,7 @@ "homepage": "https://github.com/sebastianbergmann/type", "support": { "issues": "https://github.com/sebastianbergmann/type/issues", - "source": "https://github.com/sebastianbergmann/type/tree/3.2.0" + "source": "https://github.com/sebastianbergmann/type/tree/3.2.1" }, "funding": [ { @@ -14997,7 +15762,7 @@ "type": "github" } ], - "time": "2022-09-12T14:47:03+00:00" + "time": "2023-02-03T06:13:03+00:00" }, { "name": "sebastian/version", @@ -15052,307 +15817,18 @@ ], "time": "2020-09-28T06:39:44+00:00" }, - { - "name": "sllh/composer-versions-check", - "version": "v2.0.5", - "source": { - "type": "git", - "url": "https://github.com/soullivaneuh/composer-versions-check.git", - "reference": "f86f69b25fd029466e3ca16036dfcac78a5f1ce3" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/soullivaneuh/composer-versions-check/zipball/f86f69b25fd029466e3ca16036dfcac78a5f1ce3", - "reference": "f86f69b25fd029466e3ca16036dfcac78a5f1ce3", - "shasum": "" - }, - "require": { - "composer-plugin-api": "^2.0", - "composer/semver": "^3.2.5", - "php": "^7.4 || ^8.0", - "symfony/console": "^3.4 || ^4.4 || ^5.0" - }, - "require-dev": { - "composer/composer": "^2.0", - "symfony/phpunit-bridge": "^5.3.3" - }, - "type": "composer-plugin", - "extra": { - "class": "SLLH\\ComposerVersionsCheck\\VersionsCheckPlugin", - "branch-alias": { - "dev-master": "2.x-dev" - } - }, - "autoload": { - "psr-4": { - "SLLH\\ComposerVersionsCheck\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Sullivan SENECHAL", - "email": "soullivaneuh@gmail.com" - } - ], - "description": "Checks if packages are up to date to last major versions after update", - "keywords": [ - "composer", - "plugin", - "update", - "versions" - ], - "support": { - "issues": "https://github.com/soullivaneuh/composer-versions-check/issues", - "source": "https://github.com/soullivaneuh/composer-versions-check/tree/v2.0.5" - }, - "time": "2021-07-12T14:38:48+00:00" - }, - { - "name": "softcreatr/jsonpath", - "version": "0.7.6", - "source": { - "type": "git", - "url": "https://github.com/SoftCreatR/JSONPath.git", - "reference": "e04c02cb78bcc242c69d17dac5b29436bf3e1076" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/SoftCreatR/JSONPath/zipball/e04c02cb78bcc242c69d17dac5b29436bf3e1076", - "reference": "e04c02cb78bcc242c69d17dac5b29436bf3e1076", - "shasum": "" - }, - "require": { - "ext-json": "*", - "php": ">=7.1,<8.2" - }, - "replace": { - "flow/jsonpath": "*" - }, - "require-dev": { - "phpunit/phpunit": ">=7.0", - "roave/security-advisories": "dev-latest", - "squizlabs/php_codesniffer": "^3.5" - }, - "type": "library", - "autoload": { - "psr-4": { - "Flow\\JSONPath\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Stephen Frank", - "email": "stephen@flowsa.com", - "homepage": "https://prismaticbytes.com", - "role": "Developer" - }, - { - "name": "Sascha Greuel", - "email": "hello@1-2.dev", - "homepage": "https://1-2.dev", - "role": "Developer" - } - ], - "description": "JSONPath implementation for parsing, searching and flattening arrays", - "support": { - "email": "hello@1-2.dev", - "forum": "https://github.com/SoftCreatR/JSONPath/discussions", - "issues": "https://github.com/SoftCreatR/JSONPath/issues", - "source": "https://github.com/SoftCreatR/JSONPath" - }, - "funding": [ - { - "url": "https://ecologi.com/softcreatr?r=61212ab3fc69b8eb8a2014f4", - "type": "custom" - }, - { - "url": "https://github.com/softcreatr", - "type": "github" - } - ], - "time": "2022-09-27T09:27:12+00:00" - }, - { - "name": "spryker-sdk/brancho", - "version": "dev-master", - "source": { - "type": "git", - "url": "https://github.com/spryker-sdk/brancho.git", - "reference": "c27f4d60dec5fe203ce490caa806a586485280fa" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/spryker-sdk/brancho/zipball/c27f4d60dec5fe203ce490caa806a586485280fa", - "reference": "c27f4d60dec5fe203ce490caa806a586485280fa", - "shasum": "" - }, - "require": { - "chobie/jira-api-restclient": "^2.0@dev", - "cocur/slugify": "^4.0", - "laminas/laminas-filter": "^2.9", - "php": ">=7.3", - "symfony-cmf/slugifier-api": "^2.0", - "symfony/console": "^5.0", - "symfony/options-resolver": "^5.0", - "symfony/process": "^5.0", - "symfony/yaml": "^5.0" - }, - "require-dev": { - "codeception/codeception": "^4.1", - "codeception/module-asserts": "^1.1", - "codeception/module-phpbrowser": "^1.0.0", - "mikey179/vfsstream": "^1.6", - "phpstan/phpstan": "^0.12.18", - "spryker/code-sniffer": "*", - "symfony/var-dumper": "^5.0" - }, - "default-branch": true, - "bin": [ - "bin/brancho" - ], - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0.x-dev" - } - }, - "autoload": { - "psr-4": { - "Brancho\\": "src/Brancho/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "proprietary" - ], - "description": "Builds nice branch names.", - "support": { - "issues": "https://github.com/spryker-sdk/brancho/issues", - "source": "https://github.com/spryker-sdk/brancho/tree/master" - }, - "time": "2021-12-08T09:43:14+00:00" - }, - { - "name": "spryker-sdk/security-checker", - "version": "0.1.2", - "source": { - "type": "git", - "url": "https://github.com/spryker-sdk/security-checker.git", - "reference": "560362239dac498166656699fe9ab25c4c70a462" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/spryker-sdk/security-checker/zipball/560362239dac498166656699fe9ab25c4c70a462", - "reference": "560362239dac498166656699fe9ab25c4c70a462", - "shasum": "" - }, - "require": { - "php": ">=7.3", - "symfony/console": "^4.0.0 || ^5.0.0", - "symfony/options-resolver": "^4.0.0 || ^5.0.0", - "symfony/process": "^4.0.0 || ^5.0.0" - }, - "require-dev": { - "phpstan/phpstan": "^1.2.0", - "slevomat/coding-standard": "^6.2", - "spryker/code-sniffer": "^0.15.6", - "squizlabs/php_codesniffer": "^3.5" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0.x-dev" - } - }, - "autoload": { - "psr-4": { - "SecurityChecker\\": "src/SecurityChecker/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "proprietary" - ], - "description": "A security checker for your composer.lock", - "support": { - "issues": "https://github.com/spryker-sdk/security-checker/issues", - "source": "https://github.com/spryker-sdk/security-checker/tree/0.1.2" - }, - "time": "2022-01-26T11:23:21+00:00" - }, - { - "name": "symfony-cmf/slugifier-api", - "version": "2.1.0", - "source": { - "type": "git", - "url": "https://github.com/symfony-cmf/slugifier-api.git", - "reference": "64e0b48bce38fb7e6b1bf284d4574fa183d1cc94" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony-cmf/slugifier-api/zipball/64e0b48bce38fb7e6b1bf284d4574fa183d1cc94", - "reference": "64e0b48bce38fb7e6b1bf284d4574fa183d1cc94", - "shasum": "" - }, - "require": { - "php": "^5.6|^7.0|^8.0" - }, - "require-dev": { - "symfony/phpunit-bridge": "^5.2" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.0-dev" - } - }, - "autoload": { - "psr-4": { - "Symfony\\Cmf\\Api\\Slugifier\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Symfony CMF Community", - "homepage": "https://github.com/symfony-cmf/slugifier-api/contributors" - } - ], - "description": "Provides a basic slugifier interface to transform text into strings suitable for URLs", - "homepage": "http://cmf.symfony.com", - "keywords": [ - "slugify", - "urlize" - ], - "support": { - "issues": "https://github.com/symfony-cmf/slugifier-api/issues", - "source": "https://github.com/symfony-cmf/slugifier-api/tree/2.1.0" - }, - "time": "2021-01-22T09:05:45+00:00" - }, { "name": "symfony/browser-kit", - "version": "v5.4.11", + "version": "v5.4.21", "source": { "type": "git", "url": "https://github.com/symfony/browser-kit.git", - "reference": "081fe28a26b6bd671dea85ef3a4b5003f3c88027" + "reference": "a866ca7e396f15d7efb6d74a8a7d364d4e05b704" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/browser-kit/zipball/081fe28a26b6bd671dea85ef3a4b5003f3c88027", - "reference": "081fe28a26b6bd671dea85ef3a4b5003f3c88027", + "url": "https://api.github.com/repos/symfony/browser-kit/zipball/a866ca7e396f15d7efb6d74a8a7d364d4e05b704", + "reference": "a866ca7e396f15d7efb6d74a8a7d364d4e05b704", "shasum": "" }, "require": { @@ -15395,7 +15871,7 @@ "description": "Simulates the behavior of a web browser, allowing you to make requests, click on links and submit forms programmatically", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/browser-kit/tree/v5.4.11" + "source": "https://github.com/symfony/browser-kit/tree/v5.4.21" }, "funding": [ { @@ -15411,20 +15887,20 @@ "type": "tidelift" } ], - "time": "2022-07-27T15:50:05+00:00" + "time": "2023-02-14T08:03:56+00:00" }, { "name": "symfony/css-selector", - "version": "v5.4.11", + "version": "v5.4.21", "source": { "type": "git", "url": "https://github.com/symfony/css-selector.git", - "reference": "c1681789f059ab756001052164726ae88512ae3d" + "reference": "95f3c7468db1da8cc360b24fa2a26e7cefcb355d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/css-selector/zipball/c1681789f059ab756001052164726ae88512ae3d", - "reference": "c1681789f059ab756001052164726ae88512ae3d", + "url": "https://api.github.com/repos/symfony/css-selector/zipball/95f3c7468db1da8cc360b24fa2a26e7cefcb355d", + "reference": "95f3c7468db1da8cc360b24fa2a26e7cefcb355d", "shasum": "" }, "require": { @@ -15461,7 +15937,7 @@ "description": "Converts CSS selectors to XPath expressions", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/css-selector/tree/v5.4.11" + "source": "https://github.com/symfony/css-selector/tree/v5.4.21" }, "funding": [ { @@ -15477,20 +15953,20 @@ "type": "tidelift" } ], - "time": "2022-06-27T16:58:25+00:00" + "time": "2023-02-14T08:03:56+00:00" }, { "name": "symfony/dom-crawler", - "version": "v5.4.12", + "version": "v5.4.23", "source": { "type": "git", "url": "https://github.com/symfony/dom-crawler.git", - "reference": "291c1e92281a09152dda089f782e23dedd34bd4f" + "reference": "4a286c916b74ecfb6e2caf1aa31d3fe2a34b7e08" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/dom-crawler/zipball/291c1e92281a09152dda089f782e23dedd34bd4f", - "reference": "291c1e92281a09152dda089f782e23dedd34bd4f", + "url": "https://api.github.com/repos/symfony/dom-crawler/zipball/4a286c916b74ecfb6e2caf1aa31d3fe2a34b7e08", + "reference": "4a286c916b74ecfb6e2caf1aa31d3fe2a34b7e08", "shasum": "" }, "require": { @@ -15536,7 +16012,7 @@ "description": "Eases DOM navigation for HTML and XML documents", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/dom-crawler/tree/v5.4.12" + "source": "https://github.com/symfony/dom-crawler/tree/v5.4.23" }, "funding": [ { @@ -15552,7 +16028,7 @@ "type": "tidelift" } ], - "time": "2022-08-03T13:09:21+00:00" + "time": "2023-04-08T21:20:19+00:00" }, { "name": "theseer/tokenizer", @@ -15605,20 +16081,12 @@ "time": "2021-07-28T10:34:58+00:00" } ], - "aliases": [ - { - "package": "spryker-sdk/spryk", - "version": "9999999-dev", - "alias": "0.4.6", - "alias_normalized": "0.4.6.0" - } - ], + "aliases": [], "minimum-stability": "dev", "stability-flags": { + "spryker-sdk/brancho": 20, "spryker-sdk/composer-replace": 20, - "spryker-sdk/spryk": 20, - "spryker-sdk/upgrader": 20, - "spryker-sdk/brancho": 20 + "spryker-sdk/upgrader": 20 }, "prefer-stable": true, "prefer-lowest": false, diff --git a/config/bundles.php b/config/bundles.php index 6e99517ea..979af8320 100644 --- a/config/bundles.php +++ b/config/bundles.php @@ -13,4 +13,5 @@ Symfony\Bundle\TwigBundle\TwigBundle::class => ['all' => true], SprykerSdk\Sdk\Presentation\RestApi\SprykerSdkRestApiBundle::class => ['all' => true], Nelmio\ApiDocBundle\NelmioApiDocBundle::class => ['all' => true], + SprykerSdk\Evaluator\EvaluatorBundle::class => ['all' => true], ]; diff --git a/config/packages/http_discovery.yaml b/config/packages/http_discovery.yaml new file mode 100644 index 000000000..2a789e73c --- /dev/null +++ b/config/packages/http_discovery.yaml @@ -0,0 +1,10 @@ +services: + Psr\Http\Message\RequestFactoryInterface: '@http_discovery.psr17_factory' + Psr\Http\Message\ResponseFactoryInterface: '@http_discovery.psr17_factory' + Psr\Http\Message\ServerRequestFactoryInterface: '@http_discovery.psr17_factory' + Psr\Http\Message\StreamFactoryInterface: '@http_discovery.psr17_factory' + Psr\Http\Message\UploadedFileFactoryInterface: '@http_discovery.psr17_factory' + Psr\Http\Message\UriFactoryInterface: '@http_discovery.psr17_factory' + + http_discovery.psr17_factory: + class: Http\Discovery\Psr17Factory diff --git a/config/packages/monolog.yaml b/config/packages/monolog.yaml index 9b276f7a5..d3a1aebe1 100644 --- a/config/packages/monolog.yaml +++ b/config/packages/monolog.yaml @@ -45,3 +45,19 @@ when@prod: type: console process_psr_3_messages: false channels: ["!event", "!doctrine"] + +when@sprykerci: + monolog: + handlers: + main: + type: fingers_crossed + action_level: error + handler: newrelic + excluded_http_codes: [404, 405] + buffer_size: 50 # How many messages should be saved? Prevent memory leaks + newrelic: + type: newrelic + app_name: '%env(NEWRELIC_APPNAME)%' + channels: ["!event"] + level: error + formatter: 'logger_new_relic_formatter' diff --git a/config/packages/workflow.yaml b/config/packages/workflow.yaml index e36b02296..e3ec81528 100644 --- a/config/packages/workflow.yaml +++ b/config/packages/workflow.yaml @@ -90,7 +90,7 @@ framework: from: [openapi-created, asyncapi-created] to: app-validated metadata: - task: install + task: project:installer:run ValidateProject: from: [app-validated, asyncapi-created] to: done diff --git a/config/routes.yaml b/config/routes.yaml index ba18457fd..962da6a7e 100644 --- a/config/routes.yaml +++ b/config/routes.yaml @@ -2,3 +2,5 @@ rest_api: prefix: '/api/v1' name_prefix: 'api_v1_' resource: "@SprykerSdkRestApiBundle/Resources/config/routing_v1.yaml" + defaults: + _rest_api: ~ diff --git a/config/services.yaml b/config/services.yaml index 3a3934a44..2357274e6 100644 --- a/config/services.yaml +++ b/config/services.yaml @@ -17,10 +17,10 @@ services: exclude: '../app/{DependencyInjection,Entity,Tests,Kernel.php}' SprykerSdk\Sdk\Core\: resource: '../src/Core' - exclude: '../src/{DependencyInjection,Entity,Enum,Tests,Kernel.php}' + exclude: '../src/Core/{DependencyInjection,Entity,Enum,Tests,Kernel.php}' SprykerSdk\Sdk\Infrastructure\: resource: '../src/Infrastructure' - exclude: '../src/{DependencyInjection,Entity,Tests,Kernel.php}' + exclude: '../src/Infrastructure/{DependencyInjection,Entity,Tests,Kernel.php}' SprykerSdk\Sdk\Presentation\Console\: resource: '../src/Presentation/Console' - exclude: '../src/{DependencyInjection,Entity,Tests,Kernel.php}' + exclude: '../src/Presentation/Console/{DependencyInjection,Entity,Tests,Kernel.php}' diff --git a/config/services_sprykerci.yaml b/config/services_sprykerci.yaml new file mode 100644 index 000000000..986123423 --- /dev/null +++ b/config/services_sprykerci.yaml @@ -0,0 +1,23 @@ +parameters: + env(ORGANIZATION_NAME): 'spryker' + env(REPOSITORY_NAME): 'spryker-sdk' + env(CI_WORKSPACE_NAME): '-' + env(CI_EXECUTION_ID): '-' + new_relic_transaction_name: '%env(CI_WORKSPACE_NAME)%/%env(ORGANIZATION_NAME)%/%env(REPOSITORY_NAME)%' +services: + logger_transaction_name_new_relic_processor: + class: SprykerSdk\Sdk\Infrastructure\Logger\TransactionNameNewRelicProcessor + arguments: [ '%new_relic_transaction_name%' ] + tags: + - { name: monolog.processor, handler: newrelic } + + logger_new_relic_formatter: + class: SprykerSdk\Sdk\Infrastructure\Logger\NewRelicFormatter + arguments: + - '%env(CI_WORKSPACE_NAME)%' + - '%env(CI_EXECUTION_ID)%' + + metric_sender.new_relic_sender_client: + class: SprykerSdk\Sdk\Infrastructure\MetricsSender\NewRelicMetricSenderClient + arguments: [ '%new_relic_transaction_name%' ] + tags: [ 'metric_sender_client' ] diff --git a/docker-compose.yml b/docker-compose.yml index 92cf4de1f..ed18c4616 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,29 +1,29 @@ version: '3' services: - spryker-sdk: - image: spryker/php-sdk-local:${SDK_VERSION:-latest} - network_mode: "host" - build: - context: ./ - dockerfile: ./infrastructure/sdk.local.Dockerfile - args: - USER_UID: ${USER_UID} - SDK_VERSION: ${SDK_VERSION:-latest} - working_dir: "/project" - env_file: - - ./infrastructure/env/.env - environment: - APP_ENV: prod - APP_DEBUG: 0 - volumes: - - $PWD:/project:rw - - ./db:/data/db:rw - - ./var/log:/data/var/log:rw - - ./extension:/data/extension:rw - - ./VERSION:/data/VERSION:rw - - ./config/packages/workflow.yaml:/data/config/packages/workflow.yaml:rw - - ~/.ssh:/home/spryker/.ssh:ro - - ./.gitmodules:/data/.gitmodules:rw + spryker-sdk: + image: spryker/php-sdk-local:${SDK_VERSION:-latest} + network_mode: "host" + build: + context: ./ + dockerfile: ./infrastructure/sdk.local.Dockerfile + args: + USER_UID: ${USER_UID} + SDK_VERSION: ${SDK_VERSION:-latest} + working_dir: "/project" + env_file: + - ./infrastructure/env/.env + environment: + APP_ENV: prod + APP_DEBUG: 0 + volumes: + - $PWD:/project:rw + - ./db:/data/db:rw + - ./var/log:/data/var/log:rw + - ./extension:/data/extension:rw + - ./VERSION:/data/VERSION:rw + - ./config/packages/workflow.yaml:/data/config/packages/workflow.yaml:rw + - ~/.ssh:/home/spryker/.ssh:ro + - ./.gitmodules:/data/.gitmodules:rw volumes: - project: + project: diff --git a/docs/conventions.md b/docs/conventions.md index 953890558..33d8c9ca0 100644 --- a/docs/conventions.md +++ b/docs/conventions.md @@ -70,10 +70,6 @@ A console command must meet the following conditions: - `protected static $defaultName` __SHOULD NOT__ be used because of performance reasons and future deprecation in Symfony 6.1 version. Instead `protected const NAME` __SHOULD__ be provided and passed to the parent constructor as a parameter. -## Controller - -- Controller __MUST__ have only one method `__invoke` - ## Naming conventions There are the following conventions for naming entities: @@ -96,8 +92,7 @@ Contracts must meet the following conditions: ## REST API - Controller __SHOULD__ have no business logic. -- Controller __SHOULD__ be named by template of task's id. - For example, for the task `validation:php:codestyle` - the controller name should be `ValidatePhpCodestyleController` and controller's action should be `__invoke`. +- Controller __MUST__ have only one action method `__invoke`. - Controller __MUST__ be placed in namespace `SprykerSdk\Sdk\Presentation\RestApi\Controller\v1`. The `v1` is current version of SDK API. - Route __MUST__ be placed in `src/Presentation/RestApi/Resources/routing.yaml` - Route __SHOULD__ be named by template `api_${version}_${controller_name}`. diff --git a/docs/extending_the_sdk.md b/docs/extending_the_sdk.md index 7299c6e0f..7728476ee 100644 --- a/docs/extending_the_sdk.md +++ b/docs/extending_the_sdk.md @@ -4,8 +4,8 @@ The SDK offers different extension points to enable third parties to contribute From simple to complex, the SDK can be extended by: -- Providing additional tasks or settings via YAML definition placed inside `/extension//Task/.yaml`. Those tasks can't introduce additional dependencies and are best suited to integrate existing tools that come with a standalone executable. -- Providing additional tasks, value resolvers, or settings via the PHP implementation placed inside `/extension//Task/.php`. Those tasks need to implement the [TaskInterface](https://github.com/spryker-sdk/sdk-contracts/blob/master/src/Entity/TaskInterface.php) and need to be exposed by providing a Symfony bundle to the Spryker SDK, such as `/extension//Bundle.php`, following the conventions of a [Symfony bundle](https://symfony.com/doc/current/bundles.html#creating-a-bundle). This approach is best suited for more complex tasks that don't require additional dependencies, for example, validating content of a YAML file by using Symphony validators. +- Providing additional tasks or settings via YAML definitions placed inside `/extension//Task/.yaml`. Those tasks can't introduce additional dependencies and are best suited to integrate existing tools that come with a standalone executable. +- Providing additional tasks, value resolvers, or settings via the PHP implementation placed inside `/extension//Task/.php`. Those tasks need to implement the [TaskInterface](https://github.com/spryker-sdk/sdk-contracts/blob/master/src/Entity/TaskInterface.php), and need to be exposed by providing a Symfony bundle to the Spryker SDK, such as `/extension//Bundle.php`, following the conventions of a [Symfony bundle](https://symfony.com/doc/current/bundles.html#creating-a-bundle). This approach is best suited for more complex tasks that don't require additional dependencies, for example validating the content of a YAML file by using Symfony validators. - Providing additional tasks, value resolvers, or settings that come with additional dependencies. This approach follows the same guideline as the previous approach with the PHP implementation but requires building your own [SDK docker image](./build.md) that includes those dependencies. To extend the SDK, follow these steps. @@ -14,12 +14,12 @@ To extend the SDK, follow these steps. A *task* is the execution of a very specific function. For example, executing an external tool through a CLI call is a task. -There are two possibilities to define a new task: based on YAML for simple task definitions, and -implementation via PHP and Symfony services for specialized purposes. +There are two possibilities when it comes to defining a new task: having it be based on YAML for simple task definitions, or +an implementation via PHP and Symfony services for specialized purposes. ### Implementation via YAML definition -YAML-based tasks need to fulfill a defined structure so you can execute them from the SDK. +YAML based tasks need to fulfill a defined structure so you can execute them from the SDK. The command defined in the YAML definition can have [placeholders](#implement-placeholders) that you need to define in the placeholder section. Each placeholder needs to map to one [value resolver](#add-a-value-resolver). Add the definition for your task in `/Task/.yaml`: @@ -35,7 +35,7 @@ type: string #e.g.: local_cli version: string #e.g.: 1.0.0 placeholders: - name: string #e.g.: %project_dir% - value_resolver: string #e.g.: PROJECT_DIR, mapping to a value resolver with id PROJECT_DIR or a FQCN + value_resolver: string #e.g.: PROJECT_DIR, mapping to a value resolver with id PROJECT_DIR or a FQCN optional: bool ``` @@ -47,10 +47,10 @@ You can add the tasks located in `extension//Task` to the S ### Implementation via a PHP class -In case when a task is more than just a call to an existing tool, you can implement the task as a PHP class and register the task using the Symfony service tagging feature. +If a task is more than just a call to an existing tool, you can implement the task as a PHP class and register it using the Symfony service tagging feature. This requires you to make the task a part of the Symfony bundle. To achieve this, follow these steps: -1. Create s Symfony bundle.
+1. Create a Symfony bundle.
Refer to the [official Symfony documentation](https://symfony.com/doc/current/bundles.html) for details on how to do that. {% info_block infoBox "Info" %} @@ -102,7 +102,7 @@ class YourTask implements TaskInterface ``` 3. Implement the command.
-While the task definition serves as a general description of the task and maps placeholders to value resolvers, a *command* serves as a function that is executed along with the resolved placeholders. +While a task definition serves as a general description of the task and maps placeholders to value resolvers, a *command* serves as a function that is executed along with the resolved placeholders. Implement the command as shown in the example: @@ -156,13 +156,13 @@ class YourCommand implements ExecutableCommandInterface 4. Implement placeholders.
Placeholders are resolved at runtime by using a specified value resolver. -A placeholder needs a specific name that is not used anywhere in the command the placeholder is used for. +A placeholder needs a specific name that is not used anywhere else in the command the placeholder is used for. {% info_block infoBox "Info" %} You can append `%` and suffix the placeholder, which makes the placeholder easier to recognize in a command. -You can reference the used value resolver by its ID or the fully qualified class name (FQCN), whereas the FQCN is preferred. +You can reference the used value resolver by its ID or the fully qualified class name (FQCN). The FQCN is the preferred option. {% endinfo_block %} @@ -284,7 +284,7 @@ class YourValueResolver implements ValueResolverInterface } ``` -You can define a value resolver as a Symfony service, for example, to be able to inject services into it. If the value resolver is not defined as a service, it is instantiated by its FQCN. +You can define a value resolver as a Symfony service, for example to be able to inject services into it. If the value resolver is not defined as a service, it is instantiated by its FQCN. Example of defining a value resolver as a Symfony service: @@ -297,7 +297,7 @@ services: ## 3. Add a setting -A bundle can add more settings that value resolvers can use to create a persistent behavior. +A bundle can add more settings that value resolvers can then use to create a persistent behavior. You can define settings in the `settings.yaml` file and add them to the SDK by calling `spryker-sdk setting:set setting_dirs `: @@ -365,9 +365,9 @@ Optionally, you can overwrite the existing command runners with a more suitable class: \CommandRunners\BetterLocalCliRunner ``` -## 5. Generate task by a CLI command +## 5. Generate a task by a CLI command -It might be useful to generate task via CLI command. +It might be useful to generate a task by using a CLI command. ```shell # generate yaml task @@ -382,5 +382,5 @@ After execution of the command task will be created in such directories: - `extension/Custom/src/Resources/config/task` - for yaml tasks - `extension/Custom/src/Task` - for php tasks -You can manually update it if it's needed (don't forget increase task version and run `spryker-sdk sdk:update:all` to make new updates available). +You can manually update it if it's needed. Don't forget to increase the task version and run `spryker-sdk sdk:update:all` to make new updates available. diff --git a/docs/telemetry.md b/docs/telemetry.md index 4d24f6f50..002ad8258 100644 --- a/docs/telemetry.md +++ b/docs/telemetry.md @@ -26,10 +26,10 @@ parameters: ``` ## Events -To implement custom events or extend the current ones, you must implement the following interfaces: +To implement custom events or extend current ones, you must implement the following interfaces: `SprykerSdk\SdkContracts\Entity\Telemetry\TelemetryEventInterface` - generic event data. -`SprykerSdk\SdkContracts\Entity\Telemetry\TelemetryEventPayloadInterface` - event-specific data. +`SprykerSdk\SdkContracts\Entity\Telemetry\TelemetryEventPayloadInterface` - event specific data. `SprykerSdk\SdkContracts\Entity\Telemetry\TelemetryEventMetadataInterface` - event metadata. ## Event transport @@ -44,14 +44,15 @@ To filter the appropriate events, `\SprykerSdk\Sdk\Infrastructure\Event\Telemetr ## Metadata Project settings `developer_email` and `developer_github_account` are used for user identification. -The project `composer.json` is used to populate the project name. All this data is sent in the event metadata. +The project `composer.json` is used to populate the project name. All this data is sent in the event's metadata. ## How to disable telemetry By default, telemetry is enabled. To disable it, set `TELEMETRY_ENABLED=false` in the `env` variable or update the `.env` file. ## Using in CI -To run SDK in a CI it must be executed with `SDK_CI_EXECUTION=1` env variable and with `-n` (non-interactive) flag. +To run SDK in a CI, it must be executed with the `SDK_CI_EXECUTION=1` env variable and with a `-n` (non-interactive) flag. Example: + ```shell SDK_CI_EXECUTION=1 spryker-sdk sdk:init:sdk -n ``` diff --git a/docs/troubleshooting.md b/docs/troubleshooting.md new file mode 100644 index 000000000..9237468ef --- /dev/null +++ b/docs/troubleshooting.md @@ -0,0 +1,7 @@ +# Troubleshooting + +## `spryker-sdk` command not found +`spryker-sdk` is an alias that uses the {sdk_folder}/bin/spryker-sdk.sh script. +If the `spryker-sdk` alias doesn't exist, please add it manually to your shell rc file. Depending on your shell it can be `~/.bashrc`, `~/.zshrc`, `~/.profile`, and other names. +`echo alias spryker-sdk={sdk_folder}/bin/spryker-sdk.sh` +Run `source {rc file}` to load the `spryker-sdk` alias for the current session. diff --git a/docs/value_resolver.md b/docs/value_resolver.md index b8bf92e41..96b076fac 100644 --- a/docs/value_resolver.md +++ b/docs/value_resolver.md @@ -2,22 +2,21 @@ The Spryker SDK has the following value resolvers: -| Value Resolver name | Description | -|---------------------|------------------------------------------------------------------------------------------------------| -| APP_PHP_VERSION | Resolves the PHP version (7.4, 8.0). | -| APP_TYPE | Resolves a repository for creating a project. | -| ARRAY_OPTION | Resolves multi-options. | -| B2BC_TYPE | Resolves repository for public b2b,b2c. | -| CONFIG_PATH | Resolves a relative path by priority: `project` path, then, by default, the `sdk` path if it exists. | -| FLAG | Resolves flag options. This resolver has the boolean type. | -| NAMESPACE | Used for the spryk tool to resolve namespcases for the tool. It is based on settings. | -| PC_SYSTEM | Resolves operating systems like Linux, Mac, Mac (ARM). | -| PRIORITY_PATH | Resolves relative path for the tool entry point: `project` path, then, by default, the `sdk` path if it exists. | -| REPORT_DIR | Resolves the report file path. | -| SDK_DIR | Resolves the path to the sdk folder. | -| CORE | Resolves the core level. This resolver is based on the resolved values of the `NAMESPACE` resolver. | -| STATIC | This resolver is used as a universal value resolver with additional settings. It returns the formatted value. | -| ORIGIN | This resolver is used as a universal value resolver with additional settings. It returns the original value. | +| Value Resolver name | Description | +|--------------------------|------------------------------------------------------------------------------------------------------| +| APP_PHP_VERSION | Resolves the PHP version (7.4, 8.0). | +| APP_TYPE | Resolves a repository for creating a project. | +| B2BC_TYPE | Resolves a repository for public b2b or b2c. | +| CONFIG_PATH (depricated) | Resolves a relative path by priority: `project` path, then, by default, the `sdk` path if it exists. | +| FLAG | Resolves flag options. This resolver has the boolean type. | +| NAMESPACE | Used for the spryk tool to resolve namespaces for the tool. It is based on settings. | +| PC_SYSTEM | Resolves the operating system like Linux, Mac, Mac (ARM). | +| PRIORITY_PATH | Resolves the relative path for the tool entry point: `project` path, then, by default, the `sdk` path if it exists. | +| REPORT_DIR | Resolves the report file path. | +| SDK_DIR | Resolves the path to the sdk folder. | +| CORE | Resolves the core level. This resolver is based on the resolved values of the `NAMESPACE` resolver. | +| STATIC | This resolver is used as a universal value resolver with additional settings. It returns the formatted value. | +| ORIGIN | This resolver is used as a universal value resolver with additional settings. It returns the original value. | Example of a placeholder with the `STATIC` value resolver and with the configuration. See [conventions](conventions.md#Placeholder) for details: diff --git a/docs/vcs.md b/docs/vcs.md index a178c4efe..dae20e30f 100644 --- a/docs/vcs.md +++ b/docs/vcs.md @@ -1,14 +1,14 @@ -# Vcs Connector +# VCS Connector -Vcs connector is a feature that lets you use different vcs system with one commands interface. +VCS Connector is a feature that lets you use a different VCS system with a single command interface. -## How to run a vcs +## How to run a VCS Use the following commands for tasks: - To run a task: `spryker-sdk vcs:clone` - After executing the command, you will be prompted to fill in the repository and select a specific vcs. -## Where to find cloned project +## Where to find the cloned project All project will be cloned in temporary `var/tmp` directory. diff --git a/extension/InspectionDoc/.gitignore b/extension/InspectionDoc/.gitignore new file mode 100644 index 000000000..62f907829 --- /dev/null +++ b/extension/InspectionDoc/.gitignore @@ -0,0 +1,4 @@ +###> codeception ### +tests/_output/ +tests/_support/_generated/ +###< codeception ### diff --git a/extension/InspectionDoc/codeception.yml b/extension/InspectionDoc/codeception.yml new file mode 100644 index 000000000..07aa4d93b --- /dev/null +++ b/extension/InspectionDoc/codeception.yml @@ -0,0 +1,22 @@ +namespace: InspectionDoc\Tests +suites: + unit: + path: Unit + actor: UnitTester + modules: + enabled: + - Asserts + step_decorators: ~ +settings: + shuffle: true + lint: true +paths: + tests: tests + output: tests/_output + support: tests/_support + data: tests + +coverage: + enabled: true + include: + - /src/* diff --git a/extension/InspectionDoc/src/DependencyInjection/InspectionDocExtension.php b/extension/InspectionDoc/src/DependencyInjection/InspectionDocExtension.php new file mode 100644 index 000000000..e839c50ce --- /dev/null +++ b/extension/InspectionDoc/src/DependencyInjection/InspectionDocExtension.php @@ -0,0 +1,37 @@ +createYamlFileLoader($container)->load('services.yaml'); + } + + /** + * @param \Symfony\Component\DependencyInjection\ContainerBuilder $container + * + * @return \Symfony\Component\DependencyInjection\Loader\YamlFileLoader + */ + protected function createYamlFileLoader(ContainerBuilder $container): YamlFileLoader + { + return new YamlFileLoader($container, new FileLocator(__DIR__ . '/../Resources/config')); + } +} diff --git a/extension/InspectionDoc/src/Entity/InspectionDoc.php b/extension/InspectionDoc/src/Entity/InspectionDoc.php new file mode 100644 index 000000000..e3a7bcf1b --- /dev/null +++ b/extension/InspectionDoc/src/Entity/InspectionDoc.php @@ -0,0 +1,47 @@ +id = $id; + $this->link = $link; + } + + /** + * @return string + */ + public function getId(): string + { + return $this->id; + } + + /** + * @return string + */ + public function getLink(): string + { + return $this->link; + } +} diff --git a/extension/InspectionDoc/src/Entity/InspectionDocInterface.php b/extension/InspectionDoc/src/Entity/InspectionDocInterface.php new file mode 100644 index 000000000..ffeb69498 --- /dev/null +++ b/extension/InspectionDoc/src/Entity/InspectionDocInterface.php @@ -0,0 +1,21 @@ +> + */ + public function getInspectionDocs(): array; +} diff --git a/extension/InspectionDoc/src/Infrastructure/Loader/JsonFileInspectionDocDataLoader.php b/extension/InspectionDoc/src/Infrastructure/Loader/JsonFileInspectionDocDataLoader.php new file mode 100644 index 000000000..40f59a1c1 --- /dev/null +++ b/extension/InspectionDoc/src/Infrastructure/Loader/JsonFileInspectionDocDataLoader.php @@ -0,0 +1,83 @@ +inspectionDocDataFilePath = $inspectionDocDataFilePath; + $this->logger = $logger; + } + + /** + * @return array> + */ + public function getInspectionDocs(): array + { + if ($this->loadedDocs !== null) { + return $this->loadedDocs; + } + + $this->loadedDocs = []; + + if (!file_exists($this->inspectionDocDataFilePath)) { + return $this->loadedDocs; + } + + $loadedDocs = file_get_contents($this->inspectionDocDataFilePath); + + if ($loadedDocs === false) { + $this->logger->error( + sprintf('Unable to load doc file `%s` error `%s`', $this->inspectionDocDataFilePath, error_get_last()['message'] ?? ''), + ); + + return $this->loadedDocs; + } + + try { + $loadedDocsJson = json_decode($loadedDocs, true, 512, \JSON_THROW_ON_ERROR); + } catch (JsonException $e) { + $this->logger->error($e->getMessage()); + + return $this->loadedDocs; + } + + foreach ($loadedDocsJson as $inspectionDoc) { + if (!isset($inspectionDoc['inspectionId'])) { + continue; + } + + $this->loadedDocs[$inspectionDoc['inspectionId']] = $inspectionDoc; + } + + return $this->loadedDocs; + } +} diff --git a/extension/InspectionDoc/src/Infrastructure/Reader/InspectionDocReader.php b/extension/InspectionDoc/src/Infrastructure/Reader/InspectionDocReader.php new file mode 100644 index 000000000..00aef803d --- /dev/null +++ b/extension/InspectionDoc/src/Infrastructure/Reader/InspectionDocReader.php @@ -0,0 +1,112 @@ + + */ + protected array $inspectionDocsCache = []; + + /** + * @var \InspectionDoc\Infrastructure\Loader\InspectionDocDataLoaderInterface + */ + protected InspectionDocDataLoaderInterface $inspectionDocDataLoader; + + /** + * @param \InspectionDoc\Infrastructure\Loader\InspectionDocDataLoaderInterface $inspectionDocDataLoader + */ + public function __construct(InspectionDocDataLoaderInterface $inspectionDocDataLoader) + { + $this->inspectionDocDataLoader = $inspectionDocDataLoader; + } + + /** + * @param string $errorCode + * + * @return \InspectionDoc\Entity\InspectionDocInterface|null + */ + public function findByErrorCode(string $errorCode): ?InspectionDocInterface + { + $indexedInspectionDocs = $this->inspectionDocDataLoader->getInspectionDocs(); + + $inspectionId = $this->findInspectionIdByErrorCode(array_keys($indexedInspectionDocs), $errorCode); + + if ($inspectionId === null) { + return null; + } + + $inspectionDoc = $indexedInspectionDocs[$inspectionId]; + + return $this->createInspectionDoc($inspectionId, $inspectionDoc); + } + + /** + * @param array $inspectionsIds + * @param string $errorCode + * + * @return string|null + */ + protected function findInspectionIdByErrorCode(array $inspectionsIds, string $errorCode): ?string + { + $inspectionIdCandidates = []; + + foreach ($inspectionsIds as $inspectionsId) { + if (!$this->strStartsWith($errorCode, $inspectionsId)) { + continue; + } + + $inspectionIdCandidates[] = $inspectionsId; + } + + return $this->getMaxLengthMatch($inspectionIdCandidates); + } + + /** + * @param string $haystack + * @param string $needle + * + * @return bool + */ + protected function strStartsWith(string $haystack, string $needle): bool + { + return strncmp($haystack, $needle, mb_strlen($needle)) === 0; + } + + /** + * @param array $inspectionsIds + * + * @return string|null + */ + protected function getMaxLengthMatch(array $inspectionsIds): ?string + { + usort($inspectionsIds, static fn (string $a, string $b): int => -1 * (mb_strlen($a) <=> mb_strlen($b))); + + return $inspectionsIds[0] ?? null; + } + + /** + * @param string $inspectionId + * @param array $inspectionDocData + * + * @return \InspectionDoc\Entity\InspectionDocInterface + */ + protected function createInspectionDoc(string $inspectionId, array $inspectionDocData): InspectionDocInterface + { + if (!isset($this->inspectionDocsCache[$inspectionId])) { + $this->inspectionDocsCache[$inspectionId] = new InspectionDoc($inspectionId, $inspectionDocData['link'] ?? ''); + } + + return $this->inspectionDocsCache[$inspectionId]; + } +} diff --git a/extension/InspectionDoc/src/Infrastructure/Reader/InspectionDocReaderInterface.php b/extension/InspectionDoc/src/Infrastructure/Reader/InspectionDocReaderInterface.php new file mode 100644 index 000000000..8ffe032f0 --- /dev/null +++ b/extension/InspectionDoc/src/Infrastructure/Reader/InspectionDocReaderInterface.php @@ -0,0 +1,20 @@ +inspectionDocReader = $inspectionDocReader; + $this->inspectionDocUrl = $inspectionDocUrl; + } + + /** + * @param \SprykerSdk\SdkContracts\Report\Violation\ViolationInterface $violation + * + * @return \SprykerSdk\SdkContracts\Report\Violation\ViolationInterface + */ + public function decorate(ViolationInterface $violation): ViolationInterface + { + $newViolation = new Violation( + $violation->getId(), + $this->decorateMessage($violation->getMessage(), $violation->getAdditionalAttributes()), + ); + + $newViolation->setClass($violation->getClass()) + ->setMethod($violation->getMethod()) + ->setAttributes($violation->getAdditionalAttributes()) + ->setFix($violation->getFix()) + ->setFixable($violation->isFixable()) + ->setProduced($violation->producedBy()) + ->setStartColumn($violation->getStartColumn()) + ->setEndColumn($violation->getEndColumn()) + ->setStartLine($violation->getStartLine()) + ->setEndLine($violation->getEndLine()) + ->setPriority($violation->priority()) + ->setSeverity($violation->getSeverity()); + + return $newViolation; + } + + /** + * @param string $message + * @param array $attributes + * + * @return string + */ + protected function decorateMessage(string $message, array $attributes): string + { + if (!isset($attributes['inspectionId'])) { + return $message; + } + + $inspectionId = trim($attributes['inspectionId']); + + if ($inspectionId === '') { + return $message; + } + + $inspectionDoc = $this->inspectionDocReader->findByErrorCode($inspectionId); + + if ($inspectionDoc === null) { + return $message; + } + + $link = trim($inspectionDoc->getLink()); + + if ($link === '') { + return $message; + } + + return $message . PHP_EOL . 'More information: ' . $this->inspectionDocUrl . $link; + } +} diff --git a/extension/InspectionDoc/src/InspectionDocBundle.php b/extension/InspectionDoc/src/InspectionDocBundle.php new file mode 100644 index 000000000..04495b7bf --- /dev/null +++ b/extension/InspectionDoc/src/InspectionDocBundle.php @@ -0,0 +1,23 @@ +setContent('[ + { + "inspectionId": "SprykerStrict.TypeHints.ParameterTypeHint", + "link": "/docs/sdk/dev/development-tools/sniffs/spryker-strict/type-hints/parameter-type-hint-sniff.html" + } + ]'); + + $vfsStream = vfsStream::setup(); + $vfsStream->addChild($vfsFile); + + $loggerMock = $this->createMock(LoggerInterface::class); + $jsonFileInspectionDocDataLoader = new JsonFileInspectionDocDataLoader($vfsFile->url(), $loggerMock); + + // Act + $data = $jsonFileInspectionDocDataLoader->getInspectionDocs(); + + // Assert + $this->assertSame([ + 'SprykerStrict.TypeHints.ParameterTypeHint' => [ + 'inspectionId' => 'SprykerStrict.TypeHints.ParameterTypeHint', + 'link' => '/docs/sdk/dev/development-tools/sniffs/spryker-strict/type-hints/parameter-type-hint-sniff.html', + ], + ], $data); + } + + /** + * @return void + */ + public function testGetInspectionDocsFileDoesNotExist(): void + { + // Arrange + $vfsFile = new vfsStreamFile('test.yaml'); + + $vfsStream = vfsStream::setup(); + $vfsStream->addChild($vfsFile); + + $loggerMock = $this->createMock(LoggerInterface::class); + $loggerMock + ->expects($this->once()) + ->method('error'); + $jsonFileInspectionDocDataLoader = new JsonFileInspectionDocDataLoader($vfsFile->url(), $loggerMock); + + // Act + $data = $jsonFileInspectionDocDataLoader->getInspectionDocs(); + + // Assert + $this->assertSame([], $data); + } + + /** + * @return void + */ + public function testGetInspectionDocsWrongStructure(): void + { + // Arrange + $vfsFile = new vfsStreamFile('test.yaml'); + $vfsFile->setContent(''); + + $vfsStream = vfsStream::setup(); + $vfsStream->addChild($vfsFile); + + $loggerMock = $this->createMock(LoggerInterface::class); + $loggerMock + ->expects($this->once()) + ->method('error'); + $jsonFileInspectionDocDataLoader = new JsonFileInspectionDocDataLoader($vfsFile->url(), $loggerMock); + + // Act + $data = $jsonFileInspectionDocDataLoader->getInspectionDocs(); + + // Assert + $this->assertSame([], $data); + } +} diff --git a/extension/InspectionDoc/tests/Unit/Infrastructure/Reader/InspectionDocReaderTest.php b/extension/InspectionDoc/tests/Unit/Infrastructure/Reader/InspectionDocReaderTest.php new file mode 100644 index 000000000..a08b58197 --- /dev/null +++ b/extension/InspectionDoc/tests/Unit/Infrastructure/Reader/InspectionDocReaderTest.php @@ -0,0 +1,127 @@ +outputViolationDecorator = $this->createMock(OutputViolationDecoratorInterface::class); + } + + /** + * @return void + */ + public function testFindByErrorCode(): void + { + // Arrange + $inspectionDocDataLoaderInterfaceMock = $this->createMock(InspectionDocDataLoaderInterface::class); + $inspectionDocDataLoaderInterfaceMock->expects($this->once()) + ->method('getInspectionDocs') + ->willReturn([ + 'SprykerStrict.TypeHints.ParameterTypeHint' => [ + 'inspectionId' => 'SprykerStrict.TypeHints.ParameterTypeHint', + 'link' => '/docs/sdk/dev/development-tools/sniffs/spryker-strict/type-hints/parameter-type-hint-sniff.html', + ], + ]); + + $yamlViolationReportFormatter = new InspectionDocReader($inspectionDocDataLoaderInterfaceMock); + + // Act + $inspectionDoc = $yamlViolationReportFormatter->findByErrorCode('SprykerStrict.TypeHints.ParameterTypeHint'); + + // Assert + $this->assertInstanceOf(InspectionDocInterface::class, $inspectionDoc); + } + + /** + * @return void + */ + public function testFindByErrorCodeCache(): void + { + // Arrange + $inspectionDocDataLoaderInterfaceMock = $this->createMock(InspectionDocDataLoaderInterface::class); + $inspectionDocDataLoaderInterfaceMock->expects($this->exactly(2)) + ->method('getInspectionDocs') + ->willReturn([ + 'SprykerStrict.TypeHints.ParameterTypeHint' => [ + 'inspectionId' => 'SprykerStrict.TypeHints.ParameterTypeHint', + 'link' => '/docs/sdk/dev/development-tools/sniffs/spryker-strict/type-hints/parameter-type-hint-sniff.html', + ], + ]); + + $yamlViolationReportFormatter = new InspectionDocReader($inspectionDocDataLoaderInterfaceMock); + + // Act + $inspectionDoc1 = $yamlViolationReportFormatter->findByErrorCode('SprykerStrict.TypeHints.ParameterTypeHint'); + $inspectionDoc2 = $yamlViolationReportFormatter->findByErrorCode('SprykerStrict.TypeHints.ParameterTypeHint'); + + // Assert + $this->assertInstanceOf(InspectionDocInterface::class, $inspectionDoc1); + $this->assertEquals($inspectionDoc1, $inspectionDoc2); + } + + /** + * @dataProvider provideSettingList + * + * @return void + */ + public function testFindByErrorCodeIfListEmpty(): void + { + // Arrange + $inspectionDocDataLoaderInterfaceMock = $this->createMock(InspectionDocDataLoaderInterface::class); + $inspectionDocDataLoaderInterfaceMock->expects($this->once()) + ->method('getInspectionDocs') + ->willReturn([]); + + $yamlViolationReportFormatter = new InspectionDocReader($inspectionDocDataLoaderInterfaceMock); + + // Act + $inspectionDoc = $yamlViolationReportFormatter->findByErrorCode('SprykerStrict.TypeHints.ParameterTypeHint1'); + + // Assert + $this->assertNull($inspectionDoc); + } + + /** + * @return array> + */ + public function provideSettingList(): array + { + return [ + 'wrong name' => [ + 'SprykerStrict.TypeHints.ParameterTypeHint' => [ + 'inspectionId' => 'SprykerStrict.TypeHints.ParameterTypeHint', + 'link' => '/docs/sdk/dev/development-tools/sniffs/spryker-strict/type-hints/parameter-type-hint-sniff.html', + ], + ], + 'empty doc' => [], + + ]; + } +} diff --git a/extension/InspectionDoc/tests/Unit/Infrastructure/Violation/DocLinkToMessageOutputViolationDecoratorTest.php b/extension/InspectionDoc/tests/Unit/Infrastructure/Violation/DocLinkToMessageOutputViolationDecoratorTest.php new file mode 100644 index 000000000..63cbb1256 --- /dev/null +++ b/extension/InspectionDoc/tests/Unit/Infrastructure/Violation/DocLinkToMessageOutputViolationDecoratorTest.php @@ -0,0 +1,93 @@ +createMock(InspectionDocInterface::class); + $inspectionDocInterface->expects($this->once()) + ->method('getLink') + ->willReturn('testLink'); + + $inspectionDocReader = $this->createMock(InspectionDocReaderInterface::class); + $inspectionDocReader->expects($this->once()) + ->method('findByErrorCode') + ->with('test') + ->willReturn($inspectionDocInterface); + + $docLinkToMessageOutputViolationDecorator = new DocLinkToMessageOutputViolationDecorator( + $inspectionDocReader, + 'test', + ); + $violation = $this->createMock(ViolationInterface::class); + $violation->expects($this->exactly(2)) + ->method('getAdditionalAttributes') + ->willReturn(['inspectionId' => 'test']); + + // Act + $violationData = $docLinkToMessageOutputViolationDecorator->decorate($violation); + + // Assert + $this->assertSame("\nMore information: testtestLink", $violationData->getMessage()); + } + + /** + * @return void + */ + public function testWithoutDecorator(): void + { + // Arrange + $inspectionDocInterface = $this->createMock(InspectionDocInterface::class); + $inspectionDocInterface->expects($this->never()) + ->method('getLink') + ->willReturn('testLink'); + + $inspectionDocReader = $this->createMock(InspectionDocReaderInterface::class); + $inspectionDocReader->expects($this->never()) + ->method('findByErrorCode') + ->with('test') + ->willReturn($inspectionDocInterface); + + $docLinkToMessageOutputViolationDecorator = new DocLinkToMessageOutputViolationDecorator( + $inspectionDocReader, + 'test', + ); + $violation = $this->createMock(ViolationInterface::class); + $violation->expects($this->exactly(2)) + ->method('getAdditionalAttributes') + ->willReturn([]); + + // Act + $violationData = $docLinkToMessageOutputViolationDecorator->decorate($violation); + + // Assert + $this->assertSame('', $violationData->getMessage()); + } +} diff --git a/extension/InspectionDoc/tests/_support/UnitTester.php b/extension/InspectionDoc/tests/_support/UnitTester.php new file mode 100644 index 000000000..eb78eb4fc --- /dev/null +++ b/extension/InspectionDoc/tests/_support/UnitTester.php @@ -0,0 +1,35 @@ + codeception ### +tests/_output/ +tests/_support/_generated/ +###< codeception ### diff --git a/extension/VcsConnector/tests/_support/_generated/UnitTesterActions.php b/extension/VcsConnector/tests/_support/_generated/UnitTesterActions.php deleted file mode 100644 index 01de4a3f1..000000000 --- a/extension/VcsConnector/tests/_support/_generated/UnitTesterActions.php +++ /dev/null @@ -1,1701 +0,0 @@ -expectThrowable(MyThrowable::class, function() { - * $this->doSomethingBad(); - * }); - * - * $I->expectThrowable(new MyException(), function() { - * $this->doSomethingBad(); - * }); - * ``` - * If you want to check message or throwable code, you can pass them with throwable instance: - * ```php - * expectThrowable(new MyError("Don't do bad things"), function() { - * $this->doSomethingBad(); - * }); - * ``` - * - * @param \Throwable|string $throwable - * @see \Codeception\Module\Asserts::expectThrowable() - */ - public function expectThrowable($throwable, callable $callback): void { - $this->getScenario()->runStep(new \Codeception\Step\Action('expectThrowable', func_get_args())); - } - - - /** - * [!] Method is generated. Documentation taken from corresponding module. - * - * Asserts that a file does not exist. - * @see \Codeception\Module\AbstractAsserts::assertFileNotExists() - */ - public function assertFileNotExists(string $filename, string $message = "") { - return $this->getScenario()->runStep(new \Codeception\Step\Action('assertFileNotExists', func_get_args())); - } - - - /** - * [!] Method is generated. Documentation taken from corresponding module. - * - * Asserts that a value is greater than or equal to another value. - * - * @param mixed $expected - * @param mixed $actual - * @see \Codeception\Module\AbstractAsserts::assertGreaterOrEquals() - */ - public function assertGreaterOrEquals($expected, $actual, string $message = "") { - return $this->getScenario()->runStep(new \Codeception\Step\Action('assertGreaterOrEquals', func_get_args())); - } - - - /** - * [!] Method is generated. Documentation taken from corresponding module. - * - * Asserts that a variable is empty. - * - * @param mixed $actual - * @see \Codeception\Module\AbstractAsserts::assertIsEmpty() - */ - public function assertIsEmpty($actual, string $message = "") { - return $this->getScenario()->runStep(new \Codeception\Step\Action('assertIsEmpty', func_get_args())); - } - - - /** - * [!] Method is generated. Documentation taken from corresponding module. - * - * Asserts that a value is smaller than or equal to another value. - * - * @param mixed $expected - * @param mixed $actual - * @see \Codeception\Module\AbstractAsserts::assertLessOrEquals() - */ - public function assertLessOrEquals($expected, $actual, string $message = "") { - return $this->getScenario()->runStep(new \Codeception\Step\Action('assertLessOrEquals', func_get_args())); - } - - - /** - * [!] Method is generated. Documentation taken from corresponding module. - * - * Asserts that a string does not match a given regular expression. - * @see \Codeception\Module\AbstractAsserts::assertNotRegExp() - */ - public function assertNotRegExp(string $pattern, string $string, string $message = "") { - return $this->getScenario()->runStep(new \Codeception\Step\Action('assertNotRegExp', func_get_args())); - } - - - /** - * [!] Method is generated. Documentation taken from corresponding module. - * - * Asserts that a string matches a given regular expression. - * @see \Codeception\Module\AbstractAsserts::assertRegExp() - */ - public function assertRegExp(string $pattern, string $string, string $message = "") { - return $this->getScenario()->runStep(new \Codeception\Step\Action('assertRegExp', func_get_args())); - } - - - /** - * [!] Method is generated. Documentation taken from corresponding module. - * - * Evaluates a PHPUnit\Framework\Constraint matcher object. - * - * @param mixed $value - * @see \Codeception\Module\AbstractAsserts::assertThatItsNot() - */ - public function assertThatItsNot($value, \PHPUnit\Framework\Constraint\Constraint $constraint, string $message = "") { - return $this->getScenario()->runStep(new \Codeception\Step\Action('assertThatItsNot', func_get_args())); - } - - - /** - * [!] Method is generated. Documentation taken from corresponding module. - * - * Asserts that an array has a specified key. - * - * @param int|string $key - * @param array|ArrayAccess $array - * @see \Codeception\Module\AbstractAsserts::assertArrayHasKey() - */ - public function assertArrayHasKey($key, $array, string $message = "") { - return $this->getScenario()->runStep(new \Codeception\Step\Action('assertArrayHasKey', func_get_args())); - } - - - /** - * [!] Method is generated. Documentation taken from corresponding module. - * - * Asserts that an array does not have a specified key. - * - * @param int|string $key - * @param array|ArrayAccess $array - * @see \Codeception\Module\AbstractAsserts::assertArrayNotHasKey() - */ - public function assertArrayNotHasKey($key, $array, string $message = "") { - return $this->getScenario()->runStep(new \Codeception\Step\Action('assertArrayNotHasKey', func_get_args())); - } - - - /** - * [!] Method is generated. Documentation taken from corresponding module. - * - * Asserts that a class has a specified attribute. - * @see \Codeception\Module\AbstractAsserts::assertClassHasAttribute() - */ - public function assertClassHasAttribute(string $attributeName, string $className, string $message = "") { - return $this->getScenario()->runStep(new \Codeception\Step\Action('assertClassHasAttribute', func_get_args())); - } - - - /** - * [!] Method is generated. Documentation taken from corresponding module. - * - * Asserts that a class has a specified static attribute. - * @see \Codeception\Module\AbstractAsserts::assertClassHasStaticAttribute() - */ - public function assertClassHasStaticAttribute(string $attributeName, string $className, string $message = "") { - return $this->getScenario()->runStep(new \Codeception\Step\Action('assertClassHasStaticAttribute', func_get_args())); - } - - - /** - * [!] Method is generated. Documentation taken from corresponding module. - * - * Asserts that a class does not have a specified attribute. - * @see \Codeception\Module\AbstractAsserts::assertClassNotHasAttribute() - */ - public function assertClassNotHasAttribute(string $attributeName, string $className, string $message = "") { - return $this->getScenario()->runStep(new \Codeception\Step\Action('assertClassNotHasAttribute', func_get_args())); - } - - - /** - * [!] Method is generated. Documentation taken from corresponding module. - * - * Asserts that a class does not have a specified static attribute. - * @see \Codeception\Module\AbstractAsserts::assertClassNotHasStaticAttribute() - */ - public function assertClassNotHasStaticAttribute(string $attributeName, string $className, string $message = "") { - return $this->getScenario()->runStep(new \Codeception\Step\Action('assertClassNotHasStaticAttribute', func_get_args())); - } - - - /** - * [!] Method is generated. Documentation taken from corresponding module. - * - * Asserts that a haystack contains a needle. - * - * @param mixed $needle - * @see \Codeception\Module\AbstractAsserts::assertContains() - */ - public function assertContains($needle, iterable $haystack, string $message = "") { - return $this->getScenario()->runStep(new \Codeception\Step\Action('assertContains', func_get_args())); - } - - - /** - * [!] Method is generated. Documentation taken from corresponding module. - * - * @param mixed $needle - * @see \Codeception\Module\AbstractAsserts::assertContainsEquals() - */ - public function assertContainsEquals($needle, iterable $haystack, string $message = "") { - return $this->getScenario()->runStep(new \Codeception\Step\Action('assertContainsEquals', func_get_args())); - } - - - /** - * [!] Method is generated. Documentation taken from corresponding module. - * - * Asserts that a haystack contains only values of a given type. - * @see \Codeception\Module\AbstractAsserts::assertContainsOnly() - */ - public function assertContainsOnly(string $type, iterable $haystack, ?bool $isNativeType = NULL, string $message = "") { - return $this->getScenario()->runStep(new \Codeception\Step\Action('assertContainsOnly', func_get_args())); - } - - - /** - * [!] Method is generated. Documentation taken from corresponding module. - * - * Asserts that a haystack contains only instances of a given class name. - * @see \Codeception\Module\AbstractAsserts::assertContainsOnlyInstancesOf() - */ - public function assertContainsOnlyInstancesOf(string $className, iterable $haystack, string $message = "") { - return $this->getScenario()->runStep(new \Codeception\Step\Action('assertContainsOnlyInstancesOf', func_get_args())); - } - - - /** - * [!] Method is generated. Documentation taken from corresponding module. - * - * Asserts the number of elements of an array, Countable or Traversable. - * - * @param Countable|iterable $haystack - * @see \Codeception\Module\AbstractAsserts::assertCount() - */ - public function assertCount(int $expectedCount, $haystack, string $message = "") { - return $this->getScenario()->runStep(new \Codeception\Step\Action('assertCount', func_get_args())); - } - - - /** - * [!] Method is generated. Documentation taken from corresponding module. - * - * Asserts that a directory does not exist. - * @see \Codeception\Module\AbstractAsserts::assertDirectoryDoesNotExist() - */ - public function assertDirectoryDoesNotExist(string $directory, string $message = "") { - return $this->getScenario()->runStep(new \Codeception\Step\Action('assertDirectoryDoesNotExist', func_get_args())); - } - - - /** - * [!] Method is generated. Documentation taken from corresponding module. - * - * Asserts that a directory exists. - * @see \Codeception\Module\AbstractAsserts::assertDirectoryExists() - */ - public function assertDirectoryExists(string $directory, string $message = "") { - return $this->getScenario()->runStep(new \Codeception\Step\Action('assertDirectoryExists', func_get_args())); - } - - - /** - * [!] Method is generated. Documentation taken from corresponding module. - * - * Asserts that a directory exists and is not readable. - * @see \Codeception\Module\AbstractAsserts::assertDirectoryIsNotReadable() - */ - public function assertDirectoryIsNotReadable(string $directory, string $message = "") { - return $this->getScenario()->runStep(new \Codeception\Step\Action('assertDirectoryIsNotReadable', func_get_args())); - } - - - /** - * [!] Method is generated. Documentation taken from corresponding module. - * - * Asserts that a directory exists and is not writable. - * @see \Codeception\Module\AbstractAsserts::assertDirectoryIsNotWritable() - */ - public function assertDirectoryIsNotWritable(string $directory, string $message = "") { - return $this->getScenario()->runStep(new \Codeception\Step\Action('assertDirectoryIsNotWritable', func_get_args())); - } - - - /** - * [!] Method is generated. Documentation taken from corresponding module. - * - * Asserts that a directory exists and is readable. - * @see \Codeception\Module\AbstractAsserts::assertDirectoryIsReadable() - */ - public function assertDirectoryIsReadable(string $directory, string $message = "") { - return $this->getScenario()->runStep(new \Codeception\Step\Action('assertDirectoryIsReadable', func_get_args())); - } - - - /** - * [!] Method is generated. Documentation taken from corresponding module. - * - * Asserts that a directory exists and is writable. - * @see \Codeception\Module\AbstractAsserts::assertDirectoryIsWritable() - */ - public function assertDirectoryIsWritable(string $directory, string $message = "") { - return $this->getScenario()->runStep(new \Codeception\Step\Action('assertDirectoryIsWritable', func_get_args())); - } - - - /** - * [!] Method is generated. Documentation taken from corresponding module. - * - * Asserts that a string does not match a given regular expression. - * @see \Codeception\Module\AbstractAsserts::assertDoesNotMatchRegularExpression() - */ - public function assertDoesNotMatchRegularExpression(string $pattern, string $string, string $message = "") { - return $this->getScenario()->runStep(new \Codeception\Step\Action('assertDoesNotMatchRegularExpression', func_get_args())); - } - - - /** - * [!] Method is generated. Documentation taken from corresponding module. - * - * Asserts that a variable is empty. - * - * @param mixed $actual - * @see \Codeception\Module\AbstractAsserts::assertEmpty() - */ - public function assertEmpty($actual, string $message = "") { - return $this->getScenario()->runStep(new \Codeception\Step\Action('assertEmpty', func_get_args())); - } - - - /** - * [!] Method is generated. Documentation taken from corresponding module. - * - * Asserts that two variables are equal. - * - * @param mixed $expected - * @param mixed $actual - * @see \Codeception\Module\AbstractAsserts::assertEquals() - */ - public function assertEquals($expected, $actual, string $message = "") { - return $this->getScenario()->runStep(new \Codeception\Step\Action('assertEquals', func_get_args())); - } - - - /** - * [!] Method is generated. Documentation taken from corresponding module. - * - * Asserts that two variables are equal (canonicalizing). - * - * @param mixed $expected - * @param mixed $actual - * @see \Codeception\Module\AbstractAsserts::assertEqualsCanonicalizing() - */ - public function assertEqualsCanonicalizing($expected, $actual, string $message = "") { - return $this->getScenario()->runStep(new \Codeception\Step\Action('assertEqualsCanonicalizing', func_get_args())); - } - - - /** - * [!] Method is generated. Documentation taken from corresponding module. - * - * Asserts that two variables are equal (ignoring case). - * - * @param mixed $expected - * @param mixed $actual - * @see \Codeception\Module\AbstractAsserts::assertEqualsIgnoringCase() - */ - public function assertEqualsIgnoringCase($expected, $actual, string $message = "") { - return $this->getScenario()->runStep(new \Codeception\Step\Action('assertEqualsIgnoringCase', func_get_args())); - } - - - /** - * [!] Method is generated. Documentation taken from corresponding module. - * - * Asserts that two variables are equal (with delta). - * - * @param mixed $expected - * @param mixed $actual - * @see \Codeception\Module\AbstractAsserts::assertEqualsWithDelta() - */ - public function assertEqualsWithDelta($expected, $actual, float $delta, string $message = "") { - return $this->getScenario()->runStep(new \Codeception\Step\Action('assertEqualsWithDelta', func_get_args())); - } - - - /** - * [!] Method is generated. Documentation taken from corresponding module. - * - * Asserts that a condition is false. - * - * @param mixed $condition - * @see \Codeception\Module\AbstractAsserts::assertFalse() - */ - public function assertFalse($condition, string $message = "") { - return $this->getScenario()->runStep(new \Codeception\Step\Action('assertFalse', func_get_args())); - } - - - /** - * [!] Method is generated. Documentation taken from corresponding module. - * - * Asserts that a file does not exist. - * @see \Codeception\Module\AbstractAsserts::assertFileDoesNotExist() - */ - public function assertFileDoesNotExist(string $filename, string $message = "") { - return $this->getScenario()->runStep(new \Codeception\Step\Action('assertFileDoesNotExist', func_get_args())); - } - - - /** - * [!] Method is generated. Documentation taken from corresponding module. - * - * Asserts that the contents of one file is equal to the contents of another file. - * @see \Codeception\Module\AbstractAsserts::assertFileEquals() - */ - public function assertFileEquals(string $expected, string $actual, string $message = "") { - return $this->getScenario()->runStep(new \Codeception\Step\Action('assertFileEquals', func_get_args())); - } - - - /** - * [!] Method is generated. Documentation taken from corresponding module. - * - * Asserts that the contents of one file is equal to the contents of another file (canonicalizing). - * @see \Codeception\Module\AbstractAsserts::assertFileEqualsCanonicalizing() - */ - public function assertFileEqualsCanonicalizing(string $expected, string $actual, string $message = "") { - return $this->getScenario()->runStep(new \Codeception\Step\Action('assertFileEqualsCanonicalizing', func_get_args())); - } - - - /** - * [!] Method is generated. Documentation taken from corresponding module. - * - * Asserts that the contents of one file is equal to the contents of another file (ignoring case). - * @see \Codeception\Module\AbstractAsserts::assertFileEqualsIgnoringCase() - */ - public function assertFileEqualsIgnoringCase(string $expected, string $actual, string $message = "") { - return $this->getScenario()->runStep(new \Codeception\Step\Action('assertFileEqualsIgnoringCase', func_get_args())); - } - - - /** - * [!] Method is generated. Documentation taken from corresponding module. - * - * Asserts that a file exists. - * @see \Codeception\Module\AbstractAsserts::assertFileExists() - */ - public function assertFileExists(string $filename, string $message = "") { - return $this->getScenario()->runStep(new \Codeception\Step\Action('assertFileExists', func_get_args())); - } - - - /** - * [!] Method is generated. Documentation taken from corresponding module. - * - * Asserts that a file exists and is not readable. - * @see \Codeception\Module\AbstractAsserts::assertFileIsNotReadable() - */ - public function assertFileIsNotReadable(string $file, string $message = "") { - return $this->getScenario()->runStep(new \Codeception\Step\Action('assertFileIsNotReadable', func_get_args())); - } - - - /** - * [!] Method is generated. Documentation taken from corresponding module. - * - * Asserts that a file exists and is not writable. - * @see \Codeception\Module\AbstractAsserts::assertFileIsNotWritable() - */ - public function assertFileIsNotWritable(string $file, string $message = "") { - return $this->getScenario()->runStep(new \Codeception\Step\Action('assertFileIsNotWritable', func_get_args())); - } - - - /** - * [!] Method is generated. Documentation taken from corresponding module. - * - * Asserts that a file exists and is readable. - * @see \Codeception\Module\AbstractAsserts::assertFileIsReadable() - */ - public function assertFileIsReadable(string $file, string $message = "") { - return $this->getScenario()->runStep(new \Codeception\Step\Action('assertFileIsReadable', func_get_args())); - } - - - /** - * [!] Method is generated. Documentation taken from corresponding module. - * - * Asserts that a file exists and is writable. - * @see \Codeception\Module\AbstractAsserts::assertFileIsWritable() - */ - public function assertFileIsWritable(string $file, string $message = "") { - return $this->getScenario()->runStep(new \Codeception\Step\Action('assertFileIsWritable', func_get_args())); - } - - - /** - * [!] Method is generated. Documentation taken from corresponding module. - * - * Asserts that the contents of one file is not equal to the contents of another file. - * @see \Codeception\Module\AbstractAsserts::assertFileNotEquals() - */ - public function assertFileNotEquals(string $expected, string $actual, string $message = "") { - return $this->getScenario()->runStep(new \Codeception\Step\Action('assertFileNotEquals', func_get_args())); - } - - - /** - * [!] Method is generated. Documentation taken from corresponding module. - * - * Asserts that the contents of one file is not equal to the contents of another file (canonicalizing). - * @see \Codeception\Module\AbstractAsserts::assertFileNotEqualsCanonicalizing() - */ - public function assertFileNotEqualsCanonicalizing(string $expected, string $actual, string $message = "") { - return $this->getScenario()->runStep(new \Codeception\Step\Action('assertFileNotEqualsCanonicalizing', func_get_args())); - } - - - /** - * [!] Method is generated. Documentation taken from corresponding module. - * - * Asserts that the contents of one file is not equal to the contents of another file (ignoring case). - * @see \Codeception\Module\AbstractAsserts::assertFileNotEqualsIgnoringCase() - */ - public function assertFileNotEqualsIgnoringCase(string $expected, string $actual, string $message = "") { - return $this->getScenario()->runStep(new \Codeception\Step\Action('assertFileNotEqualsIgnoringCase', func_get_args())); - } - - - /** - * [!] Method is generated. Documentation taken from corresponding module. - * - * Asserts that a variable is finite. - * - * @param mixed $actual - * @see \Codeception\Module\AbstractAsserts::assertFinite() - */ - public function assertFinite($actual, string $message = "") { - return $this->getScenario()->runStep(new \Codeception\Step\Action('assertFinite', func_get_args())); - } - - - /** - * [!] Method is generated. Documentation taken from corresponding module. - * - * Asserts that a value is greater than another value. - * - * @param mixed $expected - * @param mixed $actual - * @see \Codeception\Module\AbstractAsserts::assertGreaterThan() - */ - public function assertGreaterThan($expected, $actual, string $message = "") { - return $this->getScenario()->runStep(new \Codeception\Step\Action('assertGreaterThan', func_get_args())); - } - - - /** - * [!] Method is generated. Documentation taken from corresponding module. - * - * Asserts that a value is greater than or equal to another value. - * - * @param mixed $expected - * @param mixed $actual - * @see \Codeception\Module\AbstractAsserts::assertGreaterThanOrEqual() - */ - public function assertGreaterThanOrEqual($expected, $actual, string $message = "") { - return $this->getScenario()->runStep(new \Codeception\Step\Action('assertGreaterThanOrEqual', func_get_args())); - } - - - /** - * [!] Method is generated. Documentation taken from corresponding module. - * - * Asserts that a variable is infinite. - * - * @param mixed $actual - * @see \Codeception\Module\AbstractAsserts::assertInfinite() - */ - public function assertInfinite($actual, string $message = "") { - return $this->getScenario()->runStep(new \Codeception\Step\Action('assertInfinite', func_get_args())); - } - - - /** - * [!] Method is generated. Documentation taken from corresponding module. - * - * Asserts that a variable is of a given type. - * - * @param mixed $actual - * @see \Codeception\Module\AbstractAsserts::assertInstanceOf() - */ - public function assertInstanceOf(string $expected, $actual, string $message = "") { - return $this->getScenario()->runStep(new \Codeception\Step\Action('assertInstanceOf', func_get_args())); - } - - - /** - * [!] Method is generated. Documentation taken from corresponding module. - * - * Asserts that a variable is of type array. - * - * @param mixed $actual - * @see \Codeception\Module\AbstractAsserts::assertIsArray() - */ - public function assertIsArray($actual, string $message = "") { - return $this->getScenario()->runStep(new \Codeception\Step\Action('assertIsArray', func_get_args())); - } - - - /** - * [!] Method is generated. Documentation taken from corresponding module. - * - * Asserts that a variable is of type bool. - * - * @param mixed $actual - * @see \Codeception\Module\AbstractAsserts::assertIsBool() - */ - public function assertIsBool($actual, string $message = "") { - return $this->getScenario()->runStep(new \Codeception\Step\Action('assertIsBool', func_get_args())); - } - - - /** - * [!] Method is generated. Documentation taken from corresponding module. - * - * Asserts that a variable is of type callable. - * - * @param mixed $actual - * @see \Codeception\Module\AbstractAsserts::assertIsCallable() - */ - public function assertIsCallable($actual, string $message = "") { - return $this->getScenario()->runStep(new \Codeception\Step\Action('assertIsCallable', func_get_args())); - } - - - /** - * [!] Method is generated. Documentation taken from corresponding module. - * - * Asserts that a variable is of type resource and is closed. - * - * @param mixed $actual - * @see \Codeception\Module\AbstractAsserts::assertIsClosedResource() - */ - public function assertIsClosedResource($actual, string $message = "") { - return $this->getScenario()->runStep(new \Codeception\Step\Action('assertIsClosedResource', func_get_args())); - } - - - /** - * [!] Method is generated. Documentation taken from corresponding module. - * - * Asserts that a variable is of type float. - * - * @param mixed $actual - * @see \Codeception\Module\AbstractAsserts::assertIsFloat() - */ - public function assertIsFloat($actual, string $message = "") { - return $this->getScenario()->runStep(new \Codeception\Step\Action('assertIsFloat', func_get_args())); - } - - - /** - * [!] Method is generated. Documentation taken from corresponding module. - * - * Asserts that a variable is of type int. - * - * @param mixed $actual - * @see \Codeception\Module\AbstractAsserts::assertIsInt() - */ - public function assertIsInt($actual, string $message = "") { - return $this->getScenario()->runStep(new \Codeception\Step\Action('assertIsInt', func_get_args())); - } - - - /** - * [!] Method is generated. Documentation taken from corresponding module. - * - * Asserts that a variable is of type iterable. - * - * @param mixed $actual - * @see \Codeception\Module\AbstractAsserts::assertIsIterable() - */ - public function assertIsIterable($actual, string $message = "") { - return $this->getScenario()->runStep(new \Codeception\Step\Action('assertIsIterable', func_get_args())); - } - - - /** - * [!] Method is generated. Documentation taken from corresponding module. - * - * Asserts that a variable is not of type array. - * - * @param mixed $actual - * @see \Codeception\Module\AbstractAsserts::assertIsNotArray() - */ - public function assertIsNotArray($actual, string $message = "") { - return $this->getScenario()->runStep(new \Codeception\Step\Action('assertIsNotArray', func_get_args())); - } - - - /** - * [!] Method is generated. Documentation taken from corresponding module. - * - * Asserts that a variable is not of type bool. - * - * @param mixed $actual - * @see \Codeception\Module\AbstractAsserts::assertIsNotBool() - */ - public function assertIsNotBool($actual, string $message = "") { - return $this->getScenario()->runStep(new \Codeception\Step\Action('assertIsNotBool', func_get_args())); - } - - - /** - * [!] Method is generated. Documentation taken from corresponding module. - * - * Asserts that a variable is not of type callable. - * - * @param mixed $actual - * @see \Codeception\Module\AbstractAsserts::assertIsNotCallable() - */ - public function assertIsNotCallable($actual, string $message = "") { - return $this->getScenario()->runStep(new \Codeception\Step\Action('assertIsNotCallable', func_get_args())); - } - - - /** - * [!] Method is generated. Documentation taken from corresponding module. - * - * Asserts that a variable is not of type resource. - * - * @param mixed $actual - * @see \Codeception\Module\AbstractAsserts::assertIsNotClosedResource() - */ - public function assertIsNotClosedResource($actual, string $message = "") { - return $this->getScenario()->runStep(new \Codeception\Step\Action('assertIsNotClosedResource', func_get_args())); - } - - - /** - * [!] Method is generated. Documentation taken from corresponding module. - * - * Asserts that a variable is not of type float. - * - * @param mixed $actual - * @see \Codeception\Module\AbstractAsserts::assertIsNotFloat() - */ - public function assertIsNotFloat($actual, string $message = "") { - return $this->getScenario()->runStep(new \Codeception\Step\Action('assertIsNotFloat', func_get_args())); - } - - - /** - * [!] Method is generated. Documentation taken from corresponding module. - * - * Asserts that a variable is not of type int. - * - * @param mixed $actual - * @see \Codeception\Module\AbstractAsserts::assertIsNotInt() - */ - public function assertIsNotInt($actual, string $message = "") { - return $this->getScenario()->runStep(new \Codeception\Step\Action('assertIsNotInt', func_get_args())); - } - - - /** - * [!] Method is generated. Documentation taken from corresponding module. - * - * Asserts that a variable is not of type iterable. - * - * @param mixed $actual - * @see \Codeception\Module\AbstractAsserts::assertIsNotIterable() - */ - public function assertIsNotIterable($actual, string $message = "") { - return $this->getScenario()->runStep(new \Codeception\Step\Action('assertIsNotIterable', func_get_args())); - } - - - /** - * [!] Method is generated. Documentation taken from corresponding module. - * - * Asserts that a variable is not of type numeric. - * - * @param mixed $actual - * @see \Codeception\Module\AbstractAsserts::assertIsNotNumeric() - */ - public function assertIsNotNumeric($actual, string $message = "") { - return $this->getScenario()->runStep(new \Codeception\Step\Action('assertIsNotNumeric', func_get_args())); - } - - - /** - * [!] Method is generated. Documentation taken from corresponding module. - * - * Asserts that a variable is not of type object. - * - * @param mixed $actual - * @see \Codeception\Module\AbstractAsserts::assertIsNotObject() - */ - public function assertIsNotObject($actual, string $message = "") { - return $this->getScenario()->runStep(new \Codeception\Step\Action('assertIsNotObject', func_get_args())); - } - - - /** - * [!] Method is generated. Documentation taken from corresponding module. - * - * Asserts that a file/dir exists and is not readable. - * @see \Codeception\Module\AbstractAsserts::assertIsNotReadable() - */ - public function assertIsNotReadable(string $filename, string $message = "") { - return $this->getScenario()->runStep(new \Codeception\Step\Action('assertIsNotReadable', func_get_args())); - } - - - /** - * [!] Method is generated. Documentation taken from corresponding module. - * - * Asserts that a variable is not of type resource. - * - * @param mixed $actual - * @see \Codeception\Module\AbstractAsserts::assertIsNotResource() - */ - public function assertIsNotResource($actual, string $message = "") { - return $this->getScenario()->runStep(new \Codeception\Step\Action('assertIsNotResource', func_get_args())); - } - - - /** - * [!] Method is generated. Documentation taken from corresponding module. - * - * Asserts that a variable is not of type scalar. - * - * @param mixed $actual - * @see \Codeception\Module\AbstractAsserts::assertIsNotScalar() - */ - public function assertIsNotScalar($actual, string $message = "") { - return $this->getScenario()->runStep(new \Codeception\Step\Action('assertIsNotScalar', func_get_args())); - } - - - /** - * [!] Method is generated. Documentation taken from corresponding module. - * - * Asserts that a variable is not of type string. - * - * @param mixed $actual - * @see \Codeception\Module\AbstractAsserts::assertIsNotString() - */ - public function assertIsNotString($actual, string $message = "") { - return $this->getScenario()->runStep(new \Codeception\Step\Action('assertIsNotString', func_get_args())); - } - - - /** - * [!] Method is generated. Documentation taken from corresponding module. - * - * Asserts that a file/dir exists and is not writable. - * @see \Codeception\Module\AbstractAsserts::assertIsNotWritable() - */ - public function assertIsNotWritable(string $filename, string $message = "") { - return $this->getScenario()->runStep(new \Codeception\Step\Action('assertIsNotWritable', func_get_args())); - } - - - /** - * [!] Method is generated. Documentation taken from corresponding module. - * - * Asserts that a variable is of type numeric. - * - * @param mixed $actual - * @see \Codeception\Module\AbstractAsserts::assertIsNumeric() - */ - public function assertIsNumeric($actual, string $message = "") { - return $this->getScenario()->runStep(new \Codeception\Step\Action('assertIsNumeric', func_get_args())); - } - - - /** - * [!] Method is generated. Documentation taken from corresponding module. - * - * Asserts that a variable is of type object. - * - * @param mixed $actual - * @see \Codeception\Module\AbstractAsserts::assertIsObject() - */ - public function assertIsObject($actual, string $message = "") { - return $this->getScenario()->runStep(new \Codeception\Step\Action('assertIsObject', func_get_args())); - } - - - /** - * [!] Method is generated. Documentation taken from corresponding module. - * - * Asserts that a file/dir is readable. - * @see \Codeception\Module\AbstractAsserts::assertIsReadable() - */ - public function assertIsReadable(string $filename, string $message = "") { - return $this->getScenario()->runStep(new \Codeception\Step\Action('assertIsReadable', func_get_args())); - } - - - /** - * [!] Method is generated. Documentation taken from corresponding module. - * - * Asserts that a variable is of type resource. - * - * @param mixed $actual - * @see \Codeception\Module\AbstractAsserts::assertIsResource() - */ - public function assertIsResource($actual, string $message = "") { - return $this->getScenario()->runStep(new \Codeception\Step\Action('assertIsResource', func_get_args())); - } - - - /** - * [!] Method is generated. Documentation taken from corresponding module. - * - * Asserts that a variable is of type scalar. - * - * @param mixed $actual - * @see \Codeception\Module\AbstractAsserts::assertIsScalar() - */ - public function assertIsScalar($actual, string $message = "") { - return $this->getScenario()->runStep(new \Codeception\Step\Action('assertIsScalar', func_get_args())); - } - - - /** - * [!] Method is generated. Documentation taken from corresponding module. - * - * Asserts that a variable is of type string. - * - * @param mixed $actual - * @see \Codeception\Module\AbstractAsserts::assertIsString() - */ - public function assertIsString($actual, string $message = "") { - return $this->getScenario()->runStep(new \Codeception\Step\Action('assertIsString', func_get_args())); - } - - - /** - * [!] Method is generated. Documentation taken from corresponding module. - * - * Asserts that a file/dir exists and is writable. - * @see \Codeception\Module\AbstractAsserts::assertIsWritable() - */ - public function assertIsWritable(string $filename, string $message = "") { - return $this->getScenario()->runStep(new \Codeception\Step\Action('assertIsWritable', func_get_args())); - } - - - /** - * [!] Method is generated. Documentation taken from corresponding module. - * - * Asserts that a string is a valid JSON string. - * @see \Codeception\Module\AbstractAsserts::assertJson() - */ - public function assertJson(string $actualJson, string $message = "") { - return $this->getScenario()->runStep(new \Codeception\Step\Action('assertJson', func_get_args())); - } - - - /** - * [!] Method is generated. Documentation taken from corresponding module. - * - * Asserts that two JSON files are equal. - * @see \Codeception\Module\AbstractAsserts::assertJsonFileEqualsJsonFile() - */ - public function assertJsonFileEqualsJsonFile(string $expectedFile, string $actualFile, string $message = "") { - return $this->getScenario()->runStep(new \Codeception\Step\Action('assertJsonFileEqualsJsonFile', func_get_args())); - } - - - /** - * [!] Method is generated. Documentation taken from corresponding module. - * - * Asserts that two JSON files are not equal. - * @see \Codeception\Module\AbstractAsserts::assertJsonFileNotEqualsJsonFile() - */ - public function assertJsonFileNotEqualsJsonFile(string $expectedFile, string $actualFile, string $message = "") { - return $this->getScenario()->runStep(new \Codeception\Step\Action('assertJsonFileNotEqualsJsonFile', func_get_args())); - } - - - /** - * [!] Method is generated. Documentation taken from corresponding module. - * - * Asserts that the generated JSON encoded object and the content of the given file are equal. - * @see \Codeception\Module\AbstractAsserts::assertJsonStringEqualsJsonFile() - */ - public function assertJsonStringEqualsJsonFile(string $expectedFile, string $actualJson, string $message = "") { - return $this->getScenario()->runStep(new \Codeception\Step\Action('assertJsonStringEqualsJsonFile', func_get_args())); - } - - - /** - * [!] Method is generated. Documentation taken from corresponding module. - * - * Asserts that two given JSON encoded objects or arrays are equal. - * @see \Codeception\Module\AbstractAsserts::assertJsonStringEqualsJsonString() - */ - public function assertJsonStringEqualsJsonString(string $expectedJson, string $actualJson, string $message = "") { - return $this->getScenario()->runStep(new \Codeception\Step\Action('assertJsonStringEqualsJsonString', func_get_args())); - } - - - /** - * [!] Method is generated. Documentation taken from corresponding module. - * - * Asserts that the generated JSON encoded object and the content of the given file are not equal. - * @see \Codeception\Module\AbstractAsserts::assertJsonStringNotEqualsJsonFile() - */ - public function assertJsonStringNotEqualsJsonFile(string $expectedFile, string $actualJson, string $message = "") { - return $this->getScenario()->runStep(new \Codeception\Step\Action('assertJsonStringNotEqualsJsonFile', func_get_args())); - } - - - /** - * [!] Method is generated. Documentation taken from corresponding module. - * - * Asserts that two given JSON encoded objects or arrays are not equal. - * @see \Codeception\Module\AbstractAsserts::assertJsonStringNotEqualsJsonString() - */ - public function assertJsonStringNotEqualsJsonString(string $expectedJson, string $actualJson, string $message = "") { - return $this->getScenario()->runStep(new \Codeception\Step\Action('assertJsonStringNotEqualsJsonString', func_get_args())); - } - - - /** - * [!] Method is generated. Documentation taken from corresponding module. - * - * Asserts that a value is smaller than another value. - * - * @param mixed $expected - * @param mixed $actual - * @see \Codeception\Module\AbstractAsserts::assertLessThan() - */ - public function assertLessThan($expected, $actual, string $message = "") { - return $this->getScenario()->runStep(new \Codeception\Step\Action('assertLessThan', func_get_args())); - } - - - /** - * [!] Method is generated. Documentation taken from corresponding module. - * - * Asserts that a value is smaller than or equal to another value. - * - * @param mixed $expected - * @param mixed $actual - * @see \Codeception\Module\AbstractAsserts::assertLessThanOrEqual() - */ - public function assertLessThanOrEqual($expected, $actual, string $message = "") { - return $this->getScenario()->runStep(new \Codeception\Step\Action('assertLessThanOrEqual', func_get_args())); - } - - - /** - * [!] Method is generated. Documentation taken from corresponding module. - * - * Asserts that a string matches a given regular expression. - * @see \Codeception\Module\AbstractAsserts::assertMatchesRegularExpression() - */ - public function assertMatchesRegularExpression(string $pattern, string $string, string $message = "") { - return $this->getScenario()->runStep(new \Codeception\Step\Action('assertMatchesRegularExpression', func_get_args())); - } - - - /** - * [!] Method is generated. Documentation taken from corresponding module. - * - * Asserts that a variable is nan. - * - * @param mixed $actual - * @see \Codeception\Module\AbstractAsserts::assertNan() - */ - public function assertNan($actual, string $message = "") { - return $this->getScenario()->runStep(new \Codeception\Step\Action('assertNan', func_get_args())); - } - - - /** - * [!] Method is generated. Documentation taken from corresponding module. - * - * Asserts that a haystack does not contain a needle. - * - * @param mixed $needle - * @see \Codeception\Module\AbstractAsserts::assertNotContains() - */ - public function assertNotContains($needle, iterable $haystack, string $message = "") { - return $this->getScenario()->runStep(new \Codeception\Step\Action('assertNotContains', func_get_args())); - } - - - /** - * [!] Method is generated. Documentation taken from corresponding module. - * - * - * @see \Codeception\Module\AbstractAsserts::assertNotContainsEquals() - */ - public function assertNotContainsEquals($needle, iterable $haystack, string $message = "") { - return $this->getScenario()->runStep(new \Codeception\Step\Action('assertNotContainsEquals', func_get_args())); - } - - - /** - * [!] Method is generated. Documentation taken from corresponding module. - * - * Asserts that a haystack does not contain only values of a given type. - * @see \Codeception\Module\AbstractAsserts::assertNotContainsOnly() - */ - public function assertNotContainsOnly(string $type, iterable $haystack, ?bool $isNativeType = NULL, string $message = "") { - return $this->getScenario()->runStep(new \Codeception\Step\Action('assertNotContainsOnly', func_get_args())); - } - - - /** - * [!] Method is generated. Documentation taken from corresponding module. - * - * Asserts the number of elements of an array, Countable or Traversable. - * - * @param Countable|iterable $haystack - * @see \Codeception\Module\AbstractAsserts::assertNotCount() - */ - public function assertNotCount(int $expectedCount, $haystack, string $message = "") { - return $this->getScenario()->runStep(new \Codeception\Step\Action('assertNotCount', func_get_args())); - } - - - /** - * [!] Method is generated. Documentation taken from corresponding module. - * - * Asserts that a variable is not empty. - * - * @param mixed $actual - * @see \Codeception\Module\AbstractAsserts::assertNotEmpty() - */ - public function assertNotEmpty($actual, string $message = "") { - return $this->getScenario()->runStep(new \Codeception\Step\Action('assertNotEmpty', func_get_args())); - } - - - /** - * [!] Method is generated. Documentation taken from corresponding module. - * - * Asserts that two variables are not equal. - * - * @param mixed $expected - * @param mixed $actual - * @see \Codeception\Module\AbstractAsserts::assertNotEquals() - */ - public function assertNotEquals($expected, $actual, string $message = "") { - return $this->getScenario()->runStep(new \Codeception\Step\Action('assertNotEquals', func_get_args())); - } - - - /** - * [!] Method is generated. Documentation taken from corresponding module. - * - * Asserts that two variables are not equal (canonicalizing). - * - * @param mixed $expected - * @param mixed $actual - * @see \Codeception\Module\AbstractAsserts::assertNotEqualsCanonicalizing() - */ - public function assertNotEqualsCanonicalizing($expected, $actual, string $message = "") { - return $this->getScenario()->runStep(new \Codeception\Step\Action('assertNotEqualsCanonicalizing', func_get_args())); - } - - - /** - * [!] Method is generated. Documentation taken from corresponding module. - * - * Asserts that two variables are not equal (ignoring case). - * - * @param mixed $expected - * @param mixed $actual - * @see \Codeception\Module\AbstractAsserts::assertNotEqualsIgnoringCase() - */ - public function assertNotEqualsIgnoringCase($expected, $actual, string $message = "") { - return $this->getScenario()->runStep(new \Codeception\Step\Action('assertNotEqualsIgnoringCase', func_get_args())); - } - - - /** - * [!] Method is generated. Documentation taken from corresponding module. - * - * Asserts that two variables are not equal (with delta). - * - * @param mixed $expected - * @param mixed $actual - * @see \Codeception\Module\AbstractAsserts::assertNotEqualsWithDelta() - */ - public function assertNotEqualsWithDelta($expected, $actual, float $delta, string $message = "") { - return $this->getScenario()->runStep(new \Codeception\Step\Action('assertNotEqualsWithDelta', func_get_args())); - } - - - /** - * [!] Method is generated. Documentation taken from corresponding module. - * - * Asserts that a condition is not false. - * - * @param mixed $condition - * @see \Codeception\Module\AbstractAsserts::assertNotFalse() - */ - public function assertNotFalse($condition, string $message = "") { - return $this->getScenario()->runStep(new \Codeception\Step\Action('assertNotFalse', func_get_args())); - } - - - /** - * [!] Method is generated. Documentation taken from corresponding module. - * - * Asserts that a variable is not of a given type. - * - * @param mixed $actual - * @see \Codeception\Module\AbstractAsserts::assertNotInstanceOf() - */ - public function assertNotInstanceOf(string $expected, $actual, string $message = "") { - return $this->getScenario()->runStep(new \Codeception\Step\Action('assertNotInstanceOf', func_get_args())); - } - - - /** - * [!] Method is generated. Documentation taken from corresponding module. - * - * Asserts that a variable is not null. - * - * @param mixed $actual - * @see \Codeception\Module\AbstractAsserts::assertNotNull() - */ - public function assertNotNull($actual, string $message = "") { - return $this->getScenario()->runStep(new \Codeception\Step\Action('assertNotNull', func_get_args())); - } - - - /** - * [!] Method is generated. Documentation taken from corresponding module. - * - * Asserts that two variables do not have the same type and value. - * - * @param mixed $expected - * @param mixed $actual - * @see \Codeception\Module\AbstractAsserts::assertNotSame() - */ - public function assertNotSame($expected, $actual, string $message = "") { - return $this->getScenario()->runStep(new \Codeception\Step\Action('assertNotSame', func_get_args())); - } - - - /** - * [!] Method is generated. Documentation taken from corresponding module. - * - * Assert that the size of two arrays (or `Countable` or `Traversable` objects) is not the same. - * - * @param Countable|iterable $expected - * @param Countable|iterable $actual - * @see \Codeception\Module\AbstractAsserts::assertNotSameSize() - */ - public function assertNotSameSize($expected, $actual, string $message = "") { - return $this->getScenario()->runStep(new \Codeception\Step\Action('assertNotSameSize', func_get_args())); - } - - - /** - * [!] Method is generated. Documentation taken from corresponding module. - * - * Asserts that a condition is not true. - * - * @param mixed $condition - * @see \Codeception\Module\AbstractAsserts::assertNotTrue() - */ - public function assertNotTrue($condition, string $message = "") { - return $this->getScenario()->runStep(new \Codeception\Step\Action('assertNotTrue', func_get_args())); - } - - - /** - * [!] Method is generated. Documentation taken from corresponding module. - * - * Asserts that a variable is null. - * - * @param mixed $actual - * @see \Codeception\Module\AbstractAsserts::assertNull() - */ - public function assertNull($actual, string $message = "") { - return $this->getScenario()->runStep(new \Codeception\Step\Action('assertNull', func_get_args())); - } - - - /** - * [!] Method is generated. Documentation taken from corresponding module. - * - * Asserts that an object has a specified attribute. - * @see \Codeception\Module\AbstractAsserts::assertObjectHasAttribute() - */ - public function assertObjectHasAttribute(string $attributeName, object $object, string $message = "") { - return $this->getScenario()->runStep(new \Codeception\Step\Action('assertObjectHasAttribute', func_get_args())); - } - - - /** - * [!] Method is generated. Documentation taken from corresponding module. - * - * Asserts that an object does not have a specified attribute. - * @see \Codeception\Module\AbstractAsserts::assertObjectNotHasAttribute() - */ - public function assertObjectNotHasAttribute(string $attributeName, object $object, string $message = "") { - return $this->getScenario()->runStep(new \Codeception\Step\Action('assertObjectNotHasAttribute', func_get_args())); - } - - - /** - * [!] Method is generated. Documentation taken from corresponding module. - * - * Asserts that two variables have the same type and value. - * - * @param mixed $expected - * @param mixed $actual - * @see \Codeception\Module\AbstractAsserts::assertSame() - */ - public function assertSame($expected, $actual, string $message = "") { - return $this->getScenario()->runStep(new \Codeception\Step\Action('assertSame', func_get_args())); - } - - - /** - * [!] Method is generated. Documentation taken from corresponding module. - * - * Assert that the size of two arrays (or `Countable` or `Traversable` objects) is the same. - * - * @param Countable|iterable $expected - * @param Countable|iterable $actual - * @see \Codeception\Module\AbstractAsserts::assertSameSize() - */ - public function assertSameSize($expected, $actual, string $message = "") { - return $this->getScenario()->runStep(new \Codeception\Step\Action('assertSameSize', func_get_args())); - } - - - /** - * [!] Method is generated. Documentation taken from corresponding module. - * - * - * @see \Codeception\Module\AbstractAsserts::assertStringContainsString() - */ - public function assertStringContainsString(string $needle, string $haystack, string $message = "") { - return $this->getScenario()->runStep(new \Codeception\Step\Action('assertStringContainsString', func_get_args())); - } - - - /** - * [!] Method is generated. Documentation taken from corresponding module. - * - * - * @see \Codeception\Module\AbstractAsserts::assertStringContainsStringIgnoringCase() - */ - public function assertStringContainsStringIgnoringCase(string $needle, string $haystack, string $message = "") { - return $this->getScenario()->runStep(new \Codeception\Step\Action('assertStringContainsStringIgnoringCase', func_get_args())); - } - - - /** - * [!] Method is generated. Documentation taken from corresponding module. - * - * Asserts that a string ends not with a given suffix. - * @see \Codeception\Module\AbstractAsserts::assertStringEndsNotWith() - */ - public function assertStringEndsNotWith(string $suffix, string $string, string $message = "") { - return $this->getScenario()->runStep(new \Codeception\Step\Action('assertStringEndsNotWith', func_get_args())); - } - - - /** - * [!] Method is generated. Documentation taken from corresponding module. - * - * Asserts that a string ends with a given suffix. - * @see \Codeception\Module\AbstractAsserts::assertStringEndsWith() - */ - public function assertStringEndsWith(string $suffix, string $string, string $message = "") { - return $this->getScenario()->runStep(new \Codeception\Step\Action('assertStringEndsWith', func_get_args())); - } - - - /** - * [!] Method is generated. Documentation taken from corresponding module. - * - * Asserts that the contents of a string is equal to the contents of a file. - * @see \Codeception\Module\AbstractAsserts::assertStringEqualsFile() - */ - public function assertStringEqualsFile(string $expectedFile, string $actualString, string $message = "") { - return $this->getScenario()->runStep(new \Codeception\Step\Action('assertStringEqualsFile', func_get_args())); - } - - - /** - * [!] Method is generated. Documentation taken from corresponding module. - * - * Asserts that the contents of a string is equal to the contents of a file (canonicalizing). - * @see \Codeception\Module\AbstractAsserts::assertStringEqualsFileCanonicalizing() - */ - public function assertStringEqualsFileCanonicalizing(string $expectedFile, string $actualString, string $message = "") { - return $this->getScenario()->runStep(new \Codeception\Step\Action('assertStringEqualsFileCanonicalizing', func_get_args())); - } - - - /** - * [!] Method is generated. Documentation taken from corresponding module. - * - * Asserts that the contents of a string is equal to the contents of a file (ignoring case). - * @see \Codeception\Module\AbstractAsserts::assertStringEqualsFileIgnoringCase() - */ - public function assertStringEqualsFileIgnoringCase(string $expectedFile, string $actualString, string $message = "") { - return $this->getScenario()->runStep(new \Codeception\Step\Action('assertStringEqualsFileIgnoringCase', func_get_args())); - } - - - /** - * [!] Method is generated. Documentation taken from corresponding module. - * - * Asserts that a string matches a given format string. - * @see \Codeception\Module\AbstractAsserts::assertStringMatchesFormat() - */ - public function assertStringMatchesFormat(string $format, string $string, string $message = "") { - return $this->getScenario()->runStep(new \Codeception\Step\Action('assertStringMatchesFormat', func_get_args())); - } - - - /** - * [!] Method is generated. Documentation taken from corresponding module. - * - * Asserts that a string matches a given format file. - * @see \Codeception\Module\AbstractAsserts::assertStringMatchesFormatFile() - */ - public function assertStringMatchesFormatFile(string $formatFile, string $string, string $message = "") { - return $this->getScenario()->runStep(new \Codeception\Step\Action('assertStringMatchesFormatFile', func_get_args())); - } - - - /** - * [!] Method is generated. Documentation taken from corresponding module. - * - * - * @see \Codeception\Module\AbstractAsserts::assertStringNotContainsString() - */ - public function assertStringNotContainsString(string $needle, string $haystack, string $message = "") { - return $this->getScenario()->runStep(new \Codeception\Step\Action('assertStringNotContainsString', func_get_args())); - } - - - /** - * [!] Method is generated. Documentation taken from corresponding module. - * - * - * @see \Codeception\Module\AbstractAsserts::assertStringNotContainsStringIgnoringCase() - */ - public function assertStringNotContainsStringIgnoringCase(string $needle, string $haystack, string $message = "") { - return $this->getScenario()->runStep(new \Codeception\Step\Action('assertStringNotContainsStringIgnoringCase', func_get_args())); - } - - - /** - * [!] Method is generated. Documentation taken from corresponding module. - * - * Asserts that the contents of a string is not equal to the contents of a file. - * @see \Codeception\Module\AbstractAsserts::assertStringNotEqualsFile() - */ - public function assertStringNotEqualsFile(string $expectedFile, string $actualString, string $message = "") { - return $this->getScenario()->runStep(new \Codeception\Step\Action('assertStringNotEqualsFile', func_get_args())); - } - - - /** - * [!] Method is generated. Documentation taken from corresponding module. - * - * Asserts that the contents of a string is not equal to the contents of a file (canonicalizing). - * @see \Codeception\Module\AbstractAsserts::assertStringNotEqualsFileCanonicalizing() - */ - public function assertStringNotEqualsFileCanonicalizing(string $expectedFile, string $actualString, string $message = "") { - return $this->getScenario()->runStep(new \Codeception\Step\Action('assertStringNotEqualsFileCanonicalizing', func_get_args())); - } - - - /** - * [!] Method is generated. Documentation taken from corresponding module. - * - * Asserts that the contents of a string is not equal to the contents of a file (ignoring case). - * @see \Codeception\Module\AbstractAsserts::assertStringNotEqualsFileIgnoringCase() - */ - public function assertStringNotEqualsFileIgnoringCase(string $expectedFile, string $actualString, string $message = "") { - return $this->getScenario()->runStep(new \Codeception\Step\Action('assertStringNotEqualsFileIgnoringCase', func_get_args())); - } - - - /** - * [!] Method is generated. Documentation taken from corresponding module. - * - * Asserts that a string does not match a given format string. - * @see \Codeception\Module\AbstractAsserts::assertStringNotMatchesFormat() - */ - public function assertStringNotMatchesFormat(string $format, string $string, string $message = "") { - return $this->getScenario()->runStep(new \Codeception\Step\Action('assertStringNotMatchesFormat', func_get_args())); - } - - - /** - * [!] Method is generated. Documentation taken from corresponding module. - * - * Asserts that a string does not match a given format string. - * @see \Codeception\Module\AbstractAsserts::assertStringNotMatchesFormatFile() - */ - public function assertStringNotMatchesFormatFile(string $formatFile, string $string, string $message = "") { - return $this->getScenario()->runStep(new \Codeception\Step\Action('assertStringNotMatchesFormatFile', func_get_args())); - } - - - /** - * [!] Method is generated. Documentation taken from corresponding module. - * - * Asserts that a string starts not with a given prefix. - * @see \Codeception\Module\AbstractAsserts::assertStringStartsNotWith() - */ - public function assertStringStartsNotWith(string $prefix, string $string, string $message = "") { - return $this->getScenario()->runStep(new \Codeception\Step\Action('assertStringStartsNotWith', func_get_args())); - } - - - /** - * [!] Method is generated. Documentation taken from corresponding module. - * - * Asserts that a string starts with a given prefix. - * @see \Codeception\Module\AbstractAsserts::assertStringStartsWith() - */ - public function assertStringStartsWith(string $prefix, string $string, string $message = "") { - return $this->getScenario()->runStep(new \Codeception\Step\Action('assertStringStartsWith', func_get_args())); - } - - - /** - * [!] Method is generated. Documentation taken from corresponding module. - * - * Evaluates a PHPUnit\Framework\Constraint matcher object. - * - * @param mixed $value - * @see \Codeception\Module\AbstractAsserts::assertThat() - */ - public function assertThat($value, \PHPUnit\Framework\Constraint\Constraint $constraint, string $message = "") { - return $this->getScenario()->runStep(new \Codeception\Step\Action('assertThat', func_get_args())); - } - - - /** - * [!] Method is generated. Documentation taken from corresponding module. - * - * Asserts that a condition is true. - * - * @param mixed $condition - * @see \Codeception\Module\AbstractAsserts::assertTrue() - */ - public function assertTrue($condition, string $message = "") { - return $this->getScenario()->runStep(new \Codeception\Step\Action('assertTrue', func_get_args())); - } - - - /** - * [!] Method is generated. Documentation taken from corresponding module. - * - * Asserts that two XML files are equal. - * @see \Codeception\Module\AbstractAsserts::assertXmlFileEqualsXmlFile() - */ - public function assertXmlFileEqualsXmlFile(string $expectedFile, string $actualFile, string $message = "") { - return $this->getScenario()->runStep(new \Codeception\Step\Action('assertXmlFileEqualsXmlFile', func_get_args())); - } - - - /** - * [!] Method is generated. Documentation taken from corresponding module. - * - * Asserts that two XML files are not equal. - * @see \Codeception\Module\AbstractAsserts::assertXmlFileNotEqualsXmlFile() - */ - public function assertXmlFileNotEqualsXmlFile(string $expectedFile, string $actualFile, string $message = "") { - return $this->getScenario()->runStep(new \Codeception\Step\Action('assertXmlFileNotEqualsXmlFile', func_get_args())); - } - - - /** - * [!] Method is generated. Documentation taken from corresponding module. - * - * Asserts that two XML documents are equal. - * - * @param DOMDocument|string $actualXml - * @see \Codeception\Module\AbstractAsserts::assertXmlStringEqualsXmlFile() - */ - public function assertXmlStringEqualsXmlFile(string $expectedFile, $actualXml, string $message = "") { - return $this->getScenario()->runStep(new \Codeception\Step\Action('assertXmlStringEqualsXmlFile', func_get_args())); - } - - - /** - * [!] Method is generated. Documentation taken from corresponding module. - * - * Asserts that two XML documents are equal. - * - * @param DOMDocument|string $expectedXml - * @param DOMDocument|string $actualXml - * @see \Codeception\Module\AbstractAsserts::assertXmlStringEqualsXmlString() - */ - public function assertXmlStringEqualsXmlString($expectedXml, $actualXml, string $message = "") { - return $this->getScenario()->runStep(new \Codeception\Step\Action('assertXmlStringEqualsXmlString', func_get_args())); - } - - - /** - * [!] Method is generated. Documentation taken from corresponding module. - * - * Asserts that two XML documents are not equal. - * - * @param DOMDocument|string $actualXml - * @see \Codeception\Module\AbstractAsserts::assertXmlStringNotEqualsXmlFile() - */ - public function assertXmlStringNotEqualsXmlFile(string $expectedFile, $actualXml, string $message = "") { - return $this->getScenario()->runStep(new \Codeception\Step\Action('assertXmlStringNotEqualsXmlFile', func_get_args())); - } - - - /** - * [!] Method is generated. Documentation taken from corresponding module. - * - * Asserts that two XML documents are not equal. - * - * @param DOMDocument|string $expectedXml - * @param DOMDocument|string $actualXml - * @see \Codeception\Module\AbstractAsserts::assertXmlStringNotEqualsXmlString() - */ - public function assertXmlStringNotEqualsXmlString($expectedXml, $actualXml, string $message = "") { - return $this->getScenario()->runStep(new \Codeception\Step\Action('assertXmlStringNotEqualsXmlString', func_get_args())); - } - - - /** - * [!] Method is generated. Documentation taken from corresponding module. - * - * Fails a test with the given message. - * @see \Codeception\Module\AbstractAsserts::fail() - */ - public function fail(string $message = "") { - return $this->getScenario()->runStep(new \Codeception\Step\Action('fail', func_get_args())); - } - - - /** - * [!] Method is generated. Documentation taken from corresponding module. - * - * Mark the test as incomplete. - * @see \Codeception\Module\AbstractAsserts::markTestIncomplete() - */ - public function markTestIncomplete(string $message = "") { - return $this->getScenario()->runStep(new \Codeception\Step\Action('markTestIncomplete', func_get_args())); - } - - - /** - * [!] Method is generated. Documentation taken from corresponding module. - * - * Mark the test as skipped. - * @see \Codeception\Module\AbstractAsserts::markTestSkipped() - */ - public function markTestSkipped(string $message = "") { - return $this->getScenario()->runStep(new \Codeception\Step\Action('markTestSkipped', func_get_args())); - } -} diff --git a/infrastructure/env/.env b/infrastructure/env/.env index 70fdc14f1..3e3702ba5 100644 --- a/infrastructure/env/.env +++ b/infrastructure/env/.env @@ -1,5 +1,5 @@ PROJECT_DIR=/project -SDK_DIR=${SDK_DIR} +LOCAL_SDK_DIR=${LOCAL_SDK_DIR} UNAME_INFO=${UNAME_INFO} EXECUTABLE_FILE_PATH=${EXECUTABLE_FILE_PATH} SDK_CI_EXECUTION=${SDK_CI_EXECUTION:-0} diff --git a/infrastructure/installer_header.sh b/infrastructure/installer_header.sh index 5d98fafe7..defbd2a3b 100755 --- a/infrastructure/installer_header.sh +++ b/infrastructure/installer_header.sh @@ -1,4 +1,25 @@ #!/bin/bash + +function setupSdkVars { + command="$replaceCommand '/^export SPRYKER_SDK/d' ${ENV_FILE}" && eval "$command"; + command="$replaceCommand '/^alias spryker-sdk=/d' ${ENV_FILE}" && eval "$command"; + echo "export SPRYKER_SDK_PATH=\"$DESTINATION\"" >> ${ENV_FILE} && \ + echo "alias spryker-sdk=\$SPRYKER_SDK_PATH\"/bin/spryker-sdk.sh\"" >> ${ENV_FILE} && \ + echo 'Created alias in' ${ENV_FILE} && \ + echo "Run \`source $ENV_FILE\` or re-open terminal" + + return 0 +} + +function showFallbackResultMessage() { + echo "" + echo "Installation complete." + echo "Run \`export SPRYKER_SDK_PATH=\"$DESTINATION\"\`" + echo "Add alias for your system \`spryker-sdk=\"$DESTINATION/bin/spryker-sdk.sh\"\`" + echo 'Re-open terminal for apply changes.' + echo "" +} + echo "" echo "Spryker SDK Installer" echo "" @@ -48,21 +69,23 @@ if [[ $SELF_UPDATE == 1 ]]; then exit 0 fi +PLATFORM=$(uname) +ENV_FILE="" if [[ -e ~/.zshrc ]] then - echo "export SPRYKER_SDK_PATH=\"$DESTINATION\"" >> ~/.zshrc && \ - echo "alias spryker-sdk=\$SPRYKER_SDK_PATH\"/bin/spryker-sdk.sh\"" >> ~/.zshrc - echo 'Created alias in ~/.zshrc' + ENV_FILE="$HOME/.zshrc" + replaceCommand="" + [[ "$PLATFORM" == "Linux" ]] && replaceCommand='sed -i' && setupSdkVars + [[ "$PLATFORM" == "Darwin" ]] && replaceCommand="sed -i ''" && setupSdkVars + [[ "$replaceCommand" == "" ]] && showFallbackResultMessage && exit 0 elif [[ -e ~/.bashrc ]] then - echo "export SPRYKER_SDK_PATH=\"$DESTINATION\"" >> ~/.bashrc && \ - echo "alias spryker-sdk=\$SPRYKER_SDK_PATH\"/bin/spryker-sdk.sh\"" >> ~/.bashrc - echo 'Created alias in ~/.bashrc' + ENV_FILE="$HOME/.bashrc" + [[ "$PLATFORM" == "Linux" ]] && replaceCommand='sed -i' && setupSdkVars + [[ "$PLATFORM" == "Darwin" ]] && replaceCommand="sed -i ''" && setupSdkVars + [[ "$replaceCommand" == "" ]] && showFallbackResultMessage && exit 0 else - echo "" - echo "Installation complete." - echo "Add alias for your system spryker-sdk=\"$DESTINATION/bin/spryker-sdk.sh\"" - echo "" + showFallbackResultMessage fi # Exit from the script with success (0) diff --git a/infrastructure/newrelic/entrypoint.sh b/infrastructure/newrelic/entrypoint.sh new file mode 100755 index 000000000..bd9461ec5 --- /dev/null +++ b/infrastructure/newrelic/entrypoint.sh @@ -0,0 +1,43 @@ +#!/bin/bash + +# This entrypoint is needed to wait until new relic agent be initialized. +# To do it we need to execute some php code and wait until records be written in audit.log +# More info https://docs.newrelic.com/docs/apm/agents/php-agent/troubleshooting/data-stops-reporting/ + + +TRIES=10 +ATTEMPTS=0 + +php -r "echo \"Initializing new relic...\n\";" + +while true +do + if [[ $ATTEMPTS -ge $TRIES ]]; then + echo "New relic initialization timeout: $ATTEMPTS sec" + break + fi + grep -E "command='connect' .*, status=200" /var/log/newrelic/audit.log > /dev/null 2>&1 + if [[ $? -ne 0 ]]; then + php -r "echo \"...\n\";" + sleep 1 + else + echo 'New relic initialized' + break + fi + ((ATTEMPTS++)) +done + +eval $@ + +if [[ $? -ne 0 ]]; then + echo 'Sending error to new relic server...' + # Sleep is needed to wait until the log record be sent into the new relic server + sleep 6 + echo 'Upgrade failed.' + exit 1 +fi + +echo 'Upgrade successful.' + +exit 0 + diff --git a/infrastructure/newrelic/newrelic.ini b/infrastructure/newrelic/newrelic.ini new file mode 100644 index 000000000..bd79874bc --- /dev/null +++ b/infrastructure/newrelic/newrelic.ini @@ -0,0 +1,19 @@ +extension = newrelic.so +newrelic.enabled = ${NEWRELIC_ENABLED} +newrelic.license = ${NEWRELIC_LICENSE} +newrelic.appname = ${NEWRELIC_APPNAME} +newrelic.framework = "symfony4" +newrelic.loglevel = ${NEWRELIC_LOGLEVEL} +newrelic.browser_monitoring.auto_instrument = false + +;Distributed tracing +newrelic.distributed_tracing_enabled = true +newrelic.transaction_tracer.enabled = true +newrelic.span_events_enabled = true + +;Logs. This one for testing. It should work by default, but there no logs at all. Need to investigate why. +newrelic.application_logging.enabled = true +newrelic.application_logging.metrics.enabled = true +newrelic.application_logging.forwarding.enabled = true + +newrelic.daemon.auditlog = /var/log/newrelic/audit.log diff --git a/infrastructure/sdk.Dockerfile b/infrastructure/sdk.Dockerfile index 9a47c7e5b..5f4ebdcdb 100644 --- a/infrastructure/sdk.Dockerfile +++ b/infrastructure/sdk.Dockerfile @@ -44,7 +44,7 @@ WORKDIR ${srcRoot} ENV APP_ENV=prod -RUN composer install --no-scripts --no-interaction --optimize-autoloader -vvv +RUN composer install --no-scripts --no-interaction --optimize-autoloader -vvv --no-dev RUN npm install diff --git a/infrastructure/sdk.debug.Dockerfile b/infrastructure/sdk.debug.Dockerfile index de39e399a..b83a0a4e5 100644 --- a/infrastructure/sdk.debug.Dockerfile +++ b/infrastructure/sdk.debug.Dockerfile @@ -13,11 +13,6 @@ RUN if [[ ! -z "${USER_UID}" ]]; then \ RUN /usr/bin/install -d -m 777 /var/run/opcache/debug && docker-php-ext-enable xdebug COPY infrastructure/debug/php/69-xdebug.ini /usr/local/etc/php/conf.d/69-xdebug.ini -RUN apk add autoconf && \ - apk --update add gcc make g++ zlib-dev && \ - pecl install xhprof && \ - docker-php-ext-enable xhprof - COPY infrastructure/debug/php/xhprof.ini /usr/local/etc/php/conf.d/docker-php-ext-xhprof.ini COPY infrastructure/debug/sdk.sh /usr/bin/sdk diff --git a/infrastructure/sdk.local.Dockerfile b/infrastructure/sdk.local.Dockerfile index b20e20973..49ef8113e 100644 --- a/infrastructure/sdk.local.Dockerfile +++ b/infrastructure/sdk.local.Dockerfile @@ -6,6 +6,8 @@ USER root ARG USER_UID RUN if [[ ! -z "${USER_UID}" ]]; then \ usermod -u "${USER_UID}" spryker; \ + chown -R spryker /data/var; \ + chown -R spryker /data/vendor; \ fi USER spryker diff --git a/infrastructure/sdk.sprykerci74.Dockerfile b/infrastructure/sdk.sprykerci74.Dockerfile new file mode 100644 index 000000000..fe7a45ca1 --- /dev/null +++ b/infrastructure/sdk.sprykerci74.Dockerfile @@ -0,0 +1,69 @@ +ARG SPRYKER_PARENT_IMAGE=spryker/php:7.4 + +FROM ${SPRYKER_PARENT_IMAGE} AS application-production-dependencies + +USER root + +RUN apk update \ + && apk add --no-cache \ + curl \ + git \ + graphviz \ + nodejs \ + npm \ + rsync \ + && npm install -g npm@8.4.1 + +RUN git config --add --system safe.directory /project + +######################################## +# New Relic Extension +# It's already in the core image. +######################################## +COPY infrastructure/newrelic/newrelic.ini /usr/local/etc/php/conf.d/90-newrelic.ini + +ARG SPRYKER_COMPOSER_MODE + +FROM application-production-dependencies AS application-production-codebase + +RUN chown spryker:spryker ${srcRoot} + +USER spryker +# Authorize SSH Host +RUN mkdir -p /home/spryker/.ssh && \ + chmod 0700 /home/spryker/.ssh && \ + ssh-keyscan github.com > /home/spryker/.ssh/known_hosts + +COPY --chown=spryker:spryker phpstan-bootstrap.php ${srcRoot}/phpstan-bootstrap.php +COPY --chown=spryker:spryker assets ${srcRoot}/assets +COPY --chown=spryker:spryker src ${srcRoot}/src +COPY --chown=spryker:spryker app ${srcRoot}/app +COPY --chown=spryker:spryker db ${srcRoot}/db +COPY --chown=spryker:spryker extension ${srcRoot}/extension +COPY --chown=spryker:spryker config ${srcRoot}/config +COPY --chown=spryker:spryker frontend ${srcRoot}/frontend +COPY --chown=spryker:spryker bin ${srcRoot}/bin +COPY --chown=spryker:spryker .env ${srcRoot}/.env +COPY --chown=spryker:spryker .env.prod ${srcRoot}/.env.prod +COPY --chown=spryker:spryker .env.sprykerci ${srcRoot}/.env.sprykerci +COPY --chown=spryker:spryker composer.json composer.lock package.json package-lock.json bootstrap.php phpstan-bootstrap.php ${srcRoot}/ + +COPY --chown=spryker:spryker infrastructure/newrelic/entrypoint.sh ${srcRoot}/entrypoint.sh +RUN chmod +x ${srcRoot}/entrypoint.sh + +WORKDIR ${srcRoot} + +ENV APP_ENV=sprykerci +ENV NRIA_ENABLE_PROCESS_METRICS=true + +RUN npm install + +RUN composer install --no-scripts --no-interaction --optimize-autoloader -vvv --no-dev + +RUN composer dump-env sprykerci + +RUN bin/console sdk:init:sdk -n + +RUN bin/console cache:clear --no-debug + +ENTRYPOINT ["/data/entrypoint.sh"] diff --git a/infrastructure/sdk.sprykerci80.Dockerfile b/infrastructure/sdk.sprykerci80.Dockerfile new file mode 100644 index 000000000..ff2384913 --- /dev/null +++ b/infrastructure/sdk.sprykerci80.Dockerfile @@ -0,0 +1,69 @@ +ARG SPRYKER_PARENT_IMAGE=spryker/php:8.0 + +FROM ${SPRYKER_PARENT_IMAGE} AS application-production-dependencies + +USER root + +RUN apk update \ + && apk add --no-cache \ + curl \ + git \ + graphviz \ + nodejs \ + npm \ + rsync \ + && npm install -g npm@8.4.1 + +RUN git config --add --system safe.directory /project + +######################################## +# New Relic Extension +# It's already in the core image. +######################################## +COPY infrastructure/newrelic/newrelic.ini /usr/local/etc/php/conf.d/90-newrelic.ini + +ARG SPRYKER_COMPOSER_MODE + +FROM application-production-dependencies AS application-production-codebase + +RUN chown spryker:spryker ${srcRoot} + +USER spryker +# Authorize SSH Host +RUN mkdir -p /home/spryker/.ssh && \ + chmod 0700 /home/spryker/.ssh && \ + ssh-keyscan github.com > /home/spryker/.ssh/known_hosts + +COPY --chown=spryker:spryker phpstan-bootstrap.php ${srcRoot}/phpstan-bootstrap.php +COPY --chown=spryker:spryker assets ${srcRoot}/assets +COPY --chown=spryker:spryker src ${srcRoot}/src +COPY --chown=spryker:spryker app ${srcRoot}/app +COPY --chown=spryker:spryker db ${srcRoot}/db +COPY --chown=spryker:spryker extension ${srcRoot}/extension +COPY --chown=spryker:spryker config ${srcRoot}/config +COPY --chown=spryker:spryker frontend ${srcRoot}/frontend +COPY --chown=spryker:spryker bin ${srcRoot}/bin +COPY --chown=spryker:spryker .env ${srcRoot}/.env +COPY --chown=spryker:spryker .env.prod ${srcRoot}/.env.prod +COPY --chown=spryker:spryker .env.sprykerci ${srcRoot}/.env.sprykerci +COPY --chown=spryker:spryker composer.json composer.lock package.json package-lock.json bootstrap.php phpstan-bootstrap.php ${srcRoot}/ + +COPY --chown=spryker:spryker infrastructure/newrelic/entrypoint.sh ${srcRoot}/entrypoint.sh +RUN chmod +x ${srcRoot}/entrypoint.sh + +WORKDIR ${srcRoot} + +ENV APP_ENV=sprykerci +ENV NRIA_ENABLE_PROCESS_METRICS=true + +RUN npm install + +RUN composer install --no-scripts --no-interaction --optimize-autoloader -vvv --no-dev + +RUN composer dump-env sprykerci + +RUN bin/console sdk:init:sdk -n + +RUN bin/console cache:clear --no-debug + +ENTRYPOINT ["/data/entrypoint.sh"] diff --git a/infrastructure/sdk.sprykerci81.Dockerfile b/infrastructure/sdk.sprykerci81.Dockerfile new file mode 100644 index 000000000..c34af5b09 --- /dev/null +++ b/infrastructure/sdk.sprykerci81.Dockerfile @@ -0,0 +1,70 @@ +ARG SPRYKER_PARENT_IMAGE=spryker/php:8.1 + +FROM ${SPRYKER_PARENT_IMAGE} AS application-production-dependencies + +USER root + +RUN apk update \ + && apk add --no-cache \ + curl \ + git \ + graphviz \ + nodejs \ + npm \ + rsync \ + && npm install -g npm@8.4.1 + +RUN git config --add --system safe.directory /project + +######################################## +# New Relic Extension +# It's already in the core image. +######################################## + +COPY infrastructure/newrelic/newrelic.ini /usr/local/etc/php/conf.d/90-newrelic.ini + +ARG SPRYKER_COMPOSER_MODE + +FROM application-production-dependencies AS application-production-codebase + +RUN chown spryker:spryker ${srcRoot} + +USER spryker +# Authorize SSH Host +RUN mkdir -p /home/spryker/.ssh && \ + chmod 0700 /home/spryker/.ssh && \ + ssh-keyscan github.com > /home/spryker/.ssh/known_hosts + +COPY --chown=spryker:spryker phpstan-bootstrap.php ${srcRoot}/phpstan-bootstrap.php +COPY --chown=spryker:spryker assets ${srcRoot}/assets +COPY --chown=spryker:spryker src ${srcRoot}/src +COPY --chown=spryker:spryker app ${srcRoot}/app +COPY --chown=spryker:spryker db ${srcRoot}/db +COPY --chown=spryker:spryker extension ${srcRoot}/extension +COPY --chown=spryker:spryker config ${srcRoot}/config +COPY --chown=spryker:spryker frontend ${srcRoot}/frontend +COPY --chown=spryker:spryker bin ${srcRoot}/bin +COPY --chown=spryker:spryker .env ${srcRoot}/.env +COPY --chown=spryker:spryker .env.prod ${srcRoot}/.env.prod +COPY --chown=spryker:spryker .env.sprykerci ${srcRoot}/.env.sprykerci +COPY --chown=spryker:spryker composer.json composer.lock package.json package-lock.json bootstrap.php phpstan-bootstrap.php ${srcRoot}/ + +COPY --chown=spryker:spryker infrastructure/newrelic/entrypoint.sh ${srcRoot}/entrypoint.sh +RUN chmod +x ${srcRoot}/entrypoint.sh + +WORKDIR ${srcRoot} + +ENV APP_ENV=sprykerci +ENV NRIA_ENABLE_PROCESS_METRICS=true + +RUN npm install + +RUN composer install --no-scripts --no-interaction --optimize-autoloader -vvv --no-dev + +RUN composer dump-env sprykerci + +RUN bin/console sdk:init:sdk -n + +RUN bin/console cache:clear --no-debug + +ENTRYPOINT ["/data/entrypoint.sh"] diff --git a/package-lock.json b/package-lock.json index 2f8e4575d..2a1fa1ed3 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1482,9 +1482,9 @@ } }, "node_modules/decode-uri-component": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz", - "integrity": "sha512-hjf+xovcEn31w/EUYdTXQh/8smFL/dzYjohQGEIgjyNavaJfBY2p5F527Bo1VPATxv0VYTUC2bOcXvqFwk78Og==", + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.2.tgz", + "integrity": "sha512-FqUYQ+8o158GyGTrMFJms9qh3CqTKvAqgqsTnkLI8sKu0028orqBhxNMFkFen0zGyg6epACD32pjVk58ngIErQ==", "engines": { "node": ">=0.10" } @@ -3656,9 +3656,9 @@ "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==" }, "node_modules/json5": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.1.tgz", - "integrity": "sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA==", + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", "bin": { "json5": "lib/cli.js" }, @@ -8266,9 +8266,9 @@ } }, "decode-uri-component": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz", - "integrity": "sha512-hjf+xovcEn31w/EUYdTXQh/8smFL/dzYjohQGEIgjyNavaJfBY2p5F527Bo1VPATxv0VYTUC2bOcXvqFwk78Og==" + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.2.tgz", + "integrity": "sha512-FqUYQ+8o158GyGTrMFJms9qh3CqTKvAqgqsTnkLI8sKu0028orqBhxNMFkFen0zGyg6epACD32pjVk58ngIErQ==" }, "deep-is": { "version": "0.1.4", @@ -9972,9 +9972,9 @@ "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==" }, "json5": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.1.tgz", - "integrity": "sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA==" + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==" }, "jsonfile": { "version": "4.0.0", @@ -12646,9 +12646,9 @@ } }, "decode-uri-component": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz", - "integrity": "sha512-hjf+xovcEn31w/EUYdTXQh/8smFL/dzYjohQGEIgjyNavaJfBY2p5F527Bo1VPATxv0VYTUC2bOcXvqFwk78Og==" + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.2.tgz", + "integrity": "sha512-FqUYQ+8o158GyGTrMFJms9qh3CqTKvAqgqsTnkLI8sKu0028orqBhxNMFkFen0zGyg6epACD32pjVk58ngIErQ==" }, "deep-is": { "version": "0.1.4", @@ -14352,9 +14352,9 @@ "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==" }, "json5": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.1.tgz", - "integrity": "sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA==" + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==" }, "jsonfile": { "version": "4.0.0", diff --git a/phpcs.xml b/phpcs.xml index 48a445910..ea2e67b69 100644 --- a/phpcs.xml +++ b/phpcs.xml @@ -8,20 +8,6 @@ - - - - - - - - - - - - - src/Presentation/RestApi/Controller/v1/* - src/ tests/ diff --git a/src/Core/Application/Cache/ContextCacheStorageInterface.php b/src/Core/Application/Cache/ContextCacheStorageInterface.php deleted file mode 100644 index 009c6cafb..000000000 --- a/src/Core/Application/Cache/ContextCacheStorageInterface.php +++ /dev/null @@ -1,40 +0,0 @@ - - */ - public function getAll(): array; - - /** - * @param string $key - * @param \SprykerSdk\Sdk\Core\Domain\Entity\ContextInterface $context - * - * @return void - */ - public function set(string $key, ContextInterface $context): void; - - /** - * @param string $key - * - * @return void - */ - public function remove(string $key): void; -} diff --git a/src/Core/Application/Dependency/ContextFactoryInterface.php b/src/Core/Application/Dependency/ContextFactoryInterface.php index db9c9c5b7..e2430d8de 100644 --- a/src/Core/Application/Dependency/ContextFactoryInterface.php +++ b/src/Core/Application/Dependency/ContextFactoryInterface.php @@ -15,4 +15,9 @@ interface ContextFactoryInterface * @return \SprykerSdk\Sdk\Core\Domain\Entity\ContextInterface */ public function getContext(): ContextInterface; + + /** + * @return bool + */ + public function hasContext(): bool; } diff --git a/src/Core/Application/Dependency/FileManagerInterface.php b/src/Core/Application/Dependency/FileManagerInterface.php deleted file mode 100644 index 4dc77e75a..000000000 --- a/src/Core/Application/Dependency/FileManagerInterface.php +++ /dev/null @@ -1,27 +0,0 @@ - + */ + public function getTaskIds(): array; + /** * @param bool $realCommand * diff --git a/src/Core/Application/Dependency/Repository/TaskSetTaskRelationRepositoryInterface.php b/src/Core/Application/Dependency/Repository/TaskSetTaskRelationRepositoryInterface.php new file mode 100644 index 000000000..c24a83e63 --- /dev/null +++ b/src/Core/Application/Dependency/Repository/TaskSetTaskRelationRepositoryInterface.php @@ -0,0 +1,32 @@ + $relations + * + * @return void + */ + public function createMany(array $relations): void; + + /** + * @param string $taskSetId + * + * @return void + */ + public function removeByTaskSetId(string $taskSetId): void; + + /** + * @param string $taskSetId + * + * @return array<\SprykerSdk\Sdk\Core\Domain\Entity\TaskSetTaskRelationInterface> + */ + public function getByTaskSetId(string $taskSetId): array; +} diff --git a/src/Core/Application/Resources/config/services.yaml b/src/Core/Application/Resources/config/services.yaml index cc5b0c055..6a19615f2 100644 --- a/src/Core/Application/Resources/config/services.yaml +++ b/src/Core/Application/Resources/config/services.yaml @@ -1,6 +1,3 @@ -parameters: - project_log_file: ".ssdk/.ssdk.log" - project_settings_file: "./.ssdk/settings" services: value_receiver: abstract: true @@ -58,6 +55,7 @@ services: class: SprykerSdk\Sdk\Core\Application\Service\ContextSerializer arguments: - "@report_array_converter_factory" + - "@context_factory" context_repository: synthetic: true task_executor: @@ -78,36 +76,6 @@ services: - "@project_setting_repository" - "@setting_repository" - service.file_manager: - class: SprykerSdk\Sdk\Core\Application\Service\FileManager - - lifecycle.initialized_subscriber: - class: SprykerSdk\Sdk\Core\Application\Lifecycle\Subscriber\InitializedEventSubscriber - tags: [ "kernel.event_subscriber" ] - arguments: - - "@service.file_manager" - - "@placeholder_resolver" - - "@service.lifecycle_command_executor" - - "@context_factory" - - lifecycle.removed_subscriber: - class: SprykerSdk\Sdk\Core\Application\Lifecycle\Subscriber\UpdatedEventSubscriber - tags: [ "kernel.event_subscriber" ] - arguments: - - "@service.file_manager" - - "@placeholder_resolver" - - "@service.lifecycle_command_executor" - - "@context_factory" - - lifecycle.updated_subscriber: - class: SprykerSdk\Sdk\Core\Application\Lifecycle\Subscriber\RemovedEventSubscriber - tags: [ "kernel.event_subscriber" ] - arguments: - - "@service.file_manager" - - "@placeholder_resolver" - - "@service.lifecycle_command_executor" - - "@context_factory" - log_event_action_after_command_executed: class: SprykerSdk\Sdk\Core\Application\Service\AfterCommandExecutedAction\LogEventAction arguments: diff --git a/src/Core/Application/Service/ContextFactory.php b/src/Core/Application/Service/ContextFactory.php index 807f1af66..2a786c65c 100644 --- a/src/Core/Application/Service/ContextFactory.php +++ b/src/Core/Application/Service/ContextFactory.php @@ -45,4 +45,12 @@ public function getContext(): ContextInterface return $this->context; } + + /** + * @return bool + */ + public function hasContext(): bool + { + return $this->context !== null; + } } diff --git a/src/Core/Application/Service/ContextSerializer.php b/src/Core/Application/Service/ContextSerializer.php index 463cc3441..213500b81 100644 --- a/src/Core/Application/Service/ContextSerializer.php +++ b/src/Core/Application/Service/ContextSerializer.php @@ -7,8 +7,8 @@ namespace SprykerSdk\Sdk\Core\Application\Service; +use SprykerSdk\Sdk\Core\Application\Dependency\ContextFactoryInterface; use SprykerSdk\Sdk\Core\Application\Exception\InvalidReportTypeException; -use SprykerSdk\Sdk\Core\Domain\Entity\Context; use SprykerSdk\Sdk\Core\Domain\Entity\ContextInterface; use SprykerSdk\Sdk\Core\Domain\Entity\Message; use SprykerSdk\SdkContracts\Entity\MessageInterface; @@ -21,12 +21,21 @@ class ContextSerializer */ protected ReportArrayConverterFactory $reportArrayConverterFactory; + /** + * @var \SprykerSdk\Sdk\Core\Application\Dependency\ContextFactoryInterface + */ + protected ContextFactoryInterface $contextFactory; + /** * @param \SprykerSdk\Sdk\Core\Application\Service\ReportArrayConverterFactory $reportArrayConverterFactory + * @param \SprykerSdk\Sdk\Core\Application\Dependency\ContextFactoryInterface $contextFactory */ - public function __construct(ReportArrayConverterFactory $reportArrayConverterFactory) - { + public function __construct( + ReportArrayConverterFactory $reportArrayConverterFactory, + ContextFactoryInterface $contextFactory + ) { $this->reportArrayConverterFactory = $reportArrayConverterFactory; + $this->contextFactory = $contextFactory; } /** @@ -53,7 +62,7 @@ public function serialize(ContextInterface $context): string */ public function deserialize(string $content): ContextInterface { - $context = new Context(); + $context = $this->contextFactory->getContext(); $data = json_decode($content, true, 512, JSON_THROW_ON_ERROR); if (array_key_exists('tags', $data) && is_array($data['tags'])) { diff --git a/src/Core/Application/Service/FileManager.php b/src/Core/Application/Service/FileManager.php deleted file mode 100644 index ecff647f5..000000000 --- a/src/Core/Application/Service/FileManager.php +++ /dev/null @@ -1,38 +0,0 @@ -getPath(), $file->getContent()); - } - - /** - * @param \SprykerSdk\Sdk\Core\Domain\Entity\FileInterface $file - * - * @return bool - */ - public function remove(FileInterface $file): bool - { - if (file_exists($file->getPath())) { - return unlink($file->getPath()); - } - - return false; - } -} diff --git a/src/Core/Domain/Entity/TaskSetTaskRelation.php b/src/Core/Domain/Entity/TaskSetTaskRelation.php new file mode 100644 index 000000000..47dd3e39b --- /dev/null +++ b/src/Core/Domain/Entity/TaskSetTaskRelation.php @@ -0,0 +1,49 @@ +taskSet = $taskSet; + $this->subTask = $subTask; + } + + /** + * @return \SprykerSdk\SdkContracts\Entity\TaskInterface + */ + public function getTaskSet(): TaskInterface + { + return $this->taskSet; + } + + /** + * @return \SprykerSdk\SdkContracts\Entity\TaskInterface + */ + public function getSubTask(): TaskInterface + { + return $this->subTask; + } +} diff --git a/src/Core/Domain/Entity/TaskSetTaskRelationInterface.php b/src/Core/Domain/Entity/TaskSetTaskRelationInterface.php new file mode 100644 index 000000000..d41c40f61 --- /dev/null +++ b/src/Core/Domain/Entity/TaskSetTaskRelationInterface.php @@ -0,0 +1,23 @@ +setClass($classNamespace) ->setStartLine($message['line']) diff --git a/src/Extension/Converter/PrettierSnifferViolationReportConverter.php b/src/Extension/Converter/PrettierSnifferViolationReportConverter.php index 96a88e38f..bdc079e6f 100644 --- a/src/Extension/Converter/PrettierSnifferViolationReportConverter.php +++ b/src/Extension/Converter/PrettierSnifferViolationReportConverter.php @@ -86,8 +86,8 @@ protected function parseViolations(string $report): array ->setSeverity( $matches['severity'] === 'warn' ? ViolationInterface::SEVERITY_WARNING : ViolationInterface::SEVERITY_ERROR, ) - ->setStartLine($matches['line'] ?? null) - ->setStartColumn($matches['column'] ?? null) + ->setStartLine(isset($matches['line']) ? (int)$matches['line'] : null) + ->setStartColumn(isset($matches['column']) ? (int)$matches['column'] : null) ->setFixable($matches['severity'] === 'error' ? false : true) ->setProduced($this->producer); } diff --git a/src/Extension/Resources/config/services.yaml b/src/Extension/Resources/config/services.yaml index de4d22fa4..049acabaa 100644 --- a/src/Extension/Resources/config/services.yaml +++ b/src/Extension/Resources/config/services.yaml @@ -31,11 +31,6 @@ services: class: SprykerSdk\Sdk\Extension\Task\Command\CheckGitCommand generate_app_command: class: SprykerSdk\Sdk\Extension\Task\Command\GenerateAppCommand - generate_app_change_php_version_command: - class: SprykerSdk\Sdk\Extension\Task\Command\ChangePhpVersionCommand - arguments: - - '@app_modify_composer_file' - - '@app_modify_docker_file' generate_app_allow_default_composer_plugins_command: class: SprykerSdk\Sdk\Extension\Task\Command\AllowDefaultComposerPluginCommand arguments: @@ -65,7 +60,6 @@ services: - '@check_git_command' - '@generate_app_command' - '@generate_app_change_name_command' - - '@generate_app_change_php_version_command' - '@generate_app_allow_default_composer_plugins_command' - '@generate_app_update_dependencies_command' - '@add_docker_sdk_command' @@ -95,12 +89,6 @@ services: - '@value_receiver' - '%uname_info%' - app_php_version_value_resolver: - class: SprykerSdk\Sdk\Extension\ValueResolver\AppPhpVersionValueResolver - tags: [ 'sdk.value_resolver' ] - arguments: - - '@value_receiver' - remove_report_dir: class: SprykerSdk\Sdk\Extension\Task\RemoveRepDirTask tags: [ "sdk.task" ] @@ -167,7 +155,7 @@ services: interaction_answer_based_transition_resolver: class: SprykerSdk\Sdk\Extension\Workflow\InteractionAnswerBasedTransitionResolver arguments: - - '@cli_interaction_processor' + - '@interaction_processor' tags: [ 'workflow.transition_resolver' ] uname_env_var_processor: diff --git a/src/Extension/Resources/config/task/AcpAppManifestCreateTask.yaml b/src/Extension/Resources/config/task/AcpAppManifestCreateTask.yaml index fb27c583b..f41e9c4d1 100644 --- a/src/Extension/Resources/config/task/AcpAppManifestCreateTask.yaml +++ b/src/Extension/Resources/config/task/AcpAppManifestCreateTask.yaml @@ -3,8 +3,8 @@ id: "acp:manifest:create" short_description: "Create ACP manifest file." help: ~ stage: build -version: 0.2.1 -command: "php %sdk_dir%/vendor/bin/acp app:manifest:create %manifest-path% %name% %locale%" +version: 0.2.3 +command: "php %sdk_dir%/vendor/bin/acp app:manifest:create %name% %locale%" type: !php/const SprykerSdk\SdkContracts\Enum\Task::TYPE_LOCAL_CLI_INTERACTIVE placeholders: - name: "%sdk_dir%" @@ -25,11 +25,3 @@ placeholders: description: "A valid locale e.g.: en_US" type: !php/const SprykerSdk\SdkContracts\Enum\ValueTypeEnum::TYPE_STRING defaultValue: "en_US" - - name: "%manifest-path%" - value_resolver: STATIC - optional: true - configuration: - alias: "manifest-path" - option: "manifest-path" - description: "Path to save manifest file to" - type: !php/const SprykerSdk\SdkContracts\Enum\ValueTypeEnum::TYPE_STRING diff --git a/src/Extension/Resources/config/task/AcpAppManifestValidateTask.yaml b/src/Extension/Resources/config/task/AcpAppManifestValidateTask.yaml index adcce3358..c35c88c5d 100644 --- a/src/Extension/Resources/config/task/AcpAppManifestValidateTask.yaml +++ b/src/Extension/Resources/config/task/AcpAppManifestValidateTask.yaml @@ -3,18 +3,10 @@ id: "acp:manifest:validate" short_description: "Validate ACP manifest file." help: ~ stage: build -version: 0.2.1 -command: "php %sdk_dir%/vendor/bin/acp app:manifest:validate %manifest-path%" +version: 0.2.3 +command: "php %sdk_dir%/vendor/bin/acp app:manifest:validate" type: !php/const SprykerSdk\SdkContracts\Enum\Task::TYPE_LOCAL_CLI placeholders: - name: "%sdk_dir%" value_resolver: SDK_DIR optional: true - - name: "%manifest-path%" - value_resolver: STATIC - optional: true - configuration: - alias: "manifest-path" - option: "manifest-path" - description: "Path to manifest file" - type: !php/const SprykerSdk\SdkContracts\Enum\ValueTypeEnum::TYPE_STRING diff --git a/src/Extension/Resources/config/task/AcpAppOpenApiCodeGenerateTask.yaml b/src/Extension/Resources/config/task/AcpAppOpenApiCodeGenerateTask.yaml index 7d36836d5..d5839201f 100644 --- a/src/Extension/Resources/config/task/AcpAppOpenApiCodeGenerateTask.yaml +++ b/src/Extension/Resources/config/task/AcpAppOpenApiCodeGenerateTask.yaml @@ -3,29 +3,21 @@ id: "acp:openapi:generate" short_description: "Generate ACP OpenAPI code." help: ~ stage: build -version: 0.2.1 -command: "INSTALLED_ROOT_DIRECTORY=%sdk_dir% php %sdk_dir%/vendor/bin/syncapi code:openapi:generate %project-root% %openapi-file% %application-type% %organization% -v" +version: 0.2.3 +command: "INSTALLED_ROOT_DIRECTORY=%sdk_dir% php %sdk_dir%/vendor/bin/syncapi code:openapi:generate %openapi-file% %application-type% %organization% -v" type: !php/const SprykerSdk\SdkContracts\Enum\Task::TYPE_LOCAL_CLI_INTERACTIVE placeholders: - name: "%sdk_dir%" value_resolver: SDK_DIR optional: true - - name: "%project-root%" - value_resolver: STATIC - optional: true - configuration: - alias: "project-root" - option: "project-root" - description: "Relative path to project root" - type: !php/const SprykerSdk\SdkContracts\Enum\ValueTypeEnum::TYPE_PATH - name: "%openapi-file%" - value_resolver: STATIC + value_resolver: PRIORITY_PATH optional: true configuration: alias: "openapi-file" option: "openapi-file" description: "Path to OpenAPI file" - type: !php/const SprykerSdk\SdkContracts\Enum\ValueTypeEnum::TYPE_STRING + settingPaths: [ !php/const SprykerSdk\SdkContracts\Enum\Setting::PATH_PROJECT_DIR ] - name: "%organization%" value_resolver: STATIC optional: true diff --git a/src/Extension/Resources/config/task/AcpAppTranslationValidateTask.yaml b/src/Extension/Resources/config/task/AcpAppTranslationValidateTask.yaml index eb8706659..3873d128c 100644 --- a/src/Extension/Resources/config/task/AcpAppTranslationValidateTask.yaml +++ b/src/Extension/Resources/config/task/AcpAppTranslationValidateTask.yaml @@ -3,8 +3,8 @@ id: "acp:translation:validate" short_description: "Validate ACP translation file." help: ~ stage: build -version: 0.2.1 -command: "php %sdk_dir%/vendor/bin/acp app:translation:validate %translation-file% %manifest-path% %configuration-file%" +version: 0.2.3 +command: "php %sdk_dir%/vendor/bin/acp app:translation:validate %translation-file% %configuration-file%" type: !php/const SprykerSdk\SdkContracts\Enum\Task::TYPE_LOCAL_CLI placeholders: - name: "%sdk_dir%" @@ -18,14 +18,7 @@ placeholders: option: "translation-file" description: "Path to translation file" type: !php/const SprykerSdk\SdkContracts\Enum\ValueTypeEnum::TYPE_STRING - - name: "%manifest-path%" - value_resolver: STATIC - optional: true - configuration: - alias: "manifest-path" - option: "manifest-path" - description: "Path to manifest file" - type: !php/const SprykerSdk\SdkContracts\Enum\ValueTypeEnum::TYPE_STRING + settingPaths: [ !php/const SprykerSdk\SdkContracts\Enum\Setting::PATH_PROJECT_DIR ] - name: "%configuration-file%" value_resolver: STATIC optional: true diff --git a/src/Extension/Resources/config/task/AcpAppValidateTask.yaml b/src/Extension/Resources/config/task/AcpAppValidateTask.yaml index 3251abd47..41be1c3c4 100644 --- a/src/Extension/Resources/config/task/AcpAppValidateTask.yaml +++ b/src/Extension/Resources/config/task/AcpAppValidateTask.yaml @@ -3,21 +3,13 @@ id: "acp:app:validate" short_description: "Create ACP AsyncAPI file." help: ~ stage: build -version: 0.2.1 -command: "php %sdk_dir%/vendor/bin/acp app:validate %manifest-path% %configuration-file% %translation-file% -v" +version: 0.2.3 +command: "php %sdk_dir%/vendor/bin/acp app:validate %configuration-file% %translation-file% -v" type: !php/const SprykerSdk\SdkContracts\Enum\Task::TYPE_LOCAL_CLI placeholders: - name: "%sdk_dir%" value_resolver: SDK_DIR optional: true - - name: "%manifest-path%" - value_resolver: STATIC - optional: true - configuration: - alias: "manifest-path" - option: "manifest-path" - description: "Path to save manifest file to" - type: !php/const SprykerSdk\SdkContracts\Enum\ValueTypeEnum::TYPE_STRING - name: "%configuration-file%" value_resolver: STATIC optional: true diff --git a/src/Extension/Resources/config/task/CodesnifferFixerTask.yaml b/src/Extension/Resources/config/task/CodesnifferFixerTask.yaml index dc8077913..8eb350acd 100644 --- a/src/Extension/Resources/config/task/CodesnifferFixerTask.yaml +++ b/src/Extension/Resources/config/task/CodesnifferFixerTask.yaml @@ -3,7 +3,7 @@ id: "validation:php:codestyle-fix" short_description: "Check your code by running a static code analysis" help: "You may need to set default phpcs standard before using it. By default uses phpcs.xml from the project root." stage: build -version: 1.1.1 +version: 1.1.2 command: "php %executable_command% %severity% %path%" type: !php/const SprykerSdk\SdkContracts\Enum\Task::TYPE_LOCAL_CLI optional: true @@ -23,10 +23,10 @@ placeholders: option: 'severity' description: 'Severity level of the CodeSniffer' - name: "%path%" - value_resolver: STATIC + value_resolver: PRIORITY_PATH optional: false configuration: alias: "path" description: "Relative path to module directory in project" - type: !php/const SprykerSdk\SdkContracts\Enum\ValueTypeEnum::TYPE_PATH + settingPaths: [ !php/const SprykerSdk\SdkContracts\Enum\Setting::PATH_PROJECT_DIR, !php/const SprykerSdk\SdkContracts\Enum\Setting::PATH_SDK_DIR ] defaultValue: 'src' diff --git a/src/Extension/Resources/config/task/CodesnifferTask.yaml b/src/Extension/Resources/config/task/CodesnifferTask.yaml index 88f78f4f3..62d1019a5 100644 --- a/src/Extension/Resources/config/task/CodesnifferTask.yaml +++ b/src/Extension/Resources/config/task/CodesnifferTask.yaml @@ -23,12 +23,12 @@ placeholders: type: !php/const SprykerSdk\SdkContracts\Enum\ValueTypeEnum::TYPE_STRING defaultValue: 'json' - name: "%path%" - value_resolver: STATIC + value_resolver: PRIORITY_PATH optional: false configuration: alias: "path" description: "Relative path to module directory in project" - type: !php/const SprykerSdk\SdkContracts\Enum\ValueTypeEnum::TYPE_PATH + settingPaths: [ !php/const SprykerSdk\SdkContracts\Enum\Setting::PATH_PROJECT_DIR, !php/const SprykerSdk\SdkContracts\Enum\Setting::PATH_SDK_DIR ] defaultValue: 'src' - name: "%reportDir%" value_resolver: REPORT_DIR diff --git a/src/Extension/Resources/config/task/DeprecationsCheckTask.yaml b/src/Extension/Resources/config/task/DeprecationsCheckTask.yaml index 998ba9a09..4ab37439c 100644 --- a/src/Extension/Resources/config/task/DeprecationsCheckTask.yaml +++ b/src/Extension/Resources/config/task/DeprecationsCheckTask.yaml @@ -3,8 +3,8 @@ id: "validation:php:deprecations-check" short_description: "Check your code by running a static code analysis and generate report with deprecations. By default uses `psalm.xml` config file." help: "By default exits with code `1` in case of critical error and with code `0` in all other cases. Adjust the depth of analysis by specifying `errorLevel=1` in the `psalm.xml` file if you want to prevent command fails in case of critical errors." stage: build -version: 1.1.1 -command: "php %executable_command% --config=%config% %no-progress% %output-format% %reportDir% 1> /dev/null" +version: 1.1.2 +command: "php %executable_command% %config% %no-progress% %output-format% %reportDir% 1> /dev/null" type: !php/const SprykerSdk\SdkContracts\Enum\Task::TYPE_LOCAL_CLI placeholders: - name: "%executable_command%" @@ -47,13 +47,14 @@ placeholders: settingPaths: [!php/const SprykerSdk\SdkContracts\Enum\Setting::PATH_REPORT_DIR] defaultValue: "psalm.deprecations_report.json" - name: "%config%" - value_resolver: CONFIG_PATH + value_resolver: PRIORITY_PATH optional: true configuration: option: "config" alias: "config" description: "Config file" defaultValue: "psalm.xml" + settingPaths: [ !php/const SprykerSdk\SdkContracts\Enum\Setting::PATH_PROJECT_DIR, !php/const SprykerSdk\SdkContracts\Enum\Setting::PATH_SDK_DIR ] report_converter: name: DeprecationsReportConverter configuration: diff --git a/src/Extension/Resources/config/task/PhpMdTask.yaml b/src/Extension/Resources/config/task/PhpMdTask.yaml index dd307e0bf..496ce715c 100644 --- a/src/Extension/Resources/config/task/PhpMdTask.yaml +++ b/src/Extension/Resources/config/task/PhpMdTask.yaml @@ -3,8 +3,8 @@ id: "validation:php:architecture" short_description: "Check the architectural correctness of your code" help: ~ stage: debug -version: 1.1.1 -command: "%executable_command% %path% %format% %config% %strict% %minimum-priority% %priority% %reportDir%" +version: 1.1.3 +command: "%executable_command% %path% %format% %config% %strict% %minimum-priority% %priority% %reportDir%" type: !php/const SprykerSdk\SdkContracts\Enum\Task::TYPE_LOCAL_CLI placeholders: - name: "%executable_command%" @@ -22,12 +22,12 @@ placeholders: type: !php/const SprykerSdk\SdkContracts\Enum\ValueTypeEnum::TYPE_PATH defaultValue: 'json' - name: "%path%" - value_resolver: STATIC + value_resolver: PRIORITY_PATH optional: true configuration: alias: "path" description: "Relative path to module directory in project" - type: !php/const SprykerSdk\SdkContracts\Enum\ValueTypeEnum::TYPE_PATH + settingPaths: [ !php/const SprykerSdk\SdkContracts\Enum\Setting::PATH_PROJECT_DIR, !php/const SprykerSdk\SdkContracts\Enum\Setting::PATH_SDK_DIR ] defaultValue: 'src' - name: "%strict%" value_resolver: FLAG @@ -38,19 +38,19 @@ placeholders: defaultValue: false - name: "%minimum-priority%" value_resolver: FLAG - optional: false + optional: true configuration: alias: "minimum-priority" description: "Minimum priority" defaultValue: true - name: "%config%" - value_resolver: CONFIG_PATH + value_resolver: PRIORITY_PATH optional: true configuration: - option: "config" alias: "config" description: "Config file" defaultValue: "vendor/spryker/architecture-sniffer/src/ruleset.xml" + settingPaths: [ !php/const SprykerSdk\SdkContracts\Enum\Setting::PATH_PROJECT_DIR, !php/const SprykerSdk\SdkContracts\Enum\Setting::PATH_SDK_DIR ] - name: "%priority%" value_resolver: STATIC optional: false diff --git a/src/Extension/Resources/config/task/PhpStanTask.yaml b/src/Extension/Resources/config/task/PhpStanTask.yaml index 62101aab9..44bbde7be 100644 --- a/src/Extension/Resources/config/task/PhpStanTask.yaml +++ b/src/Extension/Resources/config/task/PhpStanTask.yaml @@ -3,7 +3,7 @@ id: "validation:php:static" short_description: "Check your code by running a static code analysis" help: ~ stage: build -version: 1.1.1 +version: 1.1.2 command: "php %sdk_dir%/vendor/bin/phpstan analyze %path% %configuration% %config-path% %error-format% --level=%level% > %reportDir%" type: !php/const SprykerSdk\SdkContracts\Enum\Task::TYPE_LOCAL_CLI placeholders: @@ -11,12 +11,12 @@ placeholders: value_resolver: SDK_DIR optional: true - name: "%path%" - value_resolver: STATIC + value_resolver: PRIORITY_PATH optional: false configuration: alias: "path" description: "Relative path to module directory in project" - type: !php/const SprykerSdk\SdkContracts\Enum\ValueTypeEnum::TYPE_PATH + settingPaths: [ !php/const SprykerSdk\SdkContracts\Enum\Setting::PATH_PROJECT_DIR ] defaultValue: 'src' - name: '%configuration%' value_resolver: FLAG diff --git a/src/Extension/Resources/config/task/PrettierSnifferFixTask.yaml b/src/Extension/Resources/config/task/PrettierSnifferFixTask.yaml index 25fc91c4f..165e569d5 100644 --- a/src/Extension/Resources/config/task/PrettierSnifferFixTask.yaml +++ b/src/Extension/Resources/config/task/PrettierSnifferFixTask.yaml @@ -3,7 +3,7 @@ id: "validation:frontend:prettier-fix" short_description: "An opinionated code formatter" help: ~ stage: build -version: 0.2.1 +version: 0.2.2 command: "npx --prefix %sdk_dir% prettier --write --loglevel=%log_level% %path%" type: !php/const SprykerSdk\SdkContracts\Enum\Task::TYPE_LOCAL_CLI placeholders: @@ -11,12 +11,12 @@ placeholders: value_resolver: SDK_DIR optional: true - name: "%path%" - value_resolver: STATIC + value_resolver: PRIORITY_PATH optional: false configuration: alias: "path" description: "Relative path to module directory in project" - type: !php/const SprykerSdk\SdkContracts\Enum\ValueTypeEnum::TYPE_PATH + settingPaths: [ !php/const SprykerSdk\SdkContracts\Enum\Setting::PATH_PROJECT_DIR ] defaultValue: 'src' - name: "%log_level%" value_resolver: STATIC diff --git a/src/Extension/Resources/config/task/PrettierSnifferTask.yaml b/src/Extension/Resources/config/task/PrettierSnifferTask.yaml index 085578151..eb3174967 100644 --- a/src/Extension/Resources/config/task/PrettierSnifferTask.yaml +++ b/src/Extension/Resources/config/task/PrettierSnifferTask.yaml @@ -3,7 +3,7 @@ id: "validation:frontend:prettier" short_description: "An opinionated code formatter" help: ~ stage: build -version: 0.2.1 +version: 0.2.2 command: "npx --prefix %sdk_dir% prettier %check% %log-level% %path% > %reportDir% 2>&1" type: !php/const SprykerSdk\SdkContracts\Enum\Task::TYPE_LOCAL_CLI placeholders: @@ -40,12 +40,12 @@ placeholders: settingPaths: [!php/const SprykerSdk\SdkContracts\Enum\Setting::PATH_REPORT_DIR] defaultValue: "frontend.prettier.log" - name: "%path%" - value_resolver: STATIC + value_resolver: PRIORITY_PATH optional: false configuration: alias: "path" description: "Relative path to module directory in project" - type: !php/const SprykerSdk\SdkContracts\Enum\ValueTypeEnum::TYPE_PATH + settingPaths: [ !php/const SprykerSdk\SdkContracts\Enum\Setting::PATH_PROJECT_DIR ] defaultValue: 'src' report_converter: name: PrettierSnifferViolationReportConverter diff --git a/src/Extension/Resources/config/task/RectorProcessTask.yaml b/src/Extension/Resources/config/task/RectorProcessTask.yaml index 2baf2fa50..a3717a8e5 100644 --- a/src/Extension/Resources/config/task/RectorProcessTask.yaml +++ b/src/Extension/Resources/config/task/RectorProcessTask.yaml @@ -3,7 +3,7 @@ id: "validation:php:rector" short_description: "Instant Upgrades and Automated Refactoring" help: ~ stage: build -version: 0.2.1 +version: 0.2.2 command: "php %executable_command% process %path% %config% %is-ansi%" type: !php/const SprykerSdk\SdkContracts\Enum\Task::TYPE_LOCAL_CLI optional: false @@ -16,12 +16,12 @@ placeholders: defaultValue: "vendor/bin/rector" settingPaths: [ !php/const SprykerSdk\SdkContracts\Enum\Setting::PATH_PROJECT_DIR, !php/const SprykerSdk\SdkContracts\Enum\Setting::PATH_SDK_DIR ] - name: "%path%" - value_resolver: STATIC + value_resolver: PRIORITY_PATH optional: false configuration: alias: "path" description: "Relative path to module directory in project" - type: !php/const SprykerSdk\SdkContracts\Enum\ValueTypeEnum::TYPE_PATH + settingPaths: [ !php/const SprykerSdk\SdkContracts\Enum\Setting::PATH_PROJECT_DIR, !php/const SprykerSdk\SdkContracts\Enum\Setting::PATH_SDK_DIR ] defaultValue: "src" - name: "%config%" value_resolver: STATIC diff --git a/src/Extension/Resources/config/task/RunInstallTask.yaml b/src/Extension/Resources/config/task/RunInstallTask.yaml index 7754611b2..9e4175ca9 100644 --- a/src/Extension/Resources/config/task/RunInstallTask.yaml +++ b/src/Extension/Resources/config/task/RunInstallTask.yaml @@ -3,6 +3,14 @@ id: "project:installer:run" short_description: "Runs Sprykers install command." help: ~ stage: build -version: 0.4.1 -command: "php ./vendor/bin/install" +version: 0.4.2 +command: "php %executable_command%" type: !php/const SprykerSdk\SdkContracts\Enum\Task::TYPE_LOCAL_CLI +placeholders: + - name: "%executable_command%" + value_resolver: PRIORITY_PATH + optional: true + configuration: + description: "Executable folder (uses the first existing path)" + defaultValue: "vendor/bin/install" + settingPaths: [ !php/const SprykerSdk\SdkContracts\Enum\Setting::PATH_PROJECT_DIR ] diff --git a/src/Extension/Resources/config/task/ScssLinterFixerTask.yaml b/src/Extension/Resources/config/task/ScssLinterFixerTask.yaml index 5ad3d01d2..5a2a45900 100644 --- a/src/Extension/Resources/config/task/ScssLinterFixerTask.yaml +++ b/src/Extension/Resources/config/task/ScssLinterFixerTask.yaml @@ -3,7 +3,7 @@ id: "validation:scss:codestyle-fix" short_description: "Fixes violations and validates your scss code" help: ~ stage: build -version: 0.2.1 +version: 0.2.2 command: "node %sdk_dir%/frontend/libs/stylelint.js %fix% %file-path% %config-path% > %reportDir%" type: !php/const SprykerSdk\SdkContracts\Enum\Task::TYPE_LOCAL_CLI placeholders: @@ -26,21 +26,21 @@ placeholders: settingPaths: [!php/const SprykerSdk\SdkContracts\Enum\Setting::PATH_REPORT_DIR] defaultValue: "stylelint.codestyle.json" - name: "%file-path%" - value_resolver: STATIC + value_resolver: PRIORITY_PATH optional: true configuration: alias: "file-path" option: "file-path" description: "Execute stylelint only for this file" - type: !php/const SprykerSdk\SdkContracts\Enum\ValueTypeEnum::TYPE_STRING + settingPaths: [ !php/const SprykerSdk\SdkContracts\Enum\Setting::PATH_PROJECT_DIR ] - name: "%config-path%" - value_resolver: STATIC + value_resolver: PRIORITY_PATH optional: true configuration: alias: "config-path" option: "config-path" description: "Use this stylelint config instead of default" - type: !php/const SprykerSdk\SdkContracts\Enum\ValueTypeEnum::TYPE_STRING + settingPaths: [ !php/const SprykerSdk\SdkContracts\Enum\Setting::PATH_PROJECT_DIR ] report_converter: name: ScssLinterViolationReportConverter configuration: diff --git a/src/Extension/Resources/config/task/ScssLinterTask.yaml b/src/Extension/Resources/config/task/ScssLinterTask.yaml index b467dd6ec..a1206d330 100644 --- a/src/Extension/Resources/config/task/ScssLinterTask.yaml +++ b/src/Extension/Resources/config/task/ScssLinterTask.yaml @@ -3,7 +3,7 @@ id: "validation:scss:codestyle" short_description: "Check your scss styles to avoid errors and enforce conventions" help: ~ stage: build -version: 0.2.1 +version: 0.2.2 command: "node %sdk_dir%/frontend/libs/stylelint.js %file-path% %config-path% > %reportDir%" type: !php/const SprykerSdk\SdkContracts\Enum\Task::TYPE_LOCAL_CLI placeholders: @@ -19,21 +19,21 @@ placeholders: settingPaths: [!php/const SprykerSdk\SdkContracts\Enum\Setting::PATH_REPORT_DIR] defaultValue: "stylelint.codestyle.json" - name: "%file-path%" - value_resolver: STATIC + value_resolver: PRIORITY_PATH optional: true configuration: alias: "file-path" option: "file-path" description: "Execute stylelint only for this file" - type: !php/const SprykerSdk\SdkContracts\Enum\ValueTypeEnum::TYPE_STRING + settingPaths: [ !php/const SprykerSdk\SdkContracts\Enum\Setting::PATH_PROJECT_DIR ] - name: "%config-path%" - value_resolver: STATIC + value_resolver: PRIORITY_PATH optional: true configuration: alias: "config-path" option: "config-path" description: "Use this stylelint config instead of default" - type: !php/const SprykerSdk\SdkContracts\Enum\ValueTypeEnum::TYPE_STRING + settingPaths: [ !php/const SprykerSdk\SdkContracts\Enum\Setting::PATH_PROJECT_DIR ] report_converter: name: ScssLinterViolationReportConverter configuration: diff --git a/src/Extension/Resources/config/task/SprykBuildTask.yaml b/src/Extension/Resources/config/task/SprykBuildTask.yaml index cc0b4ffea..2d45330f6 100644 --- a/src/Extension/Resources/config/task/SprykBuildTask.yaml +++ b/src/Extension/Resources/config/task/SprykBuildTask.yaml @@ -11,4 +11,4 @@ placeholders: configuration: description: "Executable folder (uses the first existing path)" defaultValue: "vendor/bin/spryk-build" - settingPaths: [ !php/const SprykerSdk\SdkContracts\Enum\Setting::PATH_PROJECT_DIR, !php/const SprykerSdk\SdkContracts\Enum\Setting::PATH_SDK_DIR ] + settingPaths: [ !php/const SprykerSdk\SdkContracts\Enum\Setting::PATH_SDK_DIR ] diff --git a/src/Extension/Resources/config/task/SprykDumpTask.yaml b/src/Extension/Resources/config/task/SprykDumpTask.yaml index 7fee88479..46cb3b74f 100644 --- a/src/Extension/Resources/config/task/SprykDumpTask.yaml +++ b/src/Extension/Resources/config/task/SprykDumpTask.yaml @@ -11,7 +11,7 @@ placeholders: configuration: description: "Executable folder (uses the first existing path)" defaultValue: "vendor/bin/spryk-dump" - settingPaths: [ !php/const SprykerSdk\SdkContracts\Enum\Setting::PATH_PROJECT_DIR, !php/const SprykerSdk\SdkContracts\Enum\Setting::PATH_SDK_DIR ] + settingPaths: [ !php/const SprykerSdk\SdkContracts\Enum\Setting::PATH_SDK_DIR ] - name: "%spryk%" optional: true value_resolver: STATIC diff --git a/src/Extension/Resources/config/task/SprykRunTask.yaml b/src/Extension/Resources/config/task/SprykRunTask.yaml index af70b5abd..84593279a 100644 --- a/src/Extension/Resources/config/task/SprykRunTask.yaml +++ b/src/Extension/Resources/config/task/SprykRunTask.yaml @@ -1,8 +1,8 @@ --- id: "spryk:run" -short_description: "Runs a Spryk build process." -version: "0.1.0" -command: "php %executable_command% %spryk% %targetModule% %dependentModule% %option%" +short_description: "Runs a Spryk build process. Use --spryk option for the spryk name." +version: "0.1.1" +command: "php %executable_command% %spryk% %organization% %coreLevel% %option%" type: !php/const SprykerSdk\SdkContracts\Enum\Task::TYPE_LOCAL_CLI_INTERACTIVE placeholders: - name: "%executable_command%" @@ -11,7 +11,7 @@ placeholders: configuration: description: "Executable folder (uses the first existing path)" defaultValue: "vendor/bin/spryk-run" - settingPaths: [ !php/const SprykerSdk\SdkContracts\Enum\Setting::PATH_PROJECT_DIR, !php/const SprykerSdk\SdkContracts\Enum\Setting::PATH_SDK_DIR ] + settingPaths: [ !php/const SprykerSdk\SdkContracts\Enum\Setting::PATH_SDK_DIR ] - name: "%spryk%" value_resolver: STATIC optional: false @@ -19,24 +19,30 @@ placeholders: alias: 'spryk' description: 'Name of the Spryk which should be build.' type: !php/const SprykerSdk\SdkContracts\Enum\ValueTypeEnum::TYPE_STRING - - name: "%targetModule%" - value_resolver: STATIC - optional: true + - name: "%organization%" + value_resolver: NAMESPACE + optional: false configuration: - alias: 'targetModule' - description: 'Name of the target module in format "[Organization.]ModuleName[.LayerName]".' - type: !php/const SprykerSdk\SdkContracts\Enum\ValueTypeEnum::TYPE_STRING - - name: "%dependentModule%" - value_resolver: STATIC - optional: true + alias: "namespace" + option: "organization" + description: "Namespace name" + type: !php/const SprykerSdk\SdkContracts\Enum\ValueTypeEnum::TYPE_STRING + defaultValue: 'Pyz' + settingPaths: [ "projectNamespaces", "coreNamespaces" ] + - name: "%coreLevel%" + value_resolver: CORE + optional: false configuration: - alias: 'dependentModule' - description: 'Name of the dependent module in format "[Organization.]ModuleName[.LayerName]".' - type: !php/const SprykerSdk\SdkContracts\Enum\ValueTypeEnum::TYPE_STRING + alias: "mode" + option: "mode" + description: "Core Level" + type: !php/const SprykerSdk\SdkContracts\Enum\ValueTypeEnum::TYPE_STRING + defaultValue: 'project' + settingPaths: [ "coreNamespaces" ] - name: "%option%" - value_resolver: STATIC + value_resolver: ORIGIN optional: true configuration: - alias: 'option' - description: "Spryk-specific option" - type: !php/const SprykerSdk\SdkContracts\Enum\ValueTypeEnum::TYPE_ARRAY + alias: 'option' + description: "Spryk-specific option" + type: !php/const SprykerSdk\SdkContracts\Enum\ValueTypeEnum::TYPE_ARRAY diff --git a/src/Extension/Task/Command/ChangePhpVersionCommand.php b/src/Extension/Task/Command/ChangePhpVersionCommand.php deleted file mode 100644 index 69aa240c0..000000000 --- a/src/Extension/Task/Command/ChangePhpVersionCommand.php +++ /dev/null @@ -1,178 +0,0 @@ -composerFileModifier = $composerFileModifier; - $this->dockerFileModifier = $dockerFileModifier; - } - - /** - * {@inheritDoc} - * - * @param \SprykerSdk\SdkContracts\Entity\ContextInterface $context - * - * @return \SprykerSdk\SdkContracts\Entity\ContextInterface - */ - public function execute(ContextInterface $context): ContextInterface - { - try { - $this->changeComposerPhpVersion($context); - $this->changeDockerPhpVersion($context); - } catch (FileNotFoundException $exception) { - $context->addMessage(static::class, new Message($exception->getMessage(), MessageInterface::ERROR)); - } - - return $context; - } - - /** - * {@inheritDoc} - * - * @return string - */ - public function getCommand(): string - { - return ''; - } - - /** - * {@inheritDoc} - * - * @return string - */ - public function getType(): string - { - return 'php'; - } - - /** - * {@inheritDoc} - * - * @return bool - */ - public function hasStopOnError(): bool - { - return true; - } - - /** - * {@inheritDoc} - * - * @return array - */ - public function getTags(): array - { - return []; - } - - /** - * {@inheritDoc} - * - * @return \SprykerSdk\SdkContracts\Entity\ConverterInterface|null - */ - public function getConverter(): ?ConverterInterface - { - return null; - } - - /** - * {@inheritDoc} - * - * @return string - */ - public function getStage(): string - { - return ContextInterface::DEFAULT_STAGE; - } - - /** - * @param \SprykerSdk\SdkContracts\Entity\ContextInterface $context - * - * @return void - */ - protected function changeComposerPhpVersion(ContextInterface $context): void - { - $resolvedValues = $context->getResolvedValues(); - - $composerContent = $this->composerFileModifier->read($context, static::COMPOSER_CHANGE_ERROR); - - $phpVersion = $this->getPhpVersion($resolvedValues); - - if (isset($composerContent['require']['php'])) { - $composerContent['require']['php'] = '>=' . $phpVersion; - } - - if (isset($composerContent['config']['platform']['php'])) { - $composerContent['config']['platform']['php'] = AppPhpVersionValueResolver::PHP_VERSIONS[$phpVersion]; - } - - $this->composerFileModifier->write($composerContent, $context); - } - - /** - * @param \SprykerSdk\SdkContracts\Entity\ContextInterface $context - * - * @return void - */ - protected function changeDockerPhpVersion(ContextInterface $context): void - { - $resolvedValues = $context->getResolvedValues(); - $dockerFileContent = $this->dockerFileModifier->read($context, static::DOCKER_INITIALIZATION_ERROR); - $dockerFileContent['image']['tag'] = 'spryker/php:' . $this->getPhpVersion($resolvedValues); - $this->dockerFileModifier->write($dockerFileContent, $context); - } - - /** - * @param array $resolvedValues - * - * @return string - */ - protected function getPhpVersion(array $resolvedValues): string - { - return $resolvedValues['%' . AppPhpVersionValueResolver::VALUE_NAME . '%']; - } -} diff --git a/src/Extension/Task/GenerateAppTask.php b/src/Extension/Task/GenerateAppTask.php index cc2b293e1..09afa984c 100644 --- a/src/Extension/Task/GenerateAppTask.php +++ b/src/Extension/Task/GenerateAppTask.php @@ -12,7 +12,6 @@ use SprykerSdk\Sdk\Core\Domain\Entity\Lifecycle\RemovedEventData; use SprykerSdk\Sdk\Core\Domain\Entity\Lifecycle\UpdatedEventData; use SprykerSdk\Sdk\Core\Domain\Entity\Placeholder; -use SprykerSdk\Sdk\Extension\ValueResolver\AppPhpVersionValueResolver; use SprykerSdk\SdkContracts\Entity\Lifecycle\LifecycleInterface; use SprykerSdk\SdkContracts\Entity\TaskInterface; use SprykerSdk\SdkContracts\Enum\ValueTypeEnum; @@ -62,7 +61,7 @@ public function getPlaceholders(): array ), new Placeholder( '%app_name%', - 'STATIC', + 'ORIGIN', [ 'alias' => 'app-name', 'description' => 'Input name for new App', @@ -71,19 +70,13 @@ public function getPlaceholders(): array ), new Placeholder( '%project_url%', - 'STATIC', + 'ORIGIN', [ 'alias' => 'project_url', 'description' => 'Input repository for new App (e.g.: https://github.com//.git)', 'type' => ValueTypeEnum::TYPE_STRING, ], ), - new Placeholder( - '%' . AppPhpVersionValueResolver::VALUE_NAME . '%', - AppPhpVersionValueResolver::VALUE_RESOLVER_NAME, - [], - true, - ), ]; } diff --git a/src/Extension/ValueResolver/AppPhpVersionValueResolver.php b/src/Extension/ValueResolver/AppPhpVersionValueResolver.php deleted file mode 100644 index a5d73b721..000000000 --- a/src/Extension/ValueResolver/AppPhpVersionValueResolver.php +++ /dev/null @@ -1,97 +0,0 @@ - - */ - public const PHP_VERSIONS = [ - '7.4' => '7.4.28', - '8.0' => '8.0.7', - ]; - - /** - * {@inheritDoc} - * - * @return string - */ - public function getId(): string - { - return static::VALUE_RESOLVER_NAME; - } - - /** - * {@inheritDoc} - * - * @return string - */ - public function getDescription(): string - { - return 'PHP version to use for the App'; - } - - /** - * {@inheritDoc} - * - * @return string - */ - public function getType(): string - { - return ValueTypeEnum::TYPE_STRING; - } - - /** - * {@inheritDoc} - * - * @return string|null - */ - public function getAlias(): ?string - { - return static::VALUE_NAME; - } - - /** - * {@inheritDoc} - * - * @return mixed - */ - public function getDefaultValue() - { - return array_key_first(static::PHP_VERSIONS); - } - - /** - * {@inheritDoc} - * - * @param array $settingValues - * @param array $resolvedValues - * - * @return array - */ - public function getChoiceValues(array $settingValues, array $resolvedValues = []): array - { - return array_keys(static::PHP_VERSIONS); - } -} diff --git a/src/Extension/ValueResolver/ConfigPathValueResolver.php b/src/Extension/ValueResolver/ConfigPathValueResolver.php index 96301bddb..1b6fb1a8a 100644 --- a/src/Extension/ValueResolver/ConfigPathValueResolver.php +++ b/src/Extension/ValueResolver/ConfigPathValueResolver.php @@ -7,11 +7,12 @@ namespace SprykerSdk\Sdk\Extension\ValueResolver; -use SprykerSdk\SdkContracts\Entity\ContextInterface; use SprykerSdk\SdkContracts\Enum\Setting; -use SprykerSdk\SdkContracts\Enum\ValueTypeEnum; -class ConfigPathValueResolver extends OriginValueResolver +/** + * @deprecated Use \SprykerSdk\Sdk\Extension\ValueResolverPriorityPathValueResolver instead. + */ +class ConfigPathValueResolver extends PriorityPathValueResolver { /** * @var string @@ -28,35 +29,6 @@ public function getId(): string return static::RESOLVER_ID; } - /** - * {@inheritDoc} - * - * @return string - */ - public function getType(): string - { - return ValueTypeEnum::TYPE_STRING; - } - - /** - * {@inheritDoc} - * - * @param \SprykerSdk\SdkContracts\Entity\ContextInterface $context - * @param array $settingValues - * @param bool $optional - * - * @return string - */ - public function getValue(ContextInterface $context, array $settingValues, bool $optional = false): string - { - $value = (string)parent::getValue($context, $settingValues, $optional); - - $projectLevelSettings = sprintf('%s/%s', $settingValues[Setting::PATH_PROJECT_DIR] ?? '', $value); - $sdkLevelSettings = sprintf('%s/%s', $settingValues[Setting::PATH_SDK_DIR] ?? '', $value); - - return file_exists($projectLevelSettings) ? $projectLevelSettings : $sdkLevelSettings; - } - /** * @return array */ diff --git a/src/Extension/ValueResolver/PriorityPathValueResolver.php b/src/Extension/ValueResolver/PriorityPathValueResolver.php index b863e14a8..6f2794da4 100644 --- a/src/Extension/ValueResolver/PriorityPathValueResolver.php +++ b/src/Extension/ValueResolver/PriorityPathValueResolver.php @@ -43,12 +43,47 @@ public function getId(): string */ public function getValue(ContextInterface $context, array $settingValues, bool $optional = false): string { + if (!$this->getSettingPaths()) { + throw new InvalidConfigurationException(sprintf('`%s` resolver doesn\'t have any paths in setting.', $this->getId())); + } + $relativePath = (string)parent::getValue($context, $settingValues, $optional); - if (!$this->getSettingPaths()) { - throw new InvalidConfigurationException(sprintf('`%s` resolver doesn\'t have any paths', $this->getId())); + if (strpos($relativePath, DIRECTORY_SEPARATOR) === 0) { + throw new UnresolvableValueExceptionException('Absolute path is forbidden due to security reasons.'); + } + + if (strpos($relativePath, '..') !== false) { + throw new UnresolvableValueExceptionException('Path ../ is forbidden due to security reasons.'); } + $pathValue = $this->extractFormattedPathValue($relativePath, $settingValues); + + if ($pathValue === null) { + throw new UnresolvableValueExceptionException('Invalid path provided.'); + } + + return $pathValue; + } + + /** + * {@inheritDoc} + * + * @return string + */ + public function getType(): string + { + return ValueTypeEnum::TYPE_PATH; + } + + /** + * @param string $relativePath + * @param array $settingValues + * + * @return string|null + */ + protected function extractFormattedPathValue(string $relativePath, array $settingValues): ?string + { foreach ($this->getSettingPaths() as $settingKey) { if (!isset($settingValues[$settingKey])) { continue; @@ -58,22 +93,13 @@ public function getValue(ContextInterface $context, array $settingValues, bool $ $path = rtrim($path, DIRECTORY_SEPARATOR); } $path = implode(DIRECTORY_SEPARATOR, [$path, $relativePath]); + if (file_exists($path)) { return $this->formatValue($path); } } - throw new UnresolvableValueExceptionException('Can\'t resolve path.'); - } - - /** - * {@inheritDoc} - * - * @return string - */ - public function getType(): string - { - return ValueTypeEnum::TYPE_PATH; + return null; } /** diff --git a/src/Infrastructure/Builder/TaskSet/TaskSetTaskRelationsBuilder.php b/src/Infrastructure/Builder/TaskSet/TaskSetTaskRelationsBuilder.php new file mode 100644 index 000000000..33f886cdd --- /dev/null +++ b/src/Infrastructure/Builder/TaskSet/TaskSetTaskRelationsBuilder.php @@ -0,0 +1,75 @@ + $existingTasks + * + * @throws \InvalidArgumentException + * + * @return array<\SprykerSdk\Sdk\Core\Domain\Entity\TaskSetTaskRelationInterface> + */ + public function buildFromTaskSet(TaskSetInterface $taskSet, array $existingTasks): array + { + if (!isset($existingTasks[$taskSet->getId()])) { + throw new InvalidArgumentException(sprintf('Can\'t find loaded task set `%s`', $taskSet->getId())); + } + + $relations = []; + + foreach ($taskSet->getSubTasks() as $task) { + $subTask = is_string($task) + ? $this->getSubTaskByTaskId($task, $existingTasks) + : $this->getSubTaskByTask($task, $existingTasks); + + if ($subTask === null) { + continue; + } + + $relations[] = new TaskSetTaskRelation($existingTasks[$taskSet->getId()], $subTask); + } + + return $relations; + } + + /** + * @param string $taskId + * @param array $existingTasks + * + * @throws \InvalidArgumentException + * + * @return \SprykerSdk\SdkContracts\Entity\TaskInterface + */ + protected function getSubTaskByTaskId(string $taskId, array $existingTasks): TaskInterface + { + if (!isset($existingTasks[$taskId])) { + throw new InvalidArgumentException(sprintf('Task %s not found', $taskId)); + } + + return $existingTasks[$taskId]; + } + + /** + * @param \SprykerSdk\SdkContracts\Entity\TaskInterface $task + * @param array $existingTasks + * + * @return \SprykerSdk\SdkContracts\Entity\TaskInterface|null + */ + protected function getSubTaskByTask(TaskInterface $task, array $existingTasks): ?TaskInterface + { + return $existingTasks[$task->getId()] ?? null; + } +} diff --git a/src/Infrastructure/Builder/TaskSet/TaskSetTaskRelationsBuilderInterface.php b/src/Infrastructure/Builder/TaskSet/TaskSetTaskRelationsBuilderInterface.php new file mode 100644 index 000000000..70db837f4 --- /dev/null +++ b/src/Infrastructure/Builder/TaskSet/TaskSetTaskRelationsBuilderInterface.php @@ -0,0 +1,21 @@ + $existingTasks + * + * @return array<\SprykerSdk\Sdk\Core\Domain\Entity\TaskSetTaskRelationInterface> + */ + public function buildFromTaskSet(TaskSetInterface $taskSet, array $existingTasks): array; +} diff --git a/src/Infrastructure/Builder/TaskSet/TaskSetTaskRelationsFromYamlBuilder.php b/src/Infrastructure/Builder/TaskSet/TaskSetTaskRelationsFromYamlBuilder.php new file mode 100644 index 000000000..a65ed2722 --- /dev/null +++ b/src/Infrastructure/Builder/TaskSet/TaskSetTaskRelationsFromYamlBuilder.php @@ -0,0 +1,41 @@ + $taskSetConfiguration + * @param array $existingTasks + * + * @throws \InvalidArgumentException + * + * @return array<\SprykerSdk\Sdk\Core\Domain\Entity\TaskSetTaskRelationInterface> + */ + public function buildFromYamlTaskSet(array $taskSetConfiguration, array $existingTasks): array + { + if (!isset($existingTasks[$taskSetConfiguration['id']])) { + throw new InvalidArgumentException(sprintf('Can\'t find loaded task set `%s`', $taskSetConfiguration['id'])); + } + + $relations = []; + + foreach ($taskSetConfiguration['tasks'] as $task) { + if (!isset($existingTasks[$task['id']])) { + throw new InvalidArgumentException(sprintf('Can\'t find loaded task `%s`', $task['id'])); + } + + $relations[] = new TaskSetTaskRelation($existingTasks[$taskSetConfiguration['id']], $existingTasks[$task['id']]); + } + + return $relations; + } +} diff --git a/src/Infrastructure/Builder/TaskSet/TaskSetTaskRelationsFromYamlBuilderInterface.php b/src/Infrastructure/Builder/TaskSet/TaskSetTaskRelationsFromYamlBuilderInterface.php new file mode 100644 index 000000000..c77bd0855 --- /dev/null +++ b/src/Infrastructure/Builder/TaskSet/TaskSetTaskRelationsFromYamlBuilderInterface.php @@ -0,0 +1,19 @@ + $taskSetConfiguration + * @param array $existingTasks + * + * @return array<\SprykerSdk\Sdk\Core\Domain\Entity\TaskSetTaskRelationInterface> + */ + public function buildFromYamlTaskSet(array $taskSetConfiguration, array $existingTasks): array; +} diff --git a/src/Infrastructure/Cache/InMemoryContextCacheStorage.php b/src/Infrastructure/Cache/InMemoryContextCacheStorage.php deleted file mode 100644 index f46abd217..000000000 --- a/src/Infrastructure/Cache/InMemoryContextCacheStorage.php +++ /dev/null @@ -1,58 +0,0 @@ - - */ - protected array $contextStorage = []; - - /** - * @param string $key - * - * @return \SprykerSdk\Sdk\Core\Domain\Entity\ContextInterface|null - */ - public function get(string $key): ?ContextInterface - { - return $this->contextStorage[$key] ?? null; - } - - /** - * @return array<\SprykerSdk\Sdk\Core\Domain\Entity\ContextInterface> - */ - public function getAll(): array - { - return $this->contextStorage; - } - - /** - * @param string $key - * @param \SprykerSdk\Sdk\Core\Domain\Entity\ContextInterface $context - * - * @return void - */ - public function set(string $key, ContextInterface $context): void - { - $this->contextStorage[$key] = $context; - } - - /** - * @param string $key - * - * @return void - */ - public function remove(string $key): void - { - unset($this->contextStorage[$key]); - } -} diff --git a/src/Infrastructure/Entity/TaskSetTaskRelation.php b/src/Infrastructure/Entity/TaskSetTaskRelation.php new file mode 100644 index 000000000..e71ecf765 --- /dev/null +++ b/src/Infrastructure/Entity/TaskSetTaskRelation.php @@ -0,0 +1,18 @@ +setRequestData($event->getRequest()->request->all()); + $requestData = $event->getRequest()->request->get(OpenApiField::DATA); + + $inputOutputConnector->setRequestData($requestData[OpenApiField::ATTRIBUTES] ?? []); } if ($inputOutputConnector instanceof HelperSetInjectorInterface) { diff --git a/src/Infrastructure/EventListener/JsonRequestListener.php b/src/Infrastructure/EventListener/JsonRequestListener.php deleted file mode 100644 index 462c0592f..000000000 --- a/src/Infrastructure/EventListener/JsonRequestListener.php +++ /dev/null @@ -1,78 +0,0 @@ - - */ - protected array $contentTypes; - - /** - * @param array $contentTypes - */ - public function __construct(array $contentTypes) - { - $this->contentTypes = $contentTypes; - } - - /** - * @param \Symfony\Component\HttpKernel\Event\RequestEvent $event - * - * @return void - */ - public function onKernelRequest(RequestEvent $event): void - { - if (!$event->isMainRequest()) { - return; - } - - $request = $event->getRequest(); - - if (!$this->isApplicable($request) || !$this->supports($request)) { - return; - } - - try { - $data = json_decode((string)$request->getContent(), true, 512, \JSON_THROW_ON_ERROR); - $request->request->replace($data); - } catch (JsonException $exception) { - $event->setResponse(new JsonResponse('Invalid request.', Response::HTTP_BAD_REQUEST)); - } - } - - /** - * @param \Symfony\Component\HttpFoundation\Request $request - * - * @return bool - */ - protected function supports(Request $request): bool - { - return in_array($request->getContentType(), $this->contentTypes, true) && $request->getContent(); - } - - /** - * @param \Symfony\Component\HttpFoundation\Request $request - * - * @return bool - */ - public function isApplicable(Request $request): bool - { - return is_string($request->getContent()) - && $request->getContent() !== '' - && strpos($request->getPathInfo(), '/api/doc') !== 0 - && strpos($request->getPathInfo(), '/api/') === 0; - } -} diff --git a/src/Infrastructure/Exception/InvalidRequestDataException.php b/src/Infrastructure/Exception/InvalidRequestDataException.php index a890bf9c5..4a4a1202e 100644 --- a/src/Infrastructure/Exception/InvalidRequestDataException.php +++ b/src/Infrastructure/Exception/InvalidRequestDataException.php @@ -19,6 +19,6 @@ class InvalidRequestDataException extends SymfonyInvalidConfigurationException */ public function __construct(string $field, int $code = 0, ?Throwable $previous = null) { - parent::__construct(sprintf('Invalid request. Parameter %s is missing.', $field), $code, $previous); + parent::__construct(sprintf('Invalid request. Parameter `%s` is missing.', $field), $code, $previous); } } diff --git a/src/Core/Application/Lifecycle/Event/InitializedEvent.php b/src/Infrastructure/Lifecycle/Event/InitializedEvent.php similarity index 84% rename from src/Core/Application/Lifecycle/Event/InitializedEvent.php rename to src/Infrastructure/Lifecycle/Event/InitializedEvent.php index 49273bd68..5b6ae4095 100644 --- a/src/Core/Application/Lifecycle/Event/InitializedEvent.php +++ b/src/Infrastructure/Lifecycle/Event/InitializedEvent.php @@ -5,7 +5,7 @@ * Use of this software requires acceptance of the Evaluation License Agreement. See LICENSE file. */ -namespace SprykerSdk\Sdk\Core\Application\Lifecycle\Event; +namespace SprykerSdk\Sdk\Infrastructure\Lifecycle\Event; class InitializedEvent extends LifecycleEvent { diff --git a/src/Core/Application/Lifecycle/Event/LifecycleEvent.php b/src/Infrastructure/Lifecycle/Event/LifecycleEvent.php similarity index 92% rename from src/Core/Application/Lifecycle/Event/LifecycleEvent.php rename to src/Infrastructure/Lifecycle/Event/LifecycleEvent.php index 79f714cc5..56b5af14d 100644 --- a/src/Core/Application/Lifecycle/Event/LifecycleEvent.php +++ b/src/Infrastructure/Lifecycle/Event/LifecycleEvent.php @@ -5,7 +5,7 @@ * Use of this software requires acceptance of the Evaluation License Agreement. See LICENSE file. */ -namespace SprykerSdk\Sdk\Core\Application\Lifecycle\Event; +namespace SprykerSdk\Sdk\Infrastructure\Lifecycle\Event; use SprykerSdk\SdkContracts\Entity\TaskInterface; use Symfony\Contracts\EventDispatcher\Event; diff --git a/src/Core/Application/Lifecycle/Event/RemovedEvent.php b/src/Infrastructure/Lifecycle/Event/RemovedEvent.php similarity index 83% rename from src/Core/Application/Lifecycle/Event/RemovedEvent.php rename to src/Infrastructure/Lifecycle/Event/RemovedEvent.php index 4a3d66eb7..1e4015c19 100644 --- a/src/Core/Application/Lifecycle/Event/RemovedEvent.php +++ b/src/Infrastructure/Lifecycle/Event/RemovedEvent.php @@ -5,7 +5,7 @@ * Use of this software requires acceptance of the Evaluation License Agreement. See LICENSE file. */ -namespace SprykerSdk\Sdk\Core\Application\Lifecycle\Event; +namespace SprykerSdk\Sdk\Infrastructure\Lifecycle\Event; class RemovedEvent extends LifecycleEvent { diff --git a/src/Core/Application/Lifecycle/Event/UpdatedEvent.php b/src/Infrastructure/Lifecycle/Event/UpdatedEvent.php similarity index 83% rename from src/Core/Application/Lifecycle/Event/UpdatedEvent.php rename to src/Infrastructure/Lifecycle/Event/UpdatedEvent.php index e2f0a9aa8..e78c130f7 100644 --- a/src/Core/Application/Lifecycle/Event/UpdatedEvent.php +++ b/src/Infrastructure/Lifecycle/Event/UpdatedEvent.php @@ -5,7 +5,7 @@ * Use of this software requires acceptance of the Evaluation License Agreement. See LICENSE file. */ -namespace SprykerSdk\Sdk\Core\Application\Lifecycle\Event; +namespace SprykerSdk\Sdk\Infrastructure\Lifecycle\Event; class UpdatedEvent extends LifecycleEvent { diff --git a/src/Core/Application/Lifecycle/Subscriber/InitializedEventSubscriber.php b/src/Infrastructure/Lifecycle/Subscriber/InitializedEventSubscriber.php similarity index 83% rename from src/Core/Application/Lifecycle/Subscriber/InitializedEventSubscriber.php rename to src/Infrastructure/Lifecycle/Subscriber/InitializedEventSubscriber.php index 0f945bb41..f59dbf7e9 100644 --- a/src/Core/Application/Lifecycle/Subscriber/InitializedEventSubscriber.php +++ b/src/Infrastructure/Lifecycle/Subscriber/InitializedEventSubscriber.php @@ -5,11 +5,11 @@ * Use of this software requires acceptance of the Evaluation License Agreement. See LICENSE file. */ -namespace SprykerSdk\Sdk\Core\Application\Lifecycle\Subscriber; +namespace SprykerSdk\Sdk\Infrastructure\Lifecycle\Subscriber; -use SprykerSdk\Sdk\Core\Application\Lifecycle\Event\InitializedEvent; use SprykerSdk\Sdk\Core\Domain\Entity\FileInterface; use SprykerSdk\Sdk\Core\Domain\Entity\Lifecycle\TaskLifecycleInterface; +use SprykerSdk\Sdk\Infrastructure\Lifecycle\Event\InitializedEvent; use Symfony\Component\EventDispatcher\EventSubscriberInterface; class InitializedEventSubscriber extends LifecycleEventSubscriber implements EventSubscriberInterface @@ -25,7 +25,7 @@ public static function getSubscribedEvents(): array } /** - * @param \SprykerSdk\Sdk\Core\Application\Lifecycle\Event\InitializedEvent $event + * @param \SprykerSdk\Sdk\Infrastructure\Lifecycle\Event\InitializedEvent $event * * @return void */ @@ -51,6 +51,6 @@ public function onInitializedEvent(InitializedEvent $event): void */ protected function doManageFile(FileInterface $file): void { - $this->fileManager->create($file); + $this->filesystem->dumpFile($file->getPath(), $file->getContent()); } } diff --git a/src/Core/Application/Lifecycle/Subscriber/LifecycleEventSubscriber.php b/src/Infrastructure/Lifecycle/Subscriber/LifecycleEventSubscriber.php similarity index 90% rename from src/Core/Application/Lifecycle/Subscriber/LifecycleEventSubscriber.php rename to src/Infrastructure/Lifecycle/Subscriber/LifecycleEventSubscriber.php index cef799bf7..ee60a6dae 100644 --- a/src/Core/Application/Lifecycle/Subscriber/LifecycleEventSubscriber.php +++ b/src/Infrastructure/Lifecycle/Subscriber/LifecycleEventSubscriber.php @@ -5,25 +5,25 @@ * Use of this software requires acceptance of the Evaluation License Agreement. See LICENSE file. */ -namespace SprykerSdk\Sdk\Core\Application\Lifecycle\Subscriber; +namespace SprykerSdk\Sdk\Infrastructure\Lifecycle\Subscriber; use SprykerSdk\Sdk\Core\Application\Dependency\CommandExecutorInterface; use SprykerSdk\Sdk\Core\Application\Dependency\ContextFactoryInterface; -use SprykerSdk\Sdk\Core\Application\Dependency\FileManagerInterface; use SprykerSdk\Sdk\Core\Application\Service\PlaceholderResolver; use SprykerSdk\Sdk\Core\Domain\Entity\ContextInterface; use SprykerSdk\Sdk\Core\Domain\Entity\File; use SprykerSdk\Sdk\Core\Domain\Entity\FileInterface; use SprykerSdk\Sdk\Core\Domain\Entity\Lifecycle\LifecycleEventDataInterface; +use SprykerSdk\Sdk\Infrastructure\Filesystem\Filesystem; use SprykerSdk\SdkContracts\Entity\ContextInterface as ContractContextInterface; use SprykerSdk\SdkContracts\Entity\TaskInterface; abstract class LifecycleEventSubscriber { /** - * @var \SprykerSdk\Sdk\Core\Application\Dependency\FileManagerInterface + * @var \SprykerSdk\Sdk\Infrastructure\Filesystem\Filesystem */ - protected FileManagerInterface $fileManager; + protected Filesystem $filesystem; /** * @var \SprykerSdk\Sdk\Core\Application\Service\PlaceholderResolver @@ -41,18 +41,18 @@ abstract class LifecycleEventSubscriber protected ContextFactoryInterface $contextFactory; /** - * @param \SprykerSdk\Sdk\Core\Application\Dependency\FileManagerInterface $fileManager + * @param \SprykerSdk\Sdk\Infrastructure\Filesystem\Filesystem $filesystem * @param \SprykerSdk\Sdk\Core\Application\Service\PlaceholderResolver $placeholderResolver * @param \SprykerSdk\Sdk\Core\Application\Dependency\CommandExecutorInterface $commandExecutor * @param \SprykerSdk\Sdk\Core\Application\Dependency\ContextFactoryInterface $contextFactory */ public function __construct( - FileManagerInterface $fileManager, + Filesystem $filesystem, PlaceholderResolver $placeholderResolver, CommandExecutorInterface $commandExecutor, ContextFactoryInterface $contextFactory ) { - $this->fileManager = $fileManager; + $this->filesystem = $filesystem; $this->placeholderResolver = $placeholderResolver; $this->commandExecutor = $commandExecutor; $this->contextFactory = $contextFactory; diff --git a/src/Core/Application/Lifecycle/Subscriber/RemovedEventSubscriber.php b/src/Infrastructure/Lifecycle/Subscriber/RemovedEventSubscriber.php similarity index 84% rename from src/Core/Application/Lifecycle/Subscriber/RemovedEventSubscriber.php rename to src/Infrastructure/Lifecycle/Subscriber/RemovedEventSubscriber.php index 7a4f97c94..99df5c878 100644 --- a/src/Core/Application/Lifecycle/Subscriber/RemovedEventSubscriber.php +++ b/src/Infrastructure/Lifecycle/Subscriber/RemovedEventSubscriber.php @@ -5,11 +5,11 @@ * Use of this software requires acceptance of the Evaluation License Agreement. See LICENSE file. */ -namespace SprykerSdk\Sdk\Core\Application\Lifecycle\Subscriber; +namespace SprykerSdk\Sdk\Infrastructure\Lifecycle\Subscriber; -use SprykerSdk\Sdk\Core\Application\Lifecycle\Event\RemovedEvent; use SprykerSdk\Sdk\Core\Domain\Entity\FileInterface; use SprykerSdk\Sdk\Core\Domain\Entity\Lifecycle\PersistentLifecycleInterface; +use SprykerSdk\Sdk\Infrastructure\Lifecycle\Event\RemovedEvent; use Symfony\Component\EventDispatcher\EventSubscriberInterface; class RemovedEventSubscriber extends LifecycleEventSubscriber implements EventSubscriberInterface @@ -25,7 +25,7 @@ public static function getSubscribedEvents(): array } /** - * @param \SprykerSdk\Sdk\Core\Application\Lifecycle\Event\RemovedEvent $event + * @param \SprykerSdk\Sdk\Infrastructure\Lifecycle\Event\RemovedEvent $event * * @return void */ @@ -51,6 +51,6 @@ public function onRemovedEvent(RemovedEvent $event): void */ protected function doManageFile(FileInterface $file): void { - $this->fileManager->remove($file); + $this->filesystem->remove($file->getPath()); } } diff --git a/src/Core/Application/Lifecycle/Subscriber/UpdatedEventSubscriber.php b/src/Infrastructure/Lifecycle/Subscriber/UpdatedEventSubscriber.php similarity index 83% rename from src/Core/Application/Lifecycle/Subscriber/UpdatedEventSubscriber.php rename to src/Infrastructure/Lifecycle/Subscriber/UpdatedEventSubscriber.php index b78bc419c..12ab513c8 100644 --- a/src/Core/Application/Lifecycle/Subscriber/UpdatedEventSubscriber.php +++ b/src/Infrastructure/Lifecycle/Subscriber/UpdatedEventSubscriber.php @@ -5,11 +5,11 @@ * Use of this software requires acceptance of the Evaluation License Agreement. See LICENSE file. */ -namespace SprykerSdk\Sdk\Core\Application\Lifecycle\Subscriber; +namespace SprykerSdk\Sdk\Infrastructure\Lifecycle\Subscriber; -use SprykerSdk\Sdk\Core\Application\Lifecycle\Event\UpdatedEvent; use SprykerSdk\Sdk\Core\Domain\Entity\FileInterface; use SprykerSdk\Sdk\Core\Domain\Entity\Lifecycle\TaskLifecycleInterface; +use SprykerSdk\Sdk\Infrastructure\Lifecycle\Event\UpdatedEvent; use Symfony\Component\EventDispatcher\EventSubscriberInterface; class UpdatedEventSubscriber extends LifecycleEventSubscriber implements EventSubscriberInterface @@ -25,7 +25,7 @@ public static function getSubscribedEvents(): array } /** - * @param \SprykerSdk\Sdk\Core\Application\Lifecycle\Event\UpdatedEvent $event + * @param \SprykerSdk\Sdk\Infrastructure\Lifecycle\Event\UpdatedEvent $event * * @return void */ @@ -51,6 +51,6 @@ public function onUpdatedEvent(UpdatedEvent $event): void */ protected function doManageFile(FileInterface $file): void { - $this->fileManager->create($file); + $this->filesystem->dumpFile($file->getPath(), $file->getContent()); } } diff --git a/src/Infrastructure/Loader/TaskYaml/TaskYamlFileLoader.php b/src/Infrastructure/Loader/TaskYaml/TaskYamlFileLoader.php index a7936b2c2..66b634623 100644 --- a/src/Infrastructure/Loader/TaskYaml/TaskYamlFileLoader.php +++ b/src/Infrastructure/Loader/TaskYaml/TaskYamlFileLoader.php @@ -9,9 +9,10 @@ use SprykerSdk\Sdk\Infrastructure\Builder\TaskSet\TaskFromYamlTaskSetBuilderInterface; use SprykerSdk\Sdk\Infrastructure\Builder\TaskYaml\TaskBuilderInterface; -use SprykerSdk\Sdk\Infrastructure\Collector\TaskYamlCollectorInterface; +use SprykerSdk\Sdk\Infrastructure\Collector\TaskYamlCollector; use SprykerSdk\Sdk\Infrastructure\Dto\TaskYamlCriteriaDto; use SprykerSdk\Sdk\Infrastructure\Storage\TaskStorage; +use SprykerSdk\Sdk\Infrastructure\Task\TaskSetTaskRelation\TaskSetTaskRelationFacadeInterface; use SprykerSdk\SdkContracts\Entity\TaskInterface; class TaskYamlFileLoader implements TaskYamlFileLoaderInterface @@ -32,26 +33,34 @@ class TaskYamlFileLoader implements TaskYamlFileLoaderInterface protected TaskBuilderInterface $taskBuilder; /** - * @var \SprykerSdk\Sdk\Infrastructure\Collector\TaskYamlCollectorInterface + * @var \SprykerSdk\Sdk\Infrastructure\Collector\TaskYamlCollector */ - protected TaskYamlCollectorInterface $taskYamlCollector; + protected TaskYamlCollector $taskYamlCollector; /** - * @param \SprykerSdk\Sdk\Infrastructure\Collector\TaskYamlCollectorInterface $taskYamlCollector + * @var \SprykerSdk\Sdk\Infrastructure\Task\TaskSetTaskRelation\TaskSetTaskRelationFacadeInterface + */ + protected TaskSetTaskRelationFacadeInterface $taskSetTaskRelationFacade; + + /** + * @param \SprykerSdk\Sdk\Infrastructure\Collector\TaskYamlCollector $taskYamlCollector * @param \SprykerSdk\Sdk\Infrastructure\Builder\TaskSet\TaskFromYamlTaskSetBuilderInterface $taskFromYamlTaskSetBuilder * @param \SprykerSdk\Sdk\Infrastructure\Storage\TaskStorage $taskStorage * @param \SprykerSdk\Sdk\Infrastructure\Builder\TaskYaml\TaskBuilderInterface $taskBuilder + * @param \SprykerSdk\Sdk\Infrastructure\Task\TaskSetTaskRelation\TaskSetTaskRelationFacadeInterface $taskSetTaskRelationFacade */ public function __construct( - TaskYamlCollectorInterface $taskYamlCollector, + TaskYamlCollector $taskYamlCollector, TaskFromYamlTaskSetBuilderInterface $taskFromYamlTaskSetBuilder, TaskStorage $taskStorage, - TaskBuilderInterface $taskBuilder + TaskBuilderInterface $taskBuilder, + TaskSetTaskRelationFacadeInterface $taskSetTaskRelationFacade ) { $this->taskYamlCollector = $taskYamlCollector; $this->taskFromYamlTaskSetBuilder = $taskFromYamlTaskSetBuilder; $this->taskStorage = $taskStorage; $this->taskBuilder = $taskBuilder; + $this->taskSetTaskRelationFacade = $taskSetTaskRelationFacade; } /** @@ -71,6 +80,8 @@ public function loadAll(): array foreach ($manifestCollection->getTaskSets() as $taskData) { $task = $this->buildTaskSet($taskData, $manifestCollection->getTasks(), $taskCollection); $this->taskStorage->addTask($task); + + $this->taskSetTaskRelationFacade->collectYamlTaskSet($taskData, $this->taskStorage->getTaskCollection()); } return $this->taskStorage->getTaskCollection(); diff --git a/src/Infrastructure/Logger/NewRelicFormatter.php b/src/Infrastructure/Logger/NewRelicFormatter.php new file mode 100644 index 000000000..77ad89336 --- /dev/null +++ b/src/Infrastructure/Logger/NewRelicFormatter.php @@ -0,0 +1,64 @@ +workspaceName = $workspaceName; + $this->ciExecutionId = $ciExecutionId; + } + + /** + * @param array $record + * + * @return array + */ + public function format(array $record): array + { + if (!isset($record['context'])) { + $record['context'] = []; + } + + $record['context']['workspace_name'] = $this->workspaceName; + $record['context']['ci_execution_id'] = $this->ciExecutionId; + + return $record; + } + + /** + * @param array $records + * + * @return array + */ + public function formatBatch(array $records): array + { + foreach ($records as $key => $record) { + $records[$key] = $this->format($record); + } + + return $records; + } +} diff --git a/src/Infrastructure/Logger/TransactionNameNewRelicProcessor.php b/src/Infrastructure/Logger/TransactionNameNewRelicProcessor.php new file mode 100644 index 000000000..fef90159c --- /dev/null +++ b/src/Infrastructure/Logger/TransactionNameNewRelicProcessor.php @@ -0,0 +1,40 @@ +transactionName = $transactionName; + } + + /** + * @param array $record + * + * @return array + */ + public function __invoke(array $record): array + { + if (!isset($record['context'])) { + $record['context'] = []; + } + + $record['context']['transaction_name'] = $this->transactionName; + + return $record; + } +} diff --git a/src/Infrastructure/Mapper/TaskSetTaskRelationMapper.php b/src/Infrastructure/Mapper/TaskSetTaskRelationMapper.php new file mode 100644 index 000000000..a5b7a8d0b --- /dev/null +++ b/src/Infrastructure/Mapper/TaskSetTaskRelationMapper.php @@ -0,0 +1,53 @@ + + */ + protected ObjectRepository $taskRepository; + + /** + * @param \Doctrine\Persistence\ObjectRepository $taskRepository + */ + public function __construct(ObjectRepository $taskRepository) + { + $this->taskRepository = $taskRepository; + } + + /** + * @param \SprykerSdk\Sdk\Core\Domain\Entity\TaskSetTaskRelationInterface $taskSetRelation + * + * @throws \InvalidArgumentException + * + * @return \SprykerSdk\Sdk\Infrastructure\Entity\TaskSetTaskRelation + */ + public function mapToInfrastructureTaskSetRelation(TaskSetTaskRelationInterface $taskSetRelation): InfrastructureTaskSetRelation + { + $taskSet = $this->taskRepository->find($taskSetRelation->getTaskSet()->getId()); + + if ($taskSet === null) { + throw new InvalidArgumentException(sprintf('Task set `%s` is not found', $taskSetRelation->getTaskSet()->getId())); + } + + $subTask = $this->taskRepository->find($taskSetRelation->getSubTask()->getId()); + + if ($subTask === null) { + throw new InvalidArgumentException(sprintf('Sub-task set `%s` is not found', $taskSetRelation->getSubTask()->getId())); + } + + return new InfrastructureTaskSetRelation($taskSet, $subTask); + } +} diff --git a/src/Infrastructure/Mapper/TaskSetTaskRelationMapperInterface.php b/src/Infrastructure/Mapper/TaskSetTaskRelationMapperInterface.php new file mode 100644 index 000000000..82b2c3ab1 --- /dev/null +++ b/src/Infrastructure/Mapper/TaskSetTaskRelationMapperInterface.php @@ -0,0 +1,21 @@ +metricSenderClientFetcher = $metricSenderClientFetcher; + } + + /** + * @return array + */ + public static function getSubscribedEvents(): array + { + return [ + MetricEventInterface::class => 'onMetricEvent', + ]; + } + + /** + * @param \SprykerSdk\SdkContracts\Event\MetricEventInterface $event + * + * @return void + */ + public function onMetricEvent(MetricEventInterface $event): void + { + $senderClient = $this->metricSenderClientFetcher->getFirstApplicableClient(); + + if ($senderClient === null) { + return; + } + + $senderClient->send($event->getName(), $event->getPayLoad()); + } +} diff --git a/src/Infrastructure/MetricsSender/MetricSenderClientFetcher.php b/src/Infrastructure/MetricsSender/MetricSenderClientFetcher.php new file mode 100644 index 000000000..858189009 --- /dev/null +++ b/src/Infrastructure/MetricsSender/MetricSenderClientFetcher.php @@ -0,0 +1,40 @@ + + */ + protected iterable $metricClients; + + /** + * @param iterable<\SprykerSdk\Sdk\Infrastructure\MetricsSender\MetricSenderClientInterface> $metricClients + */ + public function __construct(iterable $metricClients) + { + $this->metricClients = $metricClients; + } + + /** + * @return \SprykerSdk\Sdk\Infrastructure\MetricsSender\MetricSenderClientInterface|null + */ + public function getFirstApplicableClient(): ?MetricSenderClientInterface + { + foreach ($this->metricClients as $metricClient) { + if (!$metricClient->isApplicable()) { + continue; + } + + return $metricClient; + } + + return null; + } +} diff --git a/src/Infrastructure/MetricsSender/MetricSenderClientInterface.php b/src/Infrastructure/MetricsSender/MetricSenderClientInterface.php new file mode 100644 index 000000000..650e1de20 --- /dev/null +++ b/src/Infrastructure/MetricsSender/MetricSenderClientInterface.php @@ -0,0 +1,24 @@ + $payload + * + * @return void + */ + public function send(string $metricName, array $payload): void; + + /** + * @return bool + */ + public function isApplicable(): bool; +} diff --git a/src/Infrastructure/MetricsSender/NewRelicMetricSenderClient.php b/src/Infrastructure/MetricsSender/NewRelicMetricSenderClient.php new file mode 100644 index 000000000..eace7bf36 --- /dev/null +++ b/src/Infrastructure/MetricsSender/NewRelicMetricSenderClient.php @@ -0,0 +1,44 @@ +transactionName = $transactionName; + } + + /** + * @param string $metricName + * @param array $payload + * + * @return void + */ + public function send(string $metricName, array $payload): void + { + newrelic_name_transaction($this->transactionName); + newrelic_record_custom_event($metricName, $payload); + } + + /** + * @return bool + */ + public function isApplicable(): bool + { + return extension_loaded('newrelic'); + } +} diff --git a/src/Infrastructure/Repository/ContextFileRepository.php b/src/Infrastructure/Repository/ContextFileRepository.php index 0d05d939d..7a01173a8 100644 --- a/src/Infrastructure/Repository/ContextFileRepository.php +++ b/src/Infrastructure/Repository/ContextFileRepository.php @@ -7,7 +7,6 @@ namespace SprykerSdk\Sdk\Infrastructure\Repository; -use SprykerSdk\Sdk\Core\Application\Cache\ContextCacheStorageInterface; use SprykerSdk\Sdk\Core\Application\Dependency\ContextRepositoryInterface; use SprykerSdk\Sdk\Core\Application\Dependency\SettingFetcherInterface; use SprykerSdk\Sdk\Core\Application\Service\ContextSerializer; @@ -22,11 +21,6 @@ class ContextFileRepository implements ContextRepositoryInterface */ protected ContextSerializer $contextSerializer; - /** - * @var \SprykerSdk\Sdk\Core\Application\Cache\ContextCacheStorageInterface - */ - protected ContextCacheStorageInterface $cacheStorage; - /** * @var \SprykerSdk\Sdk\Core\Application\Dependency\SettingFetcherInterface */ @@ -34,16 +28,13 @@ class ContextFileRepository implements ContextRepositoryInterface /** * @param \SprykerSdk\Sdk\Core\Application\Service\ContextSerializer $contextSerializer - * @param \SprykerSdk\Sdk\Core\Application\Cache\ContextCacheStorageInterface $cacheStorage * @param \SprykerSdk\Sdk\Core\Application\Dependency\SettingFetcherInterface $settingFetcher */ public function __construct( ContextSerializer $contextSerializer, - ContextCacheStorageInterface $cacheStorage, SettingFetcherInterface $settingFetcher ) { $this->contextSerializer = $contextSerializer; - $this->cacheStorage = $cacheStorage; $this->settingFetcher = $settingFetcher; } @@ -58,8 +49,6 @@ public function saveContext(ContextInterface $context): ContextInterface file_put_contents($contextFilePath, $this->contextSerializer->serialize($context)); - $this->cacheStorage->set($context->getName(), $context); - return $context; } @@ -72,11 +61,6 @@ public function saveContext(ContextInterface $context): ContextInterface */ public function findByName(string $name): ContextInterface { - $context = $this->cacheStorage->get($name); - if ($context) { - return $context; - } - $contextFilePath = $this->getContextFilePath($name); if (!is_readable($contextFilePath)) { @@ -89,11 +73,7 @@ public function findByName(string $name): ContextInterface throw new MissingContextFileException(sprintf('Context file %s could not be read', $contextFilePath)); } - $context = $this->contextSerializer->deserialize($contextFileContent); - - $this->cacheStorage->set($context->getName(), $context); - - return $context; + return $this->contextSerializer->deserialize($contextFileContent); } /** @@ -103,8 +83,6 @@ public function findByName(string $name): ContextInterface */ public function delete(ContextInterface $context): void { - $this->cacheStorage->remove($context->getName()); - $contextFilePath = $this->getContextFilePath($context->getName()); if (is_file($contextFilePath)) { diff --git a/src/Infrastructure/Repository/ProjectSettingRepository.php b/src/Infrastructure/Repository/ProjectSettingRepository.php index c809e41a4..dc7c00f4b 100644 --- a/src/Infrastructure/Repository/ProjectSettingRepository.php +++ b/src/Infrastructure/Repository/ProjectSettingRepository.php @@ -12,17 +12,13 @@ use SprykerSdk\Sdk\Core\Application\Exception\MissingSettingException; use SprykerSdk\Sdk\Infrastructure\Entity\Setting as InfrastructureSetting; use SprykerSdk\Sdk\Infrastructure\Exception\InvalidTypeException; +use SprykerSdk\Sdk\Infrastructure\Filesystem\Filesystem; use SprykerSdk\Sdk\Infrastructure\Resolver\PathResolver; use SprykerSdk\SdkContracts\Entity\SettingInterface; use Symfony\Component\Yaml\Yaml; class ProjectSettingRepository implements ProjectSettingRepositoryInterface { - /** - * @var string - */ - protected const LOCAL_SUFFIX = 'local'; - /** * @var \SprykerSdk\Sdk\Core\Application\Dependency\Repository\SettingRepositoryInterface */ @@ -38,27 +34,43 @@ class ProjectSettingRepository implements ProjectSettingRepositoryInterface */ protected string $projectSettingFileName; + /** + * @var string + */ + protected string $localProjectSettingFileName; + /** * @var \SprykerSdk\Sdk\Infrastructure\Resolver\PathResolver */ protected PathResolver $pathResolver; + /** + * @var \SprykerSdk\Sdk\Infrastructure\Filesystem\Filesystem + */ + protected Filesystem $filesystem; + /** * @param \SprykerSdk\Sdk\Core\Application\Dependency\Repository\SettingRepositoryInterface $coreSettingRepository * @param \Symfony\Component\Yaml\Yaml $yamlParser * @param string $projectSettingFileName + * @param string $localProjectSettingFileName * @param \SprykerSdk\Sdk\Infrastructure\Resolver\PathResolver $pathResolver + * @param \SprykerSdk\Sdk\Infrastructure\Filesystem\Filesystem $filesystem */ public function __construct( SettingRepositoryInterface $coreSettingRepository, Yaml $yamlParser, string $projectSettingFileName, - PathResolver $pathResolver + string $localProjectSettingFileName, + PathResolver $pathResolver, + Filesystem $filesystem ) { $this->projectSettingFileName = $projectSettingFileName; + $this->localProjectSettingFileName = $localProjectSettingFileName; $this->yamlParser = $yamlParser; $this->coreSettingRepository = $coreSettingRepository; $this->pathResolver = $pathResolver; + $this->filesystem = $filesystem; } /** @@ -78,7 +90,7 @@ public function save(SettingInterface $setting): SettingInterface */ public function saveMultiple(array $settings): array { - $localProjectValues = $this->fetchProjectValues($this->projectSettingFileName . '.' . static::LOCAL_SUFFIX); + $localProjectValues = $this->fetchProjectValues($this->localProjectSettingFileName); $sharedProjectValues = $this->fetchProjectValues($this->projectSettingFileName); /** @var \SprykerSdk\Sdk\Core\Domain\Entity\Setting $setting */ @@ -91,18 +103,12 @@ public function saveMultiple(array $settings): array $localProjectValues[$setting->getPath()] = $setting->getValues(); } - $projectSettingDir = dirname($this->projectSettingFileName); - - if (!is_dir($projectSettingDir)) { - mkdir($projectSettingDir, 0777, true); - } - if ($localProjectValues) { - file_put_contents($this->projectSettingFileName . '.' . static::LOCAL_SUFFIX, $this->yamlParser::dump($localProjectValues)); + $this->filesystem->dumpFile($this->localProjectSettingFileName, $this->yamlParser::dump($localProjectValues)); } if ($sharedProjectValues) { - file_put_contents($this->projectSettingFileName, $this->yamlParser::dump($sharedProjectValues)); + $this->filesystem->dumpFile($this->projectSettingFileName, $this->yamlParser::dump($sharedProjectValues)); } return $settings; @@ -203,7 +209,7 @@ protected function getProjectValues(): array { return array_merge( $this->fetchProjectValues($this->projectSettingFileName), - $this->fetchProjectValues($this->projectSettingFileName . '.' . static::LOCAL_SUFFIX), + $this->fetchProjectValues($this->localProjectSettingFileName), ); } diff --git a/src/Infrastructure/Repository/TaskRepository.php b/src/Infrastructure/Repository/TaskRepository.php index ebdd9c944..7d0ab5396 100644 --- a/src/Infrastructure/Repository/TaskRepository.php +++ b/src/Infrastructure/Repository/TaskRepository.php @@ -144,6 +144,19 @@ public function remove(TaskInterface $task): void $this->getEntityManager()->flush(); } + /** + * @return array + */ + public function getTaskIds(): array + { + $qb = $this->getEntityManager()->createQueryBuilder(); + + return $qb->select('t.id') + ->from(Task::class, 't') + ->getQuery() + ->getSingleColumnResult(); + } + /** * @param string $taskId * diff --git a/src/Infrastructure/Repository/TaskSetTaskRelationRepository.php b/src/Infrastructure/Repository/TaskSetTaskRelationRepository.php new file mode 100644 index 000000000..d4cd79fff --- /dev/null +++ b/src/Infrastructure/Repository/TaskSetTaskRelationRepository.php @@ -0,0 +1,95 @@ + + */ +class TaskSetTaskRelationRepository extends ServiceEntityRepository implements TaskSetTaskRelationRepositoryInterface +{ + /** + * @var \SprykerSdk\Sdk\Infrastructure\Mapper\TaskSetTaskRelationMapperInterface + */ + protected TaskSetTaskRelationMapperInterface $taskSetTaskRelationMapper; + + /** + * @param \Doctrine\Persistence\ManagerRegistry $registry + * @param \SprykerSdk\Sdk\Infrastructure\Mapper\TaskSetTaskRelationMapperInterface $taskSetTaskRelationMapper + */ + public function __construct( + ManagerRegistry $registry, + TaskSetTaskRelationMapperInterface $taskSetTaskRelationMapper + ) { + $this->taskSetTaskRelationMapper = $taskSetTaskRelationMapper; + + parent::__construct($registry, TaskSetTaskRelation::class); + } + + /** + * @param array<\SprykerSdk\Sdk\Core\Domain\Entity\TaskSetTaskRelationInterface> $relations + * + * @return void + */ + public function createMany(array $relations): void + { + foreach ($relations as $relation) { + $infrastructureRelation = $this->taskSetTaskRelationMapper->mapToInfrastructureTaskSetRelation($relation); + $this->getEntityManager()->persist($infrastructureRelation); + } + + $this->getEntityManager()->flush(); + } + + /** + * @param string $taskSetId + * + * @return void + */ + public function removeByTaskSetId(string $taskSetId): void + { + $qb = $this->createQueryBuilder('tsr'); + + $relations = $qb + ->innerJoin('tsr.taskSet', 'ts') + ->where($qb->expr()->eq('ts.id', ':taskSetId')) + ->setParameters([':taskSetId' => $taskSetId]) + ->getQuery() + ->getResult(); + + foreach ($relations as $relation) { + $this->getEntityManager()->remove($relation); + } + + $this->getEntityManager()->flush(); + } + + /** + * @param string $taskSetId + * + * @return array<\SprykerSdk\Sdk\Core\Domain\Entity\TaskSetTaskRelationInterface> + */ + public function getByTaskSetId(string $taskSetId): array + { + $qb = $this->getEntityManager()->createQueryBuilder(); + + return $qb + ->select('tsr', 'ts') + ->from(TaskSetTaskRelation::class, 'tsr') + ->innerJoin('tsr.taskSet', 'ts') + ->where($qb->expr()->eq('ts.id', ':taskSetId')) + ->setParameters([':taskSetId' => $taskSetId]) + ->getQuery() + ->getResult(); + } +} diff --git a/src/Infrastructure/Resources/config/doctrine/TaskSetTaskRelation.orm.yml b/src/Infrastructure/Resources/config/doctrine/TaskSetTaskRelation.orm.yml new file mode 100644 index 000000000..fc6f7bdff --- /dev/null +++ b/src/Infrastructure/Resources/config/doctrine/TaskSetTaskRelation.orm.yml @@ -0,0 +1,32 @@ +SprykerSdk\Sdk\Infrastructure\Entity\TaskSetTaskRelation: + type: entity + repositoryClass: \SprykerSdk\Sdk\Infrastructure\Repository\TaskSetTaskRelationRepository + changeTrackingPolicy: DEFERRED_EXPLICIT + table: sdk_task_set_task_relation + id: + id: + type: integer + generator: + strategy: AUTO + manyToOne: + taskSet: + targetEntity: SprykerSdk\Sdk\Infrastructure\Entity\Task + joinColumn: + name: task_set_id + nullable: false + referencedColumnName: id + onDelete: cascade + + subTask: + targetEntity: SprykerSdk\Sdk\Infrastructure\Entity\Task + joinColumn: + name: sub_task_id + nullable: false + referencedColumnName: id + onDelete: cascade + + uniqueConstraints: + task_set_sub_task: + columns: + - task_set_id + - sub_task_id diff --git a/src/Infrastructure/Resources/config/services.yaml b/src/Infrastructure/Resources/config/services.yaml index 5142af47b..51ee41833 100644 --- a/src/Infrastructure/Resources/config/services.yaml +++ b/src/Infrastructure/Resources/config/services.yaml @@ -6,7 +6,9 @@ parameters: manifest_task_php_template_path: "manifest/task_manifest_template.php.twig" manifest_task_yaml_file_dir: "%kernel.project_dir%/extension/Custom/src/Resources/config/task" manifest_task_php_file_dir: "%kernel.project_dir%/extension/Custom/src/Task/" - + project_log_file: ".ssdk/.ssdk.log" + project_settings_file: "./.ssdk/settings" + local_project_settings_file: "./.ssdk/settings.local" services: _instanceof: SprykerSdk\Sdk\Core\Application\Dependency\ManifestConfigurationInterface: @@ -47,6 +49,8 @@ services: factory: [ "@error_logger_factory", "createLogger" ] command_error: class: SprykerSdk\Sdk\Infrastructure\Service\ErrorCommandListener + arguments: + - "%kernel.debug%" tags: - { name: kernel.event_listener, @@ -66,7 +70,9 @@ services: - "@setting_repository" - "@yaml_parser" - "%project_settings_file%" + - "%local_project_settings_file%" - "@path_resolver" + - "@sdk_filesystem" yaml_parser: class: Symfony\Component\Yaml\Yaml @@ -87,6 +93,9 @@ services: arguments: - !tagged_iterator sdk.task + task_set_task_relation.storage: + class: SprykerSdk\Sdk\Infrastructure\Storage\TaskSetTaskRelationStorage + task.builder.yaml: class: SprykerSdk\Sdk\Infrastructure\Builder\TaskYaml\YamlTaskBuilder arguments: @@ -129,12 +138,12 @@ services: - "@task.task_from_yaml_builder" - "@task.storage" - "@task.builder.yaml" + - "@task.task_set_task_relation_facade" context_repository: class: SprykerSdk\Sdk\Infrastructure\Repository\ContextFileRepository arguments: - "@context_serializer" - - "@context.in_memory_cache_storage" - "@setting.setting_fetcher" telemetry_event_repository: class: SprykerSdk\Sdk\Infrastructure\Repository\TelemetryEventRepository @@ -209,43 +218,16 @@ services: arguments: - !tagged_iterator { tag: 'sdk.cli_value_receiver_factory', default_index_method: 'getType' } - api_exception_listener: - class: SprykerSdk\Sdk\Infrastructure\EventListener\ApiExceptionListener - arguments: - - "%kernel.debug%" - - "@logger" - tags: - - { - name: kernel.event_listener, - event: kernel.exception, - method: onKernelException, - priority: 256 - } - - json_request_transformer_listener: - class: SprykerSdk\Sdk\Infrastructure\EventListener\JsonRequestListener - tags: - - { - name: kernel.event_listener, - event: kernel.request, - method: onKernelRequest, - priority: 256 - } - arguments: - - ['json'] application_receiver_setup_listener: class: SprykerSdk\Sdk\Infrastructure\EventListener\ApplicationReceiverSetupListener tags: - - { - name: kernel.event_listener, - event: console.command, - method: beforeConsoleCommand, - } - - { - name: kernel.event_listener, - event: kernel.request, - method: onKernelRequest, - } + - name: kernel.event_listener + event: console.command + method: beforeConsoleCommand + - name: kernel.event_listener + event: kernel.request + method: onKernelRequest + arguments: - !tagged_iterator sdk.cli_receiver_setup - "@api_interaction_processor" @@ -287,6 +269,11 @@ services: - "@mapper.placeholder_mapper" - "@mapper.lifecycle_mapper" + mapper.task_set_relation: + class: SprykerSdk\Sdk\Infrastructure\Mapper\TaskSetTaskRelationMapper + arguments: + - "@task_persistence_repository" + mapper.lifecycle_mapper: class: SprykerSdk\Sdk\Infrastructure\Mapper\LifecycleMapper arguments: @@ -314,12 +301,19 @@ services: - "@task.task_set_override_map_factory" - "@task.storage" + task_set_relation_repository: + class: SprykerSdk\Sdk\Infrastructure\Repository\TaskSetTaskRelationRepository + arguments: + - "@doctrine" + - "@mapper.task_set_relation" + service.task_manager: class: SprykerSdk\Sdk\Infrastructure\Service\TaskManager arguments: - "@event_dispatcher" - "@task_persistence_repository" - "@task.task_from_task_builder" + - "@task.task_set_task_relation_facade" service.lifecycle_manager: class: SprykerSdk\Sdk\Infrastructure\Service\LifecycleManager @@ -353,8 +347,14 @@ services: tags: [ "sdk.update_action" ] arguments: - "@service.task_manager" + violation_report_decorator: + class: SprykerSdk\Sdk\Infrastructure\Violation\Formatter\ViolationReportDecorator + arguments: + - !tagged_iterator output_formatter.violation_decorator output_violation_report_formatter: class: SprykerSdk\Sdk\Infrastructure\Violation\Formatter\OutputViolationReportFormatter + arguments: + - "@violation_report_decorator" tags: [ "sdk.violation_formatter", "sdk.cli_receiver_setup" ] yaml_violation_report_formatter: class: SprykerSdk\Sdk\Infrastructure\Violation\Formatter\YamlViolationReportFormatter @@ -363,6 +363,7 @@ services: - "@violation_report_mapper" - "@violation_path_reader" - "@yaml_parser" + - "@violation_report_decorator" workflow_repository: class: SprykerSdk\Sdk\Infrastructure\Repository\WorkflowRepository arguments: @@ -472,6 +473,14 @@ services: - "@service_container" - "@context_factory" + task.task_set_task_relation_facade: + class: SprykerSdk\Sdk\Infrastructure\Task\TaskSetTaskRelation\TaskSetTaskRelationFacade + arguments: + - '@task_set_task_relation.storage' + - '@task.task_set_task_relations_builder' + - '@task.task_set_task_relations_from_yaml_builder' + - '@task_set_relation_repository' + telemetry.data_lake_sender: class: SprykerSdk\Sdk\Infrastructure\Telemetry\DataLakeTelemetryEventSender arguments: @@ -491,7 +500,6 @@ services: - "@filesystem" - "%telemetry_sender_file_report_file_name%" - "%telemetry_sender_file_report_format%" - - "%kernel.debug%" tags: - { name: telemetry.data_sender } @@ -538,7 +546,6 @@ services: class: SprykerSdk\Sdk\Infrastructure\Service\ProjectInfo\ProjectInfoFetcher arguments: - !tagged_iterator project_info_fetcher.fetcher_strategy - - "@error_logger_factory" guzzle.http_client: class: GuzzleHttp\Client @@ -588,8 +595,6 @@ services: tags: - {name: 'tagged_class_name_collection', target_tag: 'telemetry.observable_command'} - context.in_memory_cache_storage: - class: SprykerSdk\Sdk\Infrastructure\Cache\InMemoryContextCacheStorage workflow.transition_resolver_registry: class: SprykerSdk\Sdk\Core\Application\Service\WorkflowTransitionResolverRegistry arguments: @@ -608,7 +613,7 @@ services: project_settings_init.question.change_default_value: class: SprykerSdk\Sdk\Infrastructure\Setting\ProjectSettingsInitializer\Question\ChangeDefaultValueQuestion arguments: - - "@cli_interaction_processor" + - "@interaction_processor" setting.setting_fetcher: class: SprykerSdk\Sdk\Infrastructure\Setting\SettingFetcher @@ -619,13 +624,14 @@ services: project_settings_init.question.setting_value: class: SprykerSdk\Sdk\Infrastructure\Setting\ProjectSettingsInitializer\Question\SettingValueQuestion arguments: - - "@cli_interaction_processor" + - "@interaction_processor" - "@setting.setting_choices_provider_registry" project_settings_init.files_initializer: class: SprykerSdk\Sdk\Infrastructure\Setting\ProjectSettingsInitializer\ProjectFilesInitializer arguments: - "%project_settings_file%" + - "%local_project_settings_file%" - "@filesystem" project_settings_init.initializer: @@ -675,6 +681,12 @@ services: - "@task.task_set_placeholders_builder" - "@task.task_set_commands_builder" + task.task_set_task_relations_from_yaml_builder: + class: SprykerSdk\Sdk\Infrastructure\Builder\TaskSet\TaskSetTaskRelationsFromYamlBuilder + + task.task_set_task_relations_builder: + class: SprykerSdk\Sdk\Infrastructure\Builder\TaskSet\TaskSetTaskRelationsBuilder + # Validators validation_helper: class: SprykerSdk\Sdk\Infrastructure\Validator\Manifest\ManifestEntriesValidator @@ -695,17 +707,17 @@ services: manifest.interaction.need_to_ask_question: class: SprykerSdk\Sdk\Infrastructure\Manifest\Interaction\Question\NeedToAskQuestion arguments: - - "@cli_interaction_processor" + - "@interaction_processor" manifest.interaction.new_collection_item_question: class: SprykerSdk\Sdk\Infrastructure\Manifest\Interaction\Question\NewCollectionItemQuestion arguments: - - "@cli_interaction_processor" + - "@interaction_processor" manifest.interaction.value_question: class: SprykerSdk\Sdk\Infrastructure\Manifest\Interaction\Question\ValueQuestion arguments: - - "@cli_interaction_processor" + - "@interaction_processor" manifest.interaction.processor: class: SprykerSdk\Sdk\Infrastructure\Manifest\Interaction\ManifestInteractionProcessor @@ -795,6 +807,43 @@ services: arguments: - "%kernel.project_dir%" + lifecycle.initialized_subscriber: + class: SprykerSdk\Sdk\Infrastructure\Lifecycle\Subscriber\InitializedEventSubscriber + tags: [ "kernel.event_subscriber" ] + arguments: + - "@sdk_filesystem" + - "@placeholder_resolver" + - "@service.lifecycle_command_executor" + - "@context_factory" + + lifecycle.removed_subscriber: + class: SprykerSdk\Sdk\Infrastructure\Lifecycle\Subscriber\UpdatedEventSubscriber + tags: [ "kernel.event_subscriber" ] + arguments: + - "@sdk_filesystem" + - "@placeholder_resolver" + - "@service.lifecycle_command_executor" + - "@context_factory" + + lifecycle.updated_subscriber: + class: SprykerSdk\Sdk\Infrastructure\Lifecycle\Subscriber\RemovedEventSubscriber + tags: [ "kernel.event_subscriber" ] + arguments: + - "@sdk_filesystem" + - "@placeholder_resolver" + - "@service.lifecycle_command_executor" + - "@context_factory" + twig.extension.class_constant_fetcher: class: SprykerSdk\Sdk\Infrastructure\Twig\Extension\ClassConstantFetcher tags: ['twig.extension'] + + metric_sender.client_fetcher: + class: SprykerSdk\Sdk\Infrastructure\MetricsSender\MetricSenderClientFetcher + arguments: + - !tagged_iterator metric_sender_client + + metric_sender.event_subscriber: + class: SprykerSdk\Sdk\Infrastructure\MetricsSender\MetricEventSubscriber + arguments: ['@metric_sender.client_fetcher'] + tags: [ 'kernel.event_subscriber' ] diff --git a/src/Infrastructure/Service/CommandRunner/LocalCliRunner.php b/src/Infrastructure/Service/CommandRunner/LocalCliRunner.php index 5a8b0d1d4..6a9bfc696 100644 --- a/src/Infrastructure/Service/CommandRunner/LocalCliRunner.php +++ b/src/Infrastructure/Service/CommandRunner/LocalCliRunner.php @@ -123,7 +123,7 @@ public function execute(CommandInterface $command, ContextInterface $context): C ); if ( - $process->getExitCode() !== ContextInterface::SUCCESS_EXIT_CODE && + !$process->isSuccessful() && $command instanceof ErrorCommandInterface && strlen($command->getErrorMessage()) ) { @@ -133,7 +133,7 @@ public function execute(CommandInterface $command, ContextInterface $context): C ); } - $context->setExitCode($process->getExitCode() ?? ContextInterface::SUCCESS_EXIT_CODE); + $context->setExitCode($process->isSuccessful() ? ContextInterface::SUCCESS_EXIT_CODE : ContextInterface::FAILURE_EXIT_CODE); $verbosity = $process->isSuccessful() ? MessageInterface::INFO : MessageInterface::ERROR; if ($process->getOutput()) { diff --git a/src/Infrastructure/Service/ConverterRegistry.php b/src/Infrastructure/Service/ConverterRegistry.php index 08d45da03..16902fc12 100644 --- a/src/Infrastructure/Service/ConverterRegistry.php +++ b/src/Infrastructure/Service/ConverterRegistry.php @@ -174,7 +174,7 @@ protected function getConvertorDirectories(): array $paths = $this->settingRepository->findOneByPath(Setting::PATH_EXTENSION_DIRS); if (!$paths) { - throw new MissingSettingException(sprintf('Setting %s is missing', Setting::PATH_EXTENSION_DIRS)); + throw new MissingSettingException(sprintf('Setting `%s` is missing', Setting::PATH_EXTENSION_DIRS)); } $convertorDirs = []; diff --git a/src/Infrastructure/Service/ErrorCommandListener.php b/src/Infrastructure/Service/ErrorCommandListener.php index 988b0be54..e4dec6ac3 100644 --- a/src/Infrastructure/Service/ErrorCommandListener.php +++ b/src/Infrastructure/Service/ErrorCommandListener.php @@ -9,12 +9,26 @@ use Doctrine\DBAL\Exception\TableNotFoundException; use SprykerSdk\Sdk\Core\Application\Dependency\ErrorCommandListenerInterface; -use SprykerSdk\Sdk\Core\Application\Exception\ProjectWorkflowException; use SprykerSdk\Sdk\Core\Application\Exception\SettingsNotInitializedException; +use SprykerSdk\Sdk\Presentation\Console\Command\InitSdkCommand; +use SprykerSdk\Sdk\Presentation\Console\Command\UpdateSdkCommand; use Symfony\Component\Console\Event\ConsoleErrorEvent; class ErrorCommandListener implements ErrorCommandListenerInterface { + /** + * @var bool + */ + protected bool $isDebug; + + /** + * @param bool $isDebug + */ + public function __construct(bool $isDebug) + { + $this->isDebug = $isDebug; + } + /** * @param \Symfony\Component\Console\Event\ConsoleErrorEvent $event * @@ -22,20 +36,18 @@ class ErrorCommandListener implements ErrorCommandListenerInterface */ public function handle(ConsoleErrorEvent $event): void { - if ( - !($event->getError() instanceof TableNotFoundException || $event->getError() instanceof SettingsNotInitializedException) - || $event->getOutput()->isDebug() - ) { + if ($this->isDebug && $event->getOutput()->isDebug()) { return; } - $event->setError( - new ProjectWorkflowException( - 'You need to init or update the SDK. you need to run \'sdk:init:sdk\' or \'sdk:update:all\' command.', - 0, - $event->getError(), - ), - ); $event->setExitCode(0); + + if ($event->getError() instanceof TableNotFoundException || $event->getError() instanceof SettingsNotInitializedException) { + $event->getOutput()->writeln(sprintf('You need to init or update the SDK. you need to run \'%s\' or \'%s\' command.', InitSdkCommand::NAME, UpdateSdkCommand::NAME)); + + return; + } + + $event->getOutput()->writeln('' . $event->getError()->getMessage() . ''); } } diff --git a/src/Infrastructure/Service/LifecycleManager.php b/src/Infrastructure/Service/LifecycleManager.php index 46c49bd53..b319c7d0d 100644 --- a/src/Infrastructure/Service/LifecycleManager.php +++ b/src/Infrastructure/Service/LifecycleManager.php @@ -13,6 +13,7 @@ use SprykerSdk\Sdk\Infrastructure\Exception\SdkVersionNotFoundException; use SprykerSdk\Sdk\Infrastructure\Loader\TaskYaml\TaskYamlFileLoaderInterface; use SprykerSdk\Sdk\Infrastructure\Repository\TaskRepository; +use SprykerSdk\Sdk\Infrastructure\Version\FileAppVersionFetcher; use Throwable; class LifecycleManager implements LifecycleManagerInterface @@ -81,8 +82,6 @@ public function update(): void } /** - * @throws \SprykerSdk\Sdk\Infrastructure\Exception\SdkVersionNotFoundException - * * @return array<\SprykerSdk\SdkContracts\Entity\MessageInterface> */ public function checkForUpdate(): array @@ -90,18 +89,14 @@ public function checkForUpdate(): array $versionFilePath = $this->sdkDirectory . '/VERSION'; if (!is_file($versionFilePath)) { - throw new SdkVersionNotFoundException( - sprintf('Could not find %s file, skip updatable check', $versionFilePath), - ); + return [new Message(sprintf('Could not find `%s` file, skip updatable check', FileAppVersionFetcher::VERSION_FILE_NAME))]; } $currentVersion = (string)file_get_contents($versionFilePath); $currentVersion = trim($currentVersion); if (!$currentVersion) { - throw new SdkVersionNotFoundException( - sprintf('Could not find version in the file "%s". File is empty.', $versionFilePath), - ); + return [new Message(sprintf('Could not find version in the file `%s`. File is empty.', FileAppVersionFetcher::VERSION_FILE_NAME))]; } $messages = []; diff --git a/src/Infrastructure/Service/ProjectInfo/ComposerProjectInfoFetcher.php b/src/Infrastructure/Service/ProjectInfo/ComposerProjectInfoFetcher.php index 490e71db4..e28d89021 100644 --- a/src/Infrastructure/Service/ProjectInfo/ComposerProjectInfoFetcher.php +++ b/src/Infrastructure/Service/ProjectInfo/ComposerProjectInfoFetcher.php @@ -64,13 +64,12 @@ protected function getProjectInfo(): ProjectInfo $projectDirectory = rtrim($projectDirectory->getValues(), DIRECTORY_SEPARATOR); $composerFile = $projectDirectory . DIRECTORY_SEPARATOR . static::COMPOSER_FILE_NAME; - // phpcs:ignore - $composerJsonContent = @file_get_contents($composerFile); - if ($composerJsonContent === false) { + if (!file_exists($composerFile)) { throw new FetchDataException(sprintf('Unable to read the file %s: %s', $composerFile, error_get_last()['message'] ?? '')); } - $composerJson = json_decode($composerJsonContent, true, 512, \JSON_THROW_ON_ERROR); + $composerJsonContent = file_get_contents($composerFile); + $composerJson = json_decode((string)$composerJsonContent, true, 512, \JSON_THROW_ON_ERROR); if (!isset($composerJson['name'])) { throw new FetchDataException(sprintf('%s has no name key', $composerFile)); diff --git a/src/Infrastructure/Service/ProjectInfo/ProjectInfoFetcher.php b/src/Infrastructure/Service/ProjectInfo/ProjectInfoFetcher.php index c4c540e4b..e99ce5a74 100644 --- a/src/Infrastructure/Service/ProjectInfo/ProjectInfoFetcher.php +++ b/src/Infrastructure/Service/ProjectInfo/ProjectInfoFetcher.php @@ -9,7 +9,6 @@ use SprykerSdk\Sdk\Core\Application\Dependency\Service\ProjectInfo\ProjectInfoFetcherInterface; use SprykerSdk\Sdk\Core\Application\Dto\ProjectInfo\ProjectInfo; -use SprykerSdk\Sdk\Infrastructure\Logger\ErrorLoggerFactoryInterface; class ProjectInfoFetcher implements ProjectInfoFetcherInterface { @@ -18,19 +17,12 @@ class ProjectInfoFetcher implements ProjectInfoFetcherInterface */ protected iterable $projectInfoFetcherStrategies; - /** - * @var \SprykerSdk\Sdk\Infrastructure\Logger\ErrorLoggerFactoryInterface - */ - protected ErrorLoggerFactoryInterface $errorLoggerFactory; - /** * @param iterable<\SprykerSdk\Sdk\Infrastructure\Service\ProjectInfo\ProjectInfoFetcherStrategyInterface> $projectInfoFetcherStrategies - * @param \SprykerSdk\Sdk\Infrastructure\Logger\ErrorLoggerFactoryInterface $errorLoggerFactory */ - public function __construct(iterable $projectInfoFetcherStrategies, ErrorLoggerFactoryInterface $errorLoggerFactory) + public function __construct(iterable $projectInfoFetcherStrategies) { $this->projectInfoFetcherStrategies = $projectInfoFetcherStrategies; - $this->errorLoggerFactory = $errorLoggerFactory; } /** @@ -42,8 +34,6 @@ public function fetchProjectInfo(): ?ProjectInfo try { return $projectInfoFetcherStrategy->fetchProjectInfo(); } catch (FetchDataException $e) { - $this->errorLoggerFactory->getErrorLogger()->error($e->getMessage()); - continue; } } diff --git a/src/Infrastructure/Service/TaskManager.php b/src/Infrastructure/Service/TaskManager.php index da7254653..db8b89ff4 100644 --- a/src/Infrastructure/Service/TaskManager.php +++ b/src/Infrastructure/Service/TaskManager.php @@ -9,10 +9,11 @@ use SprykerSdk\Sdk\Core\Application\Dependency\Repository\TaskRepositoryInterface; use SprykerSdk\Sdk\Core\Application\Dependency\TaskManagerInterface; -use SprykerSdk\Sdk\Core\Application\Lifecycle\Event\InitializedEvent; -use SprykerSdk\Sdk\Core\Application\Lifecycle\Event\RemovedEvent; -use SprykerSdk\Sdk\Core\Application\Lifecycle\Event\UpdatedEvent; use SprykerSdk\Sdk\Infrastructure\Builder\TaskSet\TaskFromTaskSetBuilderInterface; +use SprykerSdk\Sdk\Infrastructure\Lifecycle\Event\InitializedEvent; +use SprykerSdk\Sdk\Infrastructure\Lifecycle\Event\RemovedEvent; +use SprykerSdk\Sdk\Infrastructure\Lifecycle\Event\UpdatedEvent; +use SprykerSdk\Sdk\Infrastructure\Task\TaskSetTaskRelation\TaskSetTaskRelationFacadeInterface; use SprykerSdk\SdkContracts\Entity\TaskInterface; use SprykerSdk\SdkContracts\Entity\TaskSetInterface; use Symfony\Contracts\EventDispatcher\EventDispatcherInterface; @@ -34,19 +35,27 @@ class TaskManager implements TaskManagerInterface */ protected TaskFromTaskSetBuilderInterface $taskFromTaskSetBuilder; + /** + * @var \SprykerSdk\Sdk\Infrastructure\Task\TaskSetTaskRelation\TaskSetTaskRelationFacadeInterface + */ + protected TaskSetTaskRelationFacadeInterface $taskSetTaskRelationFacade; + /** * @param \Symfony\Contracts\EventDispatcher\EventDispatcherInterface $eventDispatcher * @param \SprykerSdk\Sdk\Core\Application\Dependency\Repository\TaskRepositoryInterface $taskRepository * @param \SprykerSdk\Sdk\Infrastructure\Builder\TaskSet\TaskFromTaskSetBuilderInterface $taskFromTaskSetBuilder + * @param \SprykerSdk\Sdk\Infrastructure\Task\TaskSetTaskRelation\TaskSetTaskRelationFacadeInterface $taskSetTaskRelationFacade */ public function __construct( EventDispatcherInterface $eventDispatcher, TaskRepositoryInterface $taskRepository, - TaskFromTaskSetBuilderInterface $taskFromTaskSetBuilder + TaskFromTaskSetBuilderInterface $taskFromTaskSetBuilder, + TaskSetTaskRelationFacadeInterface $taskSetTaskRelationFacade ) { $this->eventDispatcher = $eventDispatcher; $this->taskRepository = $taskRepository; $this->taskFromTaskSetBuilder = $taskFromTaskSetBuilder; + $this->taskSetTaskRelationFacade = $taskSetTaskRelationFacade; } /** @@ -66,10 +75,12 @@ public function initialize(array $tasks): array } if ($task instanceof TaskSetInterface) { + $this->taskSetTaskRelationFacade->collectTaskSet($task, $tasks); $task = $this->taskFromTaskSetBuilder->buildTaskFromTaskSet($task, $tasks); } $entities[] = $this->taskRepository->create($task); + $this->taskSetTaskRelationFacade->createRelations($task); $this->eventDispatcher->dispatch(new InitializedEvent($task), InitializedEvent::NAME); } @@ -84,6 +95,7 @@ public function initialize(array $tasks): array public function remove(TaskInterface $task): void { $this->taskRepository->remove($task); + $this->taskSetTaskRelationFacade->removeRelations($task); $this->eventDispatcher->dispatch(new RemovedEvent($task), RemovedEvent::NAME); } @@ -97,6 +109,7 @@ public function remove(TaskInterface $task): void public function update(TaskInterface $folderTask, TaskInterface $databaseTask): void { $this->taskRepository->update($folderTask, $databaseTask); + $this->taskSetTaskRelationFacade->updateRelations($folderTask); $this->eventDispatcher->dispatch(new UpdatedEvent($folderTask), UpdatedEvent::NAME); } diff --git a/src/Infrastructure/Service/TasksRepositoryInstaller.php b/src/Infrastructure/Service/TasksRepositoryInstaller.php index fd9a212b3..ebc752a05 100644 --- a/src/Infrastructure/Service/TasksRepositoryInstaller.php +++ b/src/Infrastructure/Service/TasksRepositoryInstaller.php @@ -45,6 +45,10 @@ public function __construct(string $gitModulesPath, LoggerInterface $logger, str */ public function install(): array { + if (!is_file($this->gitModulesPath)) { + return []; + } + $gitModules = parse_ini_file($this->gitModulesPath, true); if (!$gitModules) { diff --git a/src/Infrastructure/Service/ValueReceiver/ApiInteractionProcessor.php b/src/Infrastructure/Service/ValueReceiver/ApiInteractionProcessor.php index 22e312a6e..40ee41037 100644 --- a/src/Infrastructure/Service/ValueReceiver/ApiInteractionProcessor.php +++ b/src/Infrastructure/Service/ValueReceiver/ApiInteractionProcessor.php @@ -73,7 +73,7 @@ public function receiveValue(ReceiverValueInterface $receiverValue) return $defaultValue; } - if ($receiverValue->getDefaultValue()) { + if ($receiverValue->getDefaultValue() !== null) { return $receiverValue->getDefaultValue(); } diff --git a/src/Infrastructure/Service/ValueReceiver/QuestionFactory/PathQuestionFactory.php b/src/Infrastructure/Service/ValueReceiver/QuestionFactory/PathQuestionFactory.php index 7f02052d9..6848356d6 100644 --- a/src/Infrastructure/Service/ValueReceiver/QuestionFactory/PathQuestionFactory.php +++ b/src/Infrastructure/Service/ValueReceiver/QuestionFactory/PathQuestionFactory.php @@ -7,6 +7,7 @@ namespace SprykerSdk\Sdk\Infrastructure\Service\ValueReceiver\QuestionFactory; +use SprykerSdk\Sdk\Core\Application\Exception\MissingValueException; use SprykerSdk\SdkContracts\Enum\ValueTypeEnum; use Symfony\Component\Console\Question\Question; @@ -25,6 +26,28 @@ public function createQuestion(string $description, array $choices, $defaultValu $question->setAutocompleterCallback([$this, 'autocompleteInput']); + return $this->addValidator($question); + } + + /** + * @param \Symfony\Component\Console\Question\Question $question + * + * @return \Symfony\Component\Console\Question\Question + */ + protected function addValidator(Question $question): Question + { + $question->setValidator(function ($value) { + if (!$this->isPassValid($value)) { + throw new MissingValueException('Path ../ is forbidden due to security reasons.'); + } + + if (!$this->isRelativePath($value)) { + throw new MissingValueException('Absolute path is forbidden due to security reasons.'); + } + + return $value; + }); + return $question; } @@ -35,7 +58,16 @@ public function createQuestion(string $description, array $choices, $defaultValu */ public function autocompleteInput(string $userInput): array { - $inputPath = preg_replace('%(/|^)[^/]*$%', '$1', $userInput); + $inputPath = (string)preg_replace('%(/|^)[^/]*$%', '$1', $userInput); + + if (!$this->isPassValid($inputPath)) { + return []; + } + + if (!$this->isRelativePath($inputPath)) { + return []; + } + //Autocompletion is an optional convenience feature that should not fail the whole command run //@phpcs:ignore Generic.PHP.NoSilencedErrors.Discouraged $foundFilesAndDirs = @scandir($inputPath ?: '.') ?: []; @@ -52,4 +84,24 @@ public static function getType(): string { return ValueTypeEnum::TYPE_PATH; } + + /** + * @param string $inputPath + * + * @return bool + */ + protected function isPassValid(string $inputPath): bool + { + return strpos($inputPath, '..') === false; + } + + /** + * @param string $inputPath + * + * @return bool + */ + protected function isRelativePath(string $inputPath): bool + { + return strpos($inputPath, '/') !== 0; + } } diff --git a/src/Infrastructure/Service/ValueResolverRegistry.php b/src/Infrastructure/Service/ValueResolverRegistry.php index 43d05bd7e..72e9c8d03 100644 --- a/src/Infrastructure/Service/ValueResolverRegistry.php +++ b/src/Infrastructure/Service/ValueResolverRegistry.php @@ -159,7 +159,7 @@ protected function getValueResolverDirectories(): array $paths = $this->settingRepository->findOneByPath(Setting::PATH_EXTENSION_DIRS); if (!$paths) { - throw new MissingSettingException(sprintf('Setting %s is missing', Setting::PATH_EXTENSION_DIRS)); + throw new MissingSettingException(sprintf('Setting `%s` is missing', Setting::PATH_EXTENSION_DIRS)); } return array_map(function (string $directory) { diff --git a/src/Infrastructure/Setting/ProjectSettingsInitializer/ProjectFilesInitializer.php b/src/Infrastructure/Setting/ProjectSettingsInitializer/ProjectFilesInitializer.php index 76890ef25..4b5c29142 100644 --- a/src/Infrastructure/Setting/ProjectSettingsInitializer/ProjectFilesInitializer.php +++ b/src/Infrastructure/Setting/ProjectSettingsInitializer/ProjectFilesInitializer.php @@ -16,6 +16,11 @@ class ProjectFilesInitializer */ protected string $projectSettingFileName; + /** + * @var string + */ + protected string $localProjectSettingFileName; + /** * @var \Symfony\Component\Filesystem\Filesystem */ @@ -23,11 +28,13 @@ class ProjectFilesInitializer /** * @param string $projectSettingFileName + * @param string $localProjectSettingFileName * @param \Symfony\Component\Filesystem\Filesystem $filesystem */ - public function __construct(string $projectSettingFileName, Filesystem $filesystem) + public function __construct(string $projectSettingFileName, string $localProjectSettingFileName, Filesystem $filesystem) { $this->projectSettingFileName = $projectSettingFileName; + $this->localProjectSettingFileName = $localProjectSettingFileName; $this->filesystem = $filesystem; } @@ -36,7 +43,8 @@ public function __construct(string $projectSettingFileName, Filesystem $filesyst */ public function isProjectSettingsInitialised(): bool { - return $this->filesystem->exists($this->projectSettingFileName); + return $this->filesystem->exists($this->projectSettingFileName) || + $this->filesystem->exists($this->localProjectSettingFileName); } /** diff --git a/src/Infrastructure/Storage/TaskSetTaskRelationStorage.php b/src/Infrastructure/Storage/TaskSetTaskRelationStorage.php new file mode 100644 index 000000000..de565924e --- /dev/null +++ b/src/Infrastructure/Storage/TaskSetTaskRelationStorage.php @@ -0,0 +1,43 @@ +> + */ + protected array $taskSetTaskRelations = []; + + /** + * @param array<\SprykerSdk\Sdk\Core\Domain\Entity\TaskSetTaskRelationInterface> $taskSetTaskRelations + * + * @return void + */ + public function addTaskSetTasRelations(array $taskSetTaskRelations): void + { + foreach ($taskSetTaskRelations as $taskSetTaskRelation) { + $taskSetId = $taskSetTaskRelation->getTaskSet()->getId(); + $subTaskId = $taskSetTaskRelation->getSubTask()->getId(); + + $this->taskSetTaskRelations[$taskSetId][$subTaskId] = $taskSetTaskRelation; + } + } + + /** + * @param string $taskSetId + * + * @return array<\SprykerSdk\Sdk\Core\Domain\Entity\TaskSetTaskRelationInterface> + */ + public function getTaskSetTaskRelations(string $taskSetId): array + { + return isset($this->taskSetTaskRelations[$taskSetId]) + ? array_values($this->taskSetTaskRelations[$taskSetId]) + : []; + } +} diff --git a/src/Infrastructure/Task/TaskSetTaskRelation/TaskSetTaskRelationFacade.php b/src/Infrastructure/Task/TaskSetTaskRelation/TaskSetTaskRelationFacade.php new file mode 100644 index 000000000..702ed40b8 --- /dev/null +++ b/src/Infrastructure/Task/TaskSetTaskRelation/TaskSetTaskRelationFacade.php @@ -0,0 +1,114 @@ +taskSetTaskRelationStorage = $taskSetTaskRelationStorage; + $this->taskSetTaskRelationsBuilder = $taskSetTaskRelationsBuilder; + $this->taskSetTaskRelationsFromYamlBuilder = $taskSetTaskRelationsFromYamlBuilder; + $this->taskSetTaskRelationRepository = $taskSetTaskRelationRepository; + } + + /** + * @param \SprykerSdk\SdkContracts\Entity\TaskSetInterface $taskSet + * @param array $existingTasks + * + * @return void + */ + public function collectTaskSet(TaskSetInterface $taskSet, array $existingTasks): void + { + $this->taskSetTaskRelationStorage->addTaskSetTasRelations( + $this->taskSetTaskRelationsBuilder->buildFromTaskSet($taskSet, $existingTasks), + ); + } + + /** + * @param array $taskSetConfiguration + * @param array $existingTasks + * + * @return void + */ + public function collectYamlTaskSet(array $taskSetConfiguration, array $existingTasks): void + { + $this->taskSetTaskRelationStorage->addTaskSetTasRelations( + $this->taskSetTaskRelationsFromYamlBuilder->buildFromYamlTaskSet($taskSetConfiguration, $existingTasks), + ); + } + + /** + * @param \SprykerSdk\SdkContracts\Entity\TaskInterface $task + * + * @return void + */ + public function createRelations(TaskInterface $task): void + { + $taskSetTaskRelations = $this->taskSetTaskRelationStorage->getTaskSetTaskRelations($task->getId()); + $this->taskSetTaskRelationRepository->createMany($taskSetTaskRelations); + } + + /** + * @param \SprykerSdk\SdkContracts\Entity\TaskInterface $task + * + * @return void + */ + public function removeRelations(TaskInterface $task): void + { + $this->taskSetTaskRelationRepository->removeByTaskSetId($task->getId()); + } + + /** + * @param \SprykerSdk\SdkContracts\Entity\TaskInterface $task + * + * @return void + */ + public function updateRelations(TaskInterface $task): void + { + $this->removeRelations($task); + $this->createRelations($task); + } +} diff --git a/src/Infrastructure/Task/TaskSetTaskRelation/TaskSetTaskRelationFacadeInterface.php b/src/Infrastructure/Task/TaskSetTaskRelation/TaskSetTaskRelationFacadeInterface.php new file mode 100644 index 000000000..848e05090 --- /dev/null +++ b/src/Infrastructure/Task/TaskSetTaskRelation/TaskSetTaskRelationFacadeInterface.php @@ -0,0 +1,51 @@ + $existingTasks + * + * @return void + */ + public function collectTaskSet(TaskSetInterface $taskSet, array $existingTasks): void; + + /** + * @param array $taskSetConfiguration + * @param array $existingTasks + * + * @return void + */ + public function collectYamlTaskSet(array $taskSetConfiguration, array $existingTasks): void; + + /** + * @param \SprykerSdk\SdkContracts\Entity\TaskInterface $task + * + * @return void + */ + public function createRelations(TaskInterface $task): void; + + /** + * @param \SprykerSdk\SdkContracts\Entity\TaskInterface $task + * + * @return void + */ + public function removeRelations(TaskInterface $task): void; + + /** + * @param \SprykerSdk\SdkContracts\Entity\TaskInterface $task + * + * @return void + */ + public function updateRelations(TaskInterface $task): void; +} diff --git a/src/Infrastructure/Telemetry/FileReportTelemetryEventSender.php b/src/Infrastructure/Telemetry/FileReportTelemetryEventSender.php index c1662289d..a9fabf386 100644 --- a/src/Infrastructure/Telemetry/FileReportTelemetryEventSender.php +++ b/src/Infrastructure/Telemetry/FileReportTelemetryEventSender.php @@ -55,33 +55,25 @@ class FileReportTelemetryEventSender implements TelemetryEventSenderInterface */ protected string $format; - /** - * @var bool - */ - protected bool $isDebug; - /** * @param \SprykerSdk\Sdk\Core\Application\Dependency\ProjectSettingRepositoryInterface $projectSettingRepository * @param \Symfony\Component\Serializer\SerializerInterface $serializer * @param \Symfony\Component\Filesystem\Filesystem $filesystem * @param string $reportFileName * @param string $format - * @param bool $isDebug */ public function __construct( ProjectSettingRepositoryInterface $projectSettingRepository, SerializerInterface $serializer, Filesystem $filesystem, string $reportFileName, - string $format, - bool $isDebug = false + string $format ) { $this->projectSettingRepository = $projectSettingRepository; $this->serializer = $serializer; $this->filesystem = $filesystem; $this->reportFileName = $reportFileName; $this->format = $format; - $this->isDebug = $isDebug; } /** diff --git a/src/Infrastructure/Version/FileAppVersionFetcher.php b/src/Infrastructure/Version/FileAppVersionFetcher.php index 3e880ba8e..7c04ed8e3 100644 --- a/src/Infrastructure/Version/FileAppVersionFetcher.php +++ b/src/Infrastructure/Version/FileAppVersionFetcher.php @@ -15,7 +15,7 @@ class FileAppVersionFetcher implements AppVersionFetcherInterface /** * @var string */ - protected const VERSION_FILE_NAME = 'VERSION'; + public const VERSION_FILE_NAME = 'VERSION'; /** * @var string diff --git a/src/Infrastructure/Violation/Formatter/OutputViolationDecoratorInterface.php b/src/Infrastructure/Violation/Formatter/OutputViolationDecoratorInterface.php new file mode 100644 index 000000000..6cc608b9f --- /dev/null +++ b/src/Infrastructure/Violation/Formatter/OutputViolationDecoratorInterface.php @@ -0,0 +1,20 @@ +violationReportDecorator = $violationReportDecorator; + } + /** * @return string */ @@ -53,13 +72,15 @@ public function getFormat(): string */ public function format(string $name, ViolationReportInterface $violationReport): void { + $violationReport = $this->violationReportDecorator->decorate($violationReport); + if ($violationReport->getViolations()) { $table = new Table($this->output); $table ->setHeaderTitle('Violations found on project level') - ->setHeaders(['Violation', 'Priority', 'Fixable']); + ->setHeaders(['Violation', 'Fixable']); foreach ($violationReport->getViolations() as $violation) { - $table->addRow([$violation->getMessage(), $violation->priority(), $violation->isFixable() ? 'true' : 'false']); + $table->addRow([$violation->getMessage(), $violation->isFixable() ? 'true' : 'false']); } $table->render(); } @@ -69,29 +90,32 @@ public function format(string $name, ViolationReportInterface $violationReport): $violations = []; foreach ($violationReport->getPackages() as $package) { foreach ($package->getViolations() as $violation) { - $packages[] = [$violation->getId(), $violation->priority(), $violation->isFixable() ? 'true' : 'false', $package->getPackage()]; + $packages[] = [$violation->getId(), $violation->isFixable() ? 'true' : 'false', $package->getPackage()]; } foreach ($package->getFileViolations() as $path => $fileViolations) { foreach ($fileViolations as $fileViolation) { $violations[] = [ $fileViolation->getId(), - $fileViolation->getMessage(), - $fileViolation->priority(), + $fileViolation->getMessage() ?: static::FALLBACK_VALUE_NOT_AVAILABLE, $fileViolation->isFixable() ? 'true' : 'false', $path, - $fileViolation->getStartLine(), - $fileViolation->getClass(), - $fileViolation->getMethod(), + $fileViolation->getStartLine() ?: static::FALLBACK_VALUE_NOT_AVAILABLE, + $fileViolation->getClass() ?: static::FALLBACK_VALUE_NOT_AVAILABLE, + $fileViolation->getMethod() ?: static::FALLBACK_VALUE_NOT_AVAILABLE, ]; + + $violations[] = new TableSeparator(); } } } + array_pop($violations); + if ($packages) { $table = new Table($this->output); $table ->setHeaderTitle('Violations found on package level') - ->setHeaders(['Violation', 'Priority', 'Fixable', 'Package']) + ->setHeaders(['Violation', 'Fixable', 'Package']) ->setRows($packages); $table->render(); } @@ -100,7 +124,7 @@ public function format(string $name, ViolationReportInterface $violationReport): $table = new Table($this->output); $table ->setHeaderTitle('Violations found in files') - ->setHeaders(['Violation', 'Message', 'Priority', 'Fixable', 'File', 'Line', 'Class', 'Method']) + ->setHeaders(['Violation', 'Message', 'Fixable', 'File', 'Line', 'Class', 'Method']) ->setRows($violations); $table->render(); } diff --git a/src/Infrastructure/Violation/Formatter/ViolationReportDecorator.php b/src/Infrastructure/Violation/Formatter/ViolationReportDecorator.php new file mode 100644 index 000000000..2d6ba47b0 --- /dev/null +++ b/src/Infrastructure/Violation/Formatter/ViolationReportDecorator.php @@ -0,0 +1,99 @@ + + */ + protected iterable $violationDecorators; + + /** + * @param iterable<\SprykerSdk\Sdk\Infrastructure\Violation\Formatter\OutputViolationDecoratorInterface> $violationDecorators + */ + public function __construct(iterable $violationDecorators) + { + $this->violationDecorators = $violationDecorators; + } + + /** + * @param \SprykerSdk\SdkContracts\Report\Violation\ViolationReportInterface $violationReport + * + * @return \SprykerSdk\SdkContracts\Report\Violation\ViolationReportInterface + */ + public function decorate(ViolationReportInterface $violationReport): ViolationReportInterface + { + $violations = $this->decorateViolations($violationReport->getViolations()); + $packages = []; + + foreach ($violationReport->getPackages() as $package) { + $packagesViolations = $this->decorateViolations($package->getViolations()); + $packageFileViolations = $this->decorateFileViolations($package->getFileViolations()); + $packages[] = new PackageViolationReport($package->getPackage(), $package->getPath(), $packagesViolations, $packageFileViolations); + } + + return new ViolationReport( + $violationReport->getProject(), + $violationReport->getPath(), + $violations, + $packages, + ); + } + + /** + * @param array> $fileViolationGroups + * + * @return array> + */ + protected function decorateFileViolations(array $fileViolationGroups): array + { + $packageFileViolations = []; + foreach ($fileViolationGroups as $path => $fileViolations) { + $packageFileViolations[$path] = $this->decorateViolations($fileViolations); + } + + return $packageFileViolations; + } + + /** + * @param array<\SprykerSdk\SdkContracts\Report\Violation\ViolationInterface> $violations + * + * @return array<\SprykerSdk\SdkContracts\Report\Violation\ViolationInterface> + */ + protected function decorateViolations(array $violations): array + { + $packagesViolations = []; + foreach ($violations as $violation) { + $packagesViolations[] = $this->decorateViolation($violation); + } + + return $packagesViolations; + } + + /** + * @param \SprykerSdk\SdkContracts\Report\Violation\ViolationInterface $violation + * + * @return \SprykerSdk\SdkContracts\Report\Violation\ViolationInterface + */ + protected function decorateViolation(ViolationInterface $violation): ViolationInterface + { + foreach ($this->violationDecorators as $violationDecorator) { + $violation = $violationDecorator->decorate($violation); + } + + return $violation; + } +} diff --git a/src/Infrastructure/Violation/Formatter/YamlViolationReportFormatter.php b/src/Infrastructure/Violation/Formatter/YamlViolationReportFormatter.php index 76686f092..162bc6a23 100644 --- a/src/Infrastructure/Violation/Formatter/YamlViolationReportFormatter.php +++ b/src/Infrastructure/Violation/Formatter/YamlViolationReportFormatter.php @@ -35,19 +35,27 @@ class YamlViolationReportFormatter implements ViolationReportFormatterInterface */ protected Yaml $yamlParser; + /** + * @var \SprykerSdk\Sdk\Infrastructure\Violation\Formatter\ViolationReportDecorator + */ + protected ViolationReportDecorator $violationReportDecorator; + /** * @param \SprykerSdk\Sdk\Infrastructure\Mapper\ViolationReportFileMapperInterface $violationReportFileMapper * @param \SprykerSdk\Sdk\Infrastructure\Violation\ViolationPathReader $violationPathReader * @param \Symfony\Component\Yaml\Yaml $yamlParser + * @param \SprykerSdk\Sdk\Infrastructure\Violation\Formatter\ViolationReportDecorator $violationReportDecorator */ public function __construct( ViolationReportFileMapperInterface $violationReportFileMapper, ViolationPathReader $violationPathReader, - Yaml $yamlParser + Yaml $yamlParser, + ViolationReportDecorator $violationReportDecorator ) { $this->violationReportFileMapper = $violationReportFileMapper; $this->violationPathReader = $violationPathReader; $this->yamlParser = $yamlParser; + $this->violationReportDecorator = $violationReportDecorator; } /** @@ -66,12 +74,14 @@ public function getFormat(): string */ public function format(string $name, ViolationReportInterface $violationReport): void { + $violationReport = $this->violationReportDecorator->decorate($violationReport); + $violationReportStructure = $this->violationReportFileMapper->mapViolationReportToYamlStructure($violationReport); $reportDir = $this->violationPathReader->getViolationReportDirPath(); if (!is_dir($reportDir)) { mkdir($reportDir, 0777, true); } - file_put_contents($this->violationPathReader->getViolationReportPath($name), $this->yamlParser->dump($violationReportStructure)); + file_put_contents($this->violationPathReader->getViolationReportPath($name), $this->yamlParser::dump($violationReportStructure)); } /** @@ -81,7 +91,7 @@ public function format(string $name, ViolationReportInterface $violationReport): */ public function read(string $name): ?ViolationReportInterface { - $violationReportData = $this->yamlParser->parseFile($this->violationPathReader->getViolationReportPath($name)); + $violationReportData = $this->yamlParser::parseFile($this->violationPathReader->getViolationReportPath($name)); return $this->violationReportFileMapper->mapFileStructureToViolationReport($violationReportData); } diff --git a/src/Presentation/Console/Command/AbstractInitCommand.php b/src/Presentation/Console/Command/AbstractInitCommand.php index 54d7e8635..a05a267b3 100644 --- a/src/Presentation/Console/Command/AbstractInitCommand.php +++ b/src/Presentation/Console/Command/AbstractInitCommand.php @@ -45,6 +45,10 @@ protected function configure() $settings = $this->yamlParser::parseFile($this->settingsPath, $this->yamlParser::PARSE_CONSTANT)['settings'] ?? []; foreach ($settings as $settingData) { + if (isset($settingData['values']) || isset($settingData['initializer'])) { + continue; + } + $this->addOption( $settingData['path'], null, diff --git a/src/Presentation/Console/Command/AbstractUpdateCommand.php b/src/Presentation/Console/Command/AbstractUpdateCommand.php index 72d4dae7e..bd1285234 100644 --- a/src/Presentation/Console/Command/AbstractUpdateCommand.php +++ b/src/Presentation/Console/Command/AbstractUpdateCommand.php @@ -36,16 +36,14 @@ protected function configure() $this->addOption( static::OPTION_CHECK_ONLY, 'c', - InputOption::VALUE_OPTIONAL, + InputOption::VALUE_NONE, 'Update if the current version is\'n up-to-date.', - false, ); $this->addOption( static::OPTION_NO_CHECK, null, - InputOption::VALUE_OPTIONAL, + InputOption::VALUE_NONE, 'Only checks if the current version is up-to-date', - false, ); } } diff --git a/src/Presentation/Console/Command/InitProjectCommand.php b/src/Presentation/Console/Command/InitProjectCommand.php index 1339c2d85..bd348b9f0 100644 --- a/src/Presentation/Console/Command/InitProjectCommand.php +++ b/src/Presentation/Console/Command/InitProjectCommand.php @@ -124,7 +124,7 @@ protected function isReInitializedNeeded(): bool { return $this->cliValueReceiver->receiveValue( new ReceiverValue( - 'ask-value', + 'overwrite-setting', 'Project settings file already exists, should it be overwritten?', false, ValueTypeEnum::TYPE_BOOL, diff --git a/src/Presentation/Console/Command/InitSdkCommand.php b/src/Presentation/Console/Command/InitSdkCommand.php index 00d2c3e54..d604c504e 100644 --- a/src/Presentation/Console/Command/InitSdkCommand.php +++ b/src/Presentation/Console/Command/InitSdkCommand.php @@ -19,7 +19,7 @@ class InitSdkCommand extends AbstractInitCommand /** * @var string */ - protected const NAME = 'sdk:init:sdk'; + public const NAME = 'sdk:init:sdk'; /** * @var string diff --git a/src/Presentation/Console/Command/QaAutomationCommand.php b/src/Presentation/Console/Command/QaAutomationCommand.php index bbc962b21..35c399249 100644 --- a/src/Presentation/Console/Command/QaAutomationCommand.php +++ b/src/Presentation/Console/Command/QaAutomationCommand.php @@ -7,10 +7,10 @@ namespace SprykerSdk\Sdk\Presentation\Console\Command; +use SprykerSdk\Sdk\Core\Application\Dependency\ContextFactoryInterface; use SprykerSdk\Sdk\Core\Application\Dependency\ContextRepositoryInterface; use SprykerSdk\Sdk\Core\Application\Dependency\ProjectSettingRepositoryInterface; use SprykerSdk\Sdk\Core\Application\Exception\SettingsNotInitializedException; -use SprykerSdk\Sdk\Core\Application\Service\ContextFactory; use SprykerSdk\Sdk\Core\Application\Service\ProjectWorkflow; use SprykerSdk\Sdk\Core\Application\Service\TaskExecutor; use SprykerSdk\Sdk\Infrastructure\Service\DynamicTaskSetCreator; @@ -40,7 +40,7 @@ class QaAutomationCommand extends RunTaskWrapperCommand * @param \SprykerSdk\Sdk\Core\Application\Service\ProjectWorkflow $projectWorkflow * @param \SprykerSdk\Sdk\Core\Application\Dependency\ContextRepositoryInterface $contextRepository * @param \SprykerSdk\Sdk\Core\Application\Dependency\ProjectSettingRepositoryInterface $projectSettingRepository - * @param \SprykerSdk\Sdk\Core\Application\Service\ContextFactory $contextFactory + * @param \SprykerSdk\Sdk\Core\Application\Dependency\ContextFactoryInterface $contextFactory * @param \SprykerSdk\Sdk\Infrastructure\Service\DynamicTaskSetCreator $dynamicTaskSetCreator */ public function __construct( @@ -48,7 +48,7 @@ public function __construct( ProjectWorkflow $projectWorkflow, ContextRepositoryInterface $contextRepository, ProjectSettingRepositoryInterface $projectSettingRepository, - ContextFactory $contextFactory, + ContextFactoryInterface $contextFactory, DynamicTaskSetCreator $dynamicTaskSetCreator ) { $this->dynamicTaskSetCreator = $dynamicTaskSetCreator; @@ -83,7 +83,6 @@ public function execute(InputInterface $input, OutputInterface $output): int $context->setTask($this->dynamicTaskSetCreator->getTask(Setting::PATH_QA_TASKS)); $context = $this->taskExecutor->execute($context); $this->writeContext($input, $context); - $this->writeFilteredMessages($output, $context); return $context->getExitCode(); } diff --git a/src/Presentation/Console/Command/RunTaskWrapperCommand.php b/src/Presentation/Console/Command/RunTaskWrapperCommand.php index 8f37b11bd..7ef8f5463 100644 --- a/src/Presentation/Console/Command/RunTaskWrapperCommand.php +++ b/src/Presentation/Console/Command/RunTaskWrapperCommand.php @@ -13,7 +13,6 @@ use SprykerSdk\Sdk\Core\Application\Service\ProjectWorkflow; use SprykerSdk\Sdk\Core\Application\Service\TaskExecutor; use SprykerSdk\Sdk\Core\Domain\Entity\ContextInterface; -use SprykerSdk\SdkContracts\Entity\MessageInterface; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Input\InputOption; @@ -167,69 +166,10 @@ public function execute(InputInterface $input, OutputInterface $output): int $context = $this->taskExecutor->execute($context, $this->name); $this->writeContext($input, $context); - $this->writeFilteredMessages($output, $context); return $context->getExitCode(); } - /** - * @param \Symfony\Component\Console\Output\OutputInterface $output - * @param \SprykerSdk\Sdk\Core\Domain\Entity\ContextInterface $context - * - * @return void - */ - protected function writeFilteredMessages( - OutputInterface $output, - ContextInterface $context - ): void { - $verbosity = $this->getVerbosity($output); - - foreach ($context->getMessages() as $message) { - if ($message->getVerbosity() <= $verbosity) { - $output->writeln($this->formatMessage($message)); - } - } - } - - /** - * @param \SprykerSdk\SdkContracts\Entity\MessageInterface $message - * - * @return string - */ - protected function formatMessage(MessageInterface $message): string - { - $template = [ - MessageInterface::INFO => 'Info: %s', - MessageInterface::ERROR => 'Error: %s', - MessageInterface::SUCCESS => 'Success: %s', - MessageInterface::DEBUG => 'Debug: %s', - ][$message->getVerbosity()] ?? '%s'; - - return sprintf($template, $message->getMessage()); - } - - /** - * @param \Symfony\Component\Console\Output\OutputInterface $output - * - * @return int - */ - protected function getVerbosity(OutputInterface $output): int - { - if ($output->isVerbose()) { - return MessageInterface::SUCCESS; - } - - if ($output->isVeryVerbose()) { - return MessageInterface::INFO; - } - - if ($output->isDebug()) { - return MessageInterface::DEBUG; - } - - return MessageInterface::ERROR; - } - /** * @param \Symfony\Component\Console\Input\InputInterface $input * diff --git a/src/Presentation/Console/Command/RunWorkflowCommand.php b/src/Presentation/Console/Command/RunWorkflowCommand.php index 5474b9446..a68d3877d 100644 --- a/src/Presentation/Console/Command/RunWorkflowCommand.php +++ b/src/Presentation/Console/Command/RunWorkflowCommand.php @@ -13,8 +13,6 @@ use SprykerSdk\Sdk\Core\Application\Dto\ReceiverValue; use SprykerSdk\Sdk\Core\Application\Service\ProjectWorkflow; use SprykerSdk\Sdk\Infrastructure\Workflow\WorkflowRunner; -use SprykerSdk\SdkContracts\Entity\ContextInterface; -use SprykerSdk\SdkContracts\Entity\MessageInterface; use SprykerSdk\SdkContracts\Enum\Setting; use SprykerSdk\SdkContracts\Enum\ValueTypeEnum; use Symfony\Component\Console\Command\Command; @@ -70,25 +68,41 @@ class RunWorkflowCommand extends Command */ protected SettingFetcherInterface $settingFetcher; + /** + * @var string + */ + protected string $projectSettingsFileName; + + /** + * @var string + */ + protected string $projectLocalSettingsFileName; + /** * @param \SprykerSdk\Sdk\Core\Application\Service\ProjectWorkflow $projectWorkflow * @param \SprykerSdk\Sdk\Core\Application\Dependency\InteractionProcessorInterface $cliValueReceiver * @param \SprykerSdk\Sdk\Infrastructure\Workflow\WorkflowRunner $workflowRunner * @param \SprykerSdk\Sdk\Core\Application\Dependency\ContextFactoryInterface $contextFactory * @param \SprykerSdk\Sdk\Core\Application\Dependency\SettingFetcherInterface $settingFetcher + * @param string $projectSettingsFileName + * @param string $projectLocalSettingsFileName */ public function __construct( ProjectWorkflow $projectWorkflow, InteractionProcessorInterface $cliValueReceiver, WorkflowRunner $workflowRunner, ContextFactoryInterface $contextFactory, - SettingFetcherInterface $settingFetcher + SettingFetcherInterface $settingFetcher, + string $projectSettingsFileName, + string $projectLocalSettingsFileName ) { $this->projectWorkflow = $projectWorkflow; $this->cliValueReceiver = $cliValueReceiver; $this->workflowRunner = $workflowRunner; $this->contextFactory = $contextFactory; $this->settingFetcher = $settingFetcher; + $this->projectSettingsFileName = $projectSettingsFileName; + $this->projectLocalSettingsFileName = $projectLocalSettingsFileName; parent::__construct(static::NAME); } @@ -121,7 +135,15 @@ public function execute(InputInterface $input, OutputInterface $output): int $projectWorkflows = (array)$this->settingFetcher->getOneByPath(Setting::PATH_WORKFLOW)->getValues(); if ($workflowName && !in_array($workflowName, $projectWorkflows)) { - $output->writeln('You don\'t have any active a workflows".'); + $output->writeln( + sprintf( + 'You don\'t have the `%s` workflow in this project. Please add the workflow by using `%s` command or manually add one in `%s` or `%s`.', + $workflowName, + InitProjectCommand::NAME, + $this->projectSettingsFileName, + $this->projectLocalSettingsFileName, + ), + ); return static::FAILURE; } @@ -140,42 +162,8 @@ public function execute(InputInterface $input, OutputInterface $output): int } $context = $this->contextFactory->getContext(); - $context = $this->workflowRunner->execute($workflowName, $context); - - $this->writeFilteredMessages($output, $context); + $this->workflowRunner->execute($workflowName, $context); return static::SUCCESS; } - - /** - * @param \Symfony\Component\Console\Output\OutputInterface $output - * @param \SprykerSdk\SdkContracts\Entity\ContextInterface $context - * - * @return void - */ - protected function writeFilteredMessages( - OutputInterface $output, - ContextInterface $context - ): void { - foreach ($context->getMessages() as $message) { - $output->writeln($this->formatMessage($message)); - } - } - - /** - * @param \SprykerSdk\SdkContracts\Entity\MessageInterface $message - * - * @return string - */ - protected function formatMessage(MessageInterface $message): string - { - $template = [ - MessageInterface::INFO => 'Info: %s', - MessageInterface::ERROR => 'Error: %s', - MessageInterface::SUCCESS => 'Success: %s', - MessageInterface::DEBUG => 'Debug: %s', - ][$message->getVerbosity()] ?? '%s'; - - return sprintf($template, $message->getMessage()); - } } diff --git a/src/Presentation/Console/Command/TaskLoader/TaskHelpMessageDecorator.php b/src/Presentation/Console/Command/TaskLoader/TaskHelpMessageDecorator.php new file mode 100644 index 000000000..cf299deab --- /dev/null +++ b/src/Presentation/Console/Command/TaskLoader/TaskHelpMessageDecorator.php @@ -0,0 +1,53 @@ +taskSetTaskRelationRepository = $taskSetTaskRelationRepository; + } + + /** + * @param \SprykerSdk\SdkContracts\Entity\TaskInterface $task + * + * @return string + */ + public function decorateHelpMessage(TaskInterface $task): string + { + $helpMessages = $task->getHelp() !== null ? [(string)$task->getHelp()] : []; + + $taskSetTaskRelations = $this->taskSetTaskRelationRepository->getByTaskSetId($task->getId()); + + if (count($taskSetTaskRelations) > 0) { + $helpMessages[] = 'Task set sub-tasks:'; + } + + foreach ($taskSetTaskRelations as $taskSetTaskRelation) { + $helpMessages[] = sprintf( + " - %s\t%s", + $taskSetTaskRelation->getSubTask()->getId(), + $taskSetTaskRelation->getSubTask()->getHelp(), + ); + } + + return implode(PHP_EOL, $helpMessages); + } +} diff --git a/src/Presentation/Console/Command/TaskLoader/TaskHelpMessageDecoratorInterface.php b/src/Presentation/Console/Command/TaskLoader/TaskHelpMessageDecoratorInterface.php new file mode 100644 index 000000000..725b5a8b5 --- /dev/null +++ b/src/Presentation/Console/Command/TaskLoader/TaskHelpMessageDecoratorInterface.php @@ -0,0 +1,20 @@ + $commandMap @@ -74,6 +80,7 @@ class TaskRunFactoryLoader extends ContainerCommandLoader * @param \SprykerSdk\Sdk\Core\Application\Dependency\ProjectSettingRepositoryInterface $projectSettingRepository * @param \SprykerSdk\Sdk\Core\Application\Service\ProjectWorkflow $projectWorkflow * @param \SprykerSdk\Sdk\Core\Application\Dependency\ContextFactoryInterface $contextFactory + * @param \SprykerSdk\Sdk\Presentation\Console\Command\TaskLoader\TaskHelpMessageDecoratorInterface $taskHelpMessageDecorator * @param string $environment */ public function __construct( @@ -86,6 +93,7 @@ public function __construct( ProjectSettingRepositoryInterface $projectSettingRepository, ProjectWorkflow $projectWorkflow, ContextFactoryInterface $contextFactory, + TaskHelpMessageDecoratorInterface $taskHelpMessageDecorator, string $environment = 'prod' ) { parent::__construct($container, $commandMap); @@ -96,6 +104,7 @@ public function __construct( $this->contextRepository = $contextRepository; $this->projectWorkflow = $projectWorkflow; $this->environment = $environment; + $this->taskHelpMessageDecorator = $taskHelpMessageDecorator; $this->contextFactory = $contextFactory; } @@ -150,7 +159,7 @@ public function get(string $name): Command ); if (!$command->getHelp()) { - $command->setHelp((string)$task->getHelp()); + $command->setHelp($this->taskHelpMessageDecorator->decorateHelpMessage($task)); } return $command; diff --git a/src/Presentation/Console/Command/UpdateCommand.php b/src/Presentation/Console/Command/UpdateCommand.php index ed29842bf..90d8bec6a 100644 --- a/src/Presentation/Console/Command/UpdateCommand.php +++ b/src/Presentation/Console/Command/UpdateCommand.php @@ -7,9 +7,10 @@ namespace SprykerSdk\Sdk\Presentation\Console\Command; +use SprykerSdk\Sdk\Core\Application\Dependency\ContextFactoryInterface; use SprykerSdk\Sdk\Core\Application\Dependency\InitializerInterface; use SprykerSdk\Sdk\Core\Application\Dependency\LifecycleManagerInterface; -use SprykerSdk\Sdk\Infrastructure\Exception\SdkVersionNotFoundException; +use SprykerSdk\Sdk\Core\Domain\Entity\ContextInterface; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; @@ -30,17 +31,25 @@ class UpdateCommand extends AbstractUpdateCommand */ protected InitializerInterface $initializer; + /** + * @var \SprykerSdk\Sdk\Core\Application\Dependency\ContextFactoryInterface + */ + protected ContextFactoryInterface $contextFactory; + /** * @param \SprykerSdk\Sdk\Core\Application\Dependency\LifecycleManagerInterface $lifecycleManager * @param \SprykerSdk\Sdk\Core\Application\Dependency\InitializerInterface $initializer + * @param \SprykerSdk\Sdk\Core\Application\Dependency\ContextFactoryInterface $contextFactory */ public function __construct( LifecycleManagerInterface $lifecycleManager, - InitializerInterface $initializer + InitializerInterface $initializer, + ContextFactoryInterface $contextFactory ) { parent::__construct(static::NAME); $this->lifecycleManager = $lifecycleManager; $this->initializer = $initializer; + $this->contextFactory = $contextFactory; } /** @@ -52,12 +61,13 @@ public function __construct( protected function execute(InputInterface $input, OutputInterface $output): int { $this->initializer->initialize([]); + $context = $this->contextFactory->getContext(); - if ($input->getOption(static::OPTION_NO_CHECK) !== null) { - $this->checkForUpdate($output); + if ($input->getOption(static::OPTION_NO_CHECK)) { + $this->checkForUpdate($context); } - if ($input->getOption(static::OPTION_CHECK_ONLY) !== null) { + if (!$input->getOption(static::OPTION_CHECK_ONLY)) { $this->lifecycleManager->update(); } @@ -65,22 +75,14 @@ protected function execute(InputInterface $input, OutputInterface $output): int } /** - * @param \Symfony\Component\Console\Output\OutputInterface $output + * @param \SprykerSdk\Sdk\Core\Domain\Entity\ContextInterface $context * * @return void */ - protected function checkForUpdate(OutputInterface $output): void + protected function checkForUpdate(ContextInterface $context): void { - try { - $messages = $this->lifecycleManager->checkForUpdate(); - } catch (SdkVersionNotFoundException $exception) { - $output->writeln($exception->getMessage(), OutputInterface::VERBOSITY_VERBOSE); - - return; - } - - foreach ($messages as $message) { - $output->writeln($message->getMessage(), OutputInterface::VERBOSITY_VERBOSE); + foreach ($this->lifecycleManager->checkForUpdate() as $key => $message) { + $context->addMessage('check_updates_' . $key, $message); } } } diff --git a/src/Presentation/Console/DependencyInjection/DynamicConsoleCommandsCompilerPass.php b/src/Presentation/Console/DependencyInjection/DynamicConsoleCommandsCompilerPass.php index 94eb13523..1cdced5de 100644 --- a/src/Presentation/Console/DependencyInjection/DynamicConsoleCommandsCompilerPass.php +++ b/src/Presentation/Console/DependencyInjection/DynamicConsoleCommandsCompilerPass.php @@ -7,7 +7,7 @@ namespace SprykerSdk\Sdk\Presentation\Console\DependencyInjection; -use SprykerSdk\Sdk\Presentation\Console\Command\TaskRunFactoryLoader; +use SprykerSdk\Sdk\Presentation\Console\Command\TaskLoader\TaskRunFactoryLoader; use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\DependencyInjection\Parameter; @@ -32,6 +32,7 @@ public function process(ContainerBuilder $container) ->addArgument(new Reference('project_setting_repository')) ->addArgument(new Reference('project_workflow')) ->addArgument(new Reference('context_factory')) + ->addArgument(new Reference('task_loader.task_help_message_decorator')) ->addArgument(new Parameter('kernel.environment')); } } diff --git a/src/Presentation/Console/EventListener/ContextOutputCommandListener.php b/src/Presentation/Console/EventListener/ContextOutputCommandListener.php new file mode 100644 index 000000000..81051f238 --- /dev/null +++ b/src/Presentation/Console/EventListener/ContextOutputCommandListener.php @@ -0,0 +1,76 @@ + 'Info: %s', + MessageInterface::ERROR => 'Error: %s', + MessageInterface::SUCCESS => 'Success: %s', + MessageInterface::DEBUG => 'Debug: %s', + ]; + + /** + * @var \SprykerSdk\Sdk\Core\Application\Dependency\ContextFactoryInterface + */ + protected ContextFactoryInterface $contextFactory; + + /** + * @param \SprykerSdk\Sdk\Core\Application\Dependency\ContextFactoryInterface $contextFactory + */ + public function __construct(ContextFactoryInterface $contextFactory) + { + $this->contextFactory = $contextFactory; + } + + /** + * @param \Symfony\Component\Console\Event\ConsoleTerminateEvent $event + * + * @return void + */ + public function handle(ConsoleTerminateEvent $event): void + { + if (!$this->contextFactory->hasContext()) { + return; + } + + $messages = $this->contextFactory->getContext()->getMessages(); + + if (!$messages) { + return; + } + + $isDebug = $event->getOutput()->isDebug(); + + foreach ($messages as $message) { + if ($isDebug || $message->getVerbosity() !== MessageInterface::DEBUG) { + $event->getOutput()->writeln($this->formatMessage($message)); + } + } + } + + /** + * @param \SprykerSdk\SdkContracts\Entity\MessageInterface $message + * + * @return string + */ + protected function formatMessage(MessageInterface $message): string + { + $template = static::TEMPLATES[$message->getVerbosity()] ?? '%s'; + + return sprintf($template, $message->getMessage()); + } +} diff --git a/src/Presentation/Console/Resources/config/services.yaml b/src/Presentation/Console/Resources/config/services.yaml index fa19eb5d8..d1717e3ef 100644 --- a/src/Presentation/Console/Resources/config/services.yaml +++ b/src/Presentation/Console/Resources/config/services.yaml @@ -1,13 +1,19 @@ parameters: - local_executable_file_path: '"$PhpExecutable$" %kernel.project_dir%/bin/console' - executable_file_path: '%env(default:local_executable_file_path:EXECUTABLE_FILE_PATH)%' - host_sdk_dir: '%env(default:kernel.project_dir:SDK_DIR)%' + env(LOCAL_SDK_DIR): "%kernel.project_dir%" + host_sdk_dir: '%env(LOCAL_SDK_DIR)%' + env(EXECUTABLE_FILE_PATH): '"$PhpExecutable$" %kernel.project_dir%/bin/console' + executable_file_path: '%env(EXECUTABLE_FILE_PATH)%' manifest_default_task_yaml_dir: 'src/Extension/Resources/config/task/' manifest_default_task_php_dir: 'src/Extension/Task/' services: question_helper: class: Symfony\Component\Console\Helper\SymfonyQuestionHelper + task_loader.task_help_message_decorator: + class: SprykerSdk\Sdk\Presentation\Console\Command\TaskLoader\TaskHelpMessageDecorator + arguments: + - "@task_set_relation_repository" + validate_task_command: class: SprykerSdk\Sdk\Presentation\Console\Command\Validator\ValidateTaskCommand tags: [ "console.command" ] @@ -17,7 +23,7 @@ services: init_sdk_command: autowire: false class: SprykerSdk\Sdk\Presentation\Console\Command\InitSdkCommand - tags: [ "console.command" ] + tags: [ "console.command", "rest_api.exposed_command" ] arguments: - "%kernel.project_dir%" - "@process_helper" @@ -37,10 +43,12 @@ services: tags: [ "console.command", "telemetry.observable_command" ] arguments: - "@project_workflow" - - "@cli_interaction_processor" + - "@interaction_processor" - "@workflow_runner" - "@context_factory" - "@setting.setting_fetcher" + - "%project_settings_file%" + - "%local_project_settings_file%" qa_automation_command: autowire: false class: SprykerSdk\Sdk\Presentation\Console\Command\QaAutomationCommand @@ -65,7 +73,7 @@ services: tags: [ "console.command" ] arguments: - "@project_workflow" - - "@cli_interaction_processor" + - "@interaction_processor" - "%kernel.project_dir%/var/workflow" - "%host_sdk_dir%/var/workflow" init_project_command: @@ -75,8 +83,9 @@ services: - name: 'console.command' command: !php/const SprykerSdk\Sdk\Presentation\Console\Command\InitProjectCommand::NAME - 'telemetry.observable_command' + - 'rest_api.exposed_command' arguments: - - "@cli_interaction_processor" + - "@interaction_processor" - "@setting_repository" - "@project_settings_initializer" @@ -95,6 +104,7 @@ services: arguments: - "@service.lifecycle_manager" - "@initializer_service" + - '@context_factory' update_sdk_command: class: SprykerSdk\Sdk\Presentation\Console\Command\UpdateSdkCommand tags: ["console.command", "telemetry.observable_command"] @@ -139,7 +149,7 @@ services: # Integrations security_checker_command: class: SecurityChecker\Command\SecurityCheckerCommand - tags: ["console.command", "telemetry.observable_command"] + tags: ["console.command"] composer_replace_command: class: SprykerSdk\Zed\ComposerReplace\Communication\Console\ComposerReplaceConsole tags: [ "console.command", "telemetry.observable_command"] @@ -169,3 +179,10 @@ services: manifest.task_manifest_dto_factory: class: SprykerSdk\Sdk\Presentation\Console\Manifest\Task\TaskManifestRequestDtoFactory + + command_context_output: + class: SprykerSdk\Sdk\Presentation\Console\EventListener\ContextOutputCommandListener + arguments: + - "@context_factory" + tags: + - { name: kernel.event_listener, event: console.terminate, method: handle } diff --git a/src/Presentation/Ide/PhpStorm/Service/CommandLoader.php b/src/Presentation/Ide/PhpStorm/Service/CommandLoader.php index cdeb3af5c..06487c9f6 100644 --- a/src/Presentation/Ide/PhpStorm/Service/CommandLoader.php +++ b/src/Presentation/Ide/PhpStorm/Service/CommandLoader.php @@ -8,7 +8,7 @@ namespace SprykerSdk\Sdk\Presentation\Ide\PhpStorm\Service; use SprykerSdk\Sdk\Core\Application\Dependency\Repository\TaskRepositoryInterface; -use SprykerSdk\Sdk\Presentation\Console\Command\TaskRunFactoryLoader; +use SprykerSdk\Sdk\Presentation\Console\Command\TaskLoader\TaskRunFactoryLoader; use SprykerSdk\Sdk\Presentation\Ide\PhpStorm\Dto\Command; use SprykerSdk\Sdk\Presentation\Ide\PhpStorm\Dto\CommandInterface; use Symfony\Component\Console\Command\Command as SymfonyCommand; @@ -21,7 +21,7 @@ class CommandLoader implements CommandLoaderInterface protected iterable $commands; /** - * @var \SprykerSdk\Sdk\Presentation\Console\Command\TaskRunFactoryLoader + * @var \SprykerSdk\Sdk\Presentation\Console\Command\TaskLoader\TaskRunFactoryLoader */ protected TaskRunFactoryLoader $commandContainer; @@ -32,7 +32,7 @@ class CommandLoader implements CommandLoaderInterface /** * @param iterable<\Symfony\Component\Console\Command\Command> $commands - * @param \SprykerSdk\Sdk\Presentation\Console\Command\TaskRunFactoryLoader $commandContainer + * @param \SprykerSdk\Sdk\Presentation\Console\Command\TaskLoader\TaskRunFactoryLoader $commandContainer * @param \SprykerSdk\Sdk\Core\Application\Dependency\Repository\TaskRepositoryInterface $taskRepository */ public function __construct(iterable $commands, TaskRunFactoryLoader $commandContainer, TaskRepositoryInterface $taskRepository) diff --git a/src/Presentation/Ide/PhpStorm/Service/ConfigManager.php b/src/Presentation/Ide/PhpStorm/Service/ConfigManager.php index 62970f60d..4ea3cdd5f 100644 --- a/src/Presentation/Ide/PhpStorm/Service/ConfigManager.php +++ b/src/Presentation/Ide/PhpStorm/Service/ConfigManager.php @@ -126,7 +126,7 @@ protected function getSetting(string $settingName): SettingInterface $setting = $this->settingRepository->findOneByPath($settingName); if (!$setting) { - throw new MissingSettingException(sprintf('Setting "%s" is missing', $settingName)); + throw new MissingSettingException(sprintf('Setting `%s` is missing', $settingName)); } return $setting; diff --git a/src/Presentation/RestApi/ApiDoc/BaseDescriber.php b/src/Presentation/RestApi/ApiDoc/BaseDescriber.php new file mode 100644 index 000000000..c3bae555b --- /dev/null +++ b/src/Presentation/RestApi/ApiDoc/BaseDescriber.php @@ -0,0 +1,235 @@ +describerHelper = $describerHelper; + } + + /** + * @param \OpenApi\Annotations\OpenApi $api + * @param \Symfony\Component\Console\Command\Command $command + * @param string $route + * @param string $httpMethod + * @param array $operationTags + * + * @return void + */ + protected function buildRoute( + OpenApi $api, + Command $command, + string $route, + string $httpMethod, + array $operationTags + ): void { + $path = Util::getPath($api, $route); + + $operation = Util::getOperation($path, $httpMethod); + $operation->tags = $operationTags; + + $this->buildRequestBody($operation, $command); + + $operation->responses = [ + $this->buildSuccessfulResponse($operation), + $this->buildBadRequestResponse($operation), + ]; + } + + /** + * @param \OpenApi\Annotations\Operation $operation + * @param \Symfony\Component\Console\Command\Command $command + * + * @return void + */ + protected function buildRequestBody(Operation $operation, Command $command): void + { + /** @var \OpenApi\Annotations\RequestBody $requestBody */ + $requestBody = Util::getChild($operation, RequestBody::class); + $requestBody->content = [ + static::JSON_TYPE => new MediaType(['mediaType' => static::JSON_TYPE]), + ]; + + /** @var \OpenApi\Annotations\Schema $schema */ + $schema = Util::getChild($requestBody->content[static::JSON_TYPE], Schema::class); + + $dataProperty = $this->describerHelper->getDataProperty($schema); + $attributesProperty = $this->describerHelper->getAttributesProperty($dataProperty); + $this->describerHelper->addIdProperty($dataProperty); + $this->describerHelper->addTypeProperty($dataProperty); + + $requiredArgumentProperties = $this->createPropertiesFromArguments($command, $attributesProperty); + $this->createPropertiesFromOptions($command, $attributesProperty); + + $attributesProperty->required = $requiredArgumentProperties; + } + + /** + * @param \OpenApi\Annotations\Operation $operation + * + * @return \OpenApi\Annotations\Response + */ + protected function buildSuccessfulResponse(Operation $operation): Response + { + $content = [ + static::JSON_TYPE => new MediaType(['mediaType' => static::JSON_TYPE]), + ]; + $response = $this->describerHelper->createResponse( + $operation, + SymfonyResponse::HTTP_OK, + 'OK', + $content, + ); + + /** @var \OpenApi\Annotations\Schema $responseSchema */ + $responseSchema = Util::getChild($content[static::JSON_TYPE], Schema::class); + + $responseDataProperty = $this->describerHelper->getDataProperty($responseSchema); + $this->describerHelper->getAttributesProperty($responseDataProperty); + $this->describerHelper->addIdProperty($responseDataProperty); + $this->describerHelper->addTypeProperty($responseDataProperty); + + return $response; + } + + /** + * @param \OpenApi\Annotations\Operation $operation + * + * @return \OpenApi\Annotations\Response + */ + protected function buildBadRequestResponse(Operation $operation): Response + { + $content = [ + static::JSON_TYPE => new MediaType(['mediaType' => static::JSON_TYPE]), + ]; + + $errorResponse = $this->describerHelper->createResponse( + $operation, + SymfonyResponse::HTTP_BAD_REQUEST, + 'Bad request', + $content, + ); + + /** @var \OpenApi\Annotations\Schema $responseSchema */ + $responseSchema = Util::getChild($content[static::JSON_TYPE], Schema::class); + + $this->describerHelper->addCodeProperty($responseSchema); + $this->describerHelper->addStatusProperty($responseSchema); + $this->describerHelper->addDetailsProperty($responseSchema); + + return $errorResponse; + } + + /** + * @param \Symfony\Component\Console\Command\Command $command + * @param \OpenApi\Annotations\Property $attributesProperty + * + * @return array + */ + protected function createPropertiesFromArguments(Command $command, Property $attributesProperty): array + { + $commandArguments = $command->getDefinition()->getArguments(); + + $requiredAttributes = []; + foreach ($commandArguments as $argument) { + $this->createProperty( + $attributesProperty, + $argument->getName(), + $argument->isArray(), + $argument->getDefault(), + $argument->getDescription(), + ); + + if ($argument->isRequired()) { + $requiredAttributes[] = $argument->getName(); + } + } + + return $requiredAttributes; + } + + /** + * @param \Symfony\Component\Console\Command\Command $command + * @param \OpenApi\Annotations\Property $attributesProperty + * + * @return void + */ + protected function createPropertiesFromOptions(Command $command, Property $attributesProperty): void + { + $commandOptions = $command->getDefinition()->getOptions(); + + foreach ($commandOptions as $option) { + $this->createProperty( + $attributesProperty, + $option->getName(), + $option->isArray(), + $option->getDefault(), + $option->getDescription(), + ); + } + } + + /** + * @param \OpenApi\Annotations\Property $attributesProperty + * @param string $name + * @param bool $isArray + * @param array|string|float|int|bool|null $default + * @param string $description + * + * @return void + */ + protected function createProperty( + Property $attributesProperty, + string $name, + bool $isArray, + $default, + string $description + ): void { + $property = Util::getProperty($attributesProperty, $name); + $property->type = 'string'; + + if ($isArray) { + $property->type = 'array'; + /** @var \OpenApi\Annotations\Items $items */ + $items = Util::getChild($property, Items::class); + $items->type = 'string'; + $property->items = $items; + } + + $property->default = $default; + $property->description = $description; + } +} diff --git a/src/Presentation/RestApi/ApiDoc/OpenApiDescriberHelper.php b/src/Presentation/RestApi/ApiDoc/OpenApiDescriberHelper.php new file mode 100644 index 000000000..b179cea4e --- /dev/null +++ b/src/Presentation/RestApi/ApiDoc/OpenApiDescriberHelper.php @@ -0,0 +1,124 @@ +type = 'object'; + + return $property; + } + + /** + * @param \OpenApi\Annotations\Property $dataProperty + * + * @return \OpenApi\Annotations\Property + */ + public function getAttributesProperty(Property $dataProperty): Property + { + $property = Util::getProperty($dataProperty, OpenApiField::ATTRIBUTES); + $property->type = 'object'; + + return $property; + } + + /** + * @param \OpenApi\Annotations\Property $dataProperty + * + * @return void + */ + public function addIdProperty(Property $dataProperty): void + { + $property = Util::getProperty($dataProperty, OpenApiField::ID); + $property->type = 'string'; + } + + /** + * @param \OpenApi\Annotations\Property $dataProperty + * + * @return void + */ + public function addTypeProperty(Property $dataProperty): void + { + $property = Util::getProperty($dataProperty, OpenApiField::TYPE); + $property->type = 'string'; + } + + /** + * @param \OpenApi\Annotations\Schema $responseSchema + * + * @return void + */ + public function addDetailsProperty(Schema $responseSchema): void + { + $property = Util::getProperty($responseSchema, OpenApiField::DETAILS); + $property->type = 'array'; + + /** @var \OpenApi\Annotations\Items $items */ + $items = Util::getChild($property, Items::class); + $items->type = 'string'; + $property->items = $items; + } + + /** + * @param \OpenApi\Annotations\Schema $responseSchema + * + * @return void + */ + public function addStatusProperty(Schema $responseSchema): void + { + $property = Util::getProperty($responseSchema, OpenApiField::STATUS); + $property->type = 'string'; + } + + /** + * @param \OpenApi\Annotations\Schema $responseSchema + * + * @return void + */ + public function addCodeProperty(Schema $responseSchema): void + { + $property = Util::getProperty($responseSchema, OpenApiField::CODE); + $property->type = 'integer'; + } + + /** + * @param \OpenApi\Annotations\Operation $operation + * @param int $code + * @param string $description + * @param array<(\OpenApi\Annotations\MediaType|\OpenApi\Annotations\JsonContent|\OpenApi\Annotations\XmlContent|\OpenApi\Annotations\Attachable)> $content + * + * @return \OpenApi\Annotations\Response + */ + public function createResponse(Operation $operation, int $code, string $description, array $content): Response + { + /** @var \OpenApi\Annotations\Response $errorResponse */ + $errorResponse = Util::getIndexedCollectionItem($operation, Response::class, ['responses']); + $errorResponse->response = $code; + $errorResponse->description = $description; + $errorResponse->content = $content; + + return $errorResponse; + } +} diff --git a/src/Presentation/RestApi/ApiDoc/RunTaskDescriber.php b/src/Presentation/RestApi/ApiDoc/RunTaskDescriber.php new file mode 100644 index 000000000..cebfd0f91 --- /dev/null +++ b/src/Presentation/RestApi/ApiDoc/RunTaskDescriber.php @@ -0,0 +1,86 @@ +commandLoader = $commandLoader; + $this->taskRepository = $taskRepository; + } + + /** + * @param \OpenApi\Annotations\OpenApi $api + * + * @return void + */ + public function describe(OpenApi $api): void + { + $commandNames = $this->taskRepository->getTaskIds(); + sort($commandNames); + + foreach ($commandNames as $commandName) { + $command = $this->commandLoader->get($commandName); + + $this->buildRoute( + $api, + $command, + sprintf(static::RUN_TASK_ROUTE, $commandName), + static::HTTP_METHOD, + [$this->getTaskGroupTag($commandName)], + ); + } + } + + /** + * @param string $taskName + * + * @return string + */ + protected function getTaskGroupTag(string $taskName): string + { + preg_match('/^(?[^:]*):/', $taskName, $matches); + + return isset($matches['group']) ? sprintf('Tasks: %s', $matches['group']) : 'Tasks'; + } +} diff --git a/src/Presentation/RestApi/ApiDoc/SdkCommandsDescriber.php b/src/Presentation/RestApi/ApiDoc/SdkCommandsDescriber.php new file mode 100644 index 000000000..d7522a353 --- /dev/null +++ b/src/Presentation/RestApi/ApiDoc/SdkCommandsDescriber.php @@ -0,0 +1,137 @@ + + */ + protected iterable $controllers; + + /** + * @var iterable<\Symfony\Component\Console\Command\Command> + */ + protected iterable $commands; + + /** + * @var \Symfony\Component\HttpFoundation\RequestStack + */ + protected RequestStack $requestStack; + + /** + * @var \Symfony\Component\Routing\RouterInterface + */ + protected RouterInterface $router; + + /** + * @param iterable<\SprykerSdk\Sdk\Presentation\RestApi\Controller\CommandControllerInterface> $controllers + * @param iterable<\Symfony\Component\Console\Command\Command> $commands + * @param \Symfony\Component\HttpFoundation\RequestStack $requestStack + * @param \Symfony\Component\Routing\RouterInterface $router + * @param \SprykerSdk\Sdk\Presentation\RestApi\ApiDoc\OpenApiDescriberHelper $describerHelper + */ + public function __construct( + iterable $controllers, + iterable $commands, + RequestStack $requestStack, + RouterInterface $router, + OpenApiDescriberHelper $describerHelper + ) { + parent::__construct($describerHelper); + + $this->controllers = $controllers; + $this->commands = $commands; + $this->requestStack = $requestStack; + $this->router = $router; + } + + /** + * @param \OpenApi\Annotations\OpenApi $api + * + * @return void + */ + public function describe(OpenApi $api): void + { + $routes = $this->router->getRouteCollection(); + $commands = $this->getIndexedCommands(); + + /** @var \Symfony\Component\Routing\Route $route */ + foreach ($routes as $route) { + $this->processRoute($route, $api, $commands); + } + } + + /** + * @return array + */ + protected function getIndexedCommands(): array + { + $indexedCommands = []; + + foreach ($this->commands as $command) { + $indexedCommands[$command->getName()] = $command; + } + + return $indexedCommands; + } + + /** + * @param \Symfony\Component\Routing\Route $route + * @param \OpenApi\Annotations\OpenApi $api + * @param array $commands + * + * @throws \RuntimeException + * + * @return void + */ + protected function processRoute(Route $route, OpenApi $api, array $commands): void + { + $controllerClass = $route->getDefault('_controller'); + + if ($controllerClass === null) { + return; + } + + foreach ($this->controllers as $controller) { + if (!($controller instanceof $controllerClass)) { + continue; + } + + $commandName = $controller->getCommandName(); + + if (!isset($commands[$commandName])) { + throw new RuntimeException(sprintf('Commands `%s` not fount', $commandName)); + } + + $this->buildRoute( + $api, + $commands[$commandName], + $route->getPath(), + static::HTTP_METHOD, + static::OPERATION_TAGS, + ); + } + } +} diff --git a/src/Presentation/RestApi/ApiDoc/TaskApiDocDescriber.php b/src/Presentation/RestApi/ApiDoc/TaskApiDocDescriber.php deleted file mode 100644 index 3ed7a655b..000000000 --- a/src/Presentation/RestApi/ApiDoc/TaskApiDocDescriber.php +++ /dev/null @@ -1,58 +0,0 @@ -tags = ['tasks']; - - /** @var \OpenApi\Annotations\RequestBody $requestBody */ - $requestBody = Util::getChild($operation, RequestBody::class); - $requestBody->content = [static::JSON_TYPE => new MediaType(['mediaType' => static::JSON_TYPE])]; - - /** @var \OpenApi\Annotations\Schema $schema */ - $schema = Util::getChild($requestBody->content[static::JSON_TYPE], Schema::class); - - $property = Util::getProperty($schema, 'project_dir'); - $property->type = 'string'; - $property->description = 'Project dir'; - - $property = Util::getProperty($schema, 'checks'); - $property->type = 'array'; - - /** @var \OpenApi\Annotations\Items $items */ - $items = Util::getChild($property, Items::class); - $items->type = 'string'; - $property->items = $items; - } -} diff --git a/src/Presentation/RestApi/Controller/CommandControllerInterface.php b/src/Presentation/RestApi/Controller/CommandControllerInterface.php new file mode 100644 index 000000000..657bacf44 --- /dev/null +++ b/src/Presentation/RestApi/Controller/CommandControllerInterface.php @@ -0,0 +1,16 @@ +responseFactory = $responseFactory; + } + + /** + * @param \SprykerSdk\Sdk\Presentation\RestApi\Factory\OpenApiRequestFactory $requestFactory + * + * @return void + */ + public function setRequestFactory(OpenApiRequestFactory $requestFactory): void + { + $this->requestFactory = $requestFactory; + } + + /** + * @param string $id + * @param string $type + * @param array $attributes + * + * @return \Symfony\Component\HttpFoundation\JsonResponse + */ + public function createSuccessResponse(string $id, string $type, array $attributes = []): JsonResponse + { + return $this->responseFactory->createSuccessResponse($id, $type, $attributes); + } + + /** + * @param array $details + * @param int $code + * @param string $status + * + * @return \Symfony\Component\HttpFoundation\JsonResponse + */ + public function createErrorResponse(array $details, int $code, string $status): JsonResponse + { + return $this->responseFactory->createErrorResponse($details, $code, $status); + } + + /** + * @param \Symfony\Component\HttpFoundation\Request $request + * + * @return \SprykerSdk\Sdk\Presentation\RestApi\OpenApi\OpenApiRequest + */ + public function createOpenApiRequest(Request $request): OpenApiRequest + { + return $this->requestFactory->createFromRequest($request); + } +} diff --git a/src/Presentation/RestApi/Controller/v1/IndexController.php b/src/Presentation/RestApi/Controller/v1/IndexController.php index d369db847..36fc814ed 100644 --- a/src/Presentation/RestApi/Controller/v1/IndexController.php +++ b/src/Presentation/RestApi/Controller/v1/IndexController.php @@ -9,10 +9,14 @@ use SprykerSdk\Sdk\Core\Application\Version\AppVersionFetcher; use Symfony\Component\HttpFoundation\JsonResponse; -use Symfony\Component\HttpFoundation\Response; -class IndexController +class IndexController extends BaseController { + /** + * @var string + */ + public const TYPE = 'version'; + /** * @var \SprykerSdk\Sdk\Core\Application\Version\AppVersionFetcher */ @@ -27,10 +31,12 @@ public function __construct(AppVersionFetcher $appVersionFetcher) } /** - * @return \Symfony\Component\HttpFoundation\Response + * @return \Symfony\Component\HttpFoundation\JsonResponse */ - public function __invoke(): Response + public function __invoke(): JsonResponse { - return new JsonResponse(['version' => $this->appVersionFetcher->fetchAppVersion()]); + $version = $this->appVersionFetcher->fetchAppVersion(); + + return $this->createSuccessResponse($version, static::TYPE, ['version' => $version]); } } diff --git a/src/Presentation/RestApi/Controller/v1/RunTaskController.php b/src/Presentation/RestApi/Controller/v1/RunTaskController.php index c4f7c4c57..d83da9d4c 100644 --- a/src/Presentation/RestApi/Controller/v1/RunTaskController.php +++ b/src/Presentation/RestApi/Controller/v1/RunTaskController.php @@ -9,10 +9,14 @@ use SprykerSdk\Sdk\Presentation\RestApi\Processor\RunTaskProcessor; use Symfony\Component\HttpFoundation\JsonResponse; -use Symfony\Component\HttpFoundation\Response; -class RunTaskController +class RunTaskController extends BaseController { + /** + * @var string + */ + public const TYPE = 'run-task'; + /** * @var \SprykerSdk\Sdk\Presentation\RestApi\Processor\RunTaskProcessor */ @@ -29,12 +33,12 @@ public function __construct(RunTaskProcessor $runTaskProcessor) /** * @param string $task * - * @return \Symfony\Component\HttpFoundation\Response + * @return \Symfony\Component\HttpFoundation\JsonResponse */ - public function __invoke(string $task): Response + public function __invoke(string $task): JsonResponse { $responseData = $this->runTaskProcessor->process($task); - return new JsonResponse($responseData); + return $this->createSuccessResponse($task, static::TYPE, $responseData); } } diff --git a/src/Presentation/RestApi/Controller/v1/SdkInitProjectController.php b/src/Presentation/RestApi/Controller/v1/SdkInitProjectController.php index 0ad4b21f2..728344758 100644 --- a/src/Presentation/RestApi/Controller/v1/SdkInitProjectController.php +++ b/src/Presentation/RestApi/Controller/v1/SdkInitProjectController.php @@ -7,19 +7,52 @@ namespace SprykerSdk\Sdk\Presentation\RestApi\Controller\v1; +use SprykerSdk\Sdk\Presentation\Console\Command\InitProjectCommand; +use SprykerSdk\Sdk\Presentation\RestApi\Controller\CommandControllerInterface; +use SprykerSdk\Sdk\Presentation\RestApi\Processor\SdkInitProjectProcessor; use Symfony\Component\HttpFoundation\JsonResponse; use Symfony\Component\HttpFoundation\Request; -use Symfony\Component\HttpFoundation\Response; -class SdkInitProjectController +class SdkInitProjectController extends BaseController implements CommandControllerInterface { + /** + * @var string + */ + public const TYPE = 'sdk-init-project'; + + /** + * @var \SprykerSdk\Sdk\Presentation\RestApi\Processor\SdkInitProjectProcessor + */ + protected SdkInitProjectProcessor $sdkInitProjectProcessor; + + /** + * @param \SprykerSdk\Sdk\Presentation\RestApi\Processor\SdkInitProjectProcessor $sdkInitProjectProcessor + */ + public function __construct(SdkInitProjectProcessor $sdkInitProjectProcessor) + { + $this->sdkInitProjectProcessor = $sdkInitProjectProcessor; + } + /** * @param \Symfony\Component\HttpFoundation\Request $request * - * @return \Symfony\Component\HttpFoundation\Response + * @return \Symfony\Component\HttpFoundation\JsonResponse + */ + public function __invoke(Request $request): JsonResponse + { + $this->sdkInitProjectProcessor->process($this->createOpenApiRequest($request)); + + return $this->createSuccessResponse( + static::TYPE, + static::TYPE, + ); + } + + /** + * @return string */ - public function __invoke(Request $request): Response + public function getCommandName(): string { - return new JsonResponse($request->request->all()); + return InitProjectCommand::NAME; } } diff --git a/src/Presentation/RestApi/Controller/v1/SdkInitSdkController.php b/src/Presentation/RestApi/Controller/v1/SdkInitSdkController.php index 8c4af694f..b44d2e7f3 100644 --- a/src/Presentation/RestApi/Controller/v1/SdkInitSdkController.php +++ b/src/Presentation/RestApi/Controller/v1/SdkInitSdkController.php @@ -8,12 +8,18 @@ namespace SprykerSdk\Sdk\Presentation\RestApi\Controller\v1; use SprykerSdk\Sdk\Infrastructure\Service\Initializer; +use SprykerSdk\Sdk\Presentation\Console\Command\InitSdkCommand; +use SprykerSdk\Sdk\Presentation\RestApi\Controller\CommandControllerInterface; use Symfony\Component\HttpFoundation\JsonResponse; use Symfony\Component\HttpFoundation\Request; -use Symfony\Component\HttpFoundation\Response; -class SdkInitSdkController +class SdkInitSdkController extends BaseController implements CommandControllerInterface { + /** + * @var string + */ + public const TYPE = 'sdk-init-sdk'; + /** * @var \SprykerSdk\Sdk\Infrastructure\Service\Initializer */ @@ -30,12 +36,20 @@ public function __construct(Initializer $initializerService) /** * @param \Symfony\Component\HttpFoundation\Request $request * - * @return \Symfony\Component\HttpFoundation\Response + * @return \Symfony\Component\HttpFoundation\JsonResponse */ - public function __invoke(Request $request): Response + public function __invoke(Request $request): JsonResponse { - $this->initializerService->initialize($request->request->all()); + $this->initializerService->initialize($this->createOpenApiRequest($request)->getAttributes()); + + return $this->createSuccessResponse(static::TYPE, static::TYPE); + } - return new JsonResponse([]); + /** + * @return string + */ + public function getCommandName(): string + { + return InitSdkCommand::NAME; } } diff --git a/src/Presentation/RestApi/Controller/v1/SdkUpdateSdkController.php b/src/Presentation/RestApi/Controller/v1/SdkUpdateSdkController.php index ee6f98ba3..8445bb078 100644 --- a/src/Presentation/RestApi/Controller/v1/SdkUpdateSdkController.php +++ b/src/Presentation/RestApi/Controller/v1/SdkUpdateSdkController.php @@ -7,12 +7,21 @@ namespace SprykerSdk\Sdk\Presentation\RestApi\Controller\v1; +use SprykerSdk\Sdk\Infrastructure\Exception\SdkVersionNotFoundException; +use SprykerSdk\Sdk\Presentation\Console\Command\UpdateSdkCommand; +use SprykerSdk\Sdk\Presentation\RestApi\Controller\CommandControllerInterface; use SprykerSdk\Sdk\Presentation\RestApi\Processor\SdkUpdateSdkProcessor; +use Symfony\Component\HttpFoundation\JsonResponse; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; -class SdkUpdateSdkController +class SdkUpdateSdkController extends BaseController implements CommandControllerInterface { + /** + * @var string + */ + public const TYPE = 'sdk-update-sdk'; + /** * @var \SprykerSdk\Sdk\Presentation\RestApi\Processor\SdkUpdateSdkProcessor */ @@ -29,10 +38,28 @@ public function __construct(SdkUpdateSdkProcessor $sdkUpdateSdkProcessor) /** * @param \Symfony\Component\HttpFoundation\Request $request * - * @return \Symfony\Component\HttpFoundation\Response + * @return \Symfony\Component\HttpFoundation\JsonResponse + */ + public function __invoke(Request $request): JsonResponse + { + try { + $attributes = $this->sdkUpdateSdkProcessor->process($this->createOpenApiRequest($request)); + } catch (SdkVersionNotFoundException $exception) { + return $this->responseFactory->createErrorResponse( + [$exception->getMessage()], + Response::HTTP_BAD_REQUEST, + (string)Response::HTTP_BAD_REQUEST, + ); + } + + return $this->createSuccessResponse(static::TYPE, static::TYPE, $attributes); + } + + /** + * @return string */ - public function __invoke(Request $request): Response + public function getCommandName(): string { - return $this->sdkUpdateSdkProcessor->process($request); + return UpdateSdkCommand::NAME; } } diff --git a/src/Presentation/RestApi/DependencyInjection/SprykerSdkRestApiExtension.php b/src/Presentation/RestApi/DependencyInjection/SprykerSdkRestApiExtension.php index 07fe7f662..6d9fc3289 100644 --- a/src/Presentation/RestApi/DependencyInjection/SprykerSdkRestApiExtension.php +++ b/src/Presentation/RestApi/DependencyInjection/SprykerSdkRestApiExtension.php @@ -23,5 +23,6 @@ class SprykerSdkRestApiExtension extends Extension public function load(array $configs, ContainerBuilder $container): void { (new YamlFileLoader($container, new FileLocator(__DIR__ . '/../Resources/config')))->load('services.yaml'); + (new YamlFileLoader($container, new FileLocator(__DIR__ . '/../Resources/config')))->load('api_doc_describers_services.yaml'); } } diff --git a/src/Presentation/RestApi/Enum/OpenApiField.php b/src/Presentation/RestApi/Enum/OpenApiField.php new file mode 100644 index 000000000..ce030083f --- /dev/null +++ b/src/Presentation/RestApi/Enum/OpenApiField.php @@ -0,0 +1,46 @@ +logger = $logger; $this->isDebug = $isDebug; + $this->responseFactory = $responseFactory; } /** @@ -46,23 +53,23 @@ public function onKernelException(ExceptionEvent $event): void if ($exception instanceof InvalidRequestDataException) { $event->setResponse( - new JsonResponse( - [ - 'message' => $exception->getMessage(), - ], + $this->responseFactory->createErrorResponse( + [$exception->getMessage()], Response::HTTP_BAD_REQUEST, + (string)Response::HTTP_BAD_REQUEST, ), ); + + return; } $this->logger->error($exception->getMessage()); $event->setResponse( - new JsonResponse( - [ - 'message' => $this->isDebug ? $exception->getMessage() : 'Error', - ], + $this->responseFactory->createErrorResponse( + $this->isDebug ? [$exception->getMessage()] : ['Error'], Response::HTTP_INTERNAL_SERVER_ERROR, + (string)Response::HTTP_INTERNAL_SERVER_ERROR, ), ); } diff --git a/src/Presentation/RestApi/EventListener/JsonRequestListener.php b/src/Presentation/RestApi/EventListener/JsonRequestListener.php new file mode 100644 index 000000000..53208dc41 --- /dev/null +++ b/src/Presentation/RestApi/EventListener/JsonRequestListener.php @@ -0,0 +1,99 @@ + + */ + protected array $contentTypes; + + /** + * @var \SprykerSdk\Sdk\Presentation\RestApi\Validator\Json\JsonSchemaValidator + */ + protected JsonSchemaValidator $jsonSchemaValidator; + + /** + * @var \SprykerSdk\Sdk\Presentation\RestApi\Factory\OpenApiResponseFactory + */ + protected OpenApiResponseFactory $responseFactory; + + /** + * @param array $contentTypes + * @param \SprykerSdk\Sdk\Presentation\RestApi\Validator\Json\JsonSchemaValidator $jsonSchemaValidator + * @param \SprykerSdk\Sdk\Presentation\RestApi\Factory\OpenApiResponseFactory $responseFactory + */ + public function __construct( + array $contentTypes, + JsonSchemaValidator $jsonSchemaValidator, + OpenApiResponseFactory $responseFactory + ) { + $this->contentTypes = $contentTypes; + $this->jsonSchemaValidator = $jsonSchemaValidator; + $this->responseFactory = $responseFactory; + } + + /** + * @param \Symfony\Component\HttpKernel\Event\RequestEvent $event + * + * @return void + */ + public function onKernelRequest(RequestEvent $event): void + { + if (!$event->isMainRequest()) { + return; + } + + $request = $event->getRequest(); + + if (!$this->isApplicable($request) || !$this->supports($request)) { + return; + } + + try { + $this->jsonSchemaValidator->validate($request); + } catch (InvalidJsonSchemaException $exception) { + $errorResponse = $this->responseFactory->createErrorResponse( + $exception->getDetails(), + $exception->getCode(), + $exception->getStatus(), + ); + + $event->setResponse($errorResponse); + } + } + + /** + * @param \Symfony\Component\HttpFoundation\Request $request + * + * @return bool + */ + protected function supports(Request $request): bool + { + return in_array($request->getContentType(), $this->contentTypes, true) && $request->getContent(); + } + + /** + * @param \Symfony\Component\HttpFoundation\Request $request + * + * @return bool + */ + public function isApplicable(Request $request): bool + { + return is_string($request->getContent()) + && $request->getContent() !== '' + && $request->attributes->has('_rest_api'); + } +} diff --git a/src/Presentation/RestApi/Exception/InvalidJsonSchemaException.php b/src/Presentation/RestApi/Exception/InvalidJsonSchemaException.php new file mode 100644 index 000000000..d044efa67 --- /dev/null +++ b/src/Presentation/RestApi/Exception/InvalidJsonSchemaException.php @@ -0,0 +1,57 @@ + + */ + protected array $details = []; + + /** + * @var string + */ + protected string $status; + + /** + * @param array $details + * @param int $code + * @param string $status + */ + public function __construct( + array $details = [], + int $code = Response::HTTP_BAD_REQUEST, + string $status = '' + ) { + $this->details = $details; + $this->code = $code; + $this->status = $status; + + parent::__construct($details[0] ?? '', $code); + } + + /** + * @return array + */ + public function getDetails(): array + { + return $this->details; + } + + /** + * @return string + */ + public function getStatus(): string + { + return $this->status; + } +} diff --git a/src/Presentation/RestApi/Factory/OpenApiRequestFactory.php b/src/Presentation/RestApi/Factory/OpenApiRequestFactory.php new file mode 100644 index 000000000..bd778835a --- /dev/null +++ b/src/Presentation/RestApi/Factory/OpenApiRequestFactory.php @@ -0,0 +1,24 @@ + [ + OpenApiField::ID => $id, + OpenApiField::TYPE => $type, + OpenApiField::ATTRIBUTES => $attributes, + ], + ]); + } + + /** + * @param array $details + * @param int $code + * @param string $status + * + * @return \Symfony\Component\HttpFoundation\JsonResponse + */ + public function createErrorResponse(array $details, int $code, string $status): JsonResponse + { + return new JsonResponse([ + OpenApiField::DETAILS => $details, + OpenApiField::CODE => $code, + OpenApiField::STATUS => $status, + ], $code); + } +} diff --git a/src/Presentation/RestApi/OpenApi/OpenApiRequest.php b/src/Presentation/RestApi/OpenApi/OpenApiRequest.php new file mode 100644 index 000000000..73c7620d2 --- /dev/null +++ b/src/Presentation/RestApi/OpenApi/OpenApiRequest.php @@ -0,0 +1,115 @@ +request = $request; + } + + /** + * @throws \InvalidArgumentException + * + * @return array + */ + public function getData(): array + { + if (!$this->request->request->has(OpenApiField::DATA)) { + throw new InvalidArgumentException(sprintf('Request field `%s` doesn\'t exist', OpenApiField::DATA)); + } + + return $this->request->request->all(OpenApiField::DATA); + } + + /** + * @throws \InvalidArgumentException + * + * @return array + */ + public function getAttributes(): array + { + $data = $this->getData(); + + if (!isset($data[OpenApiField::ATTRIBUTES]) || !is_array($data[OpenApiField::ATTRIBUTES])) { + throw new InvalidArgumentException(sprintf('Request field `%s` doesn\'t exist or has invalid value', OpenApiField::ATTRIBUTES)); + } + + return $data[OpenApiField::ATTRIBUTES]; + } + + /** + * @param string $attributeName + * @param mixed $default + * + * @return mixed + */ + public function getAttribute(string $attributeName, $default = null) + { + $attributes = $this->getAttributes(); + + return array_key_exists($attributeName, $attributes) ? $attributes[$attributeName] : $default; + } + + /** + * @param string $attributeName + * + * @return bool + */ + public function hasAttribute(string $attributeName): bool + { + $attributes = $this->getAttributes(); + + return array_key_exists($attributeName, $attributes); + } + + /** + * @throws \InvalidArgumentException + * + * @return string + */ + public function getId(): string + { + $data = $this->getData(); + + if (!isset($data[OpenApiField::ID])) { + throw new InvalidArgumentException(sprintf('Data field `%s` is not found', OpenApiField::ID)); + } + + return (string)$data[OpenApiField::ID]; + } + + /** + * @throws \InvalidArgumentException + * + * @return string + */ + public function getType(): string + { + $data = $this->getData(); + + if (!isset($data[OpenApiField::TYPE])) { + throw new InvalidArgumentException(sprintf('Data field `%s` is not found', OpenApiField::TYPE)); + } + + return (string)$data[OpenApiField::TYPE]; + } +} diff --git a/src/Presentation/RestApi/Processor/RunTaskProcessor.php b/src/Presentation/RestApi/Processor/RunTaskProcessor.php index 6c163f5ff..403c8e1eb 100644 --- a/src/Presentation/RestApi/Processor/RunTaskProcessor.php +++ b/src/Presentation/RestApi/Processor/RunTaskProcessor.php @@ -7,7 +7,7 @@ namespace SprykerSdk\Sdk\Presentation\RestApi\Processor; -use SprykerSdk\Sdk\Core\Application\Service\ContextFactory; +use SprykerSdk\Sdk\Core\Application\Dependency\ContextFactoryInterface; use SprykerSdk\Sdk\Core\Application\Service\TaskExecutor; use SprykerSdk\Sdk\Infrastructure\Mapper\ViolationReportFileMapperInterface; use SprykerSdk\SdkContracts\Report\Violation\ViolationReportInterface; @@ -20,9 +20,9 @@ class RunTaskProcessor protected TaskExecutor $taskExecutor; /** - * @var \SprykerSdk\Sdk\Core\Application\Service\ContextFactory + * @var \SprykerSdk\Sdk\Core\Application\Dependency\ContextFactoryInterface */ - protected ContextFactory $contextFactory; + protected ContextFactoryInterface $contextFactory; /** * @var \SprykerSdk\Sdk\Infrastructure\Mapper\ViolationReportFileMapperInterface @@ -31,12 +31,12 @@ class RunTaskProcessor /** * @param \SprykerSdk\Sdk\Core\Application\Service\TaskExecutor $taskExecutor - * @param \SprykerSdk\Sdk\Core\Application\Service\ContextFactory $contextFactory + * @param \SprykerSdk\Sdk\Core\Application\Dependency\ContextFactoryInterface $contextFactory * @param \SprykerSdk\Sdk\Infrastructure\Mapper\ViolationReportFileMapperInterface $violationReportFileMapperInterface */ public function __construct( TaskExecutor $taskExecutor, - ContextFactory $contextFactory, + ContextFactoryInterface $contextFactory, ViolationReportFileMapperInterface $violationReportFileMapperInterface ) { $this->taskExecutor = $taskExecutor; diff --git a/src/Presentation/RestApi/Processor/SdkInitProjectProcessor.php b/src/Presentation/RestApi/Processor/SdkInitProjectProcessor.php new file mode 100644 index 000000000..31a9d7bd5 --- /dev/null +++ b/src/Presentation/RestApi/Processor/SdkInitProjectProcessor.php @@ -0,0 +1,43 @@ +projectSettingsInitializer = $projectSettingsInitializer; + } + + /** + * @param \SprykerSdk\Sdk\Presentation\RestApi\OpenApi\OpenApiRequest $request + * + * @return void + */ + public function process(OpenApiRequest $request): void + { + $projectSettingsInitDto = new ProjectSettingsInitDto( + $request->getAttributes(), + $request->getAttribute('default', false), + ); + + $this->projectSettingsInitializer->initialize($projectSettingsInitDto); + } +} diff --git a/src/Presentation/RestApi/Processor/SdkUpdateSdkProcessor.php b/src/Presentation/RestApi/Processor/SdkUpdateSdkProcessor.php index db9cd6b62..8c9cb4d32 100644 --- a/src/Presentation/RestApi/Processor/SdkUpdateSdkProcessor.php +++ b/src/Presentation/RestApi/Processor/SdkUpdateSdkProcessor.php @@ -11,9 +11,8 @@ use SprykerSdk\Sdk\Infrastructure\Exception\SdkVersionNotFoundException; use SprykerSdk\Sdk\Infrastructure\Service\Initializer; use SprykerSdk\Sdk\Presentation\Console\Command\AbstractUpdateCommand; -use Symfony\Component\HttpFoundation\JsonResponse; -use Symfony\Component\HttpFoundation\Request; -use Symfony\Component\HttpFoundation\Response; +use SprykerSdk\Sdk\Presentation\RestApi\OpenApi\OpenApiRequest; +use SprykerSdk\SdkContracts\Entity\MessageInterface; class SdkUpdateSdkProcessor { @@ -31,39 +30,37 @@ class SdkUpdateSdkProcessor * @param \SprykerSdk\Sdk\Infrastructure\Service\Initializer $initializerService * @param \SprykerSdk\Sdk\Core\Application\Dependency\LifecycleManagerInterface $lifecycleManager */ - public function __construct(Initializer $initializerService, LifecycleManagerInterface $lifecycleManager) - { + public function __construct( + Initializer $initializerService, + LifecycleManagerInterface $lifecycleManager + ) { $this->initializerService = $initializerService; $this->lifecycleManager = $lifecycleManager; } /** - * @param \Symfony\Component\HttpFoundation\Request $request + * @param \SprykerSdk\Sdk\Presentation\RestApi\OpenApi\OpenApiRequest $request * - * @return \Symfony\Component\HttpFoundation\Response + * @return array */ - public function process(Request $request): Response + public function process(OpenApiRequest $request): array { - $this->initializerService->initialize($request->request->all()); + $this->initializerService->initialize($request->getAttributes()); $messages = []; - if ($request->request->get(AbstractUpdateCommand::OPTION_NO_CHECK) !== null) { + if (!$request->getAttribute(AbstractUpdateCommand::OPTION_NO_CHECK, false)) { try { $messages = $this->lifecycleManager->checkForUpdate(); } catch (SdkVersionNotFoundException $exception) { - return new JsonResponse(['result' => 'FAILED', 'messages' => [$exception->getMessage()], 'code' => 400]); } } - if ($request->request->get(AbstractUpdateCommand::OPTION_CHECK_ONLY) !== null) { + if (!$request->getAttribute(AbstractUpdateCommand::OPTION_CHECK_ONLY, false)) { $this->lifecycleManager->update(); } - $result = []; - foreach ($messages as $message) { - $result[] = $message->getMessage(); - } + $result = array_map(fn (MessageInterface $message): string => $message->getMessage(), $messages); - return new JsonResponse(['messages' => $result]); + return ['messages' => $result]; } } diff --git a/src/Presentation/RestApi/Resources/config/api_doc_describers_services.yaml b/src/Presentation/RestApi/Resources/config/api_doc_describers_services.yaml new file mode 100644 index 000000000..dcd82e2eb --- /dev/null +++ b/src/Presentation/RestApi/Resources/config/api_doc_describers_services.yaml @@ -0,0 +1,21 @@ +services: + api_doc.open_api_describer_helper: + class: SprykerSdk\Sdk\Presentation\RestApi\ApiDoc\OpenApiDescriberHelper + + api_doc.sdk_commands_describer: + class: SprykerSdk\Sdk\Presentation\RestApi\ApiDoc\SdkCommandsDescriber + tags: [ 'nelmio_api_doc.describer' ] + arguments: + - !tagged_iterator 'rest_api.expose_command_api_doc' + - !tagged_iterator 'console.command' + - '@request_stack' + - '@router.default' + - '@api_doc.open_api_describer_helper' + + api_doc.task_describer: + class: SprykerSdk\Sdk\Presentation\RestApi\ApiDoc\RunTaskDescriber + tags: [ 'nelmio_api_doc.describer' ] + arguments: + - '@console.command_loader' + - '@task_persistence_repository' + - '@api_doc.open_api_describer_helper' diff --git a/src/Presentation/RestApi/Resources/config/routing_v1.yaml b/src/Presentation/RestApi/Resources/config/routing_v1.yaml index ac95978b8..9afb2060f 100644 --- a/src/Presentation/RestApi/Resources/config/routing_v1.yaml +++ b/src/Presentation/RestApi/Resources/config/routing_v1.yaml @@ -2,10 +2,6 @@ index: path: / controller: SprykerSdk\Sdk\Presentation\RestApi\Controller\v1\IndexController methods: GET|POST -init_sdk_controller: - path: /init - controller: SprykerSdk\Sdk\Presentation\RestApi\Controller\v1\SdkInitSdkController - methods: POST sdk_update_sdk_controller: path: /sdk-update-sdk controller: SprykerSdk\Sdk\Presentation\RestApi\Controller\v1\SdkUpdateSdkController diff --git a/src/Presentation/RestApi/Resources/config/services.yaml b/src/Presentation/RestApi/Resources/config/services.yaml index d9d6e9d46..98265feb9 100644 --- a/src/Presentation/RestApi/Resources/config/services.yaml +++ b/src/Presentation/RestApi/Resources/config/services.yaml @@ -1,6 +1,15 @@ parameters: ~ services: + _instanceof: + SprykerSdk\Sdk\Presentation\RestApi\Controller\v1\BaseController: + calls: + - ['setResponseFactory', ['@open_api.factory.response']] + - ['setRequestFactory', ['@open_api.factory.request']] + + SprykerSdk\Sdk\Presentation\RestApi\Controller\CommandControllerInterface: + tags: ['rest_api.expose_command_api_doc'] + SprykerSdk\Sdk\Presentation\RestApi\Controller\v1\IndexController: public: true arguments: @@ -23,6 +32,16 @@ services: arguments: - "@initializer_service" + SprykerSdk\Sdk\Presentation\RestApi\Controller\v1\SdkInitProjectController: + public: true + arguments: + - "@sdk_init_project_processor" + + sdk_init_project_processor: + class: SprykerSdk\Sdk\Presentation\RestApi\Processor\SdkInitProjectProcessor + arguments: + - "@project_settings_initializer" + SprykerSdk\Sdk\Presentation\RestApi\Controller\v1\SdkUpdateSdkController: public: true arguments: @@ -45,6 +64,41 @@ services: arguments: - '@symfony.console.application' - api_doc.task_describer: - class: SprykerSdk\Sdk\Presentation\RestApi\ApiDoc\TaskApiDocDescriber - tags: ['nelmio_api_doc.describer'] + json_schema_validator: + class: SprykerSdk\Sdk\Presentation\RestApi\Validator\Json\JsonSchemaValidator + arguments: + - '@json_validator' + - '@open_api.factory.response' + + json_validator: + class: JsonSchema\Validator + + api_exception_listener: + class: SprykerSdk\Sdk\Presentation\RestApi\EventListener\ApiExceptionListener + arguments: + - "%kernel.debug%" + - "@logger" + - '@open_api.factory.response' + tags: + - name: kernel.event_listener + event: kernel.exception + method: onKernelException + priority: 10 + + json_request_transformer_listener: + class: SprykerSdk\Sdk\Presentation\RestApi\EventListener\JsonRequestListener + tags: + - name: kernel.event_listener + event: kernel.request + method: onKernelRequest + priority: 10 + arguments: + - ['json'] + - '@json_schema_validator' + - '@open_api.factory.response' + + open_api.factory.response: + class: SprykerSdk\Sdk\Presentation\RestApi\Factory\OpenApiResponseFactory + + open_api.factory.request: + class: SprykerSdk\Sdk\Presentation\RestApi\Factory\OpenApiRequestFactory diff --git a/src/Presentation/RestApi/Validator/Json/JsonSchemaValidator.php b/src/Presentation/RestApi/Validator/Json/JsonSchemaValidator.php new file mode 100644 index 000000000..a11cbe482 --- /dev/null +++ b/src/Presentation/RestApi/Validator/Json/JsonSchemaValidator.php @@ -0,0 +1,99 @@ +validator = $validator; + } + + /** + * @param \Symfony\Component\HttpFoundation\Request $request + * + * @throws \SprykerSdk\Sdk\Presentation\RestApi\Exception\InvalidJsonSchemaException + * + * @return void + */ + public function validate(Request $request): void + { + try { + $data = json_decode((string)$request->getContent(), true, 512, \JSON_THROW_ON_ERROR); + } catch (JsonException $exception) { + throw new InvalidJsonSchemaException( + ['Invalid request.'], + Response::HTTP_BAD_REQUEST, + (string)Response::HTTP_BAD_REQUEST, + ); + } + + $this->validator->validate($data, $this->getSchema(), Constraint::CHECK_MODE_TYPE_CAST); + + $errors = $this->validator->getErrors(); + if (!$errors) { + $request->request->replace($data); + + return; + } + + $details = array_map(fn (array $error): string => $error['message'], $errors); + + throw new InvalidJsonSchemaException( + $details, + Response::HTTP_BAD_REQUEST, + (string)Response::HTTP_BAD_REQUEST, + ); + } + + /** + * @return array + */ + protected function getSchema(): array + { + return [ + 'type' => 'object', + 'properties' => [ + OpenApiField::DATA => [ + 'type' => 'object', + 'required' => true, + 'properties' => [ + OpenApiField::ID => [ + 'type' => 'string', + 'required' => true, + ], + OpenApiField::TYPE => [ + 'type' => 'string', + 'required' => true, + ], + OpenApiField::ATTRIBUTES => [ + 'type' => 'object', + 'required' => true, + ], + ], + ], + ], + ]; + } +} diff --git a/symfony.lock b/symfony.lock index 1b07dc396..a917820c7 100644 --- a/symfony.lock +++ b/symfony.lock @@ -221,6 +221,18 @@ "phar-io/version": { "version": "3.1.0" }, + "php-http/discovery": { + "version": "1.18", + "recipe": { + "repo": "github.com/symfony/recipes", + "branch": "main", + "version": "1.18", + "ref": "f45b5dd173a27873ab19f5e3180b2f661c21de02" + }, + "files": [ + "config/packages/http_discovery.yaml" + ] + }, "phpbench/container": { "version": "2.2.1" }, @@ -361,9 +373,6 @@ "slevomat/coding-standard": { "version": "7.0.16" }, - "sllh/composer-versions-check": { - "version": "v2.0.5" - }, "spryker-sdk/acp": { "version": "0.1.0" }, @@ -376,6 +385,9 @@ "spryker-sdk/composer-replace": { "version": "dev-master" }, + "spryker-sdk/evaluator": { + "version": "dev-feature/sdk-2283-sdk-evaluator-pipline-athena" + }, "spryker-sdk/integrator": { "version": "1.0.x-dev" }, diff --git a/tests/Sdk/Acceptance/Extension/Task/ArchitectureSnifferTaskCest.php b/tests/Sdk/Acceptance/Extension/Task/ArchitectureSnifferTaskCest.php index a6ae4d2c2..5035304a1 100644 --- a/tests/Sdk/Acceptance/Extension/Task/ArchitectureSnifferTaskCest.php +++ b/tests/Sdk/Acceptance/Extension/Task/ArchitectureSnifferTaskCest.php @@ -53,7 +53,7 @@ public function testArchitectureSnifferRunsSuccessfully(AcceptanceTester $I): vo ); // Assert - Assert::assertTrue($process->isSuccessful()); + Assert::assertTrue($process->isSuccessful(), $process->getErrorOutput() ?: $process->getOutput()); } /** @@ -77,6 +77,6 @@ public function testArchitectureSnifferFindingViolations(AcceptanceTester $I): v ); // Assert - Assert::assertFalse($process->isSuccessful()); + Assert::assertFalse($process->isSuccessful(), $process->getErrorOutput() ?: $process->getOutput()); } } diff --git a/tests/Sdk/Acceptance/Extension/Task/DeprecationsTaskCest.php b/tests/Sdk/Acceptance/Extension/Task/DeprecationsTaskCest.php index 6c274b8be..c78c0bc28 100644 --- a/tests/Sdk/Acceptance/Extension/Task/DeprecationsTaskCest.php +++ b/tests/Sdk/Acceptance/Extension/Task/DeprecationsTaskCest.php @@ -52,7 +52,7 @@ public function testDeprecationsCheckFoundDeprecations(AcceptanceTester $I): voi ); // Assert - Assert::assertTrue($process->isSuccessful()); + Assert::assertTrue($process->isSuccessful(), $process->getErrorOutput() ?: $process->getOutput()); Assert::assertStringContainsString('Violations found', $process->getOutput()); } } diff --git a/tests/Sdk/Acceptance/Presentation/Console/Command/TaskLoader/TaskHelpMessageDecoratorCest.php b/tests/Sdk/Acceptance/Presentation/Console/Command/TaskLoader/TaskHelpMessageDecoratorCest.php new file mode 100644 index 000000000..b0e30d769 --- /dev/null +++ b/tests/Sdk/Acceptance/Presentation/Console/Command/TaskLoader/TaskHelpMessageDecoratorCest.php @@ -0,0 +1,53 @@ +runSdkCommand( + [static::COMMAND, '--help'], + $I->getProjectRoot(static::PROJECT_DIR), + ); + + // Assert + Assert::assertTrue($process->isSuccessful()); + Assert::assertStringContainsString("Task set sub-tasks:\n - validation:php", $process->getOutput()); + } +} diff --git a/tests/Sdk/Acceptance/Presentation/RestApi/Controller/v1/RunTaskControllerCest.php b/tests/Sdk/Acceptance/Presentation/RestApi/Controller/v1/RunTaskControllerCest.php index b342cca6c..447dfeb3d 100644 --- a/tests/Sdk/Acceptance/Presentation/RestApi/Controller/v1/RunTaskControllerCest.php +++ b/tests/Sdk/Acceptance/Presentation/RestApi/Controller/v1/RunTaskControllerCest.php @@ -7,6 +7,7 @@ namespace SprykerSdk\Sdk\Acceptance\Presentation\RestApi\Controller\v1; +use SprykerSdk\Sdk\Presentation\RestApi\Controller\v1\RunTaskController; use SprykerSdk\Sdk\Tests\AcceptanceTester; use Symfony\Component\HttpFoundation\Response; @@ -34,15 +35,52 @@ class RunTaskControllerCest * * @return void */ - public function iSeeJsonResponseAfterCallHelloWorldEndpoint(AcceptanceTester $I): void + public function iSeeJsonResponseAfterCallRunTaskEndpoint(AcceptanceTester $I): void { - $I->sendPost(static::ENDPOINT, ['world' => 'World', 'somebody' => 'World']); - $I->seeResponseCodeIs(Response::HTTP_OK); - - $I->seeResponseContainsJson([ - 'messages' => [ - 'Executing stage: hello', - 'hello \'World\' \'World\'', - ]]); + $I->sendApiPost( + static::ENDPOINT, + 'hello:world', + RunTaskController::TYPE, + [ + 'world' => 'World', + 'somebody' => 'World', + ], + ); + + $I->seeSuccessApiResponse( + Response::HTTP_OK, + 'hello:world', + RunTaskController::TYPE, + [ + 'messages' => [ + 'Executing stage: hello', + 'hello \'World\' \'World\'', + ], + ], + ); + } + + /** + * @param \SprykerSdk\Sdk\Tests\AcceptanceTester $I + * + * @return void + */ + public function iSeeBadRequestAfterCallRunTaskEndpoint(AcceptanceTester $I): void + { + $I->sendApiPost( + static::ENDPOINT, + 'hello:world', + RunTaskController::TYPE, + [ + 'world' => 'World', + ], + ); + + $I->seeErrorApiResponse( + Response::HTTP_BAD_REQUEST, + ['Invalid request. Parameter `somebody` is missing.'], + Response::HTTP_BAD_REQUEST, + (string)Response::HTTP_BAD_REQUEST, + ); } } diff --git a/tests/Sdk/Acceptance/Presentation/RestApi/Controller/v1/SdkInitProjectControllerCest.php b/tests/Sdk/Acceptance/Presentation/RestApi/Controller/v1/SdkInitProjectControllerCest.php new file mode 100644 index 000000000..af8aea24f --- /dev/null +++ b/tests/Sdk/Acceptance/Presentation/RestApi/Controller/v1/SdkInitProjectControllerCest.php @@ -0,0 +1,68 @@ +sendApiPost( + static::ENDPOINT, + SdkInitProjectController::TYPE, + SdkInitProjectController::TYPE, + [ + 'report_usage_statistics' => false, + ], + ); + + $I->seeResponseCodeIs(Response::HTTP_OK); + $I->seeResponseContainsJson([]); + } + + /** + * @param \SprykerSdk\Sdk\Tests\AcceptanceTester $I + * + * @return void + */ + public function iSeeBadRequestAfterCallSdkInitProjectEndpoint(AcceptanceTester $I): void + { + $I->haveHttpHeader('Content-Type', 'application/json'); + $I->sendPost(static::ENDPOINT, [ + OpenApiField::DATA => [], + ]); + + $I->seeResponseCodeIs(Response::HTTP_BAD_REQUEST); + } +} diff --git a/tests/Sdk/Acceptance/Presentation/RestApi/Controller/v1/SdkInitSdkControllerCest.php b/tests/Sdk/Acceptance/Presentation/RestApi/Controller/v1/SdkInitSdkControllerCest.php index cd82ba38f..a0a5c7504 100644 --- a/tests/Sdk/Acceptance/Presentation/RestApi/Controller/v1/SdkInitSdkControllerCest.php +++ b/tests/Sdk/Acceptance/Presentation/RestApi/Controller/v1/SdkInitSdkControllerCest.php @@ -7,6 +7,7 @@ namespace SprykerSdk\Sdk\Acceptance\Presentation\RestApi\Controller\v1; +use SprykerSdk\Sdk\Presentation\RestApi\Controller\v1\SdkInitSdkController; use SprykerSdk\Sdk\Tests\AcceptanceTester; use Symfony\Component\HttpFoundation\Response; @@ -34,9 +35,18 @@ class SdkInitSdkControllerCest * * @return void */ - public function iSeeJsonResponseAfterCallHelloWorldEndpoint(AcceptanceTester $I): void + public function iSeeJsonResponseAfterCallSdkInitSdkEndpoint(AcceptanceTester $I): void { - $I->sendPost(static::ENDPOINT, ['developer_email' => 'test', 'developer_github_account' => 'test']); + $I->sendApiPost( + static::ENDPOINT, + SdkInitSdkController::TYPE, + SdkInitSdkController::TYPE, + [ + 'developer_email' => 'test', + 'developer_github_account' => 'test', + ], + ); + $I->seeResponseCodeIs(Response::HTTP_OK); $I->seeResponseContainsJson([]); diff --git a/tests/Sdk/Acceptance/Presentation/RestApi/Controller/v1/SdkUpdateSdkControllerCest.php b/tests/Sdk/Acceptance/Presentation/RestApi/Controller/v1/SdkUpdateSdkControllerCest.php index 0499ea53b..3455cad59 100644 --- a/tests/Sdk/Acceptance/Presentation/RestApi/Controller/v1/SdkUpdateSdkControllerCest.php +++ b/tests/Sdk/Acceptance/Presentation/RestApi/Controller/v1/SdkUpdateSdkControllerCest.php @@ -7,6 +7,7 @@ namespace SprykerSdk\Sdk\Acceptance\Presentation\RestApi\Controller\v1; +use SprykerSdk\Sdk\Presentation\RestApi\Controller\v1\SdkUpdateSdkController; use SprykerSdk\Sdk\Tests\AcceptanceTester; use Symfony\Component\HttpFoundation\Response; @@ -34,11 +35,25 @@ class SdkUpdateSdkControllerCest * * @return void */ - public function iSeeJsonResponseAfterCallHelloWorldEndpoint(AcceptanceTester $I): void + public function iSeeJsonResponseAfterCallSdkUpdateSdkEndpoint(AcceptanceTester $I): void { - $I->sendPost(static::ENDPOINT, ['developer_email' => 'test', 'developer_github_account' => 'test']); - $I->seeResponseCodeIs(Response::HTTP_OK); + $I->sendApiPost( + static::ENDPOINT, + SdkUpdateSdkController::TYPE, + SdkUpdateSdkController::TYPE, + [ + 'developer_email' => 'test', + 'developer_github_account' => 'test', + ], + ); - $I->seeResponseContainsJson(['messages' => []]); + $I->seeSuccessApiResponse( + Response::HTTP_OK, + SdkUpdateSdkController::TYPE, + SdkUpdateSdkController::TYPE, + [ + 'messages' => [], + ], + ); } } diff --git a/tests/Sdk/Acceptance/Telemetry/CodeSnifferTaskFixerCest.php b/tests/Sdk/Acceptance/Telemetry/CodeSnifferTaskFixerCest.php index 9b4e787d7..7e036152b 100644 --- a/tests/Sdk/Acceptance/Telemetry/CodeSnifferTaskFixerCest.php +++ b/tests/Sdk/Acceptance/Telemetry/CodeSnifferTaskFixerCest.php @@ -37,6 +37,7 @@ public function testSuccesfullReportSending(AcceptanceTester $I): void { // Arrange $I->cleanReports(); + $I->cleanTelemetryEventsTable(); // Act $process = $I->runSdkCommand([ diff --git a/tests/Sdk/Unit/Core/Application/Service/ContextFactoryTest.php b/tests/Sdk/Unit/Core/Application/Service/ContextFactoryTest.php index fa1111fe1..eb65a2cd2 100644 --- a/tests/Sdk/Unit/Core/Application/Service/ContextFactoryTest.php +++ b/tests/Sdk/Unit/Core/Application/Service/ContextFactoryTest.php @@ -46,6 +46,43 @@ public function testGetContext(): void $this->assertEquals($context, $foundContext); } + /** + * @return void + */ + public function testHasContext(): void + { + //Arrange + $defaultContextMock = $this->createMock(DefaultContextReceiverInterface::class); + $defaultContextMock->expects($this->once()) + ->method('getFormat') + ->willReturn('output'); + $contextFactory = new ContextFactory($defaultContextMock); + $context = new Context(); + $context->setFormat('output'); + $contextFactory->getContext(); + + //Act + $hasContext = $contextFactory->hasContext(); + + //Assert + $this->assertTrue($hasContext); + } + + /** + * @return void + */ + public function testDoesNotHasContext(): void + { + //Arrange + $defaultContextMock = $this->createMock(DefaultContextReceiverInterface::class); + $contextFactory = new ContextFactory($defaultContextMock); + //Act + $hasContext = $contextFactory->hasContext(); + + //Assert + $this->assertFalse($hasContext); + } + /** * @return void */ diff --git a/tests/Sdk/Unit/Core/Application/Service/FileManagerTest.php b/tests/Sdk/Unit/Core/Application/Service/FileManagerTest.php deleted file mode 100644 index 13d5d6b0e..000000000 --- a/tests/Sdk/Unit/Core/Application/Service/FileManagerTest.php +++ /dev/null @@ -1,133 +0,0 @@ -fileManager = new FileManager(); - $this->vfsStream = vfsStream::setup(); - } - - /** - * @dataProvider provideFileData - * - * @param string $fileName - * @param string $content - * - * @return void - */ - public function testCreateShouldCreateFileByPathWithContent(string $fileName, string $content): void - { - // Arrange - $path = $this->vfsStream->url() . '/' . $fileName; - $file = $this->tester->createFile($path, $content); - - // Act - $result = $this->fileManager->create($file); - - // Assert - $this->assertNull($result); - $this->assertTrue($this->vfsStream->hasChild($fileName)); - $this->assertSame($content, $this->vfsStream->getChild($fileName)->getContent()); - } - - /** - * @dataProvider provideFileData - * - * @param string $fileName - * @param string $content - * - * @return void - */ - public function testRemoveExistedFileShouldReturnTrue(string $fileName, string $content): void - { - // Arrange - $path = $this->vfsStream->url() . '/' . $fileName; - $file = $this->tester->createFile($path, $content); - - $vfsFile = $this->tester->createVfsStreamFile($fileName, $content); - $this->vfsStream->addChild($vfsFile); - - // Act - $result = $this->fileManager->remove($file); - - // Assert - $this->assertTrue($result); - $this->assertFalse($this->vfsStream->hasChild($fileName)); - } - - /** - * @dataProvider provideFileData - * - * @param string $fileName - * @param string $content - * - * @return void - */ - public function testRemoveNotExistedFileShouldNotRemoveFileAndShouldReturnFalse(string $fileName, string $content): void - { - // Arrange - $path = $this->vfsStream->url() . '/' . $fileName; - $file = $this->tester->createFile($path, $content); - - // Act - $result = $this->fileManager->remove($file); - - // Assert - $this->assertFalse($this->vfsStream->hasChild($fileName)); - $this->assertFalse($result); - } - - /** - * @return array> - */ - public function provideFileData(): array - { - return [ - ['data.txt', 'Test data'], - ]; - } -} diff --git a/tests/Sdk/Unit/Extension/ValueResolver/AppPhpVersionValueResolverTest.php b/tests/Sdk/Unit/Extension/ValueResolver/AppPhpVersionValueResolverTest.php deleted file mode 100644 index cd7d00dc5..000000000 --- a/tests/Sdk/Unit/Extension/ValueResolver/AppPhpVersionValueResolverTest.php +++ /dev/null @@ -1,71 +0,0 @@ -valueReceiver = $this->createMock(InteractionProcessorInterface::class); - $this->context = $this->createMock(ContextInterface::class); - - parent::setUp(); - } - - /** - * @return void - */ - public function testGetValue(): void - { - // Arrange - $receiverValue = new ReceiverValue( - 'app_php_version', - 'PHP version to use for the App', - array_key_first(AppPhpVersionValueResolver::PHP_VERSIONS), - 'string', - array_keys(AppPhpVersionValueResolver::PHP_VERSIONS), - ); - $this->valueReceiver - ->expects($this->once()) - ->method('receiveValue') - ->with($receiverValue); - $valueResolver = new AppPhpVersionValueResolver($this->valueReceiver); - - // Act - $valueResolver->getValue($this->context, []); - } -} diff --git a/tests/Sdk/Unit/Extension/ValueResolver/ConfigValueResolverTest.php b/tests/Sdk/Unit/Extension/ValueResolver/ConfigValueResolverTest.php index 7f47e2c97..750080dd8 100644 --- a/tests/Sdk/Unit/Extension/ValueResolver/ConfigValueResolverTest.php +++ b/tests/Sdk/Unit/Extension/ValueResolver/ConfigValueResolverTest.php @@ -11,6 +11,7 @@ use SprykerSdk\Sdk\Core\Application\Dependency\InteractionProcessorInterface; use SprykerSdk\Sdk\Extension\ValueResolver\ConfigPathValueResolver; use SprykerSdk\SdkContracts\Entity\ContextInterface; +use SprykerSdk\SdkContracts\Enum\Setting; /** * Auto-generated group annotations @@ -63,7 +64,7 @@ public function testGetValue(): void $valueResolver = new ConfigPathValueResolver($this->valueReceiver); $valueResolver->configure(['name' => 'key', 'description' => '']); // Act - $value = $valueResolver->getValue($this->context, ['defaultValue' => 'value']); + $value = $valueResolver->getValue($this->context, [Setting::PATH_PROJECT_DIR => '', Setting::PATH_SDK_DIR => '']); // Assert $this->assertSame('/', $value); diff --git a/tests/Sdk/Unit/Extension/ValueResolver/PriorityValueResolverTest.php b/tests/Sdk/Unit/Extension/ValueResolver/PriorityPathValueResolverTest.php similarity index 67% rename from tests/Sdk/Unit/Extension/ValueResolver/PriorityValueResolverTest.php rename to tests/Sdk/Unit/Extension/ValueResolver/PriorityPathValueResolverTest.php index 204681df6..c7650e7c8 100644 --- a/tests/Sdk/Unit/Extension/ValueResolver/PriorityValueResolverTest.php +++ b/tests/Sdk/Unit/Extension/ValueResolver/PriorityPathValueResolverTest.php @@ -21,10 +21,10 @@ * @group Unit * @group Extension * @group ValueResolver - * @group PriorityValueResolverTest + * @group PriorityPathValueResolverTest * Add your own group annotations below this line */ -class PriorityValueResolverTest extends Unit +class PriorityPathValueResolverTest extends Unit { /** * @var \SprykerSdk\Sdk\Core\Application\Dependency\InteractionProcessorInterface @@ -53,14 +53,6 @@ public function setUp(): void public function testGetValueWithoutSettings(): void { // Arrange - $this->valueReceiver - ->expects($this->once()) - ->method('hasRequestItem') - ->willReturn(true); - $this->valueReceiver - ->expects($this->once()) - ->method('getRequestItem') - ->willReturn('./'); $valueResolver = new PriorityPathValueResolver($this->valueReceiver); $valueResolver->configure(['name' => 'key', 'description' => '']); @@ -68,7 +60,7 @@ public function testGetValueWithoutSettings(): void $this->expectException(InvalidConfigurationException::class); // Act - $value = $valueResolver->getValue($this->context, ['defaultValue' => 'value']); + $valueResolver->getValue($this->context, ['defaultValue' => './']); } /** @@ -113,8 +105,59 @@ public function testGetValueException(): void // Assert $this->expectException(UnresolvableValueExceptionException::class); + $this->expectExceptionMessage('Invalid path provided.'); // Act $valueResolver->getValue($this->context, ['defaultValue' => './data/file.txt']); } + + /** + * @return void + */ + public function testGetValueExceptionAbsolutePath(): void + { + // Arrange + $this->valueReceiver + ->expects($this->once()) + ->method('hasRequestItem') + ->willReturn(true); + $this->valueReceiver + ->expects($this->once()) + ->method('getRequestItem') + ->willReturn('/none'); + $valueResolver = new PriorityPathValueResolver($this->valueReceiver); + $valueResolver->configure(['name' => 'key', 'description' => '', 'settingPaths' => ['test' => 'test']]); + + // Assert + $this->expectException(UnresolvableValueExceptionException::class); + $this->expectExceptionMessage('Absolute path is forbidden due to security reasons.'); + + // Act + $valueResolver->getValue($this->context, []); + } + + /** + * @return void + */ + public function testGetValueExceptionParentLevelPath(): void + { + // Arrange + $this->valueReceiver + ->expects($this->once()) + ->method('hasRequestItem') + ->willReturn(true); + $this->valueReceiver + ->expects($this->once()) + ->method('getRequestItem') + ->willReturn('../none'); + $valueResolver = new PriorityPathValueResolver($this->valueReceiver); + $valueResolver->configure(['name' => 'key', 'description' => '', 'settingPaths' => ['test' => 'test']]); + + // Assert + $this->expectException(UnresolvableValueExceptionException::class); + $this->expectExceptionMessage('Path ../ is forbidden due to security reasons.'); + + // Act + $valueResolver->getValue($this->context, []); + } } diff --git a/tests/Sdk/Unit/Infrastructure/Builder/TaskSet/TaskSetTaskRelationsBuilderTest.php b/tests/Sdk/Unit/Infrastructure/Builder/TaskSet/TaskSetTaskRelationsBuilderTest.php new file mode 100644 index 000000000..d4500aa8f --- /dev/null +++ b/tests/Sdk/Unit/Infrastructure/Builder/TaskSet/TaskSetTaskRelationsBuilderTest.php @@ -0,0 +1,127 @@ +createTaskSetMock('task-set:id', []); + $taskSetTaskRelationsBuilder = new TaskSetTaskRelationsBuilder(); + + // Assert + $this->expectException(InvalidArgumentException::class); + + // Act + $taskSetTaskRelationsBuilder->buildFromTaskSet($taskSetMock, []); + } + + /** + * @return void + */ + public function testBuildFromTaskSetShouldThrowExceptionWhenSubTaskIdNotInExistingTasks(): void + { + // Arrange + $taskSetMock = $this->createTaskSetMock('task-set:id', ['task:id']); + $taskSetTaskRelationsBuilder = new TaskSetTaskRelationsBuilder(); + $existingTasks = ['task-set:id' => $taskSetMock]; + + // Assert + $this->expectException(InvalidArgumentException::class); + + // Act + $taskSetTaskRelationsBuilder->buildFromTaskSet($taskSetMock, $existingTasks); + } + + /** + * @return void + */ + public function testBuildFromTaskSetShouldSkipWhenSubTaskInstanceNotInExistingTasks(): void + { + // Arrange + $taskSetMock = $this->createTaskSetMock('task-set:id', [$this->createTaskMock('task:id')]); + $taskSetTaskRelationsBuilder = new TaskSetTaskRelationsBuilder(); + $existingTasks = ['task-set:id' => $taskSetMock]; + + // Act + $relations = $taskSetTaskRelationsBuilder->buildFromTaskSet($taskSetMock, $existingTasks); + + // Assert + $this->assertEmpty($relations); + } + + /** + * @return void + */ + public function testBuildFromTaskSetShouldCreateRelations(): void + { + // Arrange + $taskMock = $this->createTaskMock('task:id'); + $taskMockOne = $this->createTaskMock('task:id:one'); + $taskSetMock = $this->createTaskSetMock('task-set:id', [$taskMock, 'task:id:one']); + $taskSetTaskRelationsBuilder = new TaskSetTaskRelationsBuilder(); + $existingTasks = ['task-set:id' => $taskSetMock, 'task:id' => $taskMock, 'task:id:one' => $taskMockOne]; + + // Act + $relations = $taskSetTaskRelationsBuilder->buildFromTaskSet($taskSetMock, $existingTasks); + + // Assert + $this->assertCount(2, $relations, 'Relations of 2 sub-tasks of task set'); + $this->assertSame($taskMock, $relations[0]->getSubTask(), 'Task object in task set'); + $this->assertSame($taskMockOne, $relations[1]->getSubTask(), 'Task id in tasks set'); + } + + /** + * @param string $id + * @param array<(\SprykerSdk\SdkContracts\Entity\TaskInterface|string)> $subTasks + * + * @return \SprykerSdk\SdkContracts\Entity\TaskSetInterface + */ + protected function createTaskSetMock(string $id, array $subTasks): TaskSetInterface + { + $taskSet = $this->createMock(TaskSetInterface::class); + + $taskSet->method('getId')->willReturn($id); + $taskSet->method('getSubTasks')->willReturn($subTasks); + + return $taskSet; + } + + /** + * @param string $taskId + * + * @return \SprykerSdk\SdkContracts\Entity\TaskInterface + */ + protected function createTaskMock(string $taskId): TaskInterface + { + $task = $this->createMock(TaskInterface::class); + $task->method('getId')->willReturn($taskId); + + return $task; + } +} diff --git a/tests/Sdk/Unit/Infrastructure/Builder/TaskSet/TaskSetTaskRelationsFromYamlBuilderTest.php b/tests/Sdk/Unit/Infrastructure/Builder/TaskSet/TaskSetTaskRelationsFromYamlBuilderTest.php new file mode 100644 index 000000000..f3b2d8141 --- /dev/null +++ b/tests/Sdk/Unit/Infrastructure/Builder/TaskSet/TaskSetTaskRelationsFromYamlBuilderTest.php @@ -0,0 +1,91 @@ + 'task-set:id', 'tasks' => []]; + $taskSetTaskRelationsFromYamlBuilder = new TaskSetTaskRelationsFromYamlBuilder(); + + // Assert + $this->expectException(InvalidArgumentException::class); + + // Act + $taskSetTaskRelationsFromYamlBuilder->buildFromYamlTaskSet($yamlTaskSet, []); + } + + /** + * @return void + */ + public function testBuildFromYamlTaskSetShouldThrowExceptionWhenSubTaskNotInExistingTasks(): void + { + // Arrange + $taskSetMock = $this->createTaskMock('task-set:id'); + $yamlTaskSet = ['id' => 'task-set:id', 'tasks' => [['id' => 'task:id']]]; + $taskSetTaskRelationsFromYamlBuilder = new TaskSetTaskRelationsFromYamlBuilder(); + + // Assert + $this->expectException(InvalidArgumentException::class); + + // Act + $taskSetTaskRelationsFromYamlBuilder->buildFromYamlTaskSet($yamlTaskSet, ['task-set:id' => $taskSetMock]); + } + + /** + * @return void + */ + public function testBuildFromYamlTaskSetShouldReturnRelations(): void + { + // Arrange + $taskSetMock = $this->createTaskMock('task-set:id'); + $taskMock = $this->createTaskMock('task:id'); + $yamlTaskSet = ['id' => 'task-set:id', 'tasks' => [['id' => 'task:id']]]; + $taskSetTaskRelationsFromYamlBuilder = new TaskSetTaskRelationsFromYamlBuilder(); + + // Act + $relations = $taskSetTaskRelationsFromYamlBuilder->buildFromYamlTaskSet($yamlTaskSet, ['task-set:id' => $taskSetMock, 'task:id' => $taskMock]); + + // Assert + $this->assertSame($taskMock, $relations[0]->getSubTask(), 'Relation has sub-task'); + $this->assertSame($taskSetMock, $relations[0]->getTaskSet(), 'Relation has task set'); + } + + /** + * @param string $taskId + * + * @return \SprykerSdk\SdkContracts\Entity\TaskInterface + */ + protected function createTaskMock(string $taskId): TaskInterface + { + $task = $this->createMock(TaskInterface::class); + $task->method('getId')->willReturn($taskId); + + return $task; + } +} diff --git a/tests/Sdk/Unit/Infrastructure/Cache/InMemoryContextCacheStorageTest.php b/tests/Sdk/Unit/Infrastructure/Cache/InMemoryContextCacheStorageTest.php deleted file mode 100644 index 0702b243b..000000000 --- a/tests/Sdk/Unit/Infrastructure/Cache/InMemoryContextCacheStorageTest.php +++ /dev/null @@ -1,118 +0,0 @@ -set($context->getName(), $context); - - // Act - $actualContext = $cacheStorage->get($context->getName()); - - // Assert - $this->assertSame($context, $actualContext); - } - - /** - * @return void - */ - public function testGetReturnsNullIfContextNotFound(): void - { - // Arrange - $cacheStorage = new InMemoryContextCacheStorage(); - - // Act - $context = $cacheStorage->get('test'); - - // Assert - $this->assertNull($context); - } - - /** - * @return void - */ - public function testGetAll(): void - { - // Arrange - $cacheStorage = new InMemoryContextCacheStorage(); - - // Act - $data = $cacheStorage->getAll(); - - // Assert - $this->assertSame([], $data); - } - - /** - * @return void - */ - public function testRemoveRemovesContextByKey(): void - { - // Arrange - $cacheStorage = new InMemoryContextCacheStorage(); - $contextShouldntBeRemoved = new Context(); - $contextShouldntBeRemoved->setName('exist'); - $contextShouldBeRemoved = new Context(); - $contextShouldBeRemoved->setName('removed'); - $cacheStorage->set($contextShouldBeRemoved->getName(), $contextShouldBeRemoved); - $cacheStorage->set($contextShouldntBeRemoved->getName(), $contextShouldntBeRemoved); - - // Act - $cacheStorage->remove($contextShouldBeRemoved->getName()); - - // Assert - $this->assertNotNull($cacheStorage->get($contextShouldntBeRemoved->getName())); - $this->assertNull($cacheStorage->get($contextShouldBeRemoved->getName())); - } - - /** - * @return void - */ - public function testSetContextWithTheSameNameOverwritesPrevious(): void - { - // Arrange - $cacheStorage = new InMemoryContextCacheStorage(); - $contextOne = new Context(); - $contextOne->setName('test'); - $contextOne->setFormat('json'); - $cacheStorage->set($contextOne->getName(), $contextOne); - - $contextTwo = new Context(); - $contextTwo->setName('test'); - $contextTwo->setFormat('yaml'); - $cacheStorage->set($contextTwo->getName(), $contextTwo); - - // Act - $actualContext = $cacheStorage->get($contextOne->getName()); - - // Assert - $this->assertSame($contextTwo, $actualContext); - } -} diff --git a/tests/Sdk/Unit/Core/Application/Lifecycle/Event/InitializedEventTest.php b/tests/Sdk/Unit/Infrastructure/Lifecycle/Event/InitializedEventTest.php similarity index 83% rename from tests/Sdk/Unit/Core/Application/Lifecycle/Event/InitializedEventTest.php rename to tests/Sdk/Unit/Infrastructure/Lifecycle/Event/InitializedEventTest.php index e4b9dbf03..96735a251 100644 --- a/tests/Sdk/Unit/Core/Application/Lifecycle/Event/InitializedEventTest.php +++ b/tests/Sdk/Unit/Infrastructure/Lifecycle/Event/InitializedEventTest.php @@ -5,19 +5,17 @@ * Use of this software requires acceptance of the Evaluation License Agreement. See LICENSE file. */ -namespace SprykerSdk\Sdk\Unit\Core\Application\Lifecycle\Event; +namespace Sdk\Unit\Infrastructure\Lifecycle\Event; use Codeception\Test\Unit; -use SprykerSdk\Sdk\Core\Application\Lifecycle\Event\InitializedEvent; +use SprykerSdk\Sdk\Infrastructure\Lifecycle\Event\InitializedEvent; use SprykerSdk\Sdk\Tests\UnitTester; /** * Auto-generated group annotations * - * @group Sdk * @group Unit - * @group Core - * @group Application + * @group Infrastructure * @group Lifecycle * @group Event * @group InitializedEventTest diff --git a/tests/Sdk/Unit/Core/Application/Lifecycle/Subscriber/InitializedEventSubscriberTest.php b/tests/Sdk/Unit/Infrastructure/Lifecycle/Subscriber/InitializedEventSubscriberTest.php similarity index 86% rename from tests/Sdk/Unit/Core/Application/Lifecycle/Subscriber/InitializedEventSubscriberTest.php rename to tests/Sdk/Unit/Infrastructure/Lifecycle/Subscriber/InitializedEventSubscriberTest.php index 0e7230e7a..c8312883a 100644 --- a/tests/Sdk/Unit/Core/Application/Lifecycle/Subscriber/InitializedEventSubscriberTest.php +++ b/tests/Sdk/Unit/Infrastructure/Lifecycle/Subscriber/InitializedEventSubscriberTest.php @@ -5,14 +5,11 @@ * Use of this software requires acceptance of the Evaluation License Agreement. See LICENSE file. */ -namespace SprykerSdk\Sdk\Unit\Core\Application\Lifecycle\Subscriber; +namespace Sdk\Unit\Infrastructure\Lifecycle\Subscriber; use Codeception\Test\Unit; use SprykerSdk\Sdk\Core\Application\Dependency\CommandExecutorInterface; use SprykerSdk\Sdk\Core\Application\Dependency\ContextFactoryInterface; -use SprykerSdk\Sdk\Core\Application\Dependency\FileManagerInterface; -use SprykerSdk\Sdk\Core\Application\Lifecycle\Event\InitializedEvent; -use SprykerSdk\Sdk\Core\Application\Lifecycle\Subscriber\InitializedEventSubscriber; use SprykerSdk\Sdk\Core\Application\Service\PlaceholderResolver; use SprykerSdk\Sdk\Core\Domain\Entity\Lifecycle\InitializedEventData; use SprykerSdk\Sdk\Core\Domain\Entity\Lifecycle\Lifecycle; @@ -20,15 +17,16 @@ use SprykerSdk\Sdk\Core\Domain\Entity\Lifecycle\UpdatedEventData; use SprykerSdk\Sdk\Infrastructure\Entity\Lifecycle as InfrastructureLifecycle; use SprykerSdk\Sdk\Infrastructure\Entity\RemovedEvent; +use SprykerSdk\Sdk\Infrastructure\Filesystem\Filesystem; +use SprykerSdk\Sdk\Infrastructure\Lifecycle\Event\InitializedEvent; +use SprykerSdk\Sdk\Infrastructure\Lifecycle\Subscriber\InitializedEventSubscriber; use SprykerSdk\Sdk\Tests\UnitTester; /** * Auto-generated group annotations * - * @group Sdk * @group Unit - * @group Core - * @group Application + * @group Infrastructure * @group Lifecycle * @group Subscriber * @group InitializedEventSubscriberTest @@ -42,14 +40,14 @@ class InitializedEventSubscriberTest extends Unit protected UnitTester $tester; /** - * @var \SprykerSdk\Sdk\Core\Application\Lifecycle\Subscriber\InitializedEventSubscriber + * @var \SprykerSdk\Sdk\Infrastructure\Lifecycle\Subscriber\InitializedEventSubscriber */ protected InitializedEventSubscriber $subscriber; /** - * @var \SprykerSdk\Sdk\Core\Application\Dependency\FileManagerInterface + * @var \SprykerSdk\Sdk\Infrastructure\Filesystem\Filesystem */ - protected FileManagerInterface $fileManager; + protected Filesystem $filesystem; /** * @var \SprykerSdk\Sdk\Core\Application\Service\PlaceholderResolver @@ -73,13 +71,13 @@ protected function setUp(): void { parent::setUp(); - $this->fileManager = $this->createMock(FileManagerInterface::class); + $this->filesystem = $this->createMock(Filesystem::class); $this->placeholderResolver = $this->createMock(PlaceholderResolver::class); $this->commandExecutor = $this->createMock(CommandExecutorInterface::class); $this->contextFactory = $this->createMock(ContextFactoryInterface::class); $this->subscriber = new InitializedEventSubscriber( - $this->fileManager, + $this->filesystem, $this->placeholderResolver, $this->commandExecutor, $this->contextFactory, @@ -139,9 +137,9 @@ public function testOnInitializedEventShouldCreateFilesAndExecuteCommands(): voi $task = $this->tester->createTask(['lifecycle' => $lifecycle]); $event = new InitializedEvent($task); - $this->fileManager + $this->filesystem ->expects($this->exactly(count($files))) - ->method('create'); + ->method('dumpFile'); $this->commandExecutor ->expects($this->exactly(count($commands))) @@ -169,9 +167,9 @@ public function testOnInitializedEventWithIncorrectLifecycleShouldDoNothing(): v $task = $this->tester->createTask(['lifecycle' => $lifecycle]); $event = new InitializedEvent($task); - $this->fileManager + $this->filesystem ->expects($this->never()) - ->method('create'); + ->method('dumpFile'); $this->commandExecutor ->expects($this->never()) diff --git a/tests/Sdk/Unit/Core/Application/Lifecycle/Subscriber/RemovedEventSubscriberTest.php b/tests/Sdk/Unit/Infrastructure/Lifecycle/Subscriber/RemovedEventSubscriberTest.php similarity index 87% rename from tests/Sdk/Unit/Core/Application/Lifecycle/Subscriber/RemovedEventSubscriberTest.php rename to tests/Sdk/Unit/Infrastructure/Lifecycle/Subscriber/RemovedEventSubscriberTest.php index 739c1cce0..3b4893e8f 100644 --- a/tests/Sdk/Unit/Core/Application/Lifecycle/Subscriber/RemovedEventSubscriberTest.php +++ b/tests/Sdk/Unit/Infrastructure/Lifecycle/Subscriber/RemovedEventSubscriberTest.php @@ -5,15 +5,12 @@ * Use of this software requires acceptance of the Evaluation License Agreement. See LICENSE file. */ -namespace SprykerSdk\Sdk\Unit\Core\Application\Lifecycle\Subscriber; +namespace Sdk\Unit\Infrastructure\Lifecycle\Subscriber; use Codeception\Test\Unit; use Doctrine\Common\Collections\ArrayCollection; use SprykerSdk\Sdk\Core\Application\Dependency\CommandExecutorInterface; use SprykerSdk\Sdk\Core\Application\Dependency\ContextFactoryInterface; -use SprykerSdk\Sdk\Core\Application\Dependency\FileManagerInterface; -use SprykerSdk\Sdk\Core\Application\Lifecycle\Event\RemovedEvent as SubscriberRemovedEvent; -use SprykerSdk\Sdk\Core\Application\Lifecycle\Subscriber\RemovedEventSubscriber; use SprykerSdk\Sdk\Core\Application\Service\PlaceholderResolver; use SprykerSdk\Sdk\Core\Domain\Entity\Lifecycle\InitializedEventData; use SprykerSdk\Sdk\Core\Domain\Entity\Lifecycle\Lifecycle; @@ -21,15 +18,16 @@ use SprykerSdk\Sdk\Core\Domain\Entity\Lifecycle\UpdatedEventData; use SprykerSdk\Sdk\Infrastructure\Entity\Lifecycle as InfrastructureLifecycle; use SprykerSdk\Sdk\Infrastructure\Entity\RemovedEvent as InfrastructureRemovedEvent; +use SprykerSdk\Sdk\Infrastructure\Filesystem\Filesystem; +use SprykerSdk\Sdk\Infrastructure\Lifecycle\Event\RemovedEvent as SubscriberRemovedEvent; +use SprykerSdk\Sdk\Infrastructure\Lifecycle\Subscriber\RemovedEventSubscriber; use SprykerSdk\Sdk\Tests\UnitTester; /** * Auto-generated group annotations * - * @group Sdk * @group Unit - * @group Core - * @group Application + * @group Infrastructure * @group Lifecycle * @group Subscriber * @group RemovedEventSubscriberTest @@ -43,14 +41,14 @@ class RemovedEventSubscriberTest extends Unit protected UnitTester $tester; /** - * @var \SprykerSdk\Sdk\Core\Application\Lifecycle\Subscriber\RemovedEventSubscriber + * @var \SprykerSdk\Sdk\Infrastructure\Lifecycle\Subscriber\RemovedEventSubscriber */ protected RemovedEventSubscriber $subscriber; /** - * @var \SprykerSdk\Sdk\Core\Application\Dependency\FileManagerInterface + * @var \SprykerSdk\Sdk\Infrastructure\Filesystem\Filesystem */ - protected FileManagerInterface $fileManager; + protected Filesystem $filesystem; /** * @var \SprykerSdk\Sdk\Core\Application\Service\PlaceholderResolver @@ -74,13 +72,13 @@ protected function setUp(): void { parent::setUp(); - $this->fileManager = $this->createMock(FileManagerInterface::class); + $this->filesystem = $this->createMock(Filesystem::class); $this->placeholderResolver = $this->createMock(PlaceholderResolver::class); $this->commandExecutor = $this->createMock(CommandExecutorInterface::class); $this->contextFactory = $this->createMock(ContextFactoryInterface::class); $this->subscriber = new RemovedEventSubscriber( - $this->fileManager, + $this->filesystem, $this->placeholderResolver, $this->commandExecutor, $this->contextFactory, @@ -141,7 +139,7 @@ public function testOnRemovedEventShouldRemoveFilesAndExecuteCommands(): void $task = $this->tester->createInfrastructureTask($lifecycle); $event = new SubscriberRemovedEvent($task); - $this->fileManager + $this->filesystem ->expects($this->exactly(count($files))) ->method('remove'); @@ -171,7 +169,7 @@ public function testOnRemovedEventWithIncorrectLifecycleShouldDoNothing(): void $task = $this->tester->createInfrastructureTask($lifecycle); $event = new SubscriberRemovedEvent($task); - $this->fileManager + $this->filesystem ->expects($this->never()) ->method('remove'); diff --git a/tests/Sdk/Unit/Core/Application/Lifecycle/Subscriber/UpdatedEventSubscriberTest.php b/tests/Sdk/Unit/Infrastructure/Lifecycle/Subscriber/UpdatedEventSubscriberTest.php similarity index 86% rename from tests/Sdk/Unit/Core/Application/Lifecycle/Subscriber/UpdatedEventSubscriberTest.php rename to tests/Sdk/Unit/Infrastructure/Lifecycle/Subscriber/UpdatedEventSubscriberTest.php index 94dd75cdf..87f953f52 100644 --- a/tests/Sdk/Unit/Core/Application/Lifecycle/Subscriber/UpdatedEventSubscriberTest.php +++ b/tests/Sdk/Unit/Infrastructure/Lifecycle/Subscriber/UpdatedEventSubscriberTest.php @@ -5,14 +5,11 @@ * Use of this software requires acceptance of the Evaluation License Agreement. See LICENSE file. */ -namespace SprykerSdk\Sdk\Unit\Core\Application\Lifecycle\Subscriber; +namespace Sdk\Unit\Infrastructure\Lifecycle\Subscriber; use Codeception\Test\Unit; use SprykerSdk\Sdk\Core\Application\Dependency\CommandExecutorInterface; use SprykerSdk\Sdk\Core\Application\Dependency\ContextFactoryInterface; -use SprykerSdk\Sdk\Core\Application\Dependency\FileManagerInterface; -use SprykerSdk\Sdk\Core\Application\Lifecycle\Event\UpdatedEvent; -use SprykerSdk\Sdk\Core\Application\Lifecycle\Subscriber\UpdatedEventSubscriber; use SprykerSdk\Sdk\Core\Application\Service\PlaceholderResolver; use SprykerSdk\Sdk\Core\Domain\Entity\Lifecycle\InitializedEventData; use SprykerSdk\Sdk\Core\Domain\Entity\Lifecycle\Lifecycle; @@ -20,15 +17,16 @@ use SprykerSdk\Sdk\Core\Domain\Entity\Lifecycle\UpdatedEventData; use SprykerSdk\Sdk\Infrastructure\Entity\Lifecycle as InfrastructureLifecycle; use SprykerSdk\Sdk\Infrastructure\Entity\RemovedEvent; +use SprykerSdk\Sdk\Infrastructure\Filesystem\Filesystem; +use SprykerSdk\Sdk\Infrastructure\Lifecycle\Event\UpdatedEvent; +use SprykerSdk\Sdk\Infrastructure\Lifecycle\Subscriber\UpdatedEventSubscriber; use SprykerSdk\Sdk\Tests\UnitTester; /** * Auto-generated group annotations * - * @group Sdk * @group Unit - * @group Core - * @group Application + * @group Infrastructure * @group Lifecycle * @group Subscriber * @group UpdatedEventSubscriberTest @@ -42,14 +40,14 @@ class UpdatedEventSubscriberTest extends Unit protected UnitTester $tester; /** - * @var \SprykerSdk\Sdk\Core\Application\Lifecycle\Subscriber\UpdatedEventSubscriber + * @var \SprykerSdk\Sdk\Infrastructure\Lifecycle\Subscriber\UpdatedEventSubscriber */ protected UpdatedEventSubscriber $subscriber; /** - * @var \SprykerSdk\Sdk\Core\Application\Dependency\FileManagerInterface + * @var \SprykerSdk\Sdk\Infrastructure\Filesystem\Filesystem */ - protected FileManagerInterface $fileManager; + protected Filesystem $filesystem; /** * @var \SprykerSdk\Sdk\Core\Application\Service\PlaceholderResolver @@ -73,13 +71,13 @@ protected function setUp(): void { parent::setUp(); - $this->fileManager = $this->createMock(FileManagerInterface::class); + $this->filesystem = $this->createMock(Filesystem::class); $this->placeholderResolver = $this->createMock(PlaceholderResolver::class); $this->commandExecutor = $this->createMock(CommandExecutorInterface::class); $this->contextFactory = $this->createMock(ContextFactoryInterface::class); $this->subscriber = new UpdatedEventSubscriber( - $this->fileManager, + $this->filesystem, $this->placeholderResolver, $this->commandExecutor, $this->contextFactory, @@ -139,9 +137,9 @@ public function testOnUpdatedEventShouldCreateFilesAndExecuteCommands(): void $task = $this->tester->createTask(['lifecycle' => $lifecycle]); $event = new UpdatedEvent($task); - $this->fileManager + $this->filesystem ->expects($this->exactly(count($files))) - ->method('create'); + ->method('dumpFile'); $this->commandExecutor ->expects($this->exactly(count($commands))) @@ -169,9 +167,9 @@ public function testOnUpdatedEventWithIncorrectLifecycleShouldDoNothing(): void $task = $this->tester->createTask(['lifecycle' => $lifecycle]); $event = new UpdatedEvent($task); - $this->fileManager + $this->filesystem ->expects($this->never()) - ->method('create'); + ->method('dumpFile'); $this->commandExecutor ->expects($this->never()) diff --git a/tests/Sdk/Unit/Infrastructure/Loader/TaskYamlFileLoaderTest.php b/tests/Sdk/Unit/Infrastructure/Loader/TaskYamlFileLoaderTest.php index 7fbc948fa..9f00aedc2 100644 --- a/tests/Sdk/Unit/Infrastructure/Loader/TaskYamlFileLoaderTest.php +++ b/tests/Sdk/Unit/Infrastructure/Loader/TaskYamlFileLoaderTest.php @@ -14,6 +14,7 @@ use SprykerSdk\Sdk\Infrastructure\Collector\TaskYamlCollector; use SprykerSdk\Sdk\Infrastructure\Loader\TaskYaml\TaskYamlFileLoader; use SprykerSdk\Sdk\Infrastructure\Storage\TaskStorage; +use SprykerSdk\Sdk\Infrastructure\Task\TaskSetTaskRelation\TaskSetTaskRelationFacadeInterface; use SprykerSdk\Sdk\Tests\UnitTester; /** @@ -58,6 +59,11 @@ class TaskYamlFileLoaderTest extends Unit */ protected TaskStorage $taskStorage; + /** + * @var \SprykerSdk\Sdk\Infrastructure\Task\TaskSetTaskRelation\TaskSetTaskRelationFacadeInterface + */ + protected TaskSetTaskRelationFacadeInterface $taskSetTaskRelationFacade; + /** * @return void */ @@ -69,12 +75,14 @@ protected function setUp(): void $this->taskStorage = new TaskStorage(); $this->taskYamlCollector = $this->createMock(TaskYamlCollector::class); $this->taskFromYamlTaskSetBuilder = $this->createMock(TaskFromYamlTaskSetBuilderInterface::class); + $this->taskSetTaskRelationFacade = $this->createMock(TaskSetTaskRelationFacadeInterface::class); $this->taskYamlFileLoader = new TaskYamlFileLoader( $this->taskYamlCollector, $this->taskFromYamlTaskSetBuilder, $this->taskStorage, $this->taskBuilder, + $this->taskSetTaskRelationFacade, ); } @@ -88,7 +96,7 @@ public function testLoadAllShouldReturnBuiltTasks(): void $taskMock->expects($this->any()) ->method('getId') ->will($this->returnCallback(function () { - return 'test:task:' . (mt_rand(100, 99999)); + return 'test:task:' . (random_int(100, 99999)); })); $this->taskBuilder diff --git a/tests/Sdk/Unit/Infrastructure/Logger/NewRelicFormatterTest.php b/tests/Sdk/Unit/Infrastructure/Logger/NewRelicFormatterTest.php new file mode 100644 index 000000000..bbfaf4896 --- /dev/null +++ b/tests/Sdk/Unit/Infrastructure/Logger/NewRelicFormatterTest.php @@ -0,0 +1,67 @@ +format($record); + + // Assert + $this->assertSame(['context' => ['workspace_name' => 'paas-demo', 'ci_execution_id' => 'ci-execution-id']], $record); + } + + /** + * @return void + */ + public function testFormatBatchShouldProcessRecordCollection(): void + { + // Arrange + $workspace = 'paas-demo'; + $ciExecutionId = 'ci-execution-id'; + $records = ['one' => [], 'two' => []]; + + $formatter = new NewRelicFormatter($workspace, $ciExecutionId); + + // Act + $records = $formatter->formatBatch($records); + + // Assert + $this->assertSame( + [ + 'one' => ['context' => ['workspace_name' => 'paas-demo', 'ci_execution_id' => 'ci-execution-id']], + 'two' => ['context' => ['workspace_name' => 'paas-demo', 'ci_execution_id' => 'ci-execution-id']], + ], + $records, + ); + } +} diff --git a/tests/Sdk/Unit/Infrastructure/Logger/TransactionNameNewRelicProcessorTest.php b/tests/Sdk/Unit/Infrastructure/Logger/TransactionNameNewRelicProcessorTest.php new file mode 100644 index 000000000..67dbdec0e --- /dev/null +++ b/tests/Sdk/Unit/Infrastructure/Logger/TransactionNameNewRelicProcessorTest.php @@ -0,0 +1,55 @@ +assertSame(['context' => ['transaction_name' => 'transaction-name']], $record); + } + + /** + * @return void + */ + public function testInvokeShouldReturnContextWhenSomeValueSetSet(): void + { + // Arrange + $record = ['context' => ['foo' => 'bar']]; + $processor = new TransactionNameNewRelicProcessor('transaction-name'); + + // Act + $record = $processor($record); + + // Assert + $this->assertSame(['context' => ['foo' => 'bar', 'transaction_name' => 'transaction-name']], $record); + } +} diff --git a/tests/Sdk/Unit/Infrastructure/Mapper/TaskSetTaskRelationMapperTest.php b/tests/Sdk/Unit/Infrastructure/Mapper/TaskSetTaskRelationMapperTest.php new file mode 100644 index 000000000..509c4ffad --- /dev/null +++ b/tests/Sdk/Unit/Infrastructure/Mapper/TaskSetTaskRelationMapperTest.php @@ -0,0 +1,123 @@ +createObjectRepositoryMock($taskSetId, $taskId, null, $this->createTaskMock($taskId)); + $taskSetTaskRelationMapper = new TaskSetTaskRelationMapper($repositoryMock); + $domainRelation = new DomainTaskSetTaskRelation($this->createTaskMock($taskSetId), $this->createTaskMock($taskId)); + + // Assert + $this->expectException(InvalidArgumentException::class); + + // Act + $taskSetTaskRelationMapper->mapToInfrastructureTaskSetRelation($domainRelation); + } + + /** + * @return void + */ + public function testMapToInfrastructureTaskSetRelationShouldThrowExceptionWhenSubTaskNotFound(): void + { + // Arrange + $taskSetId = 'test:task-set'; + $taskId = 'test:task'; + $repositoryMock = $this->createObjectRepositoryMock($taskSetId, $taskId, $this->createTaskMock($taskSetId), null); + $taskSetTaskRelationMapper = new TaskSetTaskRelationMapper($repositoryMock); + $domainRelation = new DomainTaskSetTaskRelation($this->createTaskMock($taskSetId), $this->createTaskMock($taskId)); + + // Assert + $this->expectException(InvalidArgumentException::class); + + // Act + $taskSetTaskRelationMapper->mapToInfrastructureTaskSetRelation($domainRelation); + } + + /** + * @return void + */ + public function testMapToInfrastructureTaskSetRelationShouldMapToInfrastructureRelation(): void + { + // Arrange + $taskSetId = 'test:task-set'; + $taskId = 'test:task'; + $infrastructureTaskSet = $this->createTaskMock($taskSetId); + $infrastructureSubTask = $this->createTaskMock($taskId); + $repositoryMock = $this->createObjectRepositoryMock($taskSetId, $taskId, $infrastructureTaskSet, $infrastructureSubTask); + $taskSetTaskRelationMapper = new TaskSetTaskRelationMapper($repositoryMock); + $domainRelation = new DomainTaskSetTaskRelation($this->createTaskMock($taskSetId), $this->createTaskMock($taskId)); + + // Act + $infrastructureRelation = $taskSetTaskRelationMapper->mapToInfrastructureTaskSetRelation($domainRelation); + + // Assert + $this->assertSame($infrastructureTaskSet, $infrastructureRelation->getTaskSet()); + $this->assertSame($infrastructureSubTask, $infrastructureRelation->getSubTask()); + } + + /** + * @param string $taskSetId + * @param string $taskId + * @param \SprykerSdk\SdkContracts\Entity\TaskInterface|null $taskSet + * @param \SprykerSdk\SdkContracts\Entity\TaskInterface|null $subTask + * + * @return \Doctrine\Persistence\ObjectRepository + */ + protected function createObjectRepositoryMock( + string $taskSetId, + string $taskId, + ?TaskInterface $taskSet = null, + ?TaskInterface $subTask = null + ): ObjectRepository { + $repository = $this->createMock(ObjectRepository::class); + $repository->method('find')->willReturnMap([ + [$taskSetId, $taskSet], + [$taskId, $subTask], + ]); + + return $repository; + } + + /** + * @param string $taskId + * + * @return \SprykerSdk\SdkContracts\Entity\TaskInterface + */ + protected function createTaskMock(string $taskId): TaskInterface + { + $task = $this->createMock(TaskInterface::class); + $task->method('getId')->willReturn($taskId); + + return $task; + } +} diff --git a/tests/Sdk/Unit/Infrastructure/MetricsSender/MetricEventSubscriberTest.php b/tests/Sdk/Unit/Infrastructure/MetricsSender/MetricEventSubscriberTest.php new file mode 100644 index 000000000..fdaecfe2a --- /dev/null +++ b/tests/Sdk/Unit/Infrastructure/MetricsSender/MetricEventSubscriberTest.php @@ -0,0 +1,90 @@ +assertSame($events, [MetricEventInterface::class => 'onMetricEvent']); + } + + /** + * @return void + */ + public function testOnMetricEventShouldSendMetric(): void + { + // Arrange + $senderClientMock = $this->createMetricSenderClientMock(); + $metricSenderClientFetcherMock = $this->createMetricSenderClientFetcherMock($senderClientMock); + $subscriber = new MetricEventSubscriber($metricSenderClientFetcherMock); + $eventMock = $this->createMetricEventMock(); + + // Act + $subscriber->onMetricEvent($eventMock); + } + + /** + * @return \SprykerSdk\Sdk\Infrastructure\MetricsSender\MetricSenderClientInterface + */ + public function createMetricSenderClientMock(): MetricSenderClientInterface + { + $metricSenderClient = $this->createMock(MetricSenderClientInterface::class); + $metricSenderClient->expects($this->once())->method('send'); + + return $metricSenderClient; + } + + /** + * @param \SprykerSdk\Sdk\Infrastructure\MetricsSender\MetricSenderClientInterface $metricSenderClient + * + * @return \SprykerSdk\Sdk\Infrastructure\MetricsSender\MetricSenderClientFetcher + */ + public function createMetricSenderClientFetcherMock(MetricSenderClientInterface $metricSenderClient): MetricSenderClientFetcher + { + $metricSenderClientFetcher = $this->createMock(MetricSenderClientFetcher::class); + $metricSenderClientFetcher->method('getFirstApplicableClient')->willReturn($metricSenderClient); + + return $metricSenderClientFetcher; + } + + /** + * @return \SprykerSdk\SdkContracts\Event\MetricEventInterface + */ + public function createMetricEventMock(): MetricEventInterface + { + $metricEvent = $this->createMock(MetricEventInterface::class); + + $metricEvent->method('getName')->willReturn('name'); + $metricEvent->method('getPayLoad')->willReturn([]); + + return $metricEvent; + } +} diff --git a/tests/Sdk/Unit/Infrastructure/MetricsSender/MetricSenderClientFetcherTest.php b/tests/Sdk/Unit/Infrastructure/MetricsSender/MetricSenderClientFetcherTest.php new file mode 100644 index 000000000..4b18c0a30 --- /dev/null +++ b/tests/Sdk/Unit/Infrastructure/MetricsSender/MetricSenderClientFetcherTest.php @@ -0,0 +1,71 @@ +createMetricSenderClientMock(true); + $secondClient = $this->createMetricSenderClientMock(true); + $metricSenderClientFetcher = new MetricSenderClientFetcher([$firstClient, $secondClient]); + + // Act + $client = $metricSenderClientFetcher->getFirstApplicableClient(); + + // Assert + $this->assertSame($firstClient, $client); + } + + /** + * @return void + */ + public function testGetFirstApplicableClientShouldReturnNullIfNotApplicableClientsSet(): void + { + // Arrange + $firstClient = $this->createMetricSenderClientMock(false); + $secondClient = $this->createMetricSenderClientMock(false); + $metricSenderClientFetcher = new MetricSenderClientFetcher([$firstClient, $secondClient]); + + // Act + $client = $metricSenderClientFetcher->getFirstApplicableClient(); + + // Assert + $this->assertNull($client); + } + + /** + * @param bool $isApplicable + * + * @return \SprykerSdk\Sdk\Infrastructure\MetricsSender\MetricSenderClientInterface + */ + public function createMetricSenderClientMock(bool $isApplicable): MetricSenderClientInterface + { + $metricSenderClient = $this->createMock(MetricSenderClientInterface::class); + $metricSenderClient->method('isApplicable')->willReturn($isApplicable); + + return $metricSenderClient; + } +} diff --git a/tests/Sdk/Unit/Infrastructure/Repository/ContextFileRepositoryTest.php b/tests/Sdk/Unit/Infrastructure/Repository/ContextFileRepositoryTest.php index 247d20118..4f5e84ddf 100644 --- a/tests/Sdk/Unit/Infrastructure/Repository/ContextFileRepositoryTest.php +++ b/tests/Sdk/Unit/Infrastructure/Repository/ContextFileRepositoryTest.php @@ -10,7 +10,6 @@ use Codeception\Test\Unit; use org\bovigo\vfs\vfsStream; use org\bovigo\vfs\vfsStreamDirectory; -use SprykerSdk\Sdk\Core\Application\Cache\ContextCacheStorageInterface; use SprykerSdk\Sdk\Core\Application\Dependency\SettingFetcherInterface; use SprykerSdk\Sdk\Core\Application\Service\ContextSerializer; use SprykerSdk\Sdk\Infrastructure\Exception\MissingContextFileException; @@ -50,11 +49,6 @@ class ContextFileRepositoryTest extends Unit */ protected vfsStreamDirectory $vfsStream; - /** - * @var \SprykerSdk\Sdk\Core\Application\Cache\ContextCacheStorageInterface - */ - protected ContextCacheStorageInterface $contextCacheStorage; - /** * @var \SprykerSdk\Sdk\Tests\UnitTester */ @@ -68,12 +62,10 @@ protected function setUp(): void parent::setUp(); $this->contextSerializer = $this->createMock(ContextSerializer::class); $this->settingFetcher = $this->createMock(SettingFetcherInterface::class); - $this->contextCacheStorage = $this->createMock(ContextCacheStorageInterface::class); $this->vfsStream = vfsStream::setup(); $this->contextFileRepository = new ContextFileRepository( $this->contextSerializer, - $this->contextCacheStorage, $this->settingFetcher, ); } @@ -220,24 +212,4 @@ public function testFindByNameWithoutFileInVfsShouldThrowException(): void // Act $this->contextFileRepository->findByName($context->getName()); } - - /** - * @return void - */ - public function testFindByNameReturnsCachedContextIfExists(): void - { - // Arrange - $expectedContext = $this->tester->createContext(); - $this->contextCacheStorage - ->expects($this->once()) - ->method('get') - ->with($expectedContext->getName()) - ->willReturn($expectedContext); - - // Act - $actualContext = $this->contextFileRepository->findByName($expectedContext->getName()); - - // Assert - $this->assertSame($expectedContext, $actualContext); - } } diff --git a/tests/Sdk/Unit/Infrastructure/Repository/ProjectSettingRepositoryTest.php b/tests/Sdk/Unit/Infrastructure/Repository/ProjectSettingRepositoryTest.php index e9872f16c..903c8cdf8 100644 --- a/tests/Sdk/Unit/Infrastructure/Repository/ProjectSettingRepositoryTest.php +++ b/tests/Sdk/Unit/Infrastructure/Repository/ProjectSettingRepositoryTest.php @@ -8,11 +8,10 @@ namespace SprykerSdk\Sdk\Unit\Infrastructure\Repository; use Codeception\Test\Unit; -use org\bovigo\vfs\vfsStream; -use org\bovigo\vfs\vfsStreamDirectory; use SprykerSdk\Sdk\Core\Application\Dependency\Repository\SettingRepositoryInterface; use SprykerSdk\Sdk\Core\Application\Exception\MissingSettingException; use SprykerSdk\Sdk\Infrastructure\Exception\InvalidTypeException; +use SprykerSdk\Sdk\Infrastructure\Filesystem\Filesystem; use SprykerSdk\Sdk\Infrastructure\Repository\ProjectSettingRepository; use SprykerSdk\Sdk\Infrastructure\Resolver\PathResolver; use SprykerSdk\Sdk\Tests\UnitTester; @@ -43,11 +42,6 @@ class ProjectSettingRepositoryTest extends Unit */ protected SettingRepositoryInterface $coreSettingRepository; - /** - * @var \Symfony\Component\Yaml\Yaml - */ - protected Yaml $yamlParser; - /** * @var \SprykerSdk\Sdk\Infrastructure\Resolver\PathResolver */ @@ -64,14 +58,19 @@ class ProjectSettingRepositoryTest extends Unit protected UnitTester $tester; /** - * @var \org\bovigo\vfs\vfsStreamDirectory + * @var \SprykerSdk\Sdk\Infrastructure\Filesystem\Filesystem + */ + protected Filesystem $filesystem; + + /** + * @var string */ - protected vfsStreamDirectory $vfsStream; + protected string $projectSettingFileName = 'settings'; /** * @var string */ - protected string $projectSettingFileName = ''; + protected string $localProjectSettingFileName = 'settings.local'; /** * @return void @@ -81,15 +80,16 @@ protected function setUp(): void parent::setUp(); $this->container = $this->createMock(ContainerInterface::class); $this->coreSettingRepository = $this->createMock(SettingRepositoryInterface::class); - $this->yamlParser = $this->createMock(Yaml::class); $this->pathResolver = $this->createMock(PathResolver::class); - $this->vfsStream = vfsStream::setup(); + $this->filesystem = $this->createMock(Filesystem::class); $this->projectSettingRepository = new ProjectSettingRepository( $this->coreSettingRepository, new Yaml(), $this->projectSettingFileName, + $this->localProjectSettingFileName, $this->pathResolver, + $this->filesystem, ); } @@ -249,13 +249,17 @@ public function testSaveShouldSaveSharedSetting(): void // Arrange $sharedSetting = $this->tester->createSetting('pathShared', 'valueShared', SettingInterface::STRATEGY_REPLACE, Setting::SETTING_TYPE_LOCAL); - $this->projectSettingFileName = $this->vfsStream->url() . '/settings'; + $this->filesystem->expects($this->once()) + ->method('dumpFile') + ->with('settings.local', "pathShared: valueShared\n"); $this->projectSettingRepository = new ProjectSettingRepository( $this->coreSettingRepository, new Yaml(), $this->projectSettingFileName, + $this->localProjectSettingFileName, $this->pathResolver, + $this->filesystem, ); // Act @@ -263,9 +267,6 @@ public function testSaveShouldSaveSharedSetting(): void // Assert $this->assertSame($sharedSetting, $sharedResult); - - $this->assertNotEmpty($this->vfsStream->getChildren()); - $this->assertSame("pathShared: valueShared\n", $this->vfsStream->getChild('settings.local')->getContent()); } /** @@ -276,13 +277,17 @@ public function testSaveShouldSaveSetting(): void // Arrange $setting = $this->tester->createSetting('path', 'value'); - $this->projectSettingFileName = $this->vfsStream->url() . '/settings'; + $this->filesystem->expects($this->once()) + ->method('dumpFile') + ->with('settings.local', "path: value\n"); $this->projectSettingRepository = new ProjectSettingRepository( $this->coreSettingRepository, new Yaml(), $this->projectSettingFileName, + $this->localProjectSettingFileName, $this->pathResolver, + $this->filesystem, ); // Act @@ -290,9 +295,6 @@ public function testSaveShouldSaveSetting(): void // Assert $this->assertSame($setting, $result); - - $this->assertNotEmpty($this->vfsStream->getChildren()); - $this->assertSame("path: value\n", $this->vfsStream->getChild('settings.local')->getContent()); } /** @@ -306,13 +308,17 @@ public function testSaveMultipleShouldSaveSetting(): void $this->tester->createSetting('path2', 'value2'), ]; - $this->projectSettingFileName = $this->vfsStream->url() . '/settings'; + $this->filesystem->expects($this->once()) + ->method('dumpFile') + ->with('settings.local', "path1: value1\npath2: value2\n"); $this->projectSettingRepository = new ProjectSettingRepository( $this->coreSettingRepository, new Yaml(), $this->projectSettingFileName, + $this->localProjectSettingFileName, $this->pathResolver, + $this->filesystem, ); // Act @@ -320,8 +326,6 @@ public function testSaveMultipleShouldSaveSetting(): void // Assert $this->assertSame($settings, $result); - $this->assertNotEmpty($this->vfsStream->getChildren()); - $this->assertSame("path1: value1\npath2: value2\n", $this->vfsStream->getChild('settings.local')->getContent()); } /** @@ -438,15 +442,14 @@ public function testFindByPathsShouldReturnSettingsByPaths(): void path3: value3 YAML, ); - $this->vfsStream->addChild($settingsFile); - - $this->projectSettingFileName = $settingsFile->url(); $this->projectSettingRepository = new ProjectSettingRepository( $this->coreSettingRepository, new Yaml(), $this->projectSettingFileName, + $this->localProjectSettingFileName, $this->pathResolver, + $this->filesystem, ); $this->coreSettingRepository diff --git a/tests/Sdk/Unit/Infrastructure/Service/ErrorCommandListenerTest.php b/tests/Sdk/Unit/Infrastructure/Service/ErrorCommandListenerTest.php index 962a81d9a..4406668df 100644 --- a/tests/Sdk/Unit/Infrastructure/Service/ErrorCommandListenerTest.php +++ b/tests/Sdk/Unit/Infrastructure/Service/ErrorCommandListenerTest.php @@ -10,7 +10,6 @@ use Codeception\Test\Unit; use Doctrine\DBAL\Exception\TableNotFoundException; use InvalidArgumentException; -use SprykerSdk\Sdk\Core\Application\Exception\ProjectWorkflowException; use SprykerSdk\Sdk\Infrastructure\Service\ErrorCommandListener; use Symfony\Component\Console\Event\ConsoleErrorEvent; use Symfony\Component\Console\Input\InputInterface; @@ -44,9 +43,9 @@ class ErrorCommandListenerTest extends Unit public function testSkipProcessingWhenErrorIsNotTableNotFoundException(): void { //Arrange - $event = new ConsoleErrorEvent($this->createInputMock(), $this->createOutputMock(), new InvalidArgumentException()); + $event = new ConsoleErrorEvent($this->createInputMock(), $this->createOutputMock(true), new InvalidArgumentException()); $event->setExitCode(static::DEFAULT_ERROR_CODE); - $eventListener = new ErrorCommandListener(); + $eventListener = new ErrorCommandListener(true); //Act $eventListener->handle($event); @@ -64,7 +63,7 @@ public function testSkipProcessingWhenDebugTrue(): void //Arrange $event = new ConsoleErrorEvent($this->createInputMock(), $this->createOutputMock(true), $this->createTableNotFoundExceptionMock()); $event->setExitCode(static::DEFAULT_ERROR_CODE); - $eventListener = new ErrorCommandListener(); + $eventListener = new ErrorCommandListener(true); //Act $eventListener->handle($event); @@ -75,21 +74,38 @@ public function testSkipProcessingWhenDebugTrue(): void } /** + * @dataProvider requiredDebugSetting + * + * @param bool $verbosity + * @param bool $debug + * * @return void */ - public function testProcessingWhenErrorIsTableNotFoundExceptionAndDebugFalse(): void + public function testProcessingWhenErrorIsTableNotFoundException(bool $verbosity, bool $debug): void { //Arrange - $event = new ConsoleErrorEvent($this->createInputMock(), $this->createOutputMock(), $this->createTableNotFoundExceptionMock()); + $tableNotFoundExceptionMock = $this->createTableNotFoundExceptionMock(); + $event = new ConsoleErrorEvent($this->createInputMock(), $this->createOutputMock($verbosity), $tableNotFoundExceptionMock); $event->setExitCode(static::DEFAULT_ERROR_CODE); - $eventListener = new ErrorCommandListener(); + $eventListener = new ErrorCommandListener($debug); //Act $eventListener->handle($event); //Assert $this->assertSame(static::SUCCESS_ERROR_CODE, $event->getExitCode()); - $this->assertInstanceOf(ProjectWorkflowException::class, $event->getError()); + $this->assertInstanceOf(get_class($tableNotFoundExceptionMock), $event->getError()); + } + + /** + * @return array> + */ + public function requiredDebugSetting(): array + { + return [ + [false, true], + [true, false], + ]; } /** @@ -103,7 +119,7 @@ protected function createInputMock(): InputInterface /** * @param bool $isDebug * - * @return \Symfony\Component\Console\Output\OutputInterface + * @return \PHPUnit\Framework\MockObject\MockObject|\Symfony\Component\Console\Output\OutputInterface */ protected function createOutputMock(bool $isDebug = false): OutputInterface { diff --git a/tests/Sdk/Unit/Infrastructure/Service/InitializerTest.php b/tests/Sdk/Unit/Infrastructure/Service/InitializerTest.php index c5b74e825..e523e8cf4 100644 --- a/tests/Sdk/Unit/Infrastructure/Service/InitializerTest.php +++ b/tests/Sdk/Unit/Infrastructure/Service/InitializerTest.php @@ -17,7 +17,6 @@ use SprykerSdk\Sdk\Infrastructure\Service\ValueReceiver\InteractionProcessor; use SprykerSdk\Sdk\Infrastructure\Setting\SettingInitializerRegistry; use SprykerSdk\Sdk\Tests\UnitTester; -use Symfony\Component\Yaml\Yaml; /** * Auto-generated group annotations @@ -46,11 +45,6 @@ class InitializerTest extends Unit */ protected SettingRepository $settingRepository; - /** - * @var \Symfony\Component\Yaml\Yaml - */ - protected Yaml $yamlParser; - /** * @var string */ diff --git a/tests/Sdk/Unit/Infrastructure/Service/LocalCliRunnerTest.php b/tests/Sdk/Unit/Infrastructure/Service/LocalCliRunnerTest.php index 5d5dd5ab7..461caa882 100644 --- a/tests/Sdk/Unit/Infrastructure/Service/LocalCliRunnerTest.php +++ b/tests/Sdk/Unit/Infrastructure/Service/LocalCliRunnerTest.php @@ -137,8 +137,8 @@ public function testExecute(): void // Arrange $process = $this->createMock(Process::class); $process->expects($this->atLeastOnce()) - ->method('getExitCode') - ->willReturn(0); + ->method('isSuccessful') + ->willReturn(1); $process->expects($this->exactly(2)) ->method('getOutput') ->willReturn('test' . PHP_EOL . 'test'); @@ -170,7 +170,7 @@ public function testExecuteWithError(): void // Arrange $process = $this->createMock(Process::class); $process->expects($this->atLeastOnce()) - ->method('getExitCode') + ->method('isSuccessful') ->willReturn(1); $process->expects($this->exactly(2)) ->method('getOutput') diff --git a/tests/Sdk/Unit/Infrastructure/Service/TaskManagerTest.php b/tests/Sdk/Unit/Infrastructure/Service/TaskManagerTest.php index 4313414bf..261357d02 100644 --- a/tests/Sdk/Unit/Infrastructure/Service/TaskManagerTest.php +++ b/tests/Sdk/Unit/Infrastructure/Service/TaskManagerTest.php @@ -8,13 +8,15 @@ namespace SprykerSdk\Sdk\Unit\Infrastructure\Service; use Codeception\Test\Unit; -use SprykerSdk\Sdk\Core\Application\Lifecycle\Event\InitializedEvent; -use SprykerSdk\Sdk\Core\Application\Lifecycle\Event\RemovedEvent; -use SprykerSdk\Sdk\Core\Application\Lifecycle\Event\UpdatedEvent; use SprykerSdk\Sdk\Infrastructure\Builder\TaskSet\TaskFromTaskSetBuilderInterface; +use SprykerSdk\Sdk\Infrastructure\Lifecycle\Event\InitializedEvent; +use SprykerSdk\Sdk\Infrastructure\Lifecycle\Event\RemovedEvent; +use SprykerSdk\Sdk\Infrastructure\Lifecycle\Event\UpdatedEvent; use SprykerSdk\Sdk\Infrastructure\Repository\TaskRepository; use SprykerSdk\Sdk\Infrastructure\Service\TaskManager; +use SprykerSdk\Sdk\Infrastructure\Task\TaskSetTaskRelation\TaskSetTaskRelationFacadeInterface; use SprykerSdk\SdkContracts\Entity\TaskInterface; +use SprykerSdk\SdkContracts\Entity\TaskSetInterface; use Symfony\Contracts\EventDispatcher\EventDispatcherInterface; /** @@ -50,6 +52,7 @@ public function testSkipInitializeWhenTaskExists(): void $this->createNoCallsEventDispatcherMock(), $this->createRepositoryMock($task), $this->createTaskFromTaskSetBuilderMock(), + $this->createTaskSetTaskRelationFacadeMock(), ); //Act @@ -70,6 +73,7 @@ public function testInitializeWhenTaskDoesNotExist(): void $this->createEventDispatcherMock(InitializedEvent::class, InitializedEvent::NAME), $this->createRepositoryMock($task, 'create'), $this->createTaskFromTaskSetBuilderMock(), + $this->createTaskSetTaskRelationFacadeMock('createRelations'), ); //Act @@ -79,6 +83,28 @@ public function testInitializeWhenTaskDoesNotExist(): void $this->assertCount(1, $tasks); } + /** + * @return void + */ + public function testInitializeWhenTaskSetPassed(): void + { + //Arrange + $taskSet = $this->createTaskSetMock(static::NON_EXISTENT_TASK_ID); + $taskFromTaskSet = $this->createTaskMock('task:id'); + $taskManager = new TaskManager( + $this->createEventDispatcherMock(InitializedEvent::class, InitializedEvent::NAME), + $this->createRepositoryMock($taskFromTaskSet, 'create'), + $this->createTaskFromTaskSetBuilderMock($taskFromTaskSet), + $this->createTaskSetTaskRelationFacadeMock('createRelations'), + ); + + //Act + $tasks = $taskManager->initialize([$taskSet]); + + //Assert + $this->assertCount(1, $tasks); + } + /** * @return void */ @@ -90,6 +116,7 @@ public function testTriggerEventWithRepositoryCallWhenTaskRemoved(): void $this->createEventDispatcherMock(RemovedEvent::class, RemovedEvent::NAME), $this->createRepositoryMock($task, 'remove'), $this->createTaskFromTaskSetBuilderMock(), + $this->createTaskSetTaskRelationFacadeMock('removeRelations'), ); //Act @@ -107,6 +134,7 @@ public function testTriggerEventWithRepositoryCallWhenTaskUpdated(): void $this->createEventDispatcherMock(UpdatedEvent::class, UpdatedEvent::NAME), $this->createRepositoryMock($task, 'update'), $this->createTaskFromTaskSetBuilderMock(), + $this->createTaskSetTaskRelationFacadeMock('updateRelations'), ); //Act @@ -126,6 +154,19 @@ protected function createTaskMock(string $taskId): TaskInterface return $taskMock; } + /** + * @param string $taskSetId + * + * @return \SprykerSdk\SdkContracts\Entity\TaskSetInterface + */ + protected function createTaskSetMock(string $taskSetId): TaskSetInterface + { + $taskMock = $this->createMock(TaskSetInterface::class); + $taskMock->method('getId')->willReturn($taskSetId); + + return $taskMock; + } + /** * @param \SprykerSdk\SdkContracts\Entity\TaskInterface $task * @param string|null $expectedMethodName @@ -181,10 +222,38 @@ protected function createNoCallsEventDispatcherMock(): EventDispatcherInterface } /** + * @param \SprykerSdk\SdkContracts\Entity\TaskInterface|null $task + * * @return \SprykerSdk\Sdk\Infrastructure\Builder\TaskSet\TaskFromTaskSetBuilderInterface */ - protected function createTaskFromTaskSetBuilderMock(): TaskFromTaskSetBuilderInterface + protected function createTaskFromTaskSetBuilderMock(?TaskInterface $task = null): TaskFromTaskSetBuilderInterface { - return $this->createMock(TaskFromTaskSetBuilderInterface::class); + $taskFromTaskSetBuilder = $this->createMock(TaskFromTaskSetBuilderInterface::class); + + if ($task === null) { + return $taskFromTaskSetBuilder; + } + + $taskFromTaskSetBuilder->method('buildTaskFromTaskSet')->willReturn($task); + + return $taskFromTaskSetBuilder; + } + + /** + * @param string|null $expectedMethod + * + * @return \SprykerSdk\Sdk\Infrastructure\Task\TaskSetTaskRelation\TaskSetTaskRelationFacadeInterface + */ + protected function createTaskSetTaskRelationFacadeMock(?string $expectedMethod = null): TaskSetTaskRelationFacadeInterface + { + $taskSetTaskRelationFacade = $this->createMock(TaskSetTaskRelationFacadeInterface::class); + + if ($expectedMethod === null) { + return $taskSetTaskRelationFacade; + } + + $taskSetTaskRelationFacade->expects($this->once())->method($expectedMethod); + + return $taskSetTaskRelationFacade; } } diff --git a/tests/Sdk/Unit/Infrastructure/Service/ValueReceiver/QuestionFactory/PathQuestionFactoryTest.php b/tests/Sdk/Unit/Infrastructure/Service/ValueReceiver/QuestionFactory/PathQuestionFactoryTest.php index f53ecadcd..54a3b71a5 100644 --- a/tests/Sdk/Unit/Infrastructure/Service/ValueReceiver/QuestionFactory/PathQuestionFactoryTest.php +++ b/tests/Sdk/Unit/Infrastructure/Service/ValueReceiver/QuestionFactory/PathQuestionFactoryTest.php @@ -8,6 +8,7 @@ namespace SprykerSdk\Sdk\Unit\Infrastructure\Service\ValueReceiver\QuestionFactory; use Codeception\Test\Unit; +use SprykerSdk\Sdk\Core\Application\Exception\MissingValueException; use SprykerSdk\Sdk\Infrastructure\Service\ValueReceiver\QuestionFactory\PathQuestionFactory; use SprykerSdk\SdkContracts\Enum\ValueTypeEnum; use Symfony\Component\Console\Question\Question; @@ -42,6 +43,42 @@ public function testCreatesBooleanQuestion(): void $this->assertIsCallable($question->getAutocompleterCallback()); } + /** + * @return void + */ + public function testCreateQuestionShouldThrowExceptionWhenAbsolutePathSet(): void + { + $this->expectException(MissingValueException::class); + + // Arrange + $questionFactory = new PathQuestionFactory(); + + // Act + $question = $questionFactory->createQuestion('Some description', ['one', 'two', 'three'], 'one'); + $validator = $question->getValidator(); + + if ($validator === null) { + $this->fail('Validator shouldn\'t be null'); + } + + $validator('/absolute/path'); + } + + /** + * @return void + */ + public function testAutocompleteInputShouldReturnEmptyArrayWhenAbsolutePathSet(): void + { + // Arrange + $questionFactory = new PathQuestionFactory(); + + // Act + $result = $questionFactory->autocompleteInput('/absolute/path'); + + // Assert + $this->assertEmpty($result); + } + /** * @return void */ diff --git a/tests/Sdk/Unit/Infrastructure/Setting/ProjectSettingsInitializer/ProjectFilesInitializerTest.php b/tests/Sdk/Unit/Infrastructure/Setting/ProjectSettingsInitializer/ProjectFilesInitializerTest.php index 1595d37d2..a7ae920c6 100644 --- a/tests/Sdk/Unit/Infrastructure/Setting/ProjectSettingsInitializer/ProjectFilesInitializerTest.php +++ b/tests/Sdk/Unit/Infrastructure/Setting/ProjectSettingsInitializer/ProjectFilesInitializerTest.php @@ -33,9 +33,11 @@ public function testInitProjectFilesShouldCreateProjectSettingsFiles(): void // Arrange $projectSettingsDir = vfsStream::setup('.ssdk'); $projectSettingsDir->addChild(new vfsStreamFile('settings')); + $projectSettingsDir->addChild(new vfsStreamFile('settings.local')); $projectSettingsFile = vfsStream::url('.ssdk') . '/settings'; + $localProjectSettingsFile = vfsStream::url('.ssdk') . '/settings.local'; - $fileInitializer = new ProjectFilesInitializer($projectSettingsFile, new Filesystem()); + $fileInitializer = new ProjectFilesInitializer($projectSettingsFile, $localProjectSettingsFile, new Filesystem()); // Act $fileInitializer->initProjectFiles(); @@ -52,9 +54,11 @@ public function testIsProjectSettingsInitialisedShouldReturnProjectInitializedWh // Arrange $projectSettingsDir = vfsStream::setup('.ssdk'); $projectSettingsDir->addChild(new vfsStreamFile('settings')); + $projectSettingsDir->addChild(new vfsStreamFile('settings.local')); $projectSettingsFile = vfsStream::url('.ssdk') . '/settings'; + $localProjectSettingsFile = vfsStream::url('.ssdk') . '/settings.local'; - $fileInitializer = new ProjectFilesInitializer($projectSettingsFile, new Filesystem()); + $fileInitializer = new ProjectFilesInitializer($projectSettingsFile, $localProjectSettingsFile, new Filesystem()); // Act $isInitialized = $fileInitializer->isProjectSettingsInitialised(); diff --git a/tests/Sdk/Unit/Infrastructure/Storage/TaskSetTaskRelationStorageTest.php b/tests/Sdk/Unit/Infrastructure/Storage/TaskSetTaskRelationStorageTest.php new file mode 100644 index 000000000..df8c779ec --- /dev/null +++ b/tests/Sdk/Unit/Infrastructure/Storage/TaskSetTaskRelationStorageTest.php @@ -0,0 +1,63 @@ +createTaskMock('task-set:id'), + $this->createTaskMock('task:id'), + ); + + $relationOne = new TaskSetTaskRelation( + $this->createTaskMock('task-set:id'), + $this->createTaskMock('task:id:one'), + ); + + // Act + $storage->addTaskSetTasRelations([$relation, $relationOne]); + $relations = $storage->getTaskSetTaskRelations('task-set:id'); + + // Assert + $this->assertSame([$relation, $relationOne], $relations); + } + + /** + * @param string $taskId + * + * @return \SprykerSdk\SdkContracts\Entity\TaskInterface + */ + protected function createTaskMock(string $taskId): TaskInterface + { + $task = $this->createMock(TaskInterface::class); + $task->method('getId')->willReturn($taskId); + + return $task; + } +} diff --git a/tests/Sdk/Unit/Infrastructure/Violation/Formatter/OutputViolationReportFormatterTest.php b/tests/Sdk/Unit/Infrastructure/Violation/Formatter/OutputViolationReportFormatterTest.php new file mode 100644 index 000000000..5f7540068 --- /dev/null +++ b/tests/Sdk/Unit/Infrastructure/Violation/Formatter/OutputViolationReportFormatterTest.php @@ -0,0 +1,94 @@ +violationReportDecorator = $this->createMock(ViolationReportDecorator::class); + $this->output = $this->createMock(OutputInterface::class); + $outputFormatter = $this->createMock(OutputFormatterInterface::class); + $outputFormatter + ->method('isDecorated') + ->willReturn(false); + $this->output + ->method('getFormatter') + ->willReturn($outputFormatter); + } + + /** + * @return void + */ + public function testFormat(): void + { + // Arrange + $violationReportMock = $this->createMock(ViolationReportInterface::class); + + $this->violationReportDecorator + ->expects($this->once()) + ->method('decorate') + ->willReturn($violationReportMock); + + $this->output + ->expects($this->never()) + ->method('writeln'); + + $yamlViolationReportFormatter = new OutputViolationReportFormatter($this->violationReportDecorator); + $yamlViolationReportFormatter->setOutput($this->output); + + // Act + $yamlViolationReportFormatter->format('name', $violationReportMock); + } + + /** + * @return void + */ + public function testRead(): void + { + // Arrange + $yamlViolationReportFormatter = new OutputViolationReportFormatter($this->violationReportDecorator); + + // Act + $violationReport = $yamlViolationReportFormatter->read('name'); + + // Assert + $this->assertNull($violationReport); + } +} diff --git a/tests/Sdk/Unit/Infrastructure/Violation/Formatter/ViolationReportDecoratorTest.php b/tests/Sdk/Unit/Infrastructure/Violation/Formatter/ViolationReportDecoratorTest.php new file mode 100644 index 000000000..2eda0a7b1 --- /dev/null +++ b/tests/Sdk/Unit/Infrastructure/Violation/Formatter/ViolationReportDecoratorTest.php @@ -0,0 +1,59 @@ +outputViolationDecorator = $this->createMock(OutputViolationDecoratorInterface::class); + } + + /** + * @return void + */ + public function testDecorate(): void + { + // Arrange + $violationReportMock = $this->createMock(ViolationReportInterface::class); + + $this->outputViolationDecorator + ->expects($this->never()) + ->method('decorate') + ->willReturnArgument(0); + + $yamlViolationReportFormatter = new ViolationReportDecorator([$this->outputViolationDecorator]); + + // Act + $yamlViolationReportFormatter->decorate($violationReportMock); + } +} diff --git a/tests/Sdk/Unit/Infrastructure/Violation/Formatter/YamlViolationReportFormatterTest.php b/tests/Sdk/Unit/Infrastructure/Violation/Formatter/YamlViolationReportFormatterTest.php new file mode 100644 index 000000000..3d5d48297 --- /dev/null +++ b/tests/Sdk/Unit/Infrastructure/Violation/Formatter/YamlViolationReportFormatterTest.php @@ -0,0 +1,145 @@ +violationReportFileMapper = $this->createMock(ViolationReportFileMapperInterface::class); + $this->violationPathReader = $this->createMock(ViolationPathReader::class); + $this->yamlParser = new Yaml(); + $this->violationReportDecorator = $this->createMock(ViolationReportDecorator::class); + + $this->vfsStream = vfsStream::setup(); + } + + /** + * @return void + */ + public function testRead(): void + { + // Arrange + $vfsFile = new vfsStreamFile('test.yaml'); + $vfsFile->setContent('project: test'); + + $this->vfsStream->addChild($vfsFile); + + $this->violationPathReader + ->method('getViolationReportPath') + ->with('name') + ->willReturn($vfsFile->url()); + + $violationReportMock = $this->createMock(ViolationReportInterface::class); + $this->violationReportFileMapper + ->method('mapFileStructureToViolationReport') + ->willReturn($violationReportMock); + + $yamlViolationReportFormatter = new YamlViolationReportFormatter( + $this->violationReportFileMapper, + $this->violationPathReader, + $this->yamlParser, + $this->violationReportDecorator, + ); + + // Act + $violationReport = $yamlViolationReportFormatter->read('name'); + + // Assert + $this->assertSame($violationReportMock, $violationReport); + } + + /** + * @return void + */ + public function testFormat(): void + { + // Arrange + $vfsFile = new vfsStreamFile('test.yaml'); + + $vfsDir = new vfsStreamDirectory('report'); + $vfsDir->addChild($vfsFile); + + $this->vfsStream->addChild($vfsDir); + + $this->violationPathReader + ->method('getViolationReportDirPath') + ->willReturn('report'); + $this->violationPathReader->method('getViolationReportPath') + ->with('test') + ->willReturn($vfsFile->url()); + $this->violationReportFileMapper + ->method('mapViolationReportToYamlStructure') + ->willReturn(['project' => 'test']); + + $violationReportMock = $this->createMock(ViolationReportInterface::class); + + $yamlViolationReportFormatter = new YamlViolationReportFormatter( + $this->violationReportFileMapper, + $this->violationPathReader, + $this->yamlParser, + $this->violationReportDecorator, + ); + + // Act + $yamlViolationReportFormatter->format('test', $violationReportMock); + + // Assert + $this->assertSame("project: test\n", $vfsFile->getContent()); + } +} diff --git a/tests/Sdk/Unit/Presentation/Console/Command/TaskLoader/TaskHelpMessageDecoratorTest.php b/tests/Sdk/Unit/Presentation/Console/Command/TaskLoader/TaskHelpMessageDecoratorTest.php new file mode 100644 index 000000000..5abe6b516 --- /dev/null +++ b/tests/Sdk/Unit/Presentation/Console/Command/TaskLoader/TaskHelpMessageDecoratorTest.php @@ -0,0 +1,125 @@ +createTaskMock('test:task'); + $relationRepositoryMock = $this->createTaskSetTaskRelationRepositoryMock('test:task', []); + $taskHelpMessageDecorator = new TaskHelpMessageDecorator($relationRepositoryMock); + + // Act + $helpMessage = $taskHelpMessageDecorator->decorateHelpMessage($taskMock); + + // Assert + $this->assertSame('', $helpMessage); + } + + /** + * @return void + */ + public function testDecorateHelpMessageShouldReturnTaskHelpWhenTaskHasNoRelations(): void + { + // Arrange + $taskMock = $this->createTaskMock('test:task', 'some help message'); + $relationRepositoryMock = $this->createTaskSetTaskRelationRepositoryMock('test:task', []); + $taskHelpMessageDecorator = new TaskHelpMessageDecorator($relationRepositoryMock); + + // Act + $helpMessage = $taskHelpMessageDecorator->decorateHelpMessage($taskMock); + + // Assert + $this->assertSame('some help message', $helpMessage); + } + + /** + * @return void + */ + public function testDecorateHelpMessageShouldReturnHelpMessageWithSubTaskRelations(): void + { + // Arrange + $taskMock = $this->createTaskMock('test:task', 'some help message'); + $taskRelations = [ + new TaskSetTaskRelation( + $this->createTaskMock('test:task'), + $this->createTaskMock('test:sub-task', 'sub-task help'), + ), + ]; + $relationRepositoryMock = $this->createTaskSetTaskRelationRepositoryMock('test:task', $taskRelations); + $taskHelpMessageDecorator = new TaskHelpMessageDecorator($relationRepositoryMock); + + // Act + $helpMessage = $taskHelpMessageDecorator->decorateHelpMessage($taskMock); + + // Assert + $message = <<Task set sub-tasks: + - test:sub-task sub-task help + HELP; + + $this->assertSame($message, $helpMessage); + } + + /** + * @param string $taskId + * @param string|null $helpMessage + * + * @return \SprykerSdk\SdkContracts\Entity\TaskInterface + */ + protected function createTaskMock(string $taskId, ?string $helpMessage = null): TaskInterface + { + $task = $this->createMock(TaskInterface::class); + $task->method('getId')->willReturn($taskId); + $task->method('getHelp')->willReturn($helpMessage); + + return $task; + } + + /** + * @param string $taskId + * @param array<\SprykerSdk\Sdk\Core\Domain\Entity\TaskSetTaskRelationInterface> $relations + * + * @return \SprykerSdk\Sdk\Core\Application\Dependency\Repository\TaskSetTaskRelationRepositoryInterface + */ + protected function createTaskSetTaskRelationRepositoryMock( + string $taskId, + array $relations + ): TaskSetTaskRelationRepositoryInterface { + $taskSetTaskRelationRepository = $this->createMock(TaskSetTaskRelationRepositoryInterface::class); + + $taskSetTaskRelationRepository->method('getByTaskSetId') + ->with($this->equalTo($taskId)) + ->willReturn($relations); + + return $taskSetTaskRelationRepository; + } +} diff --git a/tests/Sdk/Unit/Presentation/Console/DependencyInjection/DynamicConsoleCommandsCompilerPassTest.php b/tests/Sdk/Unit/Presentation/Console/DependencyInjection/DynamicConsoleCommandsCompilerPassTest.php index c23223a69..a87ab31c3 100644 --- a/tests/Sdk/Unit/Presentation/Console/DependencyInjection/DynamicConsoleCommandsCompilerPassTest.php +++ b/tests/Sdk/Unit/Presentation/Console/DependencyInjection/DynamicConsoleCommandsCompilerPassTest.php @@ -8,7 +8,7 @@ namespace SprykerSdk\Sdk\Unit\Presentation\Console\DependencyInjection; use Codeception\Test\Unit; -use SprykerSdk\Sdk\Presentation\Console\Command\TaskRunFactoryLoader; +use SprykerSdk\Sdk\Presentation\Console\Command\TaskLoader\TaskRunFactoryLoader; use SprykerSdk\Sdk\Presentation\Console\DependencyInjection\DynamicConsoleCommandsCompilerPass; use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\DependencyInjection\Definition; diff --git a/tests/Sdk/Unit/Presentation/Ide/PhpStorm/Service/CommandLoaderTest.php b/tests/Sdk/Unit/Presentation/Ide/PhpStorm/Service/CommandLoaderTest.php index d191085d5..6d61b3adf 100644 --- a/tests/Sdk/Unit/Presentation/Ide/PhpStorm/Service/CommandLoaderTest.php +++ b/tests/Sdk/Unit/Presentation/Ide/PhpStorm/Service/CommandLoaderTest.php @@ -9,7 +9,7 @@ use Codeception\Test\Unit; use SprykerSdk\Sdk\Core\Application\Dependency\Repository\TaskRepositoryInterface; -use SprykerSdk\Sdk\Presentation\Console\Command\TaskRunFactoryLoader; +use SprykerSdk\Sdk\Presentation\Console\Command\TaskLoader\TaskRunFactoryLoader; use SprykerSdk\Sdk\Presentation\Ide\PhpStorm\Service\CommandLoader; use SprykerSdk\Sdk\Tests\UnitTester; @@ -28,7 +28,7 @@ class CommandLoaderTest extends Unit { /** - * @var \SprykerSdk\Sdk\Presentation\Console\Command\TaskRunFactoryLoader + * @var \SprykerSdk\Sdk\Presentation\Console\Command\TaskLoader\TaskRunFactoryLoader */ protected TaskRunFactoryLoader $commandContainer; diff --git a/tests/Sdk/Unit/Presentation/RestApi/Validator/Json/JsonSchemaValidatorTest.php b/tests/Sdk/Unit/Presentation/RestApi/Validator/Json/JsonSchemaValidatorTest.php new file mode 100644 index 000000000..a2262cc28 --- /dev/null +++ b/tests/Sdk/Unit/Presentation/RestApi/Validator/Json/JsonSchemaValidatorTest.php @@ -0,0 +1,110 @@ +validator = $this->createMock(Validator::class); + $this->jsonSchemaValidator = new JsonSchemaValidator($this->validator); + } + + /** + * @return void + */ + public function testValidateWithValidBodyShouldNotThrowException(): void + { + // Arrange + $this->validator + ->expects($this->once()) + ->method('validate'); + + $this->validator + ->expects($this->once()) + ->method('getErrors') + ->willReturn([]); + + $jsonBody = json_encode([ + 'id' => 'test', + 'type' => 'test', + 'attributes' => [ + 'task' => 'hello', + ], + ]); + + $request = new Request([], [], [], [], [], [], $jsonBody); + + // Act + $this->jsonSchemaValidator->validate($request); + } + + /** + * @return void + */ + public function testValidateWithInvalidBodyShouldThrowException(): void + { + // Arrange + $expectedMessage = 'Property "attributes" is required.'; + $this->validator + ->expects($this->once()) + ->method('validate'); + + $this->validator + ->expects($this->once()) + ->method('getErrors') + ->willReturn([ + [ + 'message' => $expectedMessage, + ], + ]); + + $jsonBody = json_encode([ + 'id' => 'test', + 'type' => 'test', + ]); + + $request = new Request([], [], [], [], [], [], $jsonBody); + + $this->expectException(InvalidJsonSchemaException::class); + $this->expectExceptionMessage($expectedMessage); + + // Act + $this->jsonSchemaValidator->validate($request); + } +} diff --git a/tests/_support/AcceptanceTester.php b/tests/_support/AcceptanceTester.php index 314cb8ea1..d577ca994 100644 --- a/tests/_support/AcceptanceTester.php +++ b/tests/_support/AcceptanceTester.php @@ -8,6 +8,7 @@ namespace SprykerSdk\Sdk\Tests; use Codeception\Actor; +use PDO; use SprykerSdk\SdkContracts\Enum\Task; use Symfony\Component\Process\Process; @@ -95,6 +96,20 @@ public function cleanReports(string $project = 'project'): void $this->cleanDir($this->getPathFromProjectRoot('.ssdk/reports', $project)); } + /** + * @return void + */ + public function cleanTelemetryEventsTable(): void + { + $dbPath = $this->getPathFromSdkRoot('db/data.db'); + + $pdo = new PDO(sprintf('sqlite:%s', $dbPath), null, null, [ + PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, + ]); + + $pdo->exec('DELETE FROM sdk_telemetry_event'); + } + /** * @param string $project * diff --git a/tests/_support/Helper/Presentation/RestApi/RestApiHelper.php b/tests/_support/Helper/Presentation/RestApi/RestApiHelper.php new file mode 100644 index 000000000..94e1e15e7 --- /dev/null +++ b/tests/_support/Helper/Presentation/RestApi/RestApiHelper.php @@ -0,0 +1,53 @@ + + */ + public function createSuccessJsonStruct(string $type, string $id, array $attributes = []): array + { + $data = [ + OpenApiField::DATA => [ + OpenApiField::TYPE => $type, + OpenApiField::ID => $id, + ], + ]; + + if (count($attributes)) { + $data[OpenApiField::DATA][OpenApiField::ATTRIBUTES] = $attributes; + } + + return $data; + } + + /** + * @param array $details + * @param int $code + * @param string $status + * + * @return array + */ + public function createErrorJsonStruct(array $details, int $code, string $status): array + { + return [ + OpenApiField::DETAILS => $details, + OpenApiField::CODE => $code, + OpenApiField::STATUS => $status, + ]; + } +} diff --git a/tests/_support/Helper/RestApiHelper.php b/tests/_support/Helper/RestApiHelper.php new file mode 100644 index 000000000..95d49f0b7 --- /dev/null +++ b/tests/_support/Helper/RestApiHelper.php @@ -0,0 +1,83 @@ +haveHttpHeader('Content-Type', 'application/json'); + $this->sendPost($endpoint, [ + OpenApiField::DATA => [ + OpenApiField::ID => $id, + OpenApiField::TYPE => $type, + OpenApiField::ATTRIBUTES => $attributes, + ], + ]); + } + + /** + * @part json + * @part xml + * + * @param string $responseCode + * @param string $id + * @param string $type + * @param array $attributes + * + * @return void + */ + public function seeSuccessApiResponse(string $responseCode, string $id, string $type, array $attributes = []): void + { + $this->seeResponseCodeIs($responseCode); + + $this->seeResponseContainsJson([ + OpenApiField::DATA => [ + OpenApiField::ID => $id, + OpenApiField::TYPE => $type, + OpenApiField::ATTRIBUTES => $attributes, + ], + ]); + } + + /** + * @part json + * @part xml + * + * @param string $responseCode + * @param array $details + * @param int $code + * @param string $status + * + * @return void + */ + public function seeErrorApiResponse(string $responseCode, array $details, int $code, string $status): void + { + $this->seeResponseCodeIs($responseCode); + + $this->seeResponseContainsJson([ + OpenApiField::DETAILS => $details, + OpenApiField::CODE => $code, + OpenApiField::STATUS => $status, + ]); + } +}