From b0d5e2d90d53f5fd8375c321caff0426992eecb1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?D=C3=A1vid=20Andor?= Date: Thu, 14 Jan 2021 23:33:44 +0100 Subject: [PATCH] Basic implementation --- .circleci/config.yml | 128 + .editorconfig | 12 + .git-hooks | 31 + .gitignore | 18 + README.md | 271 +- RoboFile.php | 499 ++ codeception.dist.yml | 27 + composer.json | 62 + composer.lock | 5997 +++++++++++++++++ phpcs.xml.dist | 25 + src/Composer/Command/CommandBase.php | 86 + src/Composer/Command/GenerateCommand.php | 80 + src/Composer/CommandProvider.php | 21 + src/Composer/Plugin.php | 141 + src/NestedArray.php | 421 ++ src/SuiteHandler.php | 273 + tests/_support/Helper/Unit.php | 11 + tests/_support/UnitTester.php | 92 + tests/unit.suite.dist.yml | 7 + .../unit/Composer/Command/CommandTestBase.php | 11 + .../Composer/Command/GenerateCommandTest.php | 76 + tests/unit/SuiteHandlerTest.php | 229 + tests/unit/TestBase.php | 44 + tests/xdebug_set_filter.php | 13 + 24 files changed, 8574 insertions(+), 1 deletion(-) create mode 100644 .circleci/config.yml create mode 100644 .editorconfig create mode 100644 .git-hooks create mode 100644 .gitignore create mode 100644 RoboFile.php create mode 100644 codeception.dist.yml create mode 100644 composer.json create mode 100644 composer.lock create mode 100644 phpcs.xml.dist create mode 100644 src/Composer/Command/CommandBase.php create mode 100644 src/Composer/Command/GenerateCommand.php create mode 100644 src/Composer/CommandProvider.php create mode 100644 src/Composer/Plugin.php create mode 100644 src/NestedArray.php create mode 100644 src/SuiteHandler.php create mode 100644 tests/_support/Helper/Unit.php create mode 100644 tests/_support/UnitTester.php create mode 100644 tests/unit.suite.dist.yml create mode 100644 tests/unit/Composer/Command/CommandTestBase.php create mode 100644 tests/unit/Composer/Command/GenerateCommandTest.php create mode 100644 tests/unit/SuiteHandlerTest.php create mode 100644 tests/unit/TestBase.php create mode 100644 tests/xdebug_set_filter.php diff --git a/.circleci/config.yml b/.circleci/config.yml new file mode 100644 index 0000000..57e4fb7 --- /dev/null +++ b/.circleci/config.yml @@ -0,0 +1,128 @@ + +version: 2.1 + +.env_app: &env_app + APP_COMPOSER_VERSION: '2.0.1' + APP_COMPOSER_HASH: 'c31c1e292ad7be5f49291169c0ac8f683499edddcfd4e42232982d0fd193004208a58ff6f353fde0012d35fdd72bc394' + SHELL: '/bin/bash' + +.env_composer: &env_composer + COMPOSER_NO_INTERACTION: '1' + COMPOSER_MEMORY_LIMIT: '-1' + COMPOSER_DISABLE_XDEBUG_WARN: '1' + +orbs: + codecov: 'codecov/codecov@1.0.5' + +executors: + php704: + environment: + <<: *env_app + <<: *env_composer + + docker: + - + name: 'main' + image: 'circleci/php:7.4' + +commands: + install_composer: + description: 'Install Composer CLI tool' + steps: + - + run: + name: '' + command: |4 + mkdir -p "${HOME}/.local/bin" + php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');" + php -r "if (hash_file('sha384', 'composer-setup.php') === getenv('APP_COMPOSER_HASH')) { echo 'Installer verified'; } else { echo 'Installer corrupt'; unlink('composer-setup.php'); } echo PHP_EOL;" + php composer-setup.php \ + --filename 'composer' \ + --install-dir "${HOME}/.local/bin" \ + --version "${APP_COMPOSER_VERSION}" + php -r "unlink('composer-setup.php');" + whereis composer + which composer + type composer + composer --version + + composer_install: + description: 'Install Composer dependencies with cache restore and save' + steps: + - + restore_cache: + name: 'Composer - cache restore' + keys: + - 'composer-{{ checksum "./composer.lock" }}-2' + + - + run: + name: 'Composer - install' + command: > + composer install --no-progress --ansi + + - + save_cache: + name: 'Composer - cache save' + key: 'composer-{{ checksum "./composer.lock" }}-2' + paths: + - '~/.composer/cache/' + + + lint: + description: 'Run linters' + steps: + - + run: + name: 'Run linters' + command: 'bin/robo --ansi lint' + + test: + description: 'Run tests' + steps: + - + run: + name: 'Codeception - unit' + command: 'bin/robo --ansi test unit' + - codecov/upload: + flags: 'unit' + file: './tests/_output/machine/coverage/unit/coverage.xml' + - store_test_results: + name: 'Store unit test results' + path: './tests/_output/machine/junit' + +jobs: + build: + executor: 'php704' + working_directory: '~/repo' + steps: + - 'checkout' + - 'composer_install' + lint: + executor: 'php704' + working_directory: '~/repo' + steps: + - 'checkout' + - 'composer_install' + - 'lint' + test_php704: + executor: 'php704' + working_directory: '~/repo' + steps: + - 'checkout' + - 'composer_install' + - 'test' + +workflows: + lint_and_test: + jobs: + - + build: {} + - + lint: + requires: + - build + - + test_php704: + requires: + - build diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..178edda --- /dev/null +++ b/.editorconfig @@ -0,0 +1,12 @@ +root = true + +[*] +end_of_line = LF +indent_style = space +indent_size = 4 +charset = utf-8 +trim_trailing_whitespace = true +insert_final_newline = true + +[*.md] +trim_trailing_whitespace = false diff --git a/.git-hooks b/.git-hooks new file mode 100644 index 0000000..0571f92 --- /dev/null +++ b/.git-hooks @@ -0,0 +1,31 @@ +#!/usr/bin/env bash + +echo "BEGIN Git hook: ${sghHookName}" + +function sghExit () +{ + echo "END Git hook: ${sghHookName}" + + exit $1 +} + +export COMPOSER_DISABLE_XDEBUG_WARN=1 + +# @todo Better detection for executables: php, composer.phar. +sghRobo="$(composer config 'bin-dir')/robo" + +test -s "${sghBridge}-local" && . "${sghBridge}-local" + +sghTask="githook:${sghHookName}" + +# Exit without error if "robo" doesn't exists or it has no corresponding task. +test -x "$sghRobo" || sghExit 0 +"${sghRobo}" help "${sghTask}" 1> /dev/null 2>&1 || sghExit 0 + +if [ "$sghHasInput" = 'true' ]; then + "$sghRobo" "${sghTask}" $@ <<< $(` keys. + +An action has two main properties: +* type (string) Identifier if the action. +* config (mixed) The data type is usually array, but it depends on the `type`. + + +### Action - replaceRecursive + +Official PHP documentation: +[array_replace_recursive()](https://php.net/manual/en/function.array-replace-recursive.php) + +* parents: array +* items: array + +```json +{ + "require": { + "a/b": "^1.0", + "symfony/console": "^4.0", + "symfony/process": "^4.0" + }, + "extra": { + "composer-suite": { + "my-suite-01": [ + { + "type": " replaceRecursive", + "config": { + "parents": [], + "items": { + "require": { + "symfony/console": "^5.0", + "symfony/process": "^5.0" + } + } + } + } + ] + } + } +} +``` + +Result: +```json +{ + "require": { + "a/b": "^1.0", + "symfony/console": "^5.0", + "symfony/process": "^5.0" + }, + "extra": {} +} +``` + + +### Action - unset + +Removes the specified elements. + +* parents: array + +```json +{ + "name": "a/b", + "foo": { + "bar": "delete me" + }, + "extra": { + "sweetchuck/composer-suite": { + "my-suite-01": [ + { + "type": "unset", + "config": { + "parents": [ + "foo", + "bar" + ] + } + } + ] + } + } +} +``` + +Result: +```json +{ + "name": "a/b", + "foo": {}, + "extra": {} +} +``` + +In the "config.parents" array the last item can be an array: +```json +{ + "name": "a/b", + "foo": { + "a": "delete me 1", + "b": "keep me", + "c": "delete me 2" + }, + "extra": { + "sweetchuck/composer-suite": { + "my-suite-01": [ + { + "type": "unset", + "config": { + "parents": [ + "foo", + ["a", "c"] + ] + } + } + ] + } + } +} +``` + +Result: +```json +{ + "name": "a/b", + "foo": { + "b": "keep me" + }, + "extra": {} +} +``` + + +### Action - preprend + +Adds new elements at the beginning of an array. + +* parents: array +* items: array + + +### Action - append + +Adds new elements at the end of an array. + +* parents: array +* items: array + + +### Action - insertBefore + +Insert one or more "items". The last item in the "parents" is the reference +point. + +* parents: array +* items: array + + +### Action - insertAfter + +Insert one or more "items". The last item in the "parents" is the reference +point. + +* parents: array +* items: array + + +## Commands + +This Composer plugin defines only one command. Which is +`composer suite:generate` + + +## Validate + +You can check the status of the autogenerated files by running the following +command: +`composer validate` +If one of the autogenerated file is out-of-date, then the exit code will be +other than `0`. + +## Links + +1. [Environment variables - COMPOSER](https://getcomposer.org/doc/03-cli.md#composer) diff --git a/RoboFile.php b/RoboFile.php new file mode 100644 index 0000000..1b424be --- /dev/null +++ b/RoboFile.php @@ -0,0 +1,499 @@ +initComposerInfo() + ->initEnvVarNamePrefix() + ->initEnvironmentTypeAndName(); + } + + /** + * {@inheritdoc} + */ + public function setContainer(ContainerInterface $container) + { + BaseReporter::lintReportConfigureContainer($container); + + return parent::setContainer($container); + } + + /** + * Git "pre-commit" hook callback. + */ + public function githookPreCommit(): CollectionBuilder + { + $this->gitHook = 'pre-commit'; + + return $this + ->collectionBuilder() + ->addTask($this->taskComposerValidate()) + ->addTask($this->getTaskPhpcsLint()) + ->addTask($this->getTaskCodeceptRunSuites()); + } + + /** + * Run the Robo unit tests. + */ + public function test(array $suiteNames): CollectionBuilder + { + $this->validateArgCodeceptionSuiteNames($suiteNames); + + return $this->getTaskCodeceptRunSuites($suiteNames); + } + + /** + * Run code style checkers. + */ + public function lint(): CollectionBuilder + { + return $this + ->collectionBuilder() + ->addTask($this->taskComposerValidate()) + ->addTask($this->getTaskPhpcsLint()); + } + + protected function errorOutput(): ?OutputInterface + { + $output = $this->output(); + + return ($output instanceof ConsoleOutputInterface) ? $output->getErrorOutput() : $output; + } + + /** + * @return $this + */ + protected function initEnvVarNamePrefix() + { + $this->envVarNamePrefix = strtoupper(str_replace('-', '_', $this->packageName)); + + return $this; + } + + /** + * @return $this + */ + protected function initEnvironmentTypeAndName() + { + $this->environmentType = getenv($this->getEnvVarName('environment_type')); + $this->environmentName = getenv($this->getEnvVarName('environment_name')); + + if (!$this->environmentType) { + if (getenv('CI') === 'true') { + // CircleCI, Travis and GitLab. + $this->environmentType = 'ci'; + } elseif (getenv('JENKINS_HOME')) { + $this->environmentType = 'ci'; + if (!$this->environmentName) { + $this->environmentName = 'jenkins'; + } + } + } + + if (!$this->environmentName && $this->environmentType === 'ci') { + if (getenv('GITLAB_CI') === 'true') { + $this->environmentName = 'gitlab'; + } elseif (getenv('TRAVIS') === 'true') { + $this->environmentName = 'travis'; + } elseif (getenv('CIRCLECI') === 'true') { + $this->environmentName = 'circle'; + } + } + + if (!$this->environmentType) { + $this->environmentType = 'dev'; + } + + if (!$this->environmentName) { + $this->environmentName = 'local'; + } + + return $this; + } + + protected function getEnvVarName(string $name): string + { + return "{$this->envVarNamePrefix}_" . strtoupper($name); + } + + protected function getPhpExecutable(): string + { + return getenv($this->getEnvVarName('php_executable')) ?: PHP_BINARY; + } + + protected function getPhpdbgExecutable(): string + { + return getenv($this->getEnvVarName('phpdbg_executable')) ?: Path::join(PHP_BINDIR, 'phpdbg'); + } + + /** + * @return $this + */ + protected function initComposerInfo() + { + if ($this->composerInfo) { + return $this; + } + + $composerFile = getenv('COMPOSER') ?: 'composer.json'; + $composerContent = file_get_contents($composerFile); + if ($composerContent === false) { + return $this; + } + + $this->composerInfo = json_decode($composerContent, true); + [$this->packageVendor, $this->packageName] = explode('/', $this->composerInfo['name']); + + if (!empty($this->composerInfo['config']['bin-dir'])) { + $this->binDir = $this->composerInfo['config']['bin-dir']; + } + + return $this; + } + + /** + * @return $this + */ + protected function initCodeceptionInfo() + { + if ($this->codeceptionInfo) { + return $this; + } + + $default = [ + 'paths' => [ + 'tests' => 'tests', + 'output' => 'tests/_output', + ], + ]; + $dist = []; + $local = []; + + if (is_readable('codeception.dist.yml')) { + $dist = Yaml::parse(file_get_contents('codeception.dist.yml')); + } + + if (is_readable('codeception.yml')) { + $local = Yaml::parse(file_get_contents('codeception.yml')); + } + + $this->codeceptionInfo = array_replace_recursive($default, $dist, $local); + + return $this; + } + + protected function getTaskCodeceptRunSuites(array $suiteNames = []): CollectionBuilder + { + if (!$suiteNames) { + $suiteNames = ['all']; + } + + $cb = $this->collectionBuilder(); + foreach ($suiteNames as $suiteName) { + $cb->addTask($this->getTaskCodeceptRunSuite($suiteName)); + } + + return $cb; + } + + protected function getTaskCodeceptRunSuite(string $suite): CollectionBuilder + { + $this->initCodeceptionInfo(); + + $withCoverageHtml = in_array($this->environmentType, ['dev']); + $withCoverageXml = in_array($this->environmentType, ['ci']); + + $withUnitReportHtml = in_array($this->environmentType, ['dev']); + $withUnitReportXml = in_array($this->environmentType, ['ci']); + + $logDir = $this->getLogDir(); + + $cmdArgs = []; + if ($this->isPhpDbgAvailable()) { + $cmdPattern = '%s -qrr'; + $cmdArgs[] = escapeshellcmd($this->getPhpdbgExecutable()); + } else { + $cmdPattern = '%s'; + $cmdArgs[] = escapeshellcmd($this->getPhpExecutable()); + } + + $cmdPattern .= ' %s'; + $cmdArgs[] = escapeshellcmd("{$this->binDir}/codecept"); + + $cmdPattern .= ' --ansi'; + $cmdPattern .= ' --verbose'; + $cmdPattern .= ' --debug'; + + $cb = $this->collectionBuilder(); + if ($withCoverageHtml) { + $cmdPattern .= ' --coverage-html=%s'; + $cmdArgs[] = escapeshellarg("human/coverage/$suite/html"); + + $cb->addTask( + $this + ->taskFilesystemStack() + ->mkdir("$logDir/human/coverage/$suite") + ); + } + + if ($withCoverageXml) { + $cmdPattern .= ' --coverage-xml=%s'; + $cmdArgs[] = escapeshellarg("machine/coverage/$suite/coverage.xml"); + } + + if ($withCoverageHtml || $withCoverageXml) { + $cmdPattern .= ' --coverage=%s'; + $cmdArgs[] = escapeshellarg("machine/coverage/$suite/coverage.serialized"); + + $cb->addTask( + $this + ->taskFilesystemStack() + ->mkdir("$logDir/machine/coverage/$suite") + ); + } + + if ($withUnitReportHtml) { + $cmdPattern .= ' --html=%s'; + $cmdArgs[] = escapeshellarg("human/junit/junit.$suite.html"); + + $cb->addTask( + $this + ->taskFilesystemStack() + ->mkdir("$logDir/human/junit") + ); + } + + if ($withUnitReportXml) { + $cmdPattern .= ' --xml=%s'; + $cmdArgs[] = escapeshellarg("machine/junit/junit.$suite.xml"); + + $cb->addTask( + $this + ->taskFilesystemStack() + ->mkdir("$logDir/machine/junit") + ); + } + + $cmdPattern .= ' run'; + if ($suite !== 'all') { + $cmdPattern .= ' %s'; + $cmdArgs[] = escapeshellarg($suite); + } + + $envDir = $this->codeceptionInfo['paths']['envs']; + $envFileName = "{$this->environmentType}.{$this->environmentName}"; + if (file_exists("$envDir/$envFileName.yml")) { + $cmdPattern .= ' --env %s'; + $cmdArgs[] = escapeshellarg($envFileName); + } + + if ($this->environmentType === 'ci' && $this->environmentName === 'jenkins') { + // Jenkins has to use a post-build action to mark the build "unstable". + $cmdPattern .= ' || [[ "${?}" == "1" ]]'; + } + + $command = vsprintf($cmdPattern, $cmdArgs); + + return $cb + ->addCode(function () use ($command) { + $this->output()->writeln(strtr( + '[{name}] runs {command}', + [ + '{name}' => 'Codeception', + '{command}' => $command, + ] + )); + $process = Process::fromShellCommandline($command, null, null, null, null); + return $process->run(function ($type, $data) { + switch ($type) { + case Process::OUT: + $this->output()->write($data); + break; + + case Process::ERR: + $this->errorOutput()->write($data); + break; + } + }); + }); + } + + /** + * @return \Sweetchuck\Robo\Phpcs\Task\PhpcsLintFiles|\Robo\Collection\CollectionBuilder + */ + protected function getTaskPhpcsLint() + { + $options = [ + 'failOn' => 'warning', + 'lintReporters' => [ + 'lintVerboseReporter' => null, + ], + ]; + + if ($this->environmentType === 'ci' && $this->environmentName === 'jenkins') { + $options['failOn'] = 'never'; + $options['lintReporters']['lintCheckstyleReporter'] = $this + ->getContainer() + ->get('lintCheckstyleReporter') + ->setDestination('tests/_output/machine/checkstyle/phpcs.psr2.xml'); + } + + if ($this->gitHook === 'pre-commit') { + return $this + ->collectionBuilder() + ->addTask($this + ->taskPhpcsParseXml() + ->setAssetNamePrefix('phpcsXml.')) + ->addTask($this + ->taskGitListStagedFiles() + ->setPaths(['*.php' => true]) + ->setDiffFilter(['d' => false]) + ->setAssetNamePrefix('staged.')) + ->addTask($this + ->taskGitReadStagedFiles() + ->setCommandOnly(true) + ->setWorkingDirectory('.') + ->deferTaskConfiguration('setPaths', 'staged.fileNames')) + ->addTask($this + ->taskPhpcsLintInput($options) + ->deferTaskConfiguration('setFiles', 'files') + ->deferTaskConfiguration('setIgnore', 'phpcsXml.exclude-patterns')); + } + + return $this->taskPhpcsLintFiles($options); + } + + protected function isPhpDbgAvailable(): bool + { + $command = [$this->getPhpdbgExecutable(), '-qrr']; + + return (new Process($command))->run() === 0; + } + + protected function getLogDir(): string + { + $this->initCodeceptionInfo(); + + return !empty($this->codeceptionInfo['paths']['output']) ? + $this->codeceptionInfo['paths']['output'] + : 'tests/_output'; + } + + protected function getCodeceptionSuiteNames(): array + { + if (!$this->codeceptionSuiteNames) { + $this->initCodeceptionInfo(); + + /** @var \Symfony\Component\Finder\Finder $suiteFiles */ + $suiteFiles = Finder::create() + ->in($this->codeceptionInfo['paths']['tests']) + ->files() + ->name('*.suite.yml') + ->name('*.suite.dist.yml') + ->depth(0); + + foreach ($suiteFiles as $suiteFile) { + $parts = explode('.', $suiteFile->getBasename()); + $this->codeceptionSuiteNames[] = reset($parts); + } + + $this->codeceptionSuiteNames = array_unique($this->codeceptionSuiteNames); + } + + return $this->codeceptionSuiteNames; + } + + protected function validateArgCodeceptionSuiteNames(array $suiteNames): void + { + if (!$suiteNames) { + return; + } + + $invalidSuiteNames = array_diff($suiteNames, $this->getCodeceptionSuiteNames()); + if ($invalidSuiteNames) { + throw new InvalidArgumentException( + 'The following Codeception suite names are invalid: ' . implode(', ', $invalidSuiteNames), + 1 + ); + } + } +} diff --git a/codeception.dist.yml b/codeception.dist.yml new file mode 100644 index 0000000..2bca216 --- /dev/null +++ b/codeception.dist.yml @@ -0,0 +1,27 @@ + +namespace: Sweetchuck\ComposerSuite\Test + +paths: + data: tests/_data + envs: tests/_envs + output: tests/_output + support: tests/_support + tests: tests + +settings: + colors: true + memory_limit: '1024M' + shuffle: false + lint: false + +extensions: + enabled: + - 'Codeception\Extension\RunFailed' + +coverage: + enabled: true + show_uncovered: true + low_limit: 60 + high_limit: 90 + include: + - 'src/*' diff --git a/composer.json b/composer.json new file mode 100644 index 0000000..496c37e --- /dev/null +++ b/composer.json @@ -0,0 +1,62 @@ +{ + "type": "composer-plugin", + "name": "sweetchuck/composer-suite", + "description": "@todo project description", + "keywords": [], + "authors": [ + { + "name": "Dávid Andor", + "role": "Maintainer", + "homepage": "https://github.com/Sweetchuck" + } + ], + "homepage": "https://github.com/Sweetchuck/composer-suite", + "support": { + "source": "https://github.com/Sweetchuck/composer-suite", + "issues": "https://github.com/Sweetchuck/composer-suite/issues" + }, + "license": "GPL-3.0-or-later", + "minimum-stability": "dev", + "prefer-stable": true, + "config": { + "bin-dir": "bin", + "preferred-install": "dist", + "optimize-autoloader": true, + "sort-packages": true + }, + "repositories": {}, + "require": { + "php": ">=7.4", + "ext-json": "*", + "composer-plugin-api": "^2.0" + }, + "require-dev": { + "codeception/codeception": "^4.0", + "codeception/module-asserts": "^1.1", + "composer/composer": "^2.0", + "mikey179/vfsstream": "^1.6", + "squizlabs/php_codesniffer": "^3.5", + "sweetchuck/codeception-module-robo-task-runner": "1.x-dev", + "sweetchuck/git-hooks": "2.x-dev", + "sweetchuck/robo-git": "1.x-dev", + "sweetchuck/robo-phpcs": "1.x-dev", + "sweetchuck/robo-phpmd": "1.x-dev", + "symfony/error-handler": "^5.0" + }, + "autoload": { + "psr-4": { + "Sweetchuck\\ComposerSuite\\": "src/" + } + }, + "autoload-dev": { + "psr-4": { + "Sweetchuck\\ComposerSuite\\Test\\": "tests/_support/", + "Sweetchuck\\ComposerSuite\\Tests\\Unit\\": "tests/unit/" + } + }, + "extra": { + "class": "\\Sweetchuck\\ComposerSuite\\Composer\\Plugin" + }, + "scripts": {}, + "scripts-descriptions": {} +} diff --git a/composer.lock b/composer.lock new file mode 100644 index 0000000..0871ff7 --- /dev/null +++ b/composer.lock @@ -0,0 +1,5997 @@ +{ + "_readme": [ + "This file locks the dependencies of your project to a known state", + "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", + "This file is @generated automatically" + ], + "content-hash": "4e322df9558be0982cf80ccd28f10c63", + "packages": [], + "packages-dev": [ + { + "name": "behat/gherkin", + "version": "v4.6.2", + "source": { + "type": "git", + "url": "https://github.com/Behat/Gherkin.git", + "reference": "51ac4500c4dc30cbaaabcd2f25694299df666a31" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Behat/Gherkin/zipball/51ac4500c4dc30cbaaabcd2f25694299df666a31", + "reference": "51ac4500c4dc30cbaaabcd2f25694299df666a31", + "shasum": "" + }, + "require": { + "php": ">=5.3.1" + }, + "require-dev": { + "phpunit/phpunit": "~4.5|~5", + "symfony/phpunit-bridge": "~2.7|~3|~4", + "symfony/yaml": "~2.3|~3|~4" + }, + "suggest": { + "symfony/yaml": "If you want to parse features, represented in YAML files" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.4-dev" + } + }, + "autoload": { + "psr-0": { + "Behat\\Gherkin": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Konstantin Kudryashov", + "email": "ever.zet@gmail.com", + "homepage": "http://everzet.com" + } + ], + "description": "Gherkin DSL parser for PHP 5.3", + "homepage": "http://behat.org/", + "keywords": [ + "BDD", + "Behat", + "Cucumber", + "DSL", + "gherkin", + "parser" + ], + "support": { + "issues": "https://github.com/Behat/Gherkin/issues", + "source": "https://github.com/Behat/Gherkin/tree/master" + }, + "time": "2020-03-17T14:03:26+00:00" + }, + { + "name": "codeception/codeception", + "version": "4.1.14", + "source": { + "type": "git", + "url": "https://github.com/Codeception/Codeception.git", + "reference": "bf2d7861cc6cf4e118a21c6945f482a5c822636c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Codeception/Codeception/zipball/bf2d7861cc6cf4e118a21c6945f482a5c822636c", + "reference": "bf2d7861cc6cf4e118a21c6945f482a5c822636c", + "shasum": "" + }, + "require": { + "behat/gherkin": "^4.4.0", + "codeception/lib-asserts": "^1.0", + "codeception/phpunit-wrapper": ">6.0.15 <6.1.0 | ^6.6.1 | ^7.7.1 | ^8.1.1 | ^9.0", + "codeception/stub": "^2.0 | ^3.0", + "ext-curl": "*", + "ext-json": "*", + "ext-mbstring": "*", + "guzzlehttp/psr7": "~1.4", + "php": ">=5.6.0 <9.0", + "symfony/console": ">=2.7 <6.0", + "symfony/css-selector": ">=2.7 <6.0", + "symfony/event-dispatcher": ">=2.7 <6.0", + "symfony/finder": ">=2.7 <6.0", + "symfony/yaml": ">=2.7 <6.0" + }, + "require-dev": { + "codeception/module-asserts": "*@dev", + "codeception/module-cli": "*@dev", + "codeception/module-db": "*@dev", + "codeception/module-filesystem": "*@dev", + "codeception/module-phpbrowser": "*@dev", + "codeception/specify": "~0.3", + "codeception/util-universalframework": "*@dev", + "monolog/monolog": "~1.8", + "squizlabs/php_codesniffer": "~2.0", + "symfony/process": ">=2.7 <6.0", + "vlucas/phpdotenv": "^2.0 | ^3.0 | ^4.0 | ^5.0" + }, + "suggest": { + "codeception/specify": "BDD-style code blocks", + "codeception/verify": "BDD-style assertions", + "hoa/console": "For interactive console functionality", + "stecman/symfony-console-completion": "For BASH autocompletion", + "symfony/phpunit-bridge": "For phpunit-bridge support" + }, + "bin": [ + "codecept" + ], + "type": "library", + "extra": { + "branch-alias": [] + }, + "autoload": { + "psr-4": { + "Codeception\\": "src/Codeception", + "Codeception\\Extension\\": "ext" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Michael Bodnarchuk", + "email": "davert@mail.ua", + "homepage": "http://codegyre.com" + } + ], + "description": "BDD-style testing framework", + "homepage": "http://codeception.com/", + "keywords": [ + "BDD", + "TDD", + "acceptance testing", + "functional testing", + "unit testing" + ], + "support": { + "issues": "https://github.com/Codeception/Codeception/issues", + "source": "https://github.com/Codeception/Codeception/tree/4.1.14" + }, + "funding": [ + { + "url": "https://opencollective.com/codeception", + "type": "open_collective" + } + ], + "time": "2020-12-28T19:16:28+00:00" + }, + { + "name": "codeception/lib-asserts", + "version": "1.13.2", + "source": { + "type": "git", + "url": "https://github.com/Codeception/lib-asserts.git", + "reference": "184231d5eab66bc69afd6b9429344d80c67a33b6" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Codeception/lib-asserts/zipball/184231d5eab66bc69afd6b9429344d80c67a33b6", + "reference": "184231d5eab66bc69afd6b9429344d80c67a33b6", + "shasum": "" + }, + "require": { + "codeception/phpunit-wrapper": ">6.0.15 <6.1.0 | ^6.6.1 | ^7.7.1 | ^8.0.3 | ^9.0", + "ext-dom": "*", + "php": ">=5.6.0 <9.0" + }, + "type": "library", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Michael Bodnarchuk", + "email": "davert@mail.ua", + "homepage": "http://codegyre.com" + }, + { + "name": "Gintautas Miselis" + }, + { + "name": "Gustavo Nieves", + "homepage": "https://medium.com/@ganieves" + } + ], + "description": "Assertion methods used by Codeception core and Asserts module", + "homepage": "https://codeception.com/", + "keywords": [ + "codeception" + ], + "support": { + "issues": "https://github.com/Codeception/lib-asserts/issues", + "source": "https://github.com/Codeception/lib-asserts/tree/1.13.2" + }, + "time": "2020-10-21T16:26:20+00:00" + }, + { + "name": "codeception/module-asserts", + "version": "1.3.1", + "source": { + "type": "git", + "url": "https://github.com/Codeception/module-asserts.git", + "reference": "59374f2fef0cabb9e8ddb53277e85cdca74328de" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Codeception/module-asserts/zipball/59374f2fef0cabb9e8ddb53277e85cdca74328de", + "reference": "59374f2fef0cabb9e8ddb53277e85cdca74328de", + "shasum": "" + }, + "require": { + "codeception/codeception": "*@dev", + "codeception/lib-asserts": "^1.13.1", + "php": ">=5.6.0 <9.0" + }, + "conflict": { + "codeception/codeception": "<4.0" + }, + "type": "library", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Michael Bodnarchuk" + }, + { + "name": "Gintautas Miselis" + }, + { + "name": "Gustavo Nieves", + "homepage": "https://medium.com/@ganieves" + } + ], + "description": "Codeception module containing various assertions", + "homepage": "https://codeception.com/", + "keywords": [ + "assertions", + "asserts", + "codeception" + ], + "support": { + "issues": "https://github.com/Codeception/module-asserts/issues", + "source": "https://github.com/Codeception/module-asserts/tree/1.3.1" + }, + "time": "2020-10-21T16:48:15+00:00" + }, + { + "name": "codeception/phpunit-wrapper", + "version": "9.0.6", + "source": { + "type": "git", + "url": "https://github.com/Codeception/phpunit-wrapper.git", + "reference": "b0c06abb3181eedca690170f7ed0fd26a70bfacc" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Codeception/phpunit-wrapper/zipball/b0c06abb3181eedca690170f7ed0fd26a70bfacc", + "reference": "b0c06abb3181eedca690170f7ed0fd26a70bfacc", + "shasum": "" + }, + "require": { + "php": ">=7.2", + "phpunit/phpunit": "^9.0" + }, + "require-dev": { + "codeception/specify": "*", + "consolidation/robo": "^3.0.0-alpha3", + "vlucas/phpdotenv": "^3.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Codeception\\PHPUnit\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Davert", + "email": "davert.php@resend.cc" + }, + { + "name": "Naktibalda" + } + ], + "description": "PHPUnit classes used by Codeception", + "support": { + "issues": "https://github.com/Codeception/phpunit-wrapper/issues", + "source": "https://github.com/Codeception/phpunit-wrapper/tree/9.0.6" + }, + "time": "2020-12-28T13:59:47+00:00" + }, + { + "name": "codeception/stub", + "version": "3.7.0", + "source": { + "type": "git", + "url": "https://github.com/Codeception/Stub.git", + "reference": "468dd5fe659f131fc997f5196aad87512f9b1304" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Codeception/Stub/zipball/468dd5fe659f131fc997f5196aad87512f9b1304", + "reference": "468dd5fe659f131fc997f5196aad87512f9b1304", + "shasum": "" + }, + "require": { + "phpunit/phpunit": "^8.4 | ^9.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Codeception\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Flexible Stub wrapper for PHPUnit's Mock Builder", + "support": { + "issues": "https://github.com/Codeception/Stub/issues", + "source": "https://github.com/Codeception/Stub/tree/3.7.0" + }, + "time": "2020-07-03T15:54:43+00:00" + }, + { + "name": "composer/ca-bundle", + "version": "1.2.9", + "source": { + "type": "git", + "url": "https://github.com/composer/ca-bundle.git", + "reference": "78a0e288fdcebf92aa2318a8d3656168da6ac1a5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/composer/ca-bundle/zipball/78a0e288fdcebf92aa2318a8d3656168da6ac1a5", + "reference": "78a0e288fdcebf92aa2318a8d3656168da6ac1a5", + "shasum": "" + }, + "require": { + "ext-openssl": "*", + "ext-pcre": "*", + "php": "^5.3.2 || ^7.0 || ^8.0" + }, + "require-dev": { + "phpstan/phpstan": "^0.12.55", + "psr/log": "^1.0", + "symfony/phpunit-bridge": "^4.2 || ^5", + "symfony/process": "^2.5 || ^3.0 || ^4.0 || ^5.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.x-dev" + } + }, + "autoload": { + "psr-4": { + "Composer\\CaBundle\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be", + "homepage": "http://seld.be" + } + ], + "description": "Lets you find a path to the system CA bundle, and includes a fallback to the Mozilla CA bundle.", + "keywords": [ + "cabundle", + "cacert", + "certificate", + "ssl", + "tls" + ], + "support": { + "irc": "irc://irc.freenode.org/composer", + "issues": "https://github.com/composer/ca-bundle/issues", + "source": "https://github.com/composer/ca-bundle/tree/1.2.9" + }, + "funding": [ + { + "url": "https://packagist.com", + "type": "custom" + }, + { + "url": "https://github.com/composer", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/composer/composer", + "type": "tidelift" + } + ], + "time": "2021-01-12T12:10:35+00:00" + }, + { + "name": "composer/composer", + "version": "2.0.8", + "source": { + "type": "git", + "url": "https://github.com/composer/composer.git", + "reference": "62139b2806178adb979d76bd3437534a1a9fd490" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/composer/composer/zipball/62139b2806178adb979d76bd3437534a1a9fd490", + "reference": "62139b2806178adb979d76bd3437534a1a9fd490", + "shasum": "" + }, + "require": { + "composer/ca-bundle": "^1.0", + "composer/semver": "^3.0", + "composer/spdx-licenses": "^1.2", + "composer/xdebug-handler": "^1.1", + "justinrainbow/json-schema": "^5.2.10", + "php": "^5.3.2 || ^7.0 || ^8.0", + "psr/log": "^1.0", + "react/promise": "^1.2 || ^2.7", + "seld/jsonlint": "^1.4", + "seld/phar-utils": "^1.0", + "symfony/console": "^2.8.52 || ^3.4.35 || ^4.4 || ^5.0", + "symfony/filesystem": "^2.8.52 || ^3.4.35 || ^4.4 || ^5.0", + "symfony/finder": "^2.8.52 || ^3.4.35 || ^4.4 || ^5.0", + "symfony/process": "^2.8.52 || ^3.4.35 || ^4.4 || ^5.0" + }, + "require-dev": { + "phpspec/prophecy": "^1.10", + "symfony/phpunit-bridge": "^4.2 || ^5.0" + }, + "suggest": { + "ext-openssl": "Enabling the openssl extension allows you to access https URLs for repositories and packages", + "ext-zip": "Enabling the zip extension allows you to unzip archives", + "ext-zlib": "Allow gzip compression of HTTP requests" + }, + "bin": [ + "bin/composer" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0-dev" + } + }, + "autoload": { + "psr-4": { + "Composer\\": "src/Composer" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nils Adermann", + "email": "naderman@naderman.de", + "homepage": "https://www.naderman.de" + }, + { + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be", + "homepage": "https://seld.be" + } + ], + "description": "Composer helps you declare, manage and install dependencies of PHP projects. It ensures you have the right stack everywhere.", + "homepage": "https://getcomposer.org/", + "keywords": [ + "autoload", + "dependency", + "package" + ], + "support": { + "irc": "irc://irc.freenode.org/composer", + "issues": "https://github.com/composer/composer/issues", + "source": "https://github.com/composer/composer/tree/2.0.8" + }, + "funding": [ + { + "url": "https://packagist.com", + "type": "custom" + }, + { + "url": "https://github.com/composer", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/composer/composer", + "type": "tidelift" + } + ], + "time": "2020-12-03T16:20:39+00:00" + }, + { + "name": "composer/semver", + "version": "3.2.4", + "source": { + "type": "git", + "url": "https://github.com/composer/semver.git", + "reference": "a02fdf930a3c1c3ed3a49b5f63859c0c20e10464" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/composer/semver/zipball/a02fdf930a3c1c3ed3a49b5f63859c0c20e10464", + "reference": "a02fdf930a3c1c3ed3a49b5f63859c0c20e10464", + "shasum": "" + }, + "require": { + "php": "^5.3.2 || ^7.0 || ^8.0" + }, + "require-dev": { + "phpstan/phpstan": "^0.12.54", + "symfony/phpunit-bridge": "^4.2 || ^5" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.x-dev" + } + }, + "autoload": { + "psr-4": { + "Composer\\Semver\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nils Adermann", + "email": "naderman@naderman.de", + "homepage": "http://www.naderman.de" + }, + { + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be", + "homepage": "http://seld.be" + }, + { + "name": "Rob Bast", + "email": "rob.bast@gmail.com", + "homepage": "http://robbast.nl" + } + ], + "description": "Semver library that offers utilities, version constraint parsing and validation.", + "keywords": [ + "semantic", + "semver", + "validation", + "versioning" + ], + "support": { + "irc": "irc://irc.freenode.org/composer", + "issues": "https://github.com/composer/semver/issues", + "source": "https://github.com/composer/semver/tree/3.2.4" + }, + "funding": [ + { + "url": "https://packagist.com", + "type": "custom" + }, + { + "url": "https://github.com/composer", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/composer/composer", + "type": "tidelift" + } + ], + "time": "2020-11-13T08:59:24+00:00" + }, + { + "name": "composer/spdx-licenses", + "version": "1.5.5", + "source": { + "type": "git", + "url": "https://github.com/composer/spdx-licenses.git", + "reference": "de30328a7af8680efdc03e396aad24befd513200" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/composer/spdx-licenses/zipball/de30328a7af8680efdc03e396aad24befd513200", + "reference": "de30328a7af8680efdc03e396aad24befd513200", + "shasum": "" + }, + "require": { + "php": "^5.3.2 || ^7.0 || ^8.0" + }, + "require-dev": { + "phpunit/phpunit": "^4.8.35 || ^5.7 || 6.5 - 7" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.x-dev" + } + }, + "autoload": { + "psr-4": { + "Composer\\Spdx\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nils Adermann", + "email": "naderman@naderman.de", + "homepage": "http://www.naderman.de" + }, + { + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be", + "homepage": "http://seld.be" + }, + { + "name": "Rob Bast", + "email": "rob.bast@gmail.com", + "homepage": "http://robbast.nl" + } + ], + "description": "SPDX licenses list and validation library.", + "keywords": [ + "license", + "spdx", + "validator" + ], + "support": { + "irc": "irc://irc.freenode.org/composer", + "issues": "https://github.com/composer/spdx-licenses/issues", + "source": "https://github.com/composer/spdx-licenses/tree/1.5.5" + }, + "funding": [ + { + "url": "https://packagist.com", + "type": "custom" + }, + { + "url": "https://github.com/composer", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/composer/composer", + "type": "tidelift" + } + ], + "time": "2020-12-03T16:04:16+00:00" + }, + { + "name": "composer/xdebug-handler", + "version": "1.4.5", + "source": { + "type": "git", + "url": "https://github.com/composer/xdebug-handler.git", + "reference": "f28d44c286812c714741478d968104c5e604a1d4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/composer/xdebug-handler/zipball/f28d44c286812c714741478d968104c5e604a1d4", + "reference": "f28d44c286812c714741478d968104c5e604a1d4", + "shasum": "" + }, + "require": { + "php": "^5.3.2 || ^7.0 || ^8.0", + "psr/log": "^1.0" + }, + "require-dev": { + "phpunit/phpunit": "^4.8.35 || ^5.7 || 6.5 - 8" + }, + "type": "library", + "autoload": { + "psr-4": { + "Composer\\XdebugHandler\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "John Stevenson", + "email": "john-stevenson@blueyonder.co.uk" + } + ], + "description": "Restarts a process without Xdebug.", + "keywords": [ + "Xdebug", + "performance" + ], + "support": { + "irc": "irc://irc.freenode.org/composer", + "issues": "https://github.com/composer/xdebug-handler/issues", + "source": "https://github.com/composer/xdebug-handler/tree/1.4.5" + }, + "funding": [ + { + "url": "https://packagist.com", + "type": "custom" + }, + { + "url": "https://github.com/composer", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/composer/composer", + "type": "tidelift" + } + ], + "time": "2020-11-13T08:04:11+00:00" + }, + { + "name": "consolidation/annotated-command", + "version": "4.2.3", + "source": { + "type": "git", + "url": "https://github.com/consolidation/annotated-command.git", + "reference": "4b596872f24c39d9c04d7b3adb6bc51baa1f2fd5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/consolidation/annotated-command/zipball/4b596872f24c39d9c04d7b3adb6bc51baa1f2fd5", + "reference": "4b596872f24c39d9c04d7b3adb6bc51baa1f2fd5", + "shasum": "" + }, + "require": { + "consolidation/output-formatters": "^4.1.1", + "php": ">=7.1.3", + "psr/log": "^1|^2", + "symfony/console": "^4.4.8|^5", + "symfony/event-dispatcher": "^4.4.8|^5", + "symfony/finder": "^4.4.8|^5" + }, + "require-dev": { + "g1a/composer-test-scenarios": "^3", + "php-coveralls/php-coveralls": "^2.2", + "phpunit/phpunit": "^6", + "squizlabs/php_codesniffer": "^3" + }, + "type": "library", + "extra": { + "scenarios": { + "symfony4": { + "require": { + "symfony/console": "^4.0" + }, + "config": { + "platform": { + "php": "7.1.3" + } + } + } + }, + "branch-alias": { + "dev-main": "4.x-dev" + } + }, + "autoload": { + "psr-4": { + "Consolidation\\AnnotatedCommand\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Greg Anderson", + "email": "greg.1.anderson@greenknowe.org" + } + ], + "description": "Initialize Symfony Console commands from annotated command class methods.", + "support": { + "issues": "https://github.com/consolidation/annotated-command/issues", + "source": "https://github.com/consolidation/annotated-command/tree/4.2.3" + }, + "time": "2020-10-03T14:28:42+00:00" + }, + { + "name": "consolidation/config", + "version": "2.0.1", + "source": { + "type": "git", + "url": "https://github.com/consolidation/config.git", + "reference": "9a2c2a7b2aea1b3525984a4378743a8b74c14e1c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/consolidation/config/zipball/9a2c2a7b2aea1b3525984a4378743a8b74c14e1c", + "reference": "9a2c2a7b2aea1b3525984a4378743a8b74c14e1c", + "shasum": "" + }, + "require": { + "dflydev/dot-access-data": "^1.1.0", + "grasmash/expander": "^1", + "php": ">=7.1.3", + "psr/log": "^1.1", + "symfony/event-dispatcher": "^4||^5" + }, + "require-dev": { + "phpunit/phpunit": ">=7.5.20", + "squizlabs/php_codesniffer": "^3", + "symfony/console": "^4||^5", + "symfony/yaml": "^4||^5", + "yoast/phpunit-polyfills": "^0.2.0" + }, + "suggest": { + "symfony/event-dispatcher": "Required to inject configuration into Command options", + "symfony/yaml": "Required to use Consolidation\\Config\\Loader\\YamlConfigLoader" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "2.x-dev" + } + }, + "autoload": { + "psr-4": { + "Consolidation\\Config\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Greg Anderson", + "email": "greg.1.anderson@greenknowe.org" + } + ], + "description": "Provide configuration services for a commandline tool.", + "support": { + "issues": "https://github.com/consolidation/config/issues", + "source": "https://github.com/consolidation/config/tree/2.0.1" + }, + "time": "2020-12-06T00:03:30+00:00" + }, + { + "name": "consolidation/log", + "version": "2.0.2", + "source": { + "type": "git", + "url": "https://github.com/consolidation/log.git", + "reference": "82a2aaaa621a7b976e50a745a8d249d5085ee2b1" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/consolidation/log/zipball/82a2aaaa621a7b976e50a745a8d249d5085ee2b1", + "reference": "82a2aaaa621a7b976e50a745a8d249d5085ee2b1", + "shasum": "" + }, + "require": { + "php": ">=7.1.3", + "psr/log": "^1.0", + "symfony/console": "^4|^5" + }, + "require-dev": { + "phpunit/phpunit": ">=7.5.20", + "squizlabs/php_codesniffer": "^3", + "yoast/phpunit-polyfills": "^0.2.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "2.x-dev" + } + }, + "autoload": { + "psr-4": { + "Consolidation\\Log\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Greg Anderson", + "email": "greg.1.anderson@greenknowe.org" + } + ], + "description": "Improved Psr-3 / Psr\\Log logger based on Symfony Console components.", + "support": { + "issues": "https://github.com/consolidation/log/issues", + "source": "https://github.com/consolidation/log/tree/2.0.2" + }, + "time": "2020-12-10T16:26:23+00:00" + }, + { + "name": "consolidation/output-formatters", + "version": "4.1.2", + "source": { + "type": "git", + "url": "https://github.com/consolidation/output-formatters.git", + "reference": "5821e6ae076bf690058a4de6c94dce97398a69c9" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/consolidation/output-formatters/zipball/5821e6ae076bf690058a4de6c94dce97398a69c9", + "reference": "5821e6ae076bf690058a4de6c94dce97398a69c9", + "shasum": "" + }, + "require": { + "dflydev/dot-access-data": "^1.1.0", + "php": ">=7.1.3", + "symfony/console": "^4|^5", + "symfony/finder": "^4|^5" + }, + "require-dev": { + "php-coveralls/php-coveralls": "^2.4.2", + "phpunit/phpunit": ">=7", + "squizlabs/php_codesniffer": "^3", + "symfony/var-dumper": "^4", + "symfony/yaml": "^4", + "yoast/phpunit-polyfills": "^0.2.0" + }, + "suggest": { + "symfony/var-dumper": "For using the var_dump formatter" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "4.x-dev" + } + }, + "autoload": { + "psr-4": { + "Consolidation\\OutputFormatters\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Greg Anderson", + "email": "greg.1.anderson@greenknowe.org" + } + ], + "description": "Format text by applying transformations provided by plug-in formatters.", + "support": { + "issues": "https://github.com/consolidation/output-formatters/issues", + "source": "https://github.com/consolidation/output-formatters/tree/4.1.2" + }, + "time": "2020-12-12T19:04:59+00:00" + }, + { + "name": "consolidation/robo", + "version": "2.2.2", + "source": { + "type": "git", + "url": "https://github.com/consolidation/Robo.git", + "reference": "b365df174d9cfb0f5814e4f3275a1c558b17bc4c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/consolidation/Robo/zipball/b365df174d9cfb0f5814e4f3275a1c558b17bc4c", + "reference": "b365df174d9cfb0f5814e4f3275a1c558b17bc4c", + "shasum": "" + }, + "require": { + "consolidation/annotated-command": "^4.2.1", + "consolidation/config": "^1.2.1|^2", + "consolidation/log": "^1.1.1|^2.0.1", + "consolidation/output-formatters": "^4.1.1", + "consolidation/self-update": "^1.2", + "league/container": "^2.4.1", + "php": ">=7.1.3", + "symfony/console": "^4.4.11|^5", + "symfony/event-dispatcher": "^4.4.11|^5", + "symfony/filesystem": "^4.4.11|^5", + "symfony/finder": "^4.4.11|^5", + "symfony/process": "^4.4.11|^5", + "symfony/yaml": "^4.0 || ^5.0" + }, + "conflict": { + "codegyre/robo": "*" + }, + "require-dev": { + "g1a/composer-test-scenarios": "^3", + "natxet/cssmin": "3.0.4", + "patchwork/jsqueeze": "^2", + "pear/archive_tar": "^1.4.4", + "php-coveralls/php-coveralls": "^2.2", + "phpdocumentor/reflection-docblock": "^4.3.2", + "phpunit/phpunit": "^6.5.14", + "squizlabs/php_codesniffer": "^3" + }, + "suggest": { + "henrikbjorn/lurker": "For monitoring filesystem changes in taskWatch", + "natxet/cssmin": "For minifying CSS files in taskMinify", + "patchwork/jsqueeze": "For minifying JS files in taskMinify", + "pear/archive_tar": "Allows tar archives to be created and extracted in taskPack and taskExtract, respectively." + }, + "bin": [ + "robo" + ], + "type": "library", + "extra": { + "scenarios": { + "symfony4": { + "require": { + "symfony/console": "^4.4.11", + "symfony/event-dispatcher": "^4.4.11", + "symfony/filesystem": "^4.4.11", + "symfony/finder": "^4.4.11", + "symfony/process": "^4.4.11", + "phpunit/phpunit": "^6", + "nikic/php-parser": "^2" + }, + "remove": [ + "codeception/phpunit-wrapper" + ], + "config": { + "platform": { + "php": "7.1.3" + } + } + } + }, + "branch-alias": { + "dev-master": "2.x-dev", + "dev-main": "2.x-dev" + } + }, + "autoload": { + "psr-4": { + "Robo\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Davert", + "email": "davert.php@resend.cc" + } + ], + "description": "Modern task runner", + "support": { + "issues": "https://github.com/consolidation/Robo/issues", + "source": "https://github.com/consolidation/Robo/tree/2.2.2" + }, + "time": "2020-12-18T22:09:18+00:00" + }, + { + "name": "consolidation/self-update", + "version": "1.2.0", + "source": { + "type": "git", + "url": "https://github.com/consolidation/self-update.git", + "reference": "dba6b2c0708f20fa3ba8008a2353b637578849b4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/consolidation/self-update/zipball/dba6b2c0708f20fa3ba8008a2353b637578849b4", + "reference": "dba6b2c0708f20fa3ba8008a2353b637578849b4", + "shasum": "" + }, + "require": { + "php": ">=5.5.0", + "symfony/console": "^2.8|^3|^4|^5", + "symfony/filesystem": "^2.5|^3|^4|^5" + }, + "bin": [ + "scripts/release" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.x-dev" + } + }, + "autoload": { + "psr-4": { + "SelfUpdate\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Alexander Menk", + "email": "menk@mestrona.net" + }, + { + "name": "Greg Anderson", + "email": "greg.1.anderson@greenknowe.org" + } + ], + "description": "Provides a self:update command for Symfony Console applications.", + "support": { + "issues": "https://github.com/consolidation/self-update/issues", + "source": "https://github.com/consolidation/self-update/tree/1.2.0" + }, + "time": "2020-04-13T02:49:20+00:00" + }, + { + "name": "container-interop/container-interop", + "version": "1.2.0", + "source": { + "type": "git", + "url": "https://github.com/container-interop/container-interop.git", + "reference": "79cbf1341c22ec75643d841642dd5d6acd83bdb8" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/container-interop/container-interop/zipball/79cbf1341c22ec75643d841642dd5d6acd83bdb8", + "reference": "79cbf1341c22ec75643d841642dd5d6acd83bdb8", + "shasum": "" + }, + "require": { + "psr/container": "^1.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Interop\\Container\\": "src/Interop/Container/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Promoting the interoperability of container objects (DIC, SL, etc.)", + "homepage": "https://github.com/container-interop/container-interop", + "support": { + "issues": "https://github.com/container-interop/container-interop/issues", + "source": "https://github.com/container-interop/container-interop/tree/master" + }, + "abandoned": "psr/container", + "time": "2017-02-14T19:40:03+00:00" + }, + { + "name": "danielstjules/stringy", + "version": "3.1.0", + "source": { + "type": "git", + "url": "https://github.com/danielstjules/Stringy.git", + "reference": "df24ab62d2d8213bbbe88cc36fc35a4503b4bd7e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/danielstjules/Stringy/zipball/df24ab62d2d8213bbbe88cc36fc35a4503b4bd7e", + "reference": "df24ab62d2d8213bbbe88cc36fc35a4503b4bd7e", + "shasum": "" + }, + "require": { + "php": ">=5.4.0", + "symfony/polyfill-mbstring": "~1.1" + }, + "require-dev": { + "phpunit/phpunit": "~4.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Stringy\\": "src/" + }, + "files": [ + "src/Create.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Daniel St. Jules", + "email": "danielst.jules@gmail.com", + "homepage": "http://www.danielstjules.com" + } + ], + "description": "A string manipulation library with multibyte support", + "homepage": "https://github.com/danielstjules/Stringy", + "keywords": [ + "UTF", + "helpers", + "manipulation", + "methods", + "multibyte", + "string", + "utf-8", + "utility", + "utils" + ], + "support": { + "issues": "https://github.com/danielstjules/Stringy/issues", + "source": "https://github.com/danielstjules/Stringy" + }, + "time": "2017-06-12T01:10:27+00:00" + }, + { + "name": "dflydev/dot-access-data", + "version": "v1.1.0", + "source": { + "type": "git", + "url": "https://github.com/dflydev/dflydev-dot-access-data.git", + "reference": "3fbd874921ab2c041e899d044585a2ab9795df8a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/dflydev/dflydev-dot-access-data/zipball/3fbd874921ab2c041e899d044585a2ab9795df8a", + "reference": "3fbd874921ab2c041e899d044585a2ab9795df8a", + "shasum": "" + }, + "require": { + "php": ">=5.3.2" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0-dev" + } + }, + "autoload": { + "psr-0": { + "Dflydev\\DotAccessData": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Dragonfly Development Inc.", + "email": "info@dflydev.com", + "homepage": "http://dflydev.com" + }, + { + "name": "Beau Simensen", + "email": "beau@dflydev.com", + "homepage": "http://beausimensen.com" + }, + { + "name": "Carlos Frutos", + "email": "carlos@kiwing.it", + "homepage": "https://github.com/cfrutos" + } + ], + "description": "Given a deep data structure, access data by dot notation.", + "homepage": "https://github.com/dflydev/dflydev-dot-access-data", + "keywords": [ + "access", + "data", + "dot", + "notation" + ], + "support": { + "issues": "https://github.com/dflydev/dflydev-dot-access-data/issues", + "source": "https://github.com/dflydev/dflydev-dot-access-data/tree/master" + }, + "time": "2017-01-20T21:14:22+00:00" + }, + { + "name": "doctrine/instantiator", + "version": "1.4.0", + "source": { + "type": "git", + "url": "https://github.com/doctrine/instantiator.git", + "reference": "d56bf6102915de5702778fe20f2de3b2fe570b5b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/instantiator/zipball/d56bf6102915de5702778fe20f2de3b2fe570b5b", + "reference": "d56bf6102915de5702778fe20f2de3b2fe570b5b", + "shasum": "" + }, + "require": { + "php": "^7.1 || ^8.0" + }, + "require-dev": { + "doctrine/coding-standard": "^8.0", + "ext-pdo": "*", + "ext-phar": "*", + "phpbench/phpbench": "^0.13 || 1.0.0-alpha2", + "phpstan/phpstan": "^0.12", + "phpstan/phpstan-phpunit": "^0.12", + "phpunit/phpunit": "^7.0 || ^8.0 || ^9.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Doctrine\\Instantiator\\": "src/Doctrine/Instantiator/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Marco Pivetta", + "email": "ocramius@gmail.com", + "homepage": "https://ocramius.github.io/" + } + ], + "description": "A small, lightweight utility to instantiate objects in PHP without invoking their constructors", + "homepage": "https://www.doctrine-project.org/projects/instantiator.html", + "keywords": [ + "constructor", + "instantiate" + ], + "support": { + "issues": "https://github.com/doctrine/instantiator/issues", + "source": "https://github.com/doctrine/instantiator/tree/1.4.0" + }, + "funding": [ + { + "url": "https://www.doctrine-project.org/sponsorship.html", + "type": "custom" + }, + { + "url": "https://www.patreon.com/phpdoctrine", + "type": "patreon" + }, + { + "url": "https://tidelift.com/funding/github/packagist/doctrine%2Finstantiator", + "type": "tidelift" + } + ], + "time": "2020-11-10T18:47:58+00:00" + }, + { + "name": "grasmash/expander", + "version": "1.0.0", + "source": { + "type": "git", + "url": "https://github.com/grasmash/expander.git", + "reference": "95d6037344a4be1dd5f8e0b0b2571a28c397578f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/grasmash/expander/zipball/95d6037344a4be1dd5f8e0b0b2571a28c397578f", + "reference": "95d6037344a4be1dd5f8e0b0b2571a28c397578f", + "shasum": "" + }, + "require": { + "dflydev/dot-access-data": "^1.1.0", + "php": ">=5.4" + }, + "require-dev": { + "greg-1-anderson/composer-test-scenarios": "^1", + "phpunit/phpunit": "^4|^5.5.4", + "satooshi/php-coveralls": "^1.0.2|dev-master", + "squizlabs/php_codesniffer": "^2.7" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.x-dev" + } + }, + "autoload": { + "psr-4": { + "Grasmash\\Expander\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Matthew Grasmick" + } + ], + "description": "Expands internal property references in PHP arrays file.", + "support": { + "issues": "https://github.com/grasmash/expander/issues", + "source": "https://github.com/grasmash/expander/tree/master" + }, + "time": "2017-12-21T22:14:55+00:00" + }, + { + "name": "guzzlehttp/psr7", + "version": "1.7.0", + "source": { + "type": "git", + "url": "https://github.com/guzzle/psr7.git", + "reference": "53330f47520498c0ae1f61f7e2c90f55690c06a3" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/guzzle/psr7/zipball/53330f47520498c0ae1f61f7e2c90f55690c06a3", + "reference": "53330f47520498c0ae1f61f7e2c90f55690c06a3", + "shasum": "" + }, + "require": { + "php": ">=5.4.0", + "psr/http-message": "~1.0", + "ralouphie/getallheaders": "^2.0.5 || ^3.0.0" + }, + "provide": { + "psr/http-message-implementation": "1.0" + }, + "require-dev": { + "ext-zlib": "*", + "phpunit/phpunit": "~4.8.36 || ^5.7.27 || ^6.5.14 || ^7.5.20 || ^8.5.8 || ^9.3.10" + }, + "suggest": { + "laminas/laminas-httphandlerrunner": "Emit PSR-7 responses" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.7-dev" + } + }, + "autoload": { + "psr-4": { + "GuzzleHttp\\Psr7\\": "src/" + }, + "files": [ + "src/functions_include.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + }, + { + "name": "Tobias Schultze", + "homepage": "https://github.com/Tobion" + } + ], + "description": "PSR-7 message implementation that also provides common utility methods", + "keywords": [ + "http", + "message", + "psr-7", + "request", + "response", + "stream", + "uri", + "url" + ], + "support": { + "issues": "https://github.com/guzzle/psr7/issues", + "source": "https://github.com/guzzle/psr7/tree/1.7.0" + }, + "time": "2020-09-30T07:37:11+00:00" + }, + { + "name": "justinrainbow/json-schema", + "version": "5.2.10", + "source": { + "type": "git", + "url": "https://github.com/justinrainbow/json-schema.git", + "reference": "2ba9c8c862ecd5510ed16c6340aa9f6eadb4f31b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/justinrainbow/json-schema/zipball/2ba9c8c862ecd5510ed16c6340aa9f6eadb4f31b", + "reference": "2ba9c8c862ecd5510ed16c6340aa9f6eadb4f31b", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "require-dev": { + "friendsofphp/php-cs-fixer": "~2.2.20||~2.15.1", + "json-schema/json-schema-test-suite": "1.2.0", + "phpunit/phpunit": "^4.8.35" + }, + "bin": [ + "bin/validate-json" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "5.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "JsonSchema\\": "src/JsonSchema/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Bruno Prieto Reis", + "email": "bruno.p.reis@gmail.com" + }, + { + "name": "Justin Rainbow", + "email": "justin.rainbow@gmail.com" + }, + { + "name": "Igor Wiedler", + "email": "igor@wiedler.ch" + }, + { + "name": "Robert Schönthal", + "email": "seroscho@googlemail.com" + } + ], + "description": "A library to validate a json schema.", + "homepage": "https://github.com/justinrainbow/json-schema", + "keywords": [ + "json", + "schema" + ], + "support": { + "issues": "https://github.com/justinrainbow/json-schema/issues", + "source": "https://github.com/justinrainbow/json-schema/tree/5.2.10" + }, + "time": "2020-05-27T16:41:55+00:00" + }, + { + "name": "league/container", + "version": "2.4.1", + "source": { + "type": "git", + "url": "https://github.com/thephpleague/container.git", + "reference": "43f35abd03a12977a60ffd7095efd6a7808488c0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/thephpleague/container/zipball/43f35abd03a12977a60ffd7095efd6a7808488c0", + "reference": "43f35abd03a12977a60ffd7095efd6a7808488c0", + "shasum": "" + }, + "require": { + "container-interop/container-interop": "^1.2", + "php": "^5.4.0 || ^7.0" + }, + "provide": { + "container-interop/container-interop-implementation": "^1.2", + "psr/container-implementation": "^1.0" + }, + "replace": { + "orno/di": "~2.0" + }, + "require-dev": { + "phpunit/phpunit": "4.*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-2.x": "2.x-dev", + "dev-1.x": "1.x-dev" + } + }, + "autoload": { + "psr-4": { + "League\\Container\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Phil Bennett", + "email": "philipobenito@gmail.com", + "homepage": "http://www.philipobenito.com", + "role": "Developer" + } + ], + "description": "A fast and intuitive dependency injection container.", + "homepage": "https://github.com/thephpleague/container", + "keywords": [ + "container", + "dependency", + "di", + "injection", + "league", + "provider", + "service" + ], + "support": { + "issues": "https://github.com/thephpleague/container/issues", + "source": "https://github.com/thephpleague/container/tree/2.x" + }, + "time": "2017-05-10T09:20:27+00:00" + }, + { + "name": "mikey179/vfsstream", + "version": "v1.6.8", + "source": { + "type": "git", + "url": "https://github.com/bovigo/vfsStream.git", + "reference": "231c73783ebb7dd9ec77916c10037eff5a2b6efe" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/bovigo/vfsStream/zipball/231c73783ebb7dd9ec77916c10037eff5a2b6efe", + "reference": "231c73783ebb7dd9ec77916c10037eff5a2b6efe", + "shasum": "" + }, + "require": { + "php": ">=5.3.0" + }, + "require-dev": { + "phpunit/phpunit": "^4.5|^5.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.6.x-dev" + } + }, + "autoload": { + "psr-0": { + "org\\bovigo\\vfs\\": "src/main/php" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Frank Kleine", + "homepage": "http://frankkleine.de/", + "role": "Developer" + } + ], + "description": "Virtual file system to mock the real file system in unit tests.", + "homepage": "http://vfs.bovigo.org/", + "support": { + "issues": "https://github.com/bovigo/vfsStream/issues", + "source": "https://github.com/bovigo/vfsStream/tree/master", + "wiki": "https://github.com/bovigo/vfsStream/wiki" + }, + "time": "2019-10-30T15:31:00+00:00" + }, + { + "name": "myclabs/deep-copy", + "version": "1.10.2", + "source": { + "type": "git", + "url": "https://github.com/myclabs/DeepCopy.git", + "reference": "776f831124e9c62e1a2c601ecc52e776d8bb7220" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/776f831124e9c62e1a2c601ecc52e776d8bb7220", + "reference": "776f831124e9c62e1a2c601ecc52e776d8bb7220", + "shasum": "" + }, + "require": { + "php": "^7.1 || ^8.0" + }, + "replace": { + "myclabs/deep-copy": "self.version" + }, + "require-dev": { + "doctrine/collections": "^1.0", + "doctrine/common": "^2.6", + "phpunit/phpunit": "^7.1" + }, + "type": "library", + "autoload": { + "psr-4": { + "DeepCopy\\": "src/DeepCopy/" + }, + "files": [ + "src/DeepCopy/deep_copy.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Create deep copies (clones) of your objects", + "keywords": [ + "clone", + "copy", + "duplicate", + "object", + "object graph" + ], + "support": { + "issues": "https://github.com/myclabs/DeepCopy/issues", + "source": "https://github.com/myclabs/DeepCopy/tree/1.10.2" + }, + "funding": [ + { + "url": "https://tidelift.com/funding/github/packagist/myclabs/deep-copy", + "type": "tidelift" + } + ], + "time": "2020-11-13T09:40:50+00:00" + }, + { + "name": "nikic/php-parser", + "version": "v4.10.4", + "source": { + "type": "git", + "url": "https://github.com/nikic/PHP-Parser.git", + "reference": "c6d052fc58cb876152f89f532b95a8d7907e7f0e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/c6d052fc58cb876152f89f532b95a8d7907e7f0e", + "reference": "c6d052fc58cb876152f89f532b95a8d7907e7f0e", + "shasum": "" + }, + "require": { + "ext-tokenizer": "*", + "php": ">=7.0" + }, + "require-dev": { + "ircmaxell/php-yacc": "^0.0.7", + "phpunit/phpunit": "^6.5 || ^7.0 || ^8.0 || ^9.0" + }, + "bin": [ + "bin/php-parse" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.9-dev" + } + }, + "autoload": { + "psr-4": { + "PhpParser\\": "lib/PhpParser" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Nikita Popov" + } + ], + "description": "A PHP parser written in PHP", + "keywords": [ + "parser", + "php" + ], + "support": { + "issues": "https://github.com/nikic/PHP-Parser/issues", + "source": "https://github.com/nikic/PHP-Parser/tree/v4.10.4" + }, + "time": "2020-12-20T10:01:03+00:00" + }, + { + "name": "phar-io/manifest", + "version": "2.0.1", + "source": { + "type": "git", + "url": "https://github.com/phar-io/manifest.git", + "reference": "85265efd3af7ba3ca4b2a2c34dbfc5788dd29133" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phar-io/manifest/zipball/85265efd3af7ba3ca4b2a2c34dbfc5788dd29133", + "reference": "85265efd3af7ba3ca4b2a2c34dbfc5788dd29133", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-phar": "*", + "ext-xmlwriter": "*", + "phar-io/version": "^3.0.1", + "php": "^7.2 || ^8.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Arne Blankerts", + "email": "arne@blankerts.de", + "role": "Developer" + }, + { + "name": "Sebastian Heuer", + "email": "sebastian@phpeople.de", + "role": "Developer" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "Developer" + } + ], + "description": "Component for reading phar.io manifest information from a PHP Archive (PHAR)", + "support": { + "issues": "https://github.com/phar-io/manifest/issues", + "source": "https://github.com/phar-io/manifest/tree/master" + }, + "time": "2020-06-27T14:33:11+00:00" + }, + { + "name": "phar-io/version", + "version": "3.0.4", + "source": { + "type": "git", + "url": "https://github.com/phar-io/version.git", + "reference": "e4782611070e50613683d2b9a57730e9a3ba5451" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phar-io/version/zipball/e4782611070e50613683d2b9a57730e9a3ba5451", + "reference": "e4782611070e50613683d2b9a57730e9a3ba5451", + "shasum": "" + }, + "require": { + "php": "^7.2 || ^8.0" + }, + "type": "library", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Arne Blankerts", + "email": "arne@blankerts.de", + "role": "Developer" + }, + { + "name": "Sebastian Heuer", + "email": "sebastian@phpeople.de", + "role": "Developer" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "Developer" + } + ], + "description": "Library for handling version information and constraints", + "support": { + "issues": "https://github.com/phar-io/version/issues", + "source": "https://github.com/phar-io/version/tree/3.0.4" + }, + "time": "2020-12-13T23:18:30+00:00" + }, + { + "name": "phpdocumentor/reflection-common", + "version": "2.2.0", + "source": { + "type": "git", + "url": "https://github.com/phpDocumentor/ReflectionCommon.git", + "reference": "1d01c49d4ed62f25aa84a747ad35d5a16924662b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/1d01c49d4ed62f25aa84a747ad35d5a16924662b", + "reference": "1d01c49d4ed62f25aa84a747ad35d5a16924662b", + "shasum": "" + }, + "require": { + "php": "^7.2 || ^8.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-2.x": "2.x-dev" + } + }, + "autoload": { + "psr-4": { + "phpDocumentor\\Reflection\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jaap van Otterdijk", + "email": "opensource@ijaap.nl" + } + ], + "description": "Common reflection classes used by phpdocumentor to reflect the code structure", + "homepage": "http://www.phpdoc.org", + "keywords": [ + "FQSEN", + "phpDocumentor", + "phpdoc", + "reflection", + "static analysis" + ], + "support": { + "issues": "https://github.com/phpDocumentor/ReflectionCommon/issues", + "source": "https://github.com/phpDocumentor/ReflectionCommon/tree/2.x" + }, + "time": "2020-06-27T09:03:43+00:00" + }, + { + "name": "phpdocumentor/reflection-docblock", + "version": "5.2.2", + "source": { + "type": "git", + "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git", + "reference": "069a785b2141f5bcf49f3e353548dc1cce6df556" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/069a785b2141f5bcf49f3e353548dc1cce6df556", + "reference": "069a785b2141f5bcf49f3e353548dc1cce6df556", + "shasum": "" + }, + "require": { + "ext-filter": "*", + "php": "^7.2 || ^8.0", + "phpdocumentor/reflection-common": "^2.2", + "phpdocumentor/type-resolver": "^1.3", + "webmozart/assert": "^1.9.1" + }, + "require-dev": { + "mockery/mockery": "~1.3.2" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "5.x-dev" + } + }, + "autoload": { + "psr-4": { + "phpDocumentor\\Reflection\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Mike van Riel", + "email": "me@mikevanriel.com" + }, + { + "name": "Jaap van Otterdijk", + "email": "account@ijaap.nl" + } + ], + "description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.", + "support": { + "issues": "https://github.com/phpDocumentor/ReflectionDocBlock/issues", + "source": "https://github.com/phpDocumentor/ReflectionDocBlock/tree/master" + }, + "time": "2020-09-03T19:13:55+00:00" + }, + { + "name": "phpdocumentor/type-resolver", + "version": "1.4.0", + "source": { + "type": "git", + "url": "https://github.com/phpDocumentor/TypeResolver.git", + "reference": "6a467b8989322d92aa1c8bf2bebcc6e5c2ba55c0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/6a467b8989322d92aa1c8bf2bebcc6e5c2ba55c0", + "reference": "6a467b8989322d92aa1c8bf2bebcc6e5c2ba55c0", + "shasum": "" + }, + "require": { + "php": "^7.2 || ^8.0", + "phpdocumentor/reflection-common": "^2.0" + }, + "require-dev": { + "ext-tokenizer": "*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-1.x": "1.x-dev" + } + }, + "autoload": { + "psr-4": { + "phpDocumentor\\Reflection\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Mike van Riel", + "email": "me@mikevanriel.com" + } + ], + "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.4.0" + }, + "time": "2020-09-17T18:55:26+00:00" + }, + { + "name": "phpspec/prophecy", + "version": "1.12.2", + "source": { + "type": "git", + "url": "https://github.com/phpspec/prophecy.git", + "reference": "245710e971a030f42e08f4912863805570f23d39" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpspec/prophecy/zipball/245710e971a030f42e08f4912863805570f23d39", + "reference": "245710e971a030f42e08f4912863805570f23d39", + "shasum": "" + }, + "require": { + "doctrine/instantiator": "^1.2", + "php": "^7.2 || ~8.0, <8.1", + "phpdocumentor/reflection-docblock": "^5.2", + "sebastian/comparator": "^3.0 || ^4.0", + "sebastian/recursion-context": "^3.0 || ^4.0" + }, + "require-dev": { + "phpspec/phpspec": "^6.0", + "phpunit/phpunit": "^8.0 || ^9.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.11.x-dev" + } + }, + "autoload": { + "psr-4": { + "Prophecy\\": "src/Prophecy" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Konstantin Kudryashov", + "email": "ever.zet@gmail.com", + "homepage": "http://everzet.com" + }, + { + "name": "Marcello Duarte", + "email": "marcello.duarte@gmail.com" + } + ], + "description": "Highly opinionated mocking framework for PHP 5.3+", + "homepage": "https://github.com/phpspec/prophecy", + "keywords": [ + "Double", + "Dummy", + "fake", + "mock", + "spy", + "stub" + ], + "support": { + "issues": "https://github.com/phpspec/prophecy/issues", + "source": "https://github.com/phpspec/prophecy/tree/1.12.2" + }, + "time": "2020-12-19T10:15:11+00:00" + }, + { + "name": "phpunit/php-code-coverage", + "version": "9.2.5", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-code-coverage.git", + "reference": "f3e026641cc91909d421802dd3ac7827ebfd97e1" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/f3e026641cc91909d421802dd3ac7827ebfd97e1", + "reference": "f3e026641cc91909d421802dd3ac7827ebfd97e1", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-libxml": "*", + "ext-xmlwriter": "*", + "nikic/php-parser": "^4.10.2", + "php": ">=7.3", + "phpunit/php-file-iterator": "^3.0.3", + "phpunit/php-text-template": "^2.0.2", + "sebastian/code-unit-reverse-lookup": "^2.0.2", + "sebastian/complexity": "^2.0", + "sebastian/environment": "^5.1.2", + "sebastian/lines-of-code": "^1.0.3", + "sebastian/version": "^3.0.1", + "theseer/tokenizer": "^1.2.0" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "suggest": { + "ext-pcov": "*", + "ext-xdebug": "*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "9.2-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library that provides collection, processing, and rendering functionality for PHP code coverage information.", + "homepage": "https://github.com/sebastianbergmann/php-code-coverage", + "keywords": [ + "coverage", + "testing", + "xunit" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-code-coverage/issues", + "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.5" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-11-28T06:44:49+00:00" + }, + { + "name": "phpunit/php-file-iterator", + "version": "3.0.5", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-file-iterator.git", + "reference": "aa4be8575f26070b100fccb67faabb28f21f66f8" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/aa4be8575f26070b100fccb67faabb28f21f66f8", + "reference": "aa4be8575f26070b100fccb67faabb28f21f66f8", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "FilterIterator implementation that filters files based on a list of suffixes.", + "homepage": "https://github.com/sebastianbergmann/php-file-iterator/", + "keywords": [ + "filesystem", + "iterator" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-file-iterator/issues", + "source": "https://github.com/sebastianbergmann/php-file-iterator/tree/3.0.5" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-09-28T05:57:25+00:00" + }, + { + "name": "phpunit/php-invoker", + "version": "3.1.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-invoker.git", + "reference": "5a10147d0aaf65b58940a0b72f71c9ac0423cc67" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-invoker/zipball/5a10147d0aaf65b58940a0b72f71c9ac0423cc67", + "reference": "5a10147d0aaf65b58940a0b72f71c9ac0423cc67", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "ext-pcntl": "*", + "phpunit/phpunit": "^9.3" + }, + "suggest": { + "ext-pcntl": "*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.1-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Invoke callables with a timeout", + "homepage": "https://github.com/sebastianbergmann/php-invoker/", + "keywords": [ + "process" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-invoker/issues", + "source": "https://github.com/sebastianbergmann/php-invoker/tree/3.1.1" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-09-28T05:58:55+00:00" + }, + { + "name": "phpunit/php-text-template", + "version": "2.0.4", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-text-template.git", + "reference": "5da5f67fc95621df9ff4c4e5a84d6a8a2acf7c28" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/5da5f67fc95621df9ff4c4e5a84d6a8a2acf7c28", + "reference": "5da5f67fc95621df9ff4c4e5a84d6a8a2acf7c28", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Simple template engine.", + "homepage": "https://github.com/sebastianbergmann/php-text-template/", + "keywords": [ + "template" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-text-template/issues", + "source": "https://github.com/sebastianbergmann/php-text-template/tree/2.0.4" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-10-26T05:33:50+00:00" + }, + { + "name": "phpunit/php-timer", + "version": "5.0.3", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-timer.git", + "reference": "5a63ce20ed1b5bf577850e2c4e87f4aa902afbd2" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/5a63ce20ed1b5bf577850e2c4e87f4aa902afbd2", + "reference": "5a63ce20ed1b5bf577850e2c4e87f4aa902afbd2", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "5.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Utility class for timing", + "homepage": "https://github.com/sebastianbergmann/php-timer/", + "keywords": [ + "timer" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-timer/issues", + "source": "https://github.com/sebastianbergmann/php-timer/tree/5.0.3" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-10-26T13:16:10+00:00" + }, + { + "name": "phpunit/phpunit", + "version": "9.5.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/phpunit.git", + "reference": "8e16c225d57c3d6808014df6b1dd7598d0a5bbbe" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/8e16c225d57c3d6808014df6b1dd7598d0a5bbbe", + "reference": "8e16c225d57c3d6808014df6b1dd7598d0a5bbbe", + "shasum": "" + }, + "require": { + "doctrine/instantiator": "^1.3.1", + "ext-dom": "*", + "ext-json": "*", + "ext-libxml": "*", + "ext-mbstring": "*", + "ext-xml": "*", + "ext-xmlwriter": "*", + "myclabs/deep-copy": "^1.10.1", + "phar-io/manifest": "^2.0.1", + "phar-io/version": "^3.0.2", + "php": ">=7.3", + "phpspec/prophecy": "^1.12.1", + "phpunit/php-code-coverage": "^9.2.3", + "phpunit/php-file-iterator": "^3.0.5", + "phpunit/php-invoker": "^3.1.1", + "phpunit/php-text-template": "^2.0.3", + "phpunit/php-timer": "^5.0.2", + "sebastian/cli-parser": "^1.0.1", + "sebastian/code-unit": "^1.0.6", + "sebastian/comparator": "^4.0.5", + "sebastian/diff": "^4.0.3", + "sebastian/environment": "^5.1.3", + "sebastian/exporter": "^4.0.3", + "sebastian/global-state": "^5.0.1", + "sebastian/object-enumerator": "^4.0.3", + "sebastian/resource-operations": "^3.0.3", + "sebastian/type": "^2.3", + "sebastian/version": "^3.0.2" + }, + "require-dev": { + "ext-pdo": "*", + "phpspec/prophecy-phpunit": "^2.0.1" + }, + "suggest": { + "ext-soap": "*", + "ext-xdebug": "*" + }, + "bin": [ + "phpunit" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "9.5-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ], + "files": [ + "src/Framework/Assert/Functions.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "The PHP Unit Testing framework.", + "homepage": "https://phpunit.de/", + "keywords": [ + "phpunit", + "testing", + "xunit" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/phpunit/issues", + "source": "https://github.com/sebastianbergmann/phpunit/tree/9.5.0" + }, + "funding": [ + { + "url": "https://phpunit.de/donate.html", + "type": "custom" + }, + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-12-04T05:05:53+00:00" + }, + { + "name": "psr/container", + "version": "1.0.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/container.git", + "reference": "b7ce3b176482dbbc1245ebf52b181af44c2cf55f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/container/zipball/b7ce3b176482dbbc1245ebf52b181af44c2cf55f", + "reference": "b7ce3b176482dbbc1245ebf52b181af44c2cf55f", + "shasum": "" + }, + "require": { + "php": ">=5.3.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Container\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "description": "Common Container Interface (PHP FIG PSR-11)", + "homepage": "https://github.com/php-fig/container", + "keywords": [ + "PSR-11", + "container", + "container-interface", + "container-interop", + "psr" + ], + "support": { + "issues": "https://github.com/php-fig/container/issues", + "source": "https://github.com/php-fig/container/tree/master" + }, + "time": "2017-02-14T16:28:37+00:00" + }, + { + "name": "psr/event-dispatcher", + "version": "1.0.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/event-dispatcher.git", + "reference": "dbefd12671e8a14ec7f180cab83036ed26714bb0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/event-dispatcher/zipball/dbefd12671e8a14ec7f180cab83036ed26714bb0", + "reference": "dbefd12671e8a14ec7f180cab83036ed26714bb0", + "shasum": "" + }, + "require": { + "php": ">=7.2.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\EventDispatcher\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "description": "Standard interfaces for event handling.", + "keywords": [ + "events", + "psr", + "psr-14" + ], + "support": { + "issues": "https://github.com/php-fig/event-dispatcher/issues", + "source": "https://github.com/php-fig/event-dispatcher/tree/1.0.0" + }, + "time": "2019-01-08T18:20:26+00:00" + }, + { + "name": "psr/http-message", + "version": "1.0.1", + "source": { + "type": "git", + "url": "https://github.com/php-fig/http-message.git", + "reference": "f6561bf28d520154e4b0ec72be95418abe6d9363" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/http-message/zipball/f6561bf28d520154e4b0ec72be95418abe6d9363", + "reference": "f6561bf28d520154e4b0ec72be95418abe6d9363", + "shasum": "" + }, + "require": { + "php": ">=5.3.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Http\\Message\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "description": "Common interface for HTTP messages", + "homepage": "https://github.com/php-fig/http-message", + "keywords": [ + "http", + "http-message", + "psr", + "psr-7", + "request", + "response" + ], + "support": { + "source": "https://github.com/php-fig/http-message/tree/master" + }, + "time": "2016-08-06T14:39:51+00:00" + }, + { + "name": "psr/log", + "version": "1.1.3", + "source": { + "type": "git", + "url": "https://github.com/php-fig/log.git", + "reference": "0f73288fd15629204f9d42b7055f72dacbe811fc" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/log/zipball/0f73288fd15629204f9d42b7055f72dacbe811fc", + "reference": "0f73288fd15629204f9d42b7055f72dacbe811fc", + "shasum": "" + }, + "require": { + "php": ">=5.3.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.1.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Log\\": "Psr/Log/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "description": "Common interface for logging libraries", + "homepage": "https://github.com/php-fig/log", + "keywords": [ + "log", + "psr", + "psr-3" + ], + "support": { + "source": "https://github.com/php-fig/log/tree/1.1.3" + }, + "time": "2020-03-23T09:12:05+00:00" + }, + { + "name": "ralouphie/getallheaders", + "version": "3.0.3", + "source": { + "type": "git", + "url": "https://github.com/ralouphie/getallheaders.git", + "reference": "120b605dfeb996808c31b6477290a714d356e822" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/ralouphie/getallheaders/zipball/120b605dfeb996808c31b6477290a714d356e822", + "reference": "120b605dfeb996808c31b6477290a714d356e822", + "shasum": "" + }, + "require": { + "php": ">=5.6" + }, + "require-dev": { + "php-coveralls/php-coveralls": "^2.1", + "phpunit/phpunit": "^5 || ^6.5" + }, + "type": "library", + "autoload": { + "files": [ + "src/getallheaders.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Ralph Khattar", + "email": "ralph.khattar@gmail.com" + } + ], + "description": "A polyfill for getallheaders.", + "support": { + "issues": "https://github.com/ralouphie/getallheaders/issues", + "source": "https://github.com/ralouphie/getallheaders/tree/develop" + }, + "time": "2019-03-08T08:55:37+00:00" + }, + { + "name": "react/promise", + "version": "v2.8.0", + "source": { + "type": "git", + "url": "https://github.com/reactphp/promise.git", + "reference": "f3cff96a19736714524ca0dd1d4130de73dbbbc4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/reactphp/promise/zipball/f3cff96a19736714524ca0dd1d4130de73dbbbc4", + "reference": "f3cff96a19736714524ca0dd1d4130de73dbbbc4", + "shasum": "" + }, + "require": { + "php": ">=5.4.0" + }, + "require-dev": { + "phpunit/phpunit": "^7.0 || ^6.5 || ^5.7 || ^4.8.36" + }, + "type": "library", + "autoload": { + "psr-4": { + "React\\Promise\\": "src/" + }, + "files": [ + "src/functions_include.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jan Sorgalla", + "email": "jsorgalla@gmail.com" + } + ], + "description": "A lightweight implementation of CommonJS Promises/A for PHP", + "keywords": [ + "promise", + "promises" + ], + "support": { + "issues": "https://github.com/reactphp/promise/issues", + "source": "https://github.com/reactphp/promise/tree/v2.8.0" + }, + "time": "2020-05-12T15:16:56+00:00" + }, + { + "name": "sebastian/cli-parser", + "version": "1.0.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/cli-parser.git", + "reference": "442e7c7e687e42adc03470c7b668bc4b2402c0b2" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/cli-parser/zipball/442e7c7e687e42adc03470c7b668bc4b2402c0b2", + "reference": "442e7c7e687e42adc03470c7b668bc4b2402c0b2", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library for parsing CLI options", + "homepage": "https://github.com/sebastianbergmann/cli-parser", + "support": { + "issues": "https://github.com/sebastianbergmann/cli-parser/issues", + "source": "https://github.com/sebastianbergmann/cli-parser/tree/1.0.1" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-09-28T06:08:49+00:00" + }, + { + "name": "sebastian/code-unit", + "version": "1.0.8", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/code-unit.git", + "reference": "1fc9f64c0927627ef78ba436c9b17d967e68e120" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/code-unit/zipball/1fc9f64c0927627ef78ba436c9b17d967e68e120", + "reference": "1fc9f64c0927627ef78ba436c9b17d967e68e120", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Collection of value objects that represent the PHP code units", + "homepage": "https://github.com/sebastianbergmann/code-unit", + "support": { + "issues": "https://github.com/sebastianbergmann/code-unit/issues", + "source": "https://github.com/sebastianbergmann/code-unit/tree/1.0.8" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-10-26T13:08:54+00:00" + }, + { + "name": "sebastian/code-unit-reverse-lookup", + "version": "2.0.3", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/code-unit-reverse-lookup.git", + "reference": "ac91f01ccec49fb77bdc6fd1e548bc70f7faa3e5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/ac91f01ccec49fb77bdc6fd1e548bc70f7faa3e5", + "reference": "ac91f01ccec49fb77bdc6fd1e548bc70f7faa3e5", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Looks up which function or method a line of code belongs to", + "homepage": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/", + "support": { + "issues": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/issues", + "source": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/tree/2.0.3" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-09-28T05:30:19+00:00" + }, + { + "name": "sebastian/comparator", + "version": "4.0.6", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/comparator.git", + "reference": "55f4261989e546dc112258c7a75935a81a7ce382" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/55f4261989e546dc112258c7a75935a81a7ce382", + "reference": "55f4261989e546dc112258c7a75935a81a7ce382", + "shasum": "" + }, + "require": { + "php": ">=7.3", + "sebastian/diff": "^4.0", + "sebastian/exporter": "^4.0" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Volker Dusch", + "email": "github@wallbash.com" + }, + { + "name": "Bernhard Schussek", + "email": "bschussek@2bepublished.at" + } + ], + "description": "Provides the functionality to compare PHP values for equality", + "homepage": "https://github.com/sebastianbergmann/comparator", + "keywords": [ + "comparator", + "compare", + "equality" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/comparator/issues", + "source": "https://github.com/sebastianbergmann/comparator/tree/4.0.6" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-10-26T15:49:45+00:00" + }, + { + "name": "sebastian/complexity", + "version": "2.0.2", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/complexity.git", + "reference": "739b35e53379900cc9ac327b2147867b8b6efd88" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/complexity/zipball/739b35e53379900cc9ac327b2147867b8b6efd88", + "reference": "739b35e53379900cc9ac327b2147867b8b6efd88", + "shasum": "" + }, + "require": { + "nikic/php-parser": "^4.7", + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library for calculating the complexity of PHP code units", + "homepage": "https://github.com/sebastianbergmann/complexity", + "support": { + "issues": "https://github.com/sebastianbergmann/complexity/issues", + "source": "https://github.com/sebastianbergmann/complexity/tree/2.0.2" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-10-26T15:52:27+00:00" + }, + { + "name": "sebastian/diff", + "version": "4.0.4", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/diff.git", + "reference": "3461e3fccc7cfdfc2720be910d3bd73c69be590d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/3461e3fccc7cfdfc2720be910d3bd73c69be590d", + "reference": "3461e3fccc7cfdfc2720be910d3bd73c69be590d", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3", + "symfony/process": "^4.2 || ^5" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Kore Nordmann", + "email": "mail@kore-nordmann.de" + } + ], + "description": "Diff implementation", + "homepage": "https://github.com/sebastianbergmann/diff", + "keywords": [ + "diff", + "udiff", + "unidiff", + "unified diff" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/diff/issues", + "source": "https://github.com/sebastianbergmann/diff/tree/4.0.4" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-10-26T13:10:38+00:00" + }, + { + "name": "sebastian/environment", + "version": "5.1.3", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/environment.git", + "reference": "388b6ced16caa751030f6a69e588299fa09200ac" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/388b6ced16caa751030f6a69e588299fa09200ac", + "reference": "388b6ced16caa751030f6a69e588299fa09200ac", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "suggest": { + "ext-posix": "*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "5.1-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Provides functionality to handle HHVM/PHP environments", + "homepage": "http://www.github.com/sebastianbergmann/environment", + "keywords": [ + "Xdebug", + "environment", + "hhvm" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/environment/issues", + "source": "https://github.com/sebastianbergmann/environment/tree/5.1.3" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-09-28T05:52:38+00:00" + }, + { + "name": "sebastian/exporter", + "version": "4.0.3", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/exporter.git", + "reference": "d89cc98761b8cb5a1a235a6b703ae50d34080e65" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/d89cc98761b8cb5a1a235a6b703ae50d34080e65", + "reference": "d89cc98761b8cb5a1a235a6b703ae50d34080e65", + "shasum": "" + }, + "require": { + "php": ">=7.3", + "sebastian/recursion-context": "^4.0" + }, + "require-dev": { + "ext-mbstring": "*", + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Volker Dusch", + "email": "github@wallbash.com" + }, + { + "name": "Adam Harvey", + "email": "aharvey@php.net" + }, + { + "name": "Bernhard Schussek", + "email": "bschussek@gmail.com" + } + ], + "description": "Provides the functionality to export PHP variables for visualization", + "homepage": "http://www.github.com/sebastianbergmann/exporter", + "keywords": [ + "export", + "exporter" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/exporter/issues", + "source": "https://github.com/sebastianbergmann/exporter/tree/4.0.3" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-09-28T05:24:23+00:00" + }, + { + "name": "sebastian/global-state", + "version": "5.0.2", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/global-state.git", + "reference": "a90ccbddffa067b51f574dea6eb25d5680839455" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/a90ccbddffa067b51f574dea6eb25d5680839455", + "reference": "a90ccbddffa067b51f574dea6eb25d5680839455", + "shasum": "" + }, + "require": { + "php": ">=7.3", + "sebastian/object-reflector": "^2.0", + "sebastian/recursion-context": "^4.0" + }, + "require-dev": { + "ext-dom": "*", + "phpunit/phpunit": "^9.3" + }, + "suggest": { + "ext-uopz": "*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "5.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Snapshotting of global state", + "homepage": "http://www.github.com/sebastianbergmann/global-state", + "keywords": [ + "global state" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/global-state/issues", + "source": "https://github.com/sebastianbergmann/global-state/tree/5.0.2" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-10-26T15:55:19+00:00" + }, + { + "name": "sebastian/lines-of-code", + "version": "1.0.3", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/lines-of-code.git", + "reference": "c1c2e997aa3146983ed888ad08b15470a2e22ecc" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/lines-of-code/zipball/c1c2e997aa3146983ed888ad08b15470a2e22ecc", + "reference": "c1c2e997aa3146983ed888ad08b15470a2e22ecc", + "shasum": "" + }, + "require": { + "nikic/php-parser": "^4.6", + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library for counting the lines of code in PHP source code", + "homepage": "https://github.com/sebastianbergmann/lines-of-code", + "support": { + "issues": "https://github.com/sebastianbergmann/lines-of-code/issues", + "source": "https://github.com/sebastianbergmann/lines-of-code/tree/1.0.3" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-11-28T06:42:11+00:00" + }, + { + "name": "sebastian/object-enumerator", + "version": "4.0.4", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/object-enumerator.git", + "reference": "5c9eeac41b290a3712d88851518825ad78f45c71" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/5c9eeac41b290a3712d88851518825ad78f45c71", + "reference": "5c9eeac41b290a3712d88851518825ad78f45c71", + "shasum": "" + }, + "require": { + "php": ">=7.3", + "sebastian/object-reflector": "^2.0", + "sebastian/recursion-context": "^4.0" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Traverses array structures and object graphs to enumerate all referenced objects", + "homepage": "https://github.com/sebastianbergmann/object-enumerator/", + "support": { + "issues": "https://github.com/sebastianbergmann/object-enumerator/issues", + "source": "https://github.com/sebastianbergmann/object-enumerator/tree/4.0.4" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-10-26T13:12:34+00:00" + }, + { + "name": "sebastian/object-reflector", + "version": "2.0.4", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/object-reflector.git", + "reference": "b4f479ebdbf63ac605d183ece17d8d7fe49c15c7" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/b4f479ebdbf63ac605d183ece17d8d7fe49c15c7", + "reference": "b4f479ebdbf63ac605d183ece17d8d7fe49c15c7", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Allows reflection of object attributes, including inherited and non-public ones", + "homepage": "https://github.com/sebastianbergmann/object-reflector/", + "support": { + "issues": "https://github.com/sebastianbergmann/object-reflector/issues", + "source": "https://github.com/sebastianbergmann/object-reflector/tree/2.0.4" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-10-26T13:14:26+00:00" + }, + { + "name": "sebastian/recursion-context", + "version": "4.0.4", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/recursion-context.git", + "reference": "cd9d8cf3c5804de4341c283ed787f099f5506172" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/cd9d8cf3c5804de4341c283ed787f099f5506172", + "reference": "cd9d8cf3c5804de4341c283ed787f099f5506172", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Adam Harvey", + "email": "aharvey@php.net" + } + ], + "description": "Provides functionality to recursively process PHP variables", + "homepage": "http://www.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" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-10-26T13:17:30+00:00" + }, + { + "name": "sebastian/resource-operations", + "version": "3.0.3", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/resource-operations.git", + "reference": "0f4443cb3a1d92ce809899753bc0d5d5a8dd19a8" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/resource-operations/zipball/0f4443cb3a1d92ce809899753bc0d5d5a8dd19a8", + "reference": "0f4443cb3a1d92ce809899753bc0d5d5a8dd19a8", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Provides a list of PHP built-in functions that operate on resources", + "homepage": "https://www.github.com/sebastianbergmann/resource-operations", + "support": { + "issues": "https://github.com/sebastianbergmann/resource-operations/issues", + "source": "https://github.com/sebastianbergmann/resource-operations/tree/3.0.3" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-09-28T06:45:17+00:00" + }, + { + "name": "sebastian/type", + "version": "2.3.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/type.git", + "reference": "81cd61ab7bbf2de744aba0ea61fae32f721df3d2" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/81cd61ab7bbf2de744aba0ea61fae32f721df3d2", + "reference": "81cd61ab7bbf2de744aba0ea61fae32f721df3d2", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.3-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Collection of value objects that represent the types of the PHP type system", + "homepage": "https://github.com/sebastianbergmann/type", + "support": { + "issues": "https://github.com/sebastianbergmann/type/issues", + "source": "https://github.com/sebastianbergmann/type/tree/2.3.1" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-10-26T13:18:59+00:00" + }, + { + "name": "sebastian/version", + "version": "3.0.2", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/version.git", + "reference": "c6c1022351a901512170118436c764e473f6de8c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/c6c1022351a901512170118436c764e473f6de8c", + "reference": "c6c1022351a901512170118436c764e473f6de8c", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library that helps with managing the version number of Git-hosted PHP projects", + "homepage": "https://github.com/sebastianbergmann/version", + "support": { + "issues": "https://github.com/sebastianbergmann/version/issues", + "source": "https://github.com/sebastianbergmann/version/tree/3.0.2" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-09-28T06:39:44+00:00" + }, + { + "name": "seld/jsonlint", + "version": "1.8.3", + "source": { + "type": "git", + "url": "https://github.com/Seldaek/jsonlint.git", + "reference": "9ad6ce79c342fbd44df10ea95511a1b24dee5b57" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Seldaek/jsonlint/zipball/9ad6ce79c342fbd44df10ea95511a1b24dee5b57", + "reference": "9ad6ce79c342fbd44df10ea95511a1b24dee5b57", + "shasum": "" + }, + "require": { + "php": "^5.3 || ^7.0 || ^8.0" + }, + "require-dev": { + "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.0" + }, + "bin": [ + "bin/jsonlint" + ], + "type": "library", + "autoload": { + "psr-4": { + "Seld\\JsonLint\\": "src/Seld/JsonLint/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be", + "homepage": "http://seld.be" + } + ], + "description": "JSON Linter", + "keywords": [ + "json", + "linter", + "parser", + "validator" + ], + "support": { + "issues": "https://github.com/Seldaek/jsonlint/issues", + "source": "https://github.com/Seldaek/jsonlint/tree/1.8.3" + }, + "funding": [ + { + "url": "https://github.com/Seldaek", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/seld/jsonlint", + "type": "tidelift" + } + ], + "time": "2020-11-11T09:19:24+00:00" + }, + { + "name": "seld/phar-utils", + "version": "1.1.1", + "source": { + "type": "git", + "url": "https://github.com/Seldaek/phar-utils.git", + "reference": "8674b1d84ffb47cc59a101f5d5a3b61e87d23796" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Seldaek/phar-utils/zipball/8674b1d84ffb47cc59a101f5d5a3b61e87d23796", + "reference": "8674b1d84ffb47cc59a101f5d5a3b61e87d23796", + "shasum": "" + }, + "require": { + "php": ">=5.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.x-dev" + } + }, + "autoload": { + "psr-4": { + "Seld\\PharUtils\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be" + } + ], + "description": "PHAR file format utilities, for when PHP phars you up", + "keywords": [ + "phar" + ], + "support": { + "issues": "https://github.com/Seldaek/phar-utils/issues", + "source": "https://github.com/Seldaek/phar-utils/tree/master" + }, + "time": "2020-07-07T18:42:57+00:00" + }, + { + "name": "squizlabs/php_codesniffer", + "version": "3.5.8", + "source": { + "type": "git", + "url": "https://github.com/squizlabs/PHP_CodeSniffer.git", + "reference": "9d583721a7157ee997f235f327de038e7ea6dac4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/squizlabs/PHP_CodeSniffer/zipball/9d583721a7157ee997f235f327de038e7ea6dac4", + "reference": "9d583721a7157ee997f235f327de038e7ea6dac4", + "shasum": "" + }, + "require": { + "ext-simplexml": "*", + "ext-tokenizer": "*", + "ext-xmlwriter": "*", + "php": ">=5.4.0" + }, + "require-dev": { + "phpunit/phpunit": "^4.0 || ^5.0 || ^6.0 || ^7.0" + }, + "bin": [ + "bin/phpcs", + "bin/phpcbf" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.x-dev" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Greg Sherwood", + "role": "lead" + } + ], + "description": "PHP_CodeSniffer tokenizes PHP, JavaScript and CSS files and detects violations of a defined set of coding standards.", + "homepage": "https://github.com/squizlabs/PHP_CodeSniffer", + "keywords": [ + "phpcs", + "standards" + ], + "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": "2020-10-23T02:01:07+00:00" + }, + { + "name": "sweetchuck/codeception-module-robo-task-runner", + "version": "1.x-dev", + "source": { + "type": "git", + "url": "https://github.com/Sweetchuck/codeception-module-robo-task-runner.git", + "reference": "05c02bc348ab34a65431d71c4ecbc4bfecf1b6d4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Sweetchuck/codeception-module-robo-task-runner/zipball/05c02bc348ab34a65431d71c4ecbc4bfecf1b6d4", + "reference": "05c02bc348ab34a65431d71c4ecbc4bfecf1b6d4", + "shasum": "" + }, + "require": { + "codeception/codeception": "^4.0", + "consolidation/robo": "^2.0", + "php": ">=7.3", + "symfony/process": "^4.0 || ^5.0" + }, + "require-dev": { + "phpunit/phpunit": "^8.0", + "squizlabs/php_codesniffer": "^3.5", + "sweetchuck/git-hooks": "^2.x-dev" + }, + "default-branch": true, + "type": "library", + "autoload": { + "psr-4": { + "Sweetchuck\\Codeception\\Module\\RoboTaskRunner\\": "src/", + "Sweetchuck\\Codeception\\Module\\RoboTaskRunner\\Tests\\Unit\\": "tests/unit/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "GPL-2.0-or-later" + ], + "description": "Runs a Robo task.", + "support": { + "issues": "https://github.com/Sweetchuck/codeception-module-robo-task-runner/issues", + "source": "https://github.com/Sweetchuck/codeception-module-robo-task-runner/tree/v0.9.0" + }, + "time": "2020-12-27T19:05:38+00:00" + }, + { + "name": "sweetchuck/git-hooks", + "version": "2.x-dev", + "source": { + "type": "git", + "url": "https://github.com/Sweetchuck/git-hooks.git", + "reference": "f8b285068fe5f5ffad4525de7490760306c23e76" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Sweetchuck/git-hooks/zipball/f8b285068fe5f5ffad4525de7490760306c23e76", + "reference": "f8b285068fe5f5ffad4525de7490760306c23e76", + "shasum": "" + }, + "require": { + "composer-plugin-api": "^2.0", + "ext-json": "*", + "ext-mbstring": "*", + "php": ">=7.3", + "webmozart/path-util": "^2.3" + }, + "require-dev": { + "codeception/codeception": "^4.1", + "codeception/module-asserts": "^1.1", + "composer/composer": "^2.0", + "consolidation/robo": "^2.0", + "squizlabs/php_codesniffer": "^3.5", + "sweetchuck/robo-git": "1.x-dev", + "sweetchuck/robo-phpcs": "1.x-dev" + }, + "default-branch": true, + "type": "composer-plugin", + "extra": { + "class": "\\Sweetchuck\\GitHooks\\Composer\\Plugin", + "sweetchuck/git-hooks": { + "symlink": true + } + }, + "autoload": { + "psr-4": { + "Sweetchuck\\GitHooks\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "GPL-2.0-or-later" + ], + "authors": [ + { + "name": "Andor", + "homepage": "https://github.com/Sweetchuck", + "role": "Maintainer" + } + ], + "description": "Provides a bridge between Git hooks and scripts under VCS.", + "homepage": "https://github.com/Sweetchuck/git-hooks", + "keywords": [ + "git-hooks" + ], + "support": { + "issues": "https://github.com/Sweetchuck/git-hooks/issues", + "source": "https://github.com/Sweetchuck/git-hooks" + }, + "time": "2020-12-28T10:19:24+00:00" + }, + { + "name": "sweetchuck/lint-report", + "version": "1.x-dev", + "source": { + "type": "git", + "url": "https://github.com/Sweetchuck/lint-report.git", + "reference": "8a28efd753c918b217db88d43ef82dae5dc0498e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Sweetchuck/lint-report/zipball/8a28efd753c918b217db88d43ef82dae5dc0498e", + "reference": "8a28efd753c918b217db88d43ef82dae5dc0498e", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-json": "*", + "league/container": "^2.2 || ^3.0", + "php": ">=7.3", + "symfony/console": "^3.0 || ^4.0 || ^5.0", + "symfony/filesystem": "^3.0 || ^4.0 || ^5.0", + "webmozart/path-util": "^2.3" + }, + "require-dev": { + "codeception/codeception": "^4.1", + "codeception/module-asserts": "^1.1", + "codeception/module-filesystem": "^1.0", + "mikey179/vfsstream": "^1.6", + "phpunit/phpunit": "^8.0", + "squizlabs/php_codesniffer": "^3.4", + "stecman/symfony-console-completion": "^0.11", + "sweetchuck/codeception-module-robo-task-runner": "1.x-dev", + "sweetchuck/git-hooks": "2.x-dev", + "sweetchuck/robo-git": "1.x-dev", + "symfony/yaml": "^3.0 || ^4.0 || ^5.0" + }, + "default-branch": true, + "type": "library", + "autoload": { + "psr-4": { + "Sweetchuck\\LintReport\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "GPL-3.0-or-later" + ], + "authors": [ + { + "name": "Andor", + "homepage": "https://github.com/Sweetchuck", + "role": "Maintainer" + } + ], + "description": "Generate reports from lint results", + "homepage": "https://github.com/Sweetchuck/lint-report", + "keywords": [ + "lint" + ], + "support": { + "issues": "https://github.com/Sweetchuck/lint-report/issues", + "source": "https://github.com/Sweetchuck/lint-report" + }, + "time": "2020-12-29T20:59:30+00:00" + }, + { + "name": "sweetchuck/robo-git", + "version": "1.x-dev", + "source": { + "type": "git", + "url": "https://github.com/Sweetchuck/robo-git.git", + "reference": "52b99c48c4c2deffa29103b727f307d103c935e8" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Sweetchuck/robo-git/zipball/52b99c48c4c2deffa29103b727f307d103c935e8", + "reference": "52b99c48c4c2deffa29103b727f307d103c935e8", + "shasum": "" + }, + "require": { + "consolidation/robo": "^2.0", + "php": ">=7.3" + }, + "require-dev": { + "codeception/codeception": "^4.0", + "codeception/module-asserts": "^1.1", + "ext-json": "*", + "phpunit/phpunit": "^8.0", + "squizlabs/php_codesniffer": "^3.0", + "sweetchuck/codeception-module-robo-task-runner": "1.x-dev", + "sweetchuck/git-hooks": "2.x-dev", + "symfony/debug": "^4.4 || ^5.0", + "symfony/error-handler": "^4.4 || ^5.0", + "symfony/finder": "^4.4 || ^5.0", + "webmozart/path-util": "^2.3" + }, + "default-branch": true, + "type": "robo-tasks", + "autoload": { + "psr-4": { + "Sweetchuck\\Robo\\Git\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "GPL-2.0-or-later" + ], + "authors": [ + { + "name": "Andor", + "homepage": "https://github.com/Sweetchuck", + "role": "Maintainer" + } + ], + "description": "Git related Robo tasks", + "homepage": "https://github.com/Sweetchuck/robo-git", + "keywords": [ + "git", + "robo-tasks" + ], + "support": { + "issues": "https://github.com/Sweetchuck/robo-git/issues", + "source": "https://github.com/Sweetchuck/robo-git" + }, + "time": "2020-12-28T13:07:44+00:00" + }, + { + "name": "sweetchuck/robo-phpcs", + "version": "1.x-dev", + "source": { + "type": "git", + "url": "https://github.com/Sweetchuck/robo-phpcs.git", + "reference": "8bc27da68784d67e48b639db7f670a99ef461f33" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Sweetchuck/robo-phpcs/zipball/8bc27da68784d67e48b639db7f670a99ef461f33", + "reference": "8bc27da68784d67e48b639db7f670a99ef461f33", + "shasum": "" + }, + "require": { + "consolidation/robo": "^2.0", + "ext-dom": "*", + "ext-json": "*", + "php": ">=7.3", + "sweetchuck/lint-report": "1.x-dev", + "webmozart/path-util": "^2.3" + }, + "require-dev": { + "codeception/codeception": "^4.0", + "codeception/module-asserts": "^1.1", + "cweagans/composer-patches": "^1.6", + "mikey179/vfsstream": "^1.6", + "phpunit/phpunit": "^8.0", + "squizlabs/php_codesniffer": "^3.0", + "sweetchuck/codeception-module-robo-task-runner": "1.x-dev", + "sweetchuck/git-hooks": "2.x-dev", + "sweetchuck/robo-git": "1.x-dev", + "symfony/yaml": "^4.0 || ^5.0" + }, + "default-branch": true, + "type": "robo-tasks", + "autoload": { + "psr-4": { + "Sweetchuck\\Robo\\Phpcs\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "GPL-2.0-or-later" + ], + "authors": [ + { + "name": "Andor", + "homepage": "https://github.com/Sweetchuck", + "role": "Maintainer" + } + ], + "description": "Robo task wrapper for PHPCS", + "homepage": "https://github.com/Sweetchuck/robo-phpcs", + "keywords": [ + "PHP_CodeSniffer", + "phpcs", + "robo-tasks" + ], + "support": { + "issues": "https://github.com/Sweetchuck/robo-phpcs/issues", + "source": "https://github.com/Sweetchuck/robo-phpcs" + }, + "time": "2020-12-29T20:39:58+00:00" + }, + { + "name": "sweetchuck/robo-phpmd", + "version": "1.x-dev", + "source": { + "type": "git", + "url": "https://github.com/Sweetchuck/robo-phpmd.git", + "reference": "4ed62bdab110ccbe113525b1a82b7008294762f6" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Sweetchuck/robo-phpmd/zipball/4ed62bdab110ccbe113525b1a82b7008294762f6", + "reference": "4ed62bdab110ccbe113525b1a82b7008294762f6", + "shasum": "" + }, + "require": { + "consolidation/robo": "^2.0", + "danielstjules/stringy": "^3.1", + "php": ">=7.3", + "webmozart/path-util": "^2.3" + }, + "require-dev": { + "codeception/codeception": "^4.0", + "codeception/module-asserts": "^1.1", + "ext-json": "*", + "mikey179/vfsstream": "^1.6", + "phpmd/phpmd": "^2.6", + "phpunit/phpunit": "^8.0", + "squizlabs/php_codesniffer": "^3.5", + "sweetchuck/codeception-module-robo-task-runner": "^0.9", + "sweetchuck/git-hooks": "2.x-dev", + "sweetchuck/robo-git": "1.x-dev", + "sweetchuck/robo-phpcs": "1.x-dev", + "symfony/error-handler": "4.0 || ^5.0", + "symfony/finder": "^4.0 || ^5.0", + "symfony/yaml": "^4.0 || ^5.0" + }, + "suggest": { + "phpmd/phpmd": "After all the 'phpmd' executable has to be available." + }, + "default-branch": true, + "type": "robo-tasks", + "autoload": { + "psr-4": { + "Sweetchuck\\Robo\\PhpMessDetector\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "GPL-2.0-or-later" + ], + "authors": [ + { + "name": "Andor", + "homepage": "https://github.com/Sweetchuck", + "role": "Maintainer" + } + ], + "description": "Robo task wrapper for PHPMD commands", + "keywords": [ + "php-mess-detector", + "phpmd", + "robo-tasks" + ], + "support": { + "issues": "https://github.com/Sweetchuck/robo-phpmd/issues", + "source": "https://github.com/Sweetchuck/robo-phpmd" + }, + "time": "2020-12-28T19:40:24+00:00" + }, + { + "name": "symfony/console", + "version": "v5.2.1", + "source": { + "type": "git", + "url": "https://github.com/symfony/console.git", + "reference": "47c02526c532fb381374dab26df05e7313978976" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/console/zipball/47c02526c532fb381374dab26df05e7313978976", + "reference": "47c02526c532fb381374dab26df05e7313978976", + "shasum": "" + }, + "require": { + "php": ">=7.2.5", + "symfony/polyfill-mbstring": "~1.0", + "symfony/polyfill-php73": "^1.8", + "symfony/polyfill-php80": "^1.15", + "symfony/service-contracts": "^1.1|^2", + "symfony/string": "^5.1" + }, + "conflict": { + "symfony/dependency-injection": "<4.4", + "symfony/dotenv": "<5.1", + "symfony/event-dispatcher": "<4.4", + "symfony/lock": "<4.4", + "symfony/process": "<4.4" + }, + "provide": { + "psr/log-implementation": "1.0" + }, + "require-dev": { + "psr/log": "~1.0", + "symfony/config": "^4.4|^5.0", + "symfony/dependency-injection": "^4.4|^5.0", + "symfony/event-dispatcher": "^4.4|^5.0", + "symfony/lock": "^4.4|^5.0", + "symfony/process": "^4.4|^5.0", + "symfony/var-dumper": "^4.4|^5.0" + }, + "suggest": { + "psr/log": "For using the console logger", + "symfony/event-dispatcher": "", + "symfony/lock": "", + "symfony/process": "" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Console\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony Console Component", + "homepage": "https://symfony.com", + "keywords": [ + "cli", + "command line", + "console", + "terminal" + ], + "support": { + "source": "https://github.com/symfony/console/tree/v5.2.1" + }, + "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": "2020-12-18T08:03:05+00:00" + }, + { + "name": "symfony/css-selector", + "version": "v5.2.1", + "source": { + "type": "git", + "url": "https://github.com/symfony/css-selector.git", + "reference": "f789e7ead4c79e04ca9a6d6162fc629c89bd8054" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/css-selector/zipball/f789e7ead4c79e04ca9a6d6162fc629c89bd8054", + "reference": "f789e7ead4c79e04ca9a6d6162fc629c89bd8054", + "shasum": "" + }, + "require": { + "php": ">=7.2.5" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\CssSelector\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Jean-François Simon", + "email": "jeanfrancois.simon@sensiolabs.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony CssSelector Component", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/css-selector/tree/v5.2.1" + }, + "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": "2020-12-08T17:02:38+00:00" + }, + { + "name": "symfony/deprecation-contracts", + "version": "v2.2.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/deprecation-contracts.git", + "reference": "5fa56b4074d1ae755beb55617ddafe6f5d78f665" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/5fa56b4074d1ae755beb55617ddafe6f5d78f665", + "reference": "5fa56b4074d1ae755beb55617ddafe6f5d78f665", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.2-dev" + }, + "thanks": { + "name": "symfony/contracts", + "url": "https://github.com/symfony/contracts" + } + }, + "autoload": { + "files": [ + "function.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "A generic function and convention to trigger deprecation notices", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/deprecation-contracts/tree/master" + }, + "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": "2020-09-07T11:33:47+00:00" + }, + { + "name": "symfony/error-handler", + "version": "v5.2.1", + "source": { + "type": "git", + "url": "https://github.com/symfony/error-handler.git", + "reference": "59b190ce16ddf32771a22087b60f6dafd3407147" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/error-handler/zipball/59b190ce16ddf32771a22087b60f6dafd3407147", + "reference": "59b190ce16ddf32771a22087b60f6dafd3407147", + "shasum": "" + }, + "require": { + "php": ">=7.2.5", + "psr/log": "^1.0", + "symfony/polyfill-php80": "^1.15", + "symfony/var-dumper": "^4.4|^5.0" + }, + "require-dev": { + "symfony/deprecation-contracts": "^2.1", + "symfony/http-kernel": "^4.4|^5.0", + "symfony/serializer": "^4.4|^5.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\ErrorHandler\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony ErrorHandler Component", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/error-handler/tree/v5.2.1" + }, + "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": "2020-12-09T18:54:12+00:00" + }, + { + "name": "symfony/event-dispatcher", + "version": "v5.2.1", + "source": { + "type": "git", + "url": "https://github.com/symfony/event-dispatcher.git", + "reference": "1c93f7a1dff592c252574c79a8635a8a80856042" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/1c93f7a1dff592c252574c79a8635a8a80856042", + "reference": "1c93f7a1dff592c252574c79a8635a8a80856042", + "shasum": "" + }, + "require": { + "php": ">=7.2.5", + "symfony/deprecation-contracts": "^2.1", + "symfony/event-dispatcher-contracts": "^2", + "symfony/polyfill-php80": "^1.15" + }, + "conflict": { + "symfony/dependency-injection": "<4.4" + }, + "provide": { + "psr/event-dispatcher-implementation": "1.0", + "symfony/event-dispatcher-implementation": "2.0" + }, + "require-dev": { + "psr/log": "~1.0", + "symfony/config": "^4.4|^5.0", + "symfony/dependency-injection": "^4.4|^5.0", + "symfony/error-handler": "^4.4|^5.0", + "symfony/expression-language": "^4.4|^5.0", + "symfony/http-foundation": "^4.4|^5.0", + "symfony/service-contracts": "^1.1|^2", + "symfony/stopwatch": "^4.4|^5.0" + }, + "suggest": { + "symfony/dependency-injection": "", + "symfony/http-kernel": "" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\EventDispatcher\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony EventDispatcher Component", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/event-dispatcher/tree/v5.2.1" + }, + "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": "2020-12-18T08:03:05+00:00" + }, + { + "name": "symfony/event-dispatcher-contracts", + "version": "v2.2.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/event-dispatcher-contracts.git", + "reference": "0ba7d54483095a198fa51781bc608d17e84dffa2" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/event-dispatcher-contracts/zipball/0ba7d54483095a198fa51781bc608d17e84dffa2", + "reference": "0ba7d54483095a198fa51781bc608d17e84dffa2", + "shasum": "" + }, + "require": { + "php": ">=7.2.5", + "psr/event-dispatcher": "^1" + }, + "suggest": { + "symfony/event-dispatcher-implementation": "" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.2-dev" + }, + "thanks": { + "name": "symfony/contracts", + "url": "https://github.com/symfony/contracts" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Contracts\\EventDispatcher\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Generic abstractions related to dispatching event", + "homepage": "https://symfony.com", + "keywords": [ + "abstractions", + "contracts", + "decoupling", + "interfaces", + "interoperability", + "standards" + ], + "support": { + "source": "https://github.com/symfony/event-dispatcher-contracts/tree/v2.2.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": "2020-09-07T11:33:47+00:00" + }, + { + "name": "symfony/filesystem", + "version": "v5.2.1", + "source": { + "type": "git", + "url": "https://github.com/symfony/filesystem.git", + "reference": "fa8f8cab6b65e2d99a118e082935344c5ba8c60d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/filesystem/zipball/fa8f8cab6b65e2d99a118e082935344c5ba8c60d", + "reference": "fa8f8cab6b65e2d99a118e082935344c5ba8c60d", + "shasum": "" + }, + "require": { + "php": ">=7.2.5", + "symfony/polyfill-ctype": "~1.8" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Filesystem\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony Filesystem Component", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/filesystem/tree/v5.2.1" + }, + "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": "2020-11-30T17:05:38+00:00" + }, + { + "name": "symfony/finder", + "version": "v5.2.1", + "source": { + "type": "git", + "url": "https://github.com/symfony/finder.git", + "reference": "0b9231a5922fd7287ba5b411893c0ecd2733e5ba" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/finder/zipball/0b9231a5922fd7287ba5b411893c0ecd2733e5ba", + "reference": "0b9231a5922fd7287ba5b411893c0ecd2733e5ba", + "shasum": "" + }, + "require": { + "php": ">=7.2.5" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Finder\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony Finder Component", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/finder/tree/v5.2.1" + }, + "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": "2020-12-08T17:02:38+00:00" + }, + { + "name": "symfony/polyfill-ctype", + "version": "v1.22.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-ctype.git", + "reference": "c6c942b1ac76c82448322025e084cadc56048b4e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/c6c942b1ac76c82448322025e084cadc56048b4e", + "reference": "c6c942b1ac76c82448322025e084cadc56048b4e", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "suggest": { + "ext-ctype": "For best performance" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.22-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Polyfill\\Ctype\\": "" + }, + "files": [ + "bootstrap.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Gert de Pagter", + "email": "BackEndTea@gmail.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for ctype functions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "ctype", + "polyfill", + "portable" + ], + "support": { + "source": "https://github.com/symfony/polyfill-ctype/tree/v1.22.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": "2021-01-07T16:49:33+00:00" + }, + { + "name": "symfony/polyfill-intl-grapheme", + "version": "v1.22.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-intl-grapheme.git", + "reference": "267a9adeb8ecb8071040a740930e077cdfb987af" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/267a9adeb8ecb8071040a740930e077cdfb987af", + "reference": "267a9adeb8ecb8071040a740930e077cdfb987af", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "suggest": { + "ext-intl": "For best performance" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.22-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Polyfill\\Intl\\Grapheme\\": "" + }, + "files": [ + "bootstrap.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for intl's grapheme_* functions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "grapheme", + "intl", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.22.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": "2021-01-07T16:49:33+00:00" + }, + { + "name": "symfony/polyfill-intl-normalizer", + "version": "v1.22.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-intl-normalizer.git", + "reference": "6e971c891537eb617a00bb07a43d182a6915faba" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/6e971c891537eb617a00bb07a43d182a6915faba", + "reference": "6e971c891537eb617a00bb07a43d182a6915faba", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "suggest": { + "ext-intl": "For best performance" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.22-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Polyfill\\Intl\\Normalizer\\": "" + }, + "files": [ + "bootstrap.php" + ], + "classmap": [ + "Resources/stubs" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for intl's Normalizer class and related functions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "intl", + "normalizer", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.22.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": "2021-01-07T17:09:11+00:00" + }, + { + "name": "symfony/polyfill-mbstring", + "version": "v1.22.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-mbstring.git", + "reference": "f377a3dd1fde44d37b9831d68dc8dea3ffd28e13" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/f377a3dd1fde44d37b9831d68dc8dea3ffd28e13", + "reference": "f377a3dd1fde44d37b9831d68dc8dea3ffd28e13", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "suggest": { + "ext-mbstring": "For best performance" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.22-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Polyfill\\Mbstring\\": "" + }, + "files": [ + "bootstrap.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for the Mbstring extension", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "mbstring", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.22.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": "2021-01-07T16:49:33+00:00" + }, + { + "name": "symfony/polyfill-php73", + "version": "v1.22.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-php73.git", + "reference": "a678b42e92f86eca04b7fa4c0f6f19d097fb69e2" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-php73/zipball/a678b42e92f86eca04b7fa4c0f6f19d097fb69e2", + "reference": "a678b42e92f86eca04b7fa4c0f6f19d097fb69e2", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.22-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Polyfill\\Php73\\": "" + }, + "files": [ + "bootstrap.php" + ], + "classmap": [ + "Resources/stubs" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill backporting some PHP 7.3+ features to lower PHP versions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-php73/tree/v1.22.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": "2021-01-07T16:49:33+00:00" + }, + { + "name": "symfony/polyfill-php80", + "version": "v1.22.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-php80.git", + "reference": "dc3063ba22c2a1fd2f45ed856374d79114998f91" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/dc3063ba22c2a1fd2f45ed856374d79114998f91", + "reference": "dc3063ba22c2a1fd2f45ed856374d79114998f91", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.22-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Polyfill\\Php80\\": "" + }, + "files": [ + "bootstrap.php" + ], + "classmap": [ + "Resources/stubs" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Ion Bazan", + "email": "ion.bazan@gmail.com" + }, + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill backporting some PHP 8.0+ features to lower PHP versions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-php80/tree/v1.22.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": "2021-01-07T16:49:33+00:00" + }, + { + "name": "symfony/process", + "version": "v5.2.1", + "source": { + "type": "git", + "url": "https://github.com/symfony/process.git", + "reference": "bd8815b8b6705298beaa384f04fabd459c10bedd" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/process/zipball/bd8815b8b6705298beaa384f04fabd459c10bedd", + "reference": "bd8815b8b6705298beaa384f04fabd459c10bedd", + "shasum": "" + }, + "require": { + "php": ">=7.2.5", + "symfony/polyfill-php80": "^1.15" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Process\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony Process Component", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/process/tree/v5.2.1" + }, + "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": "2020-12-08T17:03:37+00:00" + }, + { + "name": "symfony/service-contracts", + "version": "v2.2.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/service-contracts.git", + "reference": "d15da7ba4957ffb8f1747218be9e1a121fd298a1" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/service-contracts/zipball/d15da7ba4957ffb8f1747218be9e1a121fd298a1", + "reference": "d15da7ba4957ffb8f1747218be9e1a121fd298a1", + "shasum": "" + }, + "require": { + "php": ">=7.2.5", + "psr/container": "^1.0" + }, + "suggest": { + "symfony/service-implementation": "" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.2-dev" + }, + "thanks": { + "name": "symfony/contracts", + "url": "https://github.com/symfony/contracts" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Contracts\\Service\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Generic abstractions related to writing services", + "homepage": "https://symfony.com", + "keywords": [ + "abstractions", + "contracts", + "decoupling", + "interfaces", + "interoperability", + "standards" + ], + "support": { + "source": "https://github.com/symfony/service-contracts/tree/master" + }, + "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": "2020-09-07T11:33:47+00:00" + }, + { + "name": "symfony/string", + "version": "v5.2.1", + "source": { + "type": "git", + "url": "https://github.com/symfony/string.git", + "reference": "5bd67751d2e3f7d6f770c9154b8fbcb2aa05f7ed" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/string/zipball/5bd67751d2e3f7d6f770c9154b8fbcb2aa05f7ed", + "reference": "5bd67751d2e3f7d6f770c9154b8fbcb2aa05f7ed", + "shasum": "" + }, + "require": { + "php": ">=7.2.5", + "symfony/polyfill-ctype": "~1.8", + "symfony/polyfill-intl-grapheme": "~1.0", + "symfony/polyfill-intl-normalizer": "~1.0", + "symfony/polyfill-mbstring": "~1.0", + "symfony/polyfill-php80": "~1.15" + }, + "require-dev": { + "symfony/error-handler": "^4.4|^5.0", + "symfony/http-client": "^4.4|^5.0", + "symfony/translation-contracts": "^1.1|^2", + "symfony/var-exporter": "^4.4|^5.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\String\\": "" + }, + "files": [ + "Resources/functions.php" + ], + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony String component", + "homepage": "https://symfony.com", + "keywords": [ + "grapheme", + "i18n", + "string", + "unicode", + "utf-8", + "utf8" + ], + "support": { + "source": "https://github.com/symfony/string/tree/v5.2.1" + }, + "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": "2020-12-05T07:33:16+00:00" + }, + { + "name": "symfony/var-dumper", + "version": "v5.2.1", + "source": { + "type": "git", + "url": "https://github.com/symfony/var-dumper.git", + "reference": "13e7e882eaa55863faa7c4ad7c60f12f1a8b5089" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/var-dumper/zipball/13e7e882eaa55863faa7c4ad7c60f12f1a8b5089", + "reference": "13e7e882eaa55863faa7c4ad7c60f12f1a8b5089", + "shasum": "" + }, + "require": { + "php": ">=7.2.5", + "symfony/polyfill-mbstring": "~1.0", + "symfony/polyfill-php80": "^1.15" + }, + "conflict": { + "phpunit/phpunit": "<5.4.3", + "symfony/console": "<4.4" + }, + "require-dev": { + "ext-iconv": "*", + "symfony/console": "^4.4|^5.0", + "symfony/process": "^4.4|^5.0", + "twig/twig": "^2.4|^3.0" + }, + "suggest": { + "ext-iconv": "To convert non-UTF-8 strings to UTF-8 (or symfony/polyfill-iconv in case ext-iconv cannot be used).", + "ext-intl": "To show region name in time zone dump", + "symfony/console": "To use the ServerDumpCommand and/or the bin/var-dump-server script" + }, + "bin": [ + "Resources/bin/var-dump-server" + ], + "type": "library", + "autoload": { + "files": [ + "Resources/functions/dump.php" + ], + "psr-4": { + "Symfony\\Component\\VarDumper\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony mechanism for exploring and dumping PHP variables", + "homepage": "https://symfony.com", + "keywords": [ + "debug", + "dump" + ], + "support": { + "source": "https://github.com/symfony/var-dumper/tree/v5.2.1" + }, + "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": "2020-12-16T17:02:19+00:00" + }, + { + "name": "symfony/yaml", + "version": "v5.2.1", + "source": { + "type": "git", + "url": "https://github.com/symfony/yaml.git", + "reference": "290ea5e03b8cf9b42c783163123f54441fb06939" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/yaml/zipball/290ea5e03b8cf9b42c783163123f54441fb06939", + "reference": "290ea5e03b8cf9b42c783163123f54441fb06939", + "shasum": "" + }, + "require": { + "php": ">=7.2.5", + "symfony/deprecation-contracts": "^2.1", + "symfony/polyfill-ctype": "~1.8" + }, + "conflict": { + "symfony/console": "<4.4" + }, + "require-dev": { + "symfony/console": "^4.4|^5.0" + }, + "suggest": { + "symfony/console": "For validating YAML files using the lint command" + }, + "bin": [ + "Resources/bin/yaml-lint" + ], + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Yaml\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony Yaml Component", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/yaml/tree/v5.2.1" + }, + "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": "2020-12-08T17:02:38+00:00" + }, + { + "name": "theseer/tokenizer", + "version": "1.2.0", + "source": { + "type": "git", + "url": "https://github.com/theseer/tokenizer.git", + "reference": "75a63c33a8577608444246075ea0af0d052e452a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/theseer/tokenizer/zipball/75a63c33a8577608444246075ea0af0d052e452a", + "reference": "75a63c33a8577608444246075ea0af0d052e452a", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-tokenizer": "*", + "ext-xmlwriter": "*", + "php": "^7.2 || ^8.0" + }, + "type": "library", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Arne Blankerts", + "email": "arne@blankerts.de", + "role": "Developer" + } + ], + "description": "A small library for converting tokenized PHP source code into XML and potentially other formats", + "support": { + "issues": "https://github.com/theseer/tokenizer/issues", + "source": "https://github.com/theseer/tokenizer/tree/master" + }, + "funding": [ + { + "url": "https://github.com/theseer", + "type": "github" + } + ], + "time": "2020-07-12T23:59:07+00:00" + }, + { + "name": "webmozart/assert", + "version": "1.9.1", + "source": { + "type": "git", + "url": "https://github.com/webmozart/assert.git", + "reference": "bafc69caeb4d49c39fd0779086c03a3738cbb389" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/webmozart/assert/zipball/bafc69caeb4d49c39fd0779086c03a3738cbb389", + "reference": "bafc69caeb4d49c39fd0779086c03a3738cbb389", + "shasum": "" + }, + "require": { + "php": "^5.3.3 || ^7.0 || ^8.0", + "symfony/polyfill-ctype": "^1.8" + }, + "conflict": { + "phpstan/phpstan": "<0.12.20", + "vimeo/psalm": "<3.9.1" + }, + "require-dev": { + "phpunit/phpunit": "^4.8.36 || ^7.5.13" + }, + "type": "library", + "autoload": { + "psr-4": { + "Webmozart\\Assert\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Bernhard Schussek", + "email": "bschussek@gmail.com" + } + ], + "description": "Assertions to validate method input/output with nice error messages.", + "keywords": [ + "assert", + "check", + "validate" + ], + "support": { + "issues": "https://github.com/webmozart/assert/issues", + "source": "https://github.com/webmozart/assert/tree/master" + }, + "time": "2020-07-08T17:02:28+00:00" + }, + { + "name": "webmozart/path-util", + "version": "2.3.0", + "source": { + "type": "git", + "url": "https://github.com/webmozart/path-util.git", + "reference": "d939f7edc24c9a1bb9c0dee5cb05d8e859490725" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/webmozart/path-util/zipball/d939f7edc24c9a1bb9c0dee5cb05d8e859490725", + "reference": "d939f7edc24c9a1bb9c0dee5cb05d8e859490725", + "shasum": "" + }, + "require": { + "php": ">=5.3.3", + "webmozart/assert": "~1.0" + }, + "require-dev": { + "phpunit/phpunit": "^4.6", + "sebastian/version": "^1.0.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.3-dev" + } + }, + "autoload": { + "psr-4": { + "Webmozart\\PathUtil\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Bernhard Schussek", + "email": "bschussek@gmail.com" + } + ], + "description": "A robust cross-platform utility for normalizing, comparing and modifying file paths.", + "support": { + "issues": "https://github.com/webmozart/path-util/issues", + "source": "https://github.com/webmozart/path-util/tree/2.3.0" + }, + "time": "2015-12-17T08:42:14+00:00" + } + ], + "aliases": [], + "minimum-stability": "dev", + "stability-flags": { + "sweetchuck/codeception-module-robo-task-runner": 20, + "sweetchuck/git-hooks": 20, + "sweetchuck/robo-git": 20, + "sweetchuck/robo-phpcs": 20, + "sweetchuck/robo-phpmd": 20 + }, + "prefer-stable": true, + "prefer-lowest": false, + "platform": { + "php": ">=7.4", + "ext-json": "*", + "composer-plugin-api": "^2.0" + }, + "platform-dev": [], + "plugin-api-version": "2.0.0" +} diff --git a/phpcs.xml.dist b/phpcs.xml.dist new file mode 100644 index 0000000..9818fa1 --- /dev/null +++ b/phpcs.xml.dist @@ -0,0 +1,25 @@ + + + + ./src/ + ./tests/ + ./tests/_data/ + ./tests/_output/ + ./tests/_support/generated + ./RoboFile.php + + + + + ./tests/*/*Base.php + ./tests/_support/Helper/Acceptance.php + ./tests/_support/Helper/Unit.php + + + + ./RoboFile.php + + diff --git a/src/Composer/Command/CommandBase.php b/src/Composer/Command/CommandBase.php new file mode 100644 index 0000000..e302e51 --- /dev/null +++ b/src/Composer/Command/CommandBase.php @@ -0,0 +1,86 @@ +input; + } + + /** + * @return $this + */ + public function setInput(InputInterface $input) + { + $this->input = $input; + + return $this; + } + + protected OutputInterface $output; + + public function getOutput(): OutputInterface + { + return $this->output; + } + + /** + * @return $this + */ + public function setOutput(OutputInterface $output) + { + $this->output = $output; + + return $this; + } + + /** + * {@inheritDoc} + */ + public function __construct( + string $name = null, + ?SuiteHandler $generator = null, + ?Filesystem $fs = null + ) { + $this->suiteHandler = $generator ?: new SuiteHandler(); + $this->fs = $fs ?: new Filesystem(); + parent::__construct($name); + } + + /** + * {@inheritDoc} + */ + protected function execute(InputInterface $input, OutputInterface $output) + { + try { + $this + ->setInput($input) + ->setOutput($output) + ->doIt(); + } catch (\Exception $e) { + $this->getIO()->error($e->getMessage()); + + return 1; + } + + return $this->result['exitCode']; + } +} diff --git a/src/Composer/Command/GenerateCommand.php b/src/Composer/Command/GenerateCommand.php new file mode 100644 index 0000000..118710b --- /dev/null +++ b/src/Composer/Command/GenerateCommand.php @@ -0,0 +1,80 @@ +getName()) { + $this->setName('suite:generate'); + } + + $this->setDescription('DESC Generates composer..json files.'); + $this->setHelp('HELP Generates composer..json files.'); + } + + protected function doIt() + { + $this->result = [ + 'exitCode' => 0, + ]; + + $package = $this->getComposer()->getPackage(); + //$packageDumper = new ArrayDumper(); + $composerFile = ComposerFactory::getComposerFile(); + $composerContent = file_get_contents($composerFile) ?: '{}'; + $composerData = $this->suiteHandler->decode($composerContent); + //$composerData = $packageDumper->dump($package); + + $extra = $package->getExtra(); + $suites = $extra[Plugin::NAME] ?? []; + foreach ($suites as $suiteName => $actions) { + //codecept_debug($actions); + $suiteFileName = $this->suiteHandler->suiteFileName($suiteName, $composerFile); + $suiteData = $this->suiteHandler->generate($composerData, $actions); + $action = $this->suiteHandler->whatToDo($suiteFileName, $suiteData); + $this->doItMessage($action, $suiteFileName); + if (in_array($action, ['create', 'update'])) { + $this->fs->dumpFile( + $suiteFileName, + $this->suiteHandler->encode($suiteData), + ); + } + } + + return $this; + } + + protected function doItMessage(string $action, string $fileName) + { + $io = $this->getIO(); + switch ($action) { + case 'skip': + $io->info("no need to update $fileName"); + break; + + case 'create': + $io->info("create $fileName"); + break; + + case 'update': + $io->info("update $fileName"); + break; + } + + return $this; + } +} diff --git a/src/Composer/CommandProvider.php b/src/Composer/CommandProvider.php new file mode 100644 index 0000000..0af0971 --- /dev/null +++ b/src/Composer/CommandProvider.php @@ -0,0 +1,21 @@ + 'onCommandEvent', + ]; + } + + public function __construct(?SuiteHandler $suiteHandler = null) + { + $this->suiteHandler = $suiteHandler ?: new SuiteHandler(); + } + + /** + * {@inheritDoc} + */ + public function getCapabilities() + { + return [ + ComposerCommandProvider::class => CommandProvider::class, + ]; + } + + /** + * {@inheritDoc} + */ + public function activate(Composer $composer, IOInterface $io) + { + // Nothing to do here. + $this->composer = $composer; + $this->io = $io; + } + + /** + * {@inheritDoc} + */ + public function deactivate(Composer $composer, IOInterface $io) + { + // Nothing to do here. + $this->composer = $composer; + $this->io = $io; + } + + /** + * {@inheritDoc} + */ + public function uninstall(Composer $composer, IOInterface $io) + { + // Nothing to do here. + $this->composer = $composer; + $this->io = $io; + } + + public function onCommandEvent(CommandEvent $event): bool + { + switch ($event->getCommandName()) { + case 'validate': + return $this->onCommandEventValidate(); + } + + return true; + } + + protected function onCommandEventValidate(): bool + { + $pluginName = static::NAME; + $extra = $this->composer->getPackage()->getExtra(); + $suites = $extra[$pluginName] ?? []; + + $composerFile = ComposerFactory::getComposerFile(); + // Very likely somebody else will rise an error. + $composerContent = file_get_contents($composerFile) ?: '{}'; + $composerData = $this->suiteHandler->decode($composerContent); + + $existingSuiteFiles = $this->suiteHandler->collectSuiteComposerFiles($composerFile); + $extraSuiteFiles = array_diff_key( + array_flip($existingSuiteFiles), + $suites, + ); + foreach ($extraSuiteFiles as $suiteName => $suiteFile) { + $this->io->error("{$pluginName} - ./{$suiteFile} exists, but not defined"); + } + + $isUpToDate = true; + foreach ($suites as $suiteName => $actions) { + $newData = $this->suiteHandler->generate($composerData, $actions); + $newFileName = $this->suiteHandler->suiteFileName($suiteName, $composerFile); + $whatToDo = $this->suiteHandler->whatToDo($newFileName, $newData); + if ($whatToDo === 'skip') { + continue; + } + + switch ($whatToDo) { + case 'create': + $this->io->error("{$pluginName} - {$newFileName} is is not exists"); + break; + + case 'update': + $this->io->error("{$pluginName} - {$newFileName} is is not up to date"); + break; + } + + $isUpToDate = false; + } + + return $isUpToDate; + } +} diff --git a/src/NestedArray.php b/src/NestedArray.php new file mode 100644 index 0000000..6844699 --- /dev/null +++ b/src/NestedArray.php @@ -0,0 +1,421 @@ + 'text_format', + * '#title' => t('Signature'), + * ); + * // Or, it might be further nested: + * $form['signature_settings']['user']['signature'] = array( + * '#type' => 'text_format', + * '#title' => t('Signature'), + * ); + * @endcode + * + * To deal with the situation, the code needs to figure out the route to + * the + * element, given an array of parents that is either + * @code array('signature_settings', 'signature') @endcode + * in the first case or + * @code array('signature_settings', 'user', 'signature') @endcode + * in the second case. + * + * Without this helper function the only way to set the signature element + * in + * one line would be using eval(), which should be avoided: + * @code + * // Do not do this! Avoid eval(). + * eval('$form[\'' . implode("']['", $parents) . '\'] = $element;'); + * @endcode + * + * Instead, use this helper function: + * @code + * NestedArray::setValue($form, $parents, $element); + * @endcode + * + * However if the number of array parent keys is static, the value should + * always be set directly rather than calling this function. For instance, + * for the first example we could just do: + * @code + * $form['signature_settings']['signature'] = $element; + * @endcode + * + * @param array $array + * A reference to the array to modify. + * @param array $parents + * An array of parent keys, starting with the outermost key. + * @param mixed $value + * The value to set. + * @param bool $force + * (optional) If TRUE, the value is forced into the structure even if it + * requires the deletion of an already existing non-array parent value. + * If + * FALSE, PHP throws an error if trying to add into a value that is not + * an + * array. Defaults to FALSE. + * + * @see NestedArray::unsetValue() + * @see NestedArray::getValue() + */ + public static function setValue( + array &$array, + array $parents, + $value, + $force = false + ) { + $ref = &$array; + foreach ($parents as $parent) { + // PHP auto-creates container arrays and NULL entries without error if $ref + // is NULL, but throws an error if $ref is set, but not an array. + if ($force && isset($ref) && !is_array($ref)) { + $ref = []; + } + $ref = &$ref[$parent]; + } + $ref = $value; + } + + /** + * Unsets a value in a nested array with variable depth. + * + * This helper function should be used when the depth of the array element + * you are changing may vary (that is, the number of parent keys is + * variable). It is primarily used for form structures and renderable + * arrays. + * + * Example: + * + * @code + * // Assume you have a 'signature' element somewhere in a form. It might + * be: + * $form['signature_settings']['signature'] = array( + * '#type' => 'text_format', + * '#title' => t('Signature'), + * ); + * // Or, it might be further nested: + * $form['signature_settings']['user']['signature'] = array( + * '#type' => 'text_format', + * '#title' => t('Signature'), + * ); + * @endcode + * + * To deal with the situation, the code needs to figure out the route to + * the + * element, given an array of parents that is either + * @code array('signature_settings', 'signature') @endcode + * in the first case or + * @code array('signature_settings', 'user', 'signature') @endcode + * in the second case. + * + * Without this helper function the only way to unset the signature element + * in one line would be using eval(), which should be avoided: + * @code + * // Do not do this! Avoid eval(). + * eval('unset($form[\'' . implode("']['", $parents) . '\']);'); + * @endcode + * + * Instead, use this helper function: + * @code + * NestedArray::unset_nested_value($form, $parents, $element); + * @endcode + * + * However if the number of array parent keys is static, the value should + * always be set directly rather than calling this function. For instance, + * for the first example we could just do: + * @code + * unset($form['signature_settings']['signature']); + * @endcode + * + * @param array $array + * A reference to the array to modify. + * @param array $parents + * An array of parent keys, starting with the outermost key and including + * the key to be unset. + * @param bool $key_existed + * (optional) If given, an already defined variable that is altered by + * reference. + * + * @see NestedArray::setValue() + * @see NestedArray::getValue() + */ + public static function unsetValue( + array &$array, + array $parents, + &$key_existed = null + ) { + $unset_key = array_pop($parents); + $ref = &self::getValue($array, $parents, $key_existed); + if ($key_existed && is_array($ref) + && (isset($ref[$unset_key]) + || array_key_exists($unset_key, $ref))) { + $key_existed = true; + unset($ref[$unset_key]); + } else { + $key_existed = false; + } + } + + /** + * Determines whether a nested array contains the requested keys. + * + * This helper function should be used when the depth of the array element + * to be checked may vary (that is, the number of parent keys is variable). + * See NestedArray::setValue() for details. It is primarily used for form + * structures and renderable arrays. + * + * If it is required to also get the value of the checked nested key, use + * NestedArray::getValue() instead. + * + * If the number of array parent keys is static, this helper function is + * unnecessary and the following code can be used instead: + * + * @code + * $value_exists = isset($form['signature_settings']['signature']); + * $key_exists = array_key_exists('signature', + * $form['signature_settings']); + * @endcode + * + * @param array $array + * The array with the value to check for. + * @param array $parents + * An array of parent keys of the value, starting with the outermost key. + * + * @return bool + * TRUE if all the parent keys exist, FALSE otherwise. + * + * @see NestedArray::getValue() + */ + public static function keyExists(array $array, array $parents) + { + // Although this function is similar to PHP's array_key_exists(), its + // arguments should be consistent with getValue(). + $key_exists = null; + self::getValue($array, $parents, $key_exists); + return $key_exists; + } + + /** + * Merges multiple arrays, recursively, and returns the merged array. + * + * This function is similar to PHP's array_merge_recursive() function, but + * it handles non-array values differently. When merging values that are + * not both arrays, the latter value replaces the former rather than + * merging with it. + * + * Example: + * + * @code + * $link_options_1 = array('fragment' => 'x', 'attributes' => array('title' + * => t('X'), 'class' => array('a', 'b'))); + * $link_options_2 = array('fragment' => 'y', 'attributes' => array('title' + * => t('Y'), 'class' => array('c', 'd'))); + * + * // This results in array('fragment' => array('x', 'y'), 'attributes' => + * array('title' => array(t('X'), t('Y')), 'class' => array('a', 'b', + * 'c', 'd'))). + * $incorrect = array_merge_recursive($link_options_1, $link_options_2); + * + * // This results in array('fragment' => 'y', 'attributes' => + * array('title' => t('Y'), 'class' => array('a', 'b', 'c', 'd'))). + * $correct = NestedArray::mergeDeep($link_options_1, $link_options_2); + * @endcode + * + * @param array ... + * Arrays to merge. + * + * @return array + * The merged array. + * + * @see NestedArray::mergeDeepArray() + */ + public static function mergeDeep() + { + return self::mergeDeepArray(func_get_args()); + } + + /** + * Merges multiple arrays, recursively, and returns the merged array. + * + * This function is equivalent to NestedArray::mergeDeep(), except the + * input arrays are passed as a single array parameter rather than a + * variable parameter list. + * + * The following are equivalent: + * - NestedArray::mergeDeep($a, $b); + * - NestedArray::mergeDeepArray(array($a, $b)); + * + * The following are also equivalent: + * - call_user_func_array('NestedArray::mergeDeep', $arrays_to_merge); + * - NestedArray::mergeDeepArray($arrays_to_merge); + * + * @param array $arrays + * An arrays of arrays to merge. + * @param bool $preserve_integer_keys + * (optional) If given, integer keys will be preserved and merged instead + * of appended. Defaults to FALSE. + * + * @return array + * The merged array. + * + * @see NestedArray::mergeDeep() + */ + public static function mergeDeepArray( + array $arrays, + $preserve_integer_keys = false + ) { + $result = []; + foreach ($arrays as $array) { + foreach ($array as $key => $value) { + // Renumber integer keys as array_merge_recursive() does unless + // $preserve_integer_keys is set to TRUE. Note that PHP automatically + // converts array keys that are integer strings (e.g., '1') to integers. + if (is_int($key) && !$preserve_integer_keys) { + $result[] = $value; + } elseif (isset($result[$key]) + && is_array($result[$key]) + && is_array($value) + ) { + // Recurse when both values are arrays. + $result[$key] = self::mergeDeepArray([ + $result[$key], + $value, + ], $preserve_integer_keys); + } else { + // Otherwise, use the latter value, overriding any previous value. + $result[$key] = $value; + } + } + } + return $result; + } + + /** + * Filters a nested array recursively. + * + * @param array $array + * The filtered nested array. + * @param callable|null $callable + * The callable to apply for filtering. + * + * @return array + * The filtered array. + */ + public static function filter(array $array, callable $callable = null) + { + $array = is_callable($callable) ? array_filter($array, $callable) + : array_filter($array); + foreach ($array as &$element) { + if (is_array($element)) { + $element = static::filter($element, $callable); + } + } + + return $array; + } +} diff --git a/src/SuiteHandler.php b/src/SuiteHandler.php new file mode 100644 index 0000000..850aa3e --- /dev/null +++ b/src/SuiteHandler.php @@ -0,0 +1,273 @@ +fs = $fs ?: new Filesystem(); + } + + public function suiteFileName(string $suiteName, string $composerFile = ''): string + { + if ($composerFile === '') { + $composerFile = ComposerFactory::getComposerFile(); + } + + $base = preg_replace('/\.json$/', '', $composerFile); + + return "$base.$suiteName.json"; + } + + public function generate(array $composerData, array $actions): array + { + foreach ($actions as $action) { + switch ($action['type']) { + case 'replaceRecursive': + case 'unset': + case 'prepend': + case 'append': + case 'insertBefore': + case 'insertAfter': + $action += ['config' => []]; + $method = 'action' . ucfirst($action['type']); + $this->{$method}($composerData, $action['config']); + break; + + default: + assert(false, "invalid step type: {$action['type']}"); + } + } + + unset($composerData['extra'][Plugin::NAME]); + + return $composerData; + } + + public function whatToDo(string $fileName, array $dataNew): string + { + // @todo Error handling. + $contentOld = $this->fs->exists($fileName) ? + file_get_contents($fileName) + : null; + + if ($contentOld === null) { + return 'create'; + } + + $dataOld = $this->decode($contentOld); + + return $dataOld === $dataNew ? 'skip' : 'update'; + } + + public function encode(array $data): string + { + return json_encode($data, $this->jsonEncodeFlags); + } + + public function decode(string $encoded): array + { + return json_decode($encoded, true); + } + + public function collectSuiteComposerFiles(string $composerFile): array + { + $base = preg_replace('/\.json$/', '', $composerFile); + $iterator = new \GlobIterator("$base.*.json"); + $fileNames = []; + while ($iterator->valid()) { + $fileName = $iterator->current()->getFilename(); + $parts = explode('.', $fileName); + array_pop($parts); + $fileNames[$fileName] = array_pop($parts); + $iterator->next(); + } + + return $fileNames; + } + + protected function actionReplaceRecursive(array &$data, array $config) + { + $config = array_replace_recursive( + [ + 'parents' => [], + 'items' => [], + ], + $config, + ); + $sub =& NestedArray::getValue($data, $config['parents']); + $sub = array_replace_recursive($sub, $config['items']); + + return $this; + } + + protected function actionUnset(array &$data, array $config) + { + $config = array_replace_recursive( + [ + 'parents' => [], + ], + $config, + ); + + if (!$config['parents']) { + $data = []; + + return $this; + } + + $children = (array) array_pop($config['parents']); + $keyExists = false; + $sub =& NestedArray::getValue($data, $config['parents'], $keyExists); + if (!$keyExists) { + return $this; + } + + foreach ($children as $child) { + unset($sub[$child]); + } + + return $this; + } + + protected function actionPrepend(&$data, array $config) + { + $config = array_replace_recursive( + [ + 'parents' => [], + 'items' => [], + ], + $config, + ); + $sub =& NestedArray::getValue($data, $config['parents']); + + if ($this->isVector($sub)) { + $sub = array_merge($config['items'], $sub); + + return $this; + } + + $sub = $config['items'] + $sub; + + return $this; + } + + protected function actionAppend(&$data, array $config) + { + $config = array_replace_recursive( + [ + 'parents' => [], + 'items' => [], + ], + $config, + ); + $sub =& NestedArray::getValue($data, $config['parents']); + + if (($sub && $this->isVector($sub)) + || $this->isVector($config['items']) + ) { + $sub = array_merge($sub, $config['items']); + + return $this; + } + + $sub += $config['items']; + + return $this; + } + + protected function actionInsertBefore(array &$data, array $config) + { + $config = array_replace_recursive( + [ + 'parents' => [], + 'items' => [], + ], + $config, + ); + $config['placement'] = 'before'; + + return $this->actionInsert($data, $config); + } + + protected function actionInsertAfter(array &$data, array $config) + { + $config = array_replace_recursive( + [ + 'parents' => [], + 'items' => [], + ], + $config, + ); + $config['placement'] = 'after'; + + return $this->actionInsert($data, $config); + } + + protected function actionInsert(&$data, array $config) + { + $config = array_replace_recursive( + [ + 'parents' => [], + 'items' => [], + 'placement' => 'before', + ], + $config, + ); + + $key = array_pop($config['parents']); + $sub =& NestedArray::getValue($data, $config['parents']); + + $isVector = ( + ($sub && $this->isVector($sub)) + || + (!$sub && $this->isVector($config['items'])) + ); + + if (!$isVector) { + $key = array_search($key, array_keys($sub)); + } + + if ($config['placement'] === 'after') { + $key++; + } + + if ($isVector) { + $sub = array_merge( + array_slice($sub, 0, $key, true), + $config['items'], + array_slice($sub, $key, null, true), + ); + + return $this; + } + + $sub = array_slice($sub, 0, $key, true) + + $config['items'] + + array_slice($sub, $key, null, true); + + return $this; + } + + protected function isVector(array $items): bool + { + if (!$items) { + return false; + } + + return array_keys($items) === range(0, count($items) - 1); + } +} diff --git a/tests/_support/Helper/Unit.php b/tests/_support/Helper/Unit.php new file mode 100644 index 0000000..9d3f9d0 --- /dev/null +++ b/tests/_support/Helper/Unit.php @@ -0,0 +1,11 @@ +assertFileExists($file); + + $this->assertSame( + 'link', + filetype($file), + "$file is a symbolic link" + ); + + $this->assertSame( + $expected, + readlink($file), + "symbolic link $file points to $expected" + ); + } + + public function assertDirContainsAllTheFiles(string $expected, string $actual) + { + $file = new DirectoryIterator($expected); + while ($file->valid()) { + if ($file->isDot() || $file->isDir()) { + $file->next(); + continue; + } + + $actualFile = "$actual/" . $file->getFilename(); + $this->assertFileExists($actualFile); + $this->assertSame( + $file->getPerms(), + fileperms($actualFile), + "file permissions of $actualFile" + ); + + $this->assertSame( + md5_file($file->getPathname()), + md5_file($actualFile), + "content of $actualFile file" + ); + + $file->next(); + } + } + + public function assertLogEntries(array $expected, array $actual, array $replacementPairs = [], string $message = '') + { + if ($message === '') { + $message = 'log entries'; + } + + $this->assertCount( + count($expected), + $actual, + "$message - number of log entries" + ); + + foreach ($expected as $i => $expectedLogEntry) { + $expectedLogEntry['message'] = strtr($expectedLogEntry['message'], $replacementPairs); + $this->assertSame( + $expectedLogEntry, + $actual[$i], + "$message - log entry $i" + ); + } + } +} diff --git a/tests/unit.suite.dist.yml b/tests/unit.suite.dist.yml new file mode 100644 index 0000000..4b042e9 --- /dev/null +++ b/tests/unit.suite.dist.yml @@ -0,0 +1,7 @@ + +actor: UnitTester + +modules: + enabled: + - 'Asserts' + - '\Sweetchuck\ComposerSuite\Test\Helper\Unit' diff --git a/tests/unit/Composer/Command/CommandTestBase.php b/tests/unit/Composer/Command/CommandTestBase.php new file mode 100644 index 0000000..2b540c3 --- /dev/null +++ b/tests/unit/Composer/Command/CommandTestBase.php @@ -0,0 +1,11 @@ + json_encode([ + 'require' => [ + 'a/b' => '^1.0', + ], + 'extra' => [ + 'composer-suite' => [ + 'one' => [ + [ + 'type' => 'replaceRecursive', + 'config' => [ + 'parents' => [], + 'items' => [ + 'require' => [ + 'a/b' => '1.x-dev', + ], + ], + ], + ], + ], + ], + ], + ]), + ], + ); + + putenv('COMPOSER=' . $vfsRoot->url() . '/composer.json'); + + $application = new Application(); + $command = new GenerateCommand('suite:generate'); + $command->setApplication($application); + $commandTester = new CommandTester($command); + $commandTester->execute( + [], + [ + 'verbosity' => OutputInterface::VERBOSITY_VERY_VERBOSE, + ], + ); + + $this->tester->assertStringEqualsFile( + $vfsRoot->url() . '/composer.one.json', + json_encode( + [ + 'require' => [ + 'a/b' => '1.x-dev', + ], + 'extra' => [], + ], + \JSON_PRETTY_PRINT | \JSON_UNESCAPED_SLASHES | \JSON_UNESCAPED_UNICODE, + ), + ); + } +} diff --git a/tests/unit/SuiteHandlerTest.php b/tests/unit/SuiteHandlerTest.php new file mode 100644 index 0000000..405047f --- /dev/null +++ b/tests/unit/SuiteHandlerTest.php @@ -0,0 +1,229 @@ + 'my-type', + 'name' => 'my/name', + 'description' => 'my description', + 'tags' => [ + 'd', + ], + 'authors' => [ + [ + 'a' => 'a', + ], + [ + 'c' => 'c', + ], + [ + 'e' => 'e', + ], + ], + 'repositories' => [], + 'require' => [ + 'a/a' => '^2.0', + 'a/b' => '^1.0', + 'a/c' => '^3.0', + ], + 'extra' => [ + 'a' => 'b', + 'composer-suite' => [ + 'not in use' => 'see $actions parameter', + ], + 'c' => 'd', + 'remove-me-1' => 1, + 'remove-me-2' => 2, + ], + 'remove-me-3' => 3, + ]; + + return [ + 'all-in-one' => [ + [ + 'type' => 'my-type', + 'name' => 'my/name', + 'description' => 'my description', + 'tags' => [ + "a", + "b", + "d", + "y", + "z", + ], + 'authors' => [ + [ + 'a' => 'a', + ], + [ + 'b' => 'b', + ], + [ + 'c' => 'c', + ], + [ + 'd' => 'd', + ], + [ + 'e' => 'e', + ], + ], + 'repositories' => [ + 'a/b' => [ + 'type' => 'path', + 'url' => '../../a/b-1.x-dev', + ], + ], + 'require' => [ + 'a/a' => '^2.0', + 'a/e1' => '^2.0', + 'a/e2' => '^2.0', + 'a/b' => '1.x-dev', + 'a/c' => '^3.0', + ], + 'extra' => [ + 'a' => 'b', + 'c' => 'd', + ], + ], + $rootData, + [ + [ + 'type' => 'replaceRecursive', + 'config' => [ + 'parents' => [], + 'items' => [ + 'repositories' => [ + 'a/b' => [ + 'type' => 'path', + 'url' => '../../a/b-1.x-dev', + ], + ], + 'require' => [ + 'a/b' => '1.x-dev', + ], + ], + ], + ], + [ + 'type' => 'unset', + 'config' => [ + 'parents' => [ + 'extra', + [ + 'remove-me-1', + 'remove-me-2', + ], + ], + ], + ], + [ + 'type' => 'unset', + 'config' => [ + 'parents' => [ + 'remove-me-3', + ], + ], + ], + [ + 'type' => 'append', + 'config' => [ + 'parents' => [ + 'tags', + ], + 'items' => [ + 'y', + 'z', + ], + ], + ], + [ + 'type' => 'prepend', + 'config' => [ + 'parents' => [ + 'tags', + ], + 'items' => [ + 'a', + 'b', + ], + ], + ], + [ + 'type' => 'insertBefore', + 'config' => [ + 'parents' => [ + 'authors', + 1, + ], + 'items' => [ + [ + 'b' => 'b', + ], + ], + ], + ], + [ + 'type' => 'insertAfter', + 'config' => [ + 'parents' => [ + 'authors', + 2, + ], + 'items' => [ + [ + 'd' => 'd', + ], + ], + ], + ], + [ + 'type' => 'insertBefore', + 'config' => [ + 'parents' => [ + 'require', + 'a/b', + ], + 'items' => [ + 'a/e2' => '^2.0', + ], + ], + ], + [ + 'type' => 'insertAfter', + 'config' => [ + 'parents' => [ + 'require', + 'a/a', + ], + 'items' => [ + 'a/e1' => '^2.0', + ], + ], + ], + ], + ], + ]; + } + + /** + * @dataProvider casesGenerate + */ + public function testGenerate(array $expected, array $rootData, array $actions) + { + $suiteHandler = new SuiteHandler(); + $this->tester->assertEquals($expected, $suiteHandler->generate($rootData, $actions)); + } +} diff --git a/tests/unit/TestBase.php b/tests/unit/TestBase.php new file mode 100644 index 0000000..532540f --- /dev/null +++ b/tests/unit/TestBase.php @@ -0,0 +1,44 @@ +randomTempDirName(); + mkdir($dir, 0777 - umask(), true); + + return $dir; + } + + protected function randomTempDirName(): string + { + return implode('/', [ + sys_get_temp_dir(), + 'sweetchuck', + 'composer-suite', + 'test-' . $this->randomId(), + ]); + } + + protected function randomId(): string + { + return md5((string) (microtime(true) * rand(0, 10000))); + } +} diff --git a/tests/xdebug_set_filter.php b/tests/xdebug_set_filter.php new file mode 100644 index 0000000..01566ad --- /dev/null +++ b/tests/xdebug_set_filter.php @@ -0,0 +1,13 @@ +