diff --git a/.gitattributes b/.gitattributes deleted file mode 100644 index e98291135..000000000 --- a/.gitattributes +++ /dev/null @@ -1,8 +0,0 @@ -/.gitattributes export-ignore -/.github/ export-ignore -/.gitignore export-ignore -/docs/ export-ignore -/phpcs.xml export-ignore -/phpstan.neon export-ignore -/phpunit.xml export-ignore -/tests/ export-ignore diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml deleted file mode 100644 index bc2800951..000000000 --- a/.github/FUNDING.yml +++ /dev/null @@ -1 +0,0 @@ -github: antonmedv diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md deleted file mode 100644 index 534a8a3bd..000000000 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -name: Bug report -about: Create a report to help us improve. -title: '' -labels: '' -assignees: '' ---- -- Deployer version: -- Deployment OS: - - Please, provide a minimal reproducible example of deploy.php diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml deleted file mode 100644 index e4626d2ba..000000000 --- a/.github/ISSUE_TEMPLATE/config.yml +++ /dev/null @@ -1,8 +0,0 @@ -blank_issues_enabled: false -contact_links: - - name: Ask question - url: https://github.com/deployphp/deployer/discussions/category_choices - about: Please ask questions in discussions. - - name: 💰 Paid Support - url: https://github.com/deployphp/deployer/discussions/3031 - about: We can offer a paid support for Deployer. diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md deleted file mode 100644 index 3e9561cf8..000000000 --- a/.github/ISSUE_TEMPLATE/feature_request.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -name: Feature request -about: Suggest an idea for this project. -title: '' -labels: '' -assignees: '' ---- diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md deleted file mode 100644 index 3f7bff1e8..000000000 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ /dev/null @@ -1,8 +0,0 @@ -- [ ] Bug fix #…? -- [ ] New feature? -- [ ] BC breaks? -- [ ] Tests added? -- [ ] Docs added? - - Please, regenerate docs by running next command: - $ php bin/docgen diff --git a/.github/dependabot.yml b/.github/dependabot.yml deleted file mode 100644 index 46c62116f..000000000 --- a/.github/dependabot.yml +++ /dev/null @@ -1,8 +0,0 @@ -version: 2 - -updates: - - package-ecosystem: "composer" - directory: / - schedule: - interval: "monthly" - versioning-strategy: increase-if-necessary diff --git a/.github/workflows/check.yml b/.github/workflows/check.yml deleted file mode 100644 index 0dd9b0c4e..000000000 --- a/.github/workflows/check.yml +++ /dev/null @@ -1,62 +0,0 @@ -name: check - -on: - push: - branches: [ master ] - pull_request: - branches: [ master ] - -jobs: - phpstan: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - - name: Validate composer.json and composer.lock - run: composer validate - - - name: Get Composer Cache Directory - id: composer-cache - run: | - echo "::set-output name=dir::$(composer config cache-files-dir)" - - - uses: actions/cache@v2 - with: - path: ${{ steps.composer-cache.outputs.dir }} - key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }} - restore-keys: | - ${{ runner.os }}-composer- - - - name: Install dependencies - if: steps.composer-cache.outputs.cache-hit != 'true' - run: composer install --prefer-dist --no-progress - - - name: Run test suite - run: composer phpstan - - phpcs: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - - name: Validate composer.json and composer.lock - run: composer validate - - - name: Get Composer Cache Directory - id: composer-cache - run: | - echo "::set-output name=dir::$(composer config cache-files-dir)" - - - uses: actions/cache@v2 - with: - path: ${{ steps.composer-cache.outputs.dir }} - key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }} - restore-keys: | - ${{ runner.os }}-composer- - - - name: Install dependencies - if: steps.composer-cache.outputs.cache-hit != 'true' - run: composer install --prefer-dist --no-progress - - - name: Run test suite - run: composer phpcs diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml deleted file mode 100644 index 4dd06de77..000000000 --- a/.github/workflows/docs.yml +++ /dev/null @@ -1,44 +0,0 @@ -name: doc - -on: - push: - branches: [ master ] - pull_request: - branches: [ master ] - -jobs: - docgen: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - - name: Validate composer.json and composer.lock - run: composer validate - - - name: Get Composer Cache Directory - id: composer-cache - run: | - echo "::set-output name=dir::$(composer config cache-files-dir)" - - - uses: actions/cache@v2 - with: - path: ${{ steps.composer-cache.outputs.dir }} - key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }} - restore-keys: | - ${{ runner.os }}-composer- - - - name: Install dependencies - if: steps.composer-cache.outputs.cache-hit != 'true' - run: composer install --prefer-dist --no-progress - - - name: Run docgen - run: php bin/docgen - - - name: Check for uncommitted changes - run: | - status=$(git status --porcelain docs/); - [ -z "$status" ] || { - echo "Please, run bin/docgen and commit next files:"; - echo $status; - exit 1; - } diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml deleted file mode 100644 index ab185017c..000000000 --- a/.github/workflows/release.yml +++ /dev/null @@ -1,69 +0,0 @@ -name: release - -on: - release: - types: - - created - -jobs: - release: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v3 - - - name: Get version - run: echo "RELEASE_VERSION=${GITHUB_REF#refs/*/v}" >> $GITHUB_ENV - - - name: Build phar - run: php -d phar.readonly=0 bin/build -v"$RELEASE_VERSION" - - - name: Verify version - run: php deployer.phar -V - - - name: Upload phar - run: gh release upload v"$RELEASE_VERSION" deployer.phar - env: - GITHUB_TOKEN: ${{ secrets.MY_TOKEN }} - - - name: Calculate sha1 - run: echo "SHA1=$(sha1sum deployer.phar | awk '{print $1;}')" >> $GITHUB_ENV - - - name: Update manifest - uses: deployphp/action@v1 - with: - private-key: ${{ secrets.PRIVATE_KEY }} - deployer-binary: bin/dep - dep: -f deploy.yaml release -o sha1=${{ env.SHA1 }} -o version=${{ env.RELEASE_VERSION }} - - - name: Add deployer.phar - shell: bash - run: | - set -x - git checkout -b dist - mv deployer.phar dep - chmod +x dep - git add -f dep - - - name: Remove obsolete files & dirs - shell: bash - run: | - set -x - git rm -r .github/ bin/ docs/ recipe/ src/ *.lock .gitattributes .gitignore - - - name: Update composer.json - shell: bash - run: | - set -x - cat composer.json | jq 'del(.autoload) | del(.scripts) | del(.require) | del(."require-dev") | setpath(["bin"]; "dep")' > composer-new.json - mv composer-new.json composer.json - git add composer.json - - - name: Push release tag - shell: bash - run: | - set -x - git config --global user.email "41898282+github-actions[bot]@users.noreply.github.com" - git config --global user.name "github-actions" - git commit -m "Deployer $RELEASE_VERSION" - git tag "v$RELEASE_VERSION" --force - git push origin "v$RELEASE_VERSION" --force diff --git a/.github/workflows/sync.yml b/.github/workflows/sync.yml deleted file mode 100644 index 9da229034..000000000 --- a/.github/workflows/sync.yml +++ /dev/null @@ -1,46 +0,0 @@ -name: sync - -on: - push: - branches: [ master ] - -jobs: - docs: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - - name: Validate composer.json and composer.lock - run: composer validate - - - name: Get Composer Cache Directory - id: composer-cache - run: | - echo "::set-output name=dir::$(composer config cache-files-dir)" - - - uses: actions/cache@v2 - with: - path: ${{ steps.composer-cache.outputs.dir }} - key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }} - restore-keys: | - ${{ runner.os }}-composer- - - - name: Install dependencies - if: steps.composer-cache.outputs.cache-hit != 'true' - run: composer install --prefer-dist --no-progress - - - name: Run docgen - run: php bin/docgen - - - name: Add & Commit - uses: EndBug/add-and-commit@v7 - with: - add: 'docs' - message: '[automatic] Update docs with bin/docgen' - - - name: Deploy docs - run: gh --repo "$REPO" workflow run deploy-docs - env: - GITHUB_TOKEN: ${{ secrets.MY_TOKEN }} - REPO: ${{ secrets.DOCS_REPO }} - diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml deleted file mode 100644 index 8fb575716..000000000 --- a/.github/workflows/test.yml +++ /dev/null @@ -1,75 +0,0 @@ -name: test - -on: - push: - branches: [ master ] - pull_request: - branches: [ master ] - -jobs: - unit: - runs-on: ubuntu-latest - strategy: - matrix: - php-versions: [ '7.3', '7.4', '8.0', '8.1' ] - steps: - - uses: actions/checkout@v2 - - - name: Setup PHP - uses: shivammathur/setup-php@v2 - with: - php-version: ${{ matrix.php-versions }} - extensions: mbstring, intl - coverage: xdebug - - - name: Validate composer.json and composer.lock - run: composer validate - - - name: Get Composer Cache Directory - id: composer-cache - run: | - echo "::set-output name=dir::$(composer config cache-files-dir)" - - - uses: actions/cache@v2 - with: - path: ${{ steps.composer-cache.outputs.dir }} - key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }} - restore-keys: | - ${{ runner.os }}-composer- - - - name: Install dependencies - if: steps.composer-cache.outputs.cache-hit != 'true' - run: composer install --prefer-dist --no-progress - - - name: Run test suite - run: composer test - - e2e: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - - uses: satackey/action-docker-layer-caching@v0.0.8 - continue-on-error: true - - - name: Build the docker-compose stack - run: cd tests/docker && docker-compose build - - - name: Get Composer Cache Directory - id: composer-cache - run: | - echo "::set-output name=dir::$(composer config cache-files-dir)" - - - uses: actions/cache@v2 - with: - path: ${{ steps.composer-cache.outputs.dir }} - key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }} - restore-keys: | - ${{ runner.os }}-composer- - - - name: Install dependencies - if: steps.composer-cache.outputs.cache-hit != 'true' - run: composer install --prefer-dist --no-progress - - - name: Run E2E test suite - run: cd tests/docker && docker-compose up --abort-on-container-exit diff --git a/.gitignore b/.gitignore deleted file mode 100644 index a8419a718..000000000 --- a/.gitignore +++ /dev/null @@ -1,4 +0,0 @@ -/vendor/ -*.phar -.phpunit.result.cache -docker-compose.override.yml diff --git a/bin/build b/bin/build deleted file mode 100755 index 1f34e3c81..000000000 --- a/bin/build +++ /dev/null @@ -1,92 +0,0 @@ -#!/usr/bin/env php - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -if (ini_get('phar.readonly') === '1') { - throw new \Exception('Writing to phar files is disabled. Change your `php.ini` or append `-d phar.readonly=false` to the shebang, if supported by your `env` executable.'); -} - -define('__ROOT__', realpath(__DIR__ . '/..')); -chdir(__ROOT__); - -$opt = getopt('v:', ['nozip']); - -$version = $opt['v'] ?? null; -if (empty($version)) { - echo "Please, specify version as \"-v7.0.0-beta.42\".\n"; - exit(1); -} -if (!preg_match('/^\d+\.\d+\.\d+(\-\w+(\.\d+)?)?$/', $version)) { - echo "Version must be \"7.0.0-beta.42\". Got \"$version\".\n"; - exit(1); -} - -`composer install --no-dev --prefer-dist --optimize-autoloader`; - -$pharName = "deployer.phar"; -$pharFile = __ROOT__ . '/' . $pharName; -if (file_exists($pharFile)) { - unlink($pharFile); -} - -$ignore = [ - '.anton', - '.git', - 'Tests', - 'tests', - 'deploy.php', -]; - -$phar = new \Phar($pharFile, 0, $pharName); -$phar->setSignatureAlgorithm(\Phar::SHA1); -$phar->startBuffering(); -$iterator = new RecursiveDirectoryIterator(__ROOT__, FilesystemIterator::SKIP_DOTS); -$iterator = new RecursiveCallbackFilterIterator($iterator, function (SplFileInfo $fileInfo) use ($ignore) { - return !in_array($fileInfo->getBasename(), $ignore, true); -}); -$iterator = new RecursiveIteratorIterator($iterator); -$iterator = new CallbackFilterIterator($iterator, function (SplFileInfo $fileInfo) { - return in_array($fileInfo->getExtension(), ['php', 'exe'], true); -}); - -foreach ($iterator as $fileInfo) { - $file = str_replace(__ROOT__, '', $fileInfo->getRealPath()); - echo "Add file: " . $file . "\n"; - $phar->addFile($fileInfo->getRealPath(), $file); - - if (!array_key_exists('nozip', $opt)) { - $phar[$file]->compress(Phar::GZ); - - if (!$phar[$file]->isCompressed()) { - echo "Could not compress File: $file\n"; - } - } -} - -// Add schema.json -echo "Add file: /src/schema.json\n"; -$phar->addFile(realpath(__DIR__ . '/../src/schema.json'), '/src/schema.json'); - -// Add bin/dep file -echo "Add file: /bin/dep\n"; -$depContent = file_get_contents(__ROOT__ . '/bin/dep'); -$depContent = str_replace("#!/usr/bin/env php\n", '', $depContent); -$depContent = str_replace('__FILE__', 'str_replace("phar://", "", Phar::running())', $depContent); -$depContent = preg_replace("/run\('.+?'/", "run('$version'", $depContent); -$phar->addFromString('bin/dep', $depContent); -$phar->setStub(<<stopBuffering(); -unset($phar); - -echo "$pharName was created successfully.\n"; diff --git a/bin/dep b/bin/dep deleted file mode 100755 index 2bfa43b83..000000000 --- a/bin/dep +++ /dev/null @@ -1,97 +0,0 @@ -#!/usr/bin/env php - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -// Detect deploy.php location -$deployFile = null; -foreach ($argv as $i => $arg) { - if (preg_match('/^(-f|--file)$/', $arg, $match) && $i + 1 < count($argv)) { - $deployFile = $argv[$i + 1]; - break; - } - if (preg_match('/^--file=(?.+)$/', $arg, $match)) { - $deployFile = $match['file']; - break; - } - if (preg_match('/^-f=?(?.+)$/', $arg, $match)) { - $deployFile = $match['file']; - break; - } -} -if (!empty($deployFile)) { - $deployFile = realpath($deployFile); -} -$lookUp = function (string $name): ?string { - $dir = getcwd(); - for ($i = 0; $i < 10; $i++) { - $path = "$dir/$name"; - if (is_readable($path)) { - return $path; - } - $dir = dirname($dir); - } - return ''; -}; -if (empty($deployFile)) { - $deployFile = $lookUp('deploy.php'); -} -if (empty($deployFile)) { - $deployFile = $lookUp('deploy.yaml'); -} -if (empty($deployFile)) { - $deployFile = $lookUp('deploy.yml'); -} - -// Detect autoload location -$autoload = [ - __DIR__ . '/../vendor/autoload.php', // The dep located at "deployer.phar/bin" or in development. - __DIR__ . '/../../../autoload.php', // The dep located at "vendor/deployer/deployer/bin". - __DIR__ . '/../autoload.php', // The dep located at "vendor/bin". -]; -$includes = [ - __DIR__ . '/..', - __DIR__ . '/../../../deployer/deployer', - __DIR__ . '/../deployer/deployer', -]; -$includePath = false; -for ($i = 0; $i < count($autoload); $i++) { - if (file_exists($autoload[$i]) && is_dir($includes[$i])) { - require $autoload[$i]; - $includePath = $includes[$i]; - break; - } -} -if (empty($includePath)) { - fwrite(STDERR, "Error: The `autoload.php` file not found in:\n"); - for ($i = 0; $i < count($autoload); $i++) { - $a = file_exists($autoload[$i]) ? 'true' : 'false'; - $b = is_dir($includes[$i]) ? 'true' : 'false'; - fwrite(STDERR, " - file_exists($autoload[$i]) = $a\n"); - fwrite(STDERR, " is_dir($includes[$i]) = $b\n"); - } - exit(1); -} - -// Errors to exception -set_error_handler(function ($severity, $message, $filename, $lineno) { - if (error_reporting() == 0) { - return; - } - if (error_reporting() & $severity) { - throw new ErrorException($message, 0, $severity, $filename, $lineno); - } -}); - -// Enable recipe loading -set_include_path($includePath . PATH_SEPARATOR . get_include_path()); - -// Deployer constants -define('DEPLOYER', true); -define('DEPLOYER_BIN', __FILE__); -define('DEPLOYER_DEPLOY_FILE', $deployFile); - -Deployer\Deployer::run('master', $deployFile); diff --git a/bin/docgen b/bin/docgen deleted file mode 100755 index 645358e04..000000000 --- a/bin/docgen +++ /dev/null @@ -1,56 +0,0 @@ -#!/usr/bin/env php - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Deployer; - -use Deployer\Documentation\ApiGen; -use Deployer\Documentation\DocGen; -use Symfony\Component\Console\Application; -use Symfony\Component\Console\Input\ArgvInput; -use Symfony\Component\Console\Output\ConsoleOutput; - -require __DIR__ . '/../vendor/autoload.php'; - -chdir(realpath(__DIR__ . '/..')); - -$input = new ArgvInput(); -$output = new ConsoleOutput(); -$app = new Application('DocGen', '1.0.0'); -$app->setDefaultCommand('all'); - -$api = function () use ($output) { - $parser = new ApiGen(); - $parser->parse(file_get_contents(__DIR__ . '/../src/functions.php')); - $md = $parser->markdown(); - file_put_contents(__DIR__ . '/../docs/api.md', $md); - $output->writeln('API Reference documentation updated.'); -}; - -$recipes = function () use ($input, $output) { - $docgen = new DocGen(__DIR__ . '/..'); - $docgen->parse(__DIR__ . '/../recipe'); - $docgen->parse(__DIR__ . '/../contrib'); - - if ($input->getOption('json')) { - echo json_encode($docgen->recipes, JSON_PRETTY_PRINT); - return; - } - - $docgen->gen(__DIR__ . '/../docs'); - $output->writeln('Recipes documentation updated.'); -}; - -$app->register('api')->setCode($api); -$app->register('recipes')->setCode($recipes)->addOption('json'); -$app->register('all')->setCode(function () use ($recipes, $api) { - $api(); - $recipes(); - echo `git status`; -})->addOption('json'); - -$app->run($input, $output); diff --git a/composer.json b/composer.json index c92dc5153..5bd9de8e0 100644 --- a/composer.json +++ b/composer.json @@ -1,70 +1,32 @@ { - "name": "deployer/deployer", - "description": "Deployment Tool", - "license": "MIT", - "homepage": "https://deployer.org", - "support": { - "docs": "https://deployer.org/docs", - "source": "https://github.com/deployphp/deployer", - "issues": "https://github.com/deployphp/deployer/issues" - }, - "authors": [ - { - "name": "Anton Medvedev", - "email": "anton@medv.io" - } - ], - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/antonmedv" - } - ], - "autoload": { - "psr-4": { - "Deployer\\": "src/" - }, - "files": [ - "src/Support/helpers.php", - "src/functions.php" - ] - }, - "scripts": { - "test": "pest", - "test:e2e": "pest --config tests/e2e/phpunit-e2e.xml", - "phpcs": "phpcs", - "fix": "phpcbf", - "phpstan": "phpstan analyse -c phpstan.neon", - "phpstan:baseline": "@phpstan --generate-baseline tests/phpstan-baseline.neon" - }, - "bin": [ - "bin/dep" - ], - "require": { - "php": "^8.0|^7.3", - "ext-json": "*", - "justinrainbow/json-schema": "^5.2", - "psr/http-message": "^1", - "react/http": "^1.5", - "symfony/console": "^5", - "symfony/polyfill-php80": "^1.22", - "symfony/process": "^5", - "symfony/yaml": "^5" - }, - "require-dev": { - "pestphp/pest": "^1.0", - "phpstan/phpstan": "^1.4", - "phpunit/php-code-coverage": "^9.2", - "phpunit/phpunit": "^9.3", - "slevomat/coding-standard": "^7.0", - "squizlabs/php_codesniffer": "^3.5" - }, - "config": { - "sort-packages": true, - "process-timeout": 0, - "allow-plugins": { - "pestphp/pest-plugin": true, - "dealerdirect/phpcodesniffer-composer-installer": true - } + "name": "deployer/deployer", + "description": "Deployment Tool", + "license": "MIT", + "homepage": "https://deployer.org", + "support": { + "docs": "https://deployer.org/docs", + "source": "https://github.com/deployphp/deployer", + "issues": "https://github.com/deployphp/deployer/issues" + }, + "authors": [ + { + "name": "Anton Medvedev", + "email": "anton@medv.io" } + ], + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/antonmedv" + } + ], + "bin": "dep", + "config": { + "sort-packages": true, + "process-timeout": 0, + "allow-plugins": { + "pestphp/pest-plugin": true, + "dealerdirect/phpcodesniffer-composer-installer": true + } + } } diff --git a/composer.lock b/composer.lock deleted file mode 100644 index 5f45ee781..000000000 --- a/composer.lock +++ /dev/null @@ -1,4819 +0,0 @@ -{ - "_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": "23d858f83416e3f7d060d76320142419", - "packages": [ - { - "name": "evenement/evenement", - "version": "v3.0.1", - "source": { - "type": "git", - "url": "https://github.com/igorw/evenement.git", - "reference": "531bfb9d15f8aa57454f5f0285b18bec903b8fb7" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/igorw/evenement/zipball/531bfb9d15f8aa57454f5f0285b18bec903b8fb7", - "reference": "531bfb9d15f8aa57454f5f0285b18bec903b8fb7", - "shasum": "" - }, - "require": { - "php": ">=7.0" - }, - "require-dev": { - "phpunit/phpunit": "^6.0" - }, - "type": "library", - "autoload": { - "psr-0": { - "Evenement": "src" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Igor Wiedler", - "email": "igor@wiedler.ch" - } - ], - "description": "Événement is a very simple event dispatching library for PHP", - "keywords": [ - "event-dispatcher", - "event-emitter" - ], - "support": { - "issues": "https://github.com/igorw/evenement/issues", - "source": "https://github.com/igorw/evenement/tree/master" - }, - "time": "2017-07-23T21:35:13+00:00" - }, - { - "name": "fig/http-message-util", - "version": "1.1.5", - "source": { - "type": "git", - "url": "https://github.com/php-fig/http-message-util.git", - "reference": "9d94dc0154230ac39e5bf89398b324a86f63f765" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/php-fig/http-message-util/zipball/9d94dc0154230ac39e5bf89398b324a86f63f765", - "reference": "9d94dc0154230ac39e5bf89398b324a86f63f765", - "shasum": "" - }, - "require": { - "php": "^5.3 || ^7.0 || ^8.0" - }, - "suggest": { - "psr/http-message": "The package containing the PSR-7 interfaces" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.1.x-dev" - } - }, - "autoload": { - "psr-4": { - "Fig\\Http\\Message\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "PHP-FIG", - "homepage": "https://www.php-fig.org/" - } - ], - "description": "Utility classes and constants for use with PSR-7 (psr/http-message)", - "keywords": [ - "http", - "http-message", - "psr", - "psr-7", - "request", - "response" - ], - "support": { - "issues": "https://github.com/php-fig/http-message-util/issues", - "source": "https://github.com/php-fig/http-message-util/tree/1.1.5" - }, - "time": "2020-11-24T22:02:12+00:00" - }, - { - "name": "justinrainbow/json-schema", - "version": "5.2.11", - "source": { - "type": "git", - "url": "https://github.com/justinrainbow/json-schema.git", - "reference": "2ab6744b7296ded80f8cc4f9509abbff393399aa" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/justinrainbow/json-schema/zipball/2ab6744b7296ded80f8cc4f9509abbff393399aa", - "reference": "2ab6744b7296ded80f8cc4f9509abbff393399aa", - "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.11" - }, - "time": "2021-07-22T09:24:00+00:00" - }, - { - "name": "psr/container", - "version": "1.1.1", - "source": { - "type": "git", - "url": "https://github.com/php-fig/container.git", - "reference": "8622567409010282b7aeebe4bb841fe98b58dcaf" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/php-fig/container/zipball/8622567409010282b7aeebe4bb841fe98b58dcaf", - "reference": "8622567409010282b7aeebe4bb841fe98b58dcaf", - "shasum": "" - }, - "require": { - "php": ">=7.2.0" - }, - "type": "library", - "autoload": { - "psr-4": { - "Psr\\Container\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "PHP-FIG", - "homepage": "https://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/1.1.1" - }, - "time": "2021-03-05T17:36:06+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": "react/cache", - "version": "v1.1.1", - "source": { - "type": "git", - "url": "https://github.com/reactphp/cache.git", - "reference": "4bf736a2cccec7298bdf745db77585966fc2ca7e" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/reactphp/cache/zipball/4bf736a2cccec7298bdf745db77585966fc2ca7e", - "reference": "4bf736a2cccec7298bdf745db77585966fc2ca7e", - "shasum": "" - }, - "require": { - "php": ">=5.3.0", - "react/promise": "^3.0 || ^2.0 || ^1.1" - }, - "require-dev": { - "phpunit/phpunit": "^9.3 || ^5.7 || ^4.8.35" - }, - "type": "library", - "autoload": { - "psr-4": { - "React\\Cache\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Christian Lück", - "email": "christian@clue.engineering", - "homepage": "https://clue.engineering/" - }, - { - "name": "Cees-Jan Kiewiet", - "email": "reactphp@ceesjankiewiet.nl", - "homepage": "https://wyrihaximus.net/" - }, - { - "name": "Jan Sorgalla", - "email": "jsorgalla@gmail.com", - "homepage": "https://sorgalla.com/" - }, - { - "name": "Chris Boden", - "email": "cboden@gmail.com", - "homepage": "https://cboden.dev/" - } - ], - "description": "Async, Promise-based cache interface for ReactPHP", - "keywords": [ - "cache", - "caching", - "promise", - "reactphp" - ], - "support": { - "issues": "https://github.com/reactphp/cache/issues", - "source": "https://github.com/reactphp/cache/tree/v1.1.1" - }, - "funding": [ - { - "url": "https://github.com/WyriHaximus", - "type": "github" - }, - { - "url": "https://github.com/clue", - "type": "github" - } - ], - "time": "2021-02-02T06:47:52+00:00" - }, - { - "name": "react/dns", - "version": "v1.9.0", - "source": { - "type": "git", - "url": "https://github.com/reactphp/dns.git", - "reference": "6d38296756fa644e6cb1bfe95eff0f9a4ed6edcb" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/reactphp/dns/zipball/6d38296756fa644e6cb1bfe95eff0f9a4ed6edcb", - "reference": "6d38296756fa644e6cb1bfe95eff0f9a4ed6edcb", - "shasum": "" - }, - "require": { - "php": ">=5.3.0", - "react/cache": "^1.0 || ^0.6 || ^0.5", - "react/event-loop": "^1.2", - "react/promise": "^3.0 || ^2.7 || ^1.2.1", - "react/promise-timer": "^1.8" - }, - "require-dev": { - "clue/block-react": "^1.2", - "phpunit/phpunit": "^9.3 || ^4.8.35" - }, - "type": "library", - "autoload": { - "psr-4": { - "React\\Dns\\": "src" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Christian Lück", - "email": "christian@clue.engineering", - "homepage": "https://clue.engineering/" - }, - { - "name": "Cees-Jan Kiewiet", - "email": "reactphp@ceesjankiewiet.nl", - "homepage": "https://wyrihaximus.net/" - }, - { - "name": "Jan Sorgalla", - "email": "jsorgalla@gmail.com", - "homepage": "https://sorgalla.com/" - }, - { - "name": "Chris Boden", - "email": "cboden@gmail.com", - "homepage": "https://cboden.dev/" - } - ], - "description": "Async DNS resolver for ReactPHP", - "keywords": [ - "async", - "dns", - "dns-resolver", - "reactphp" - ], - "support": { - "issues": "https://github.com/reactphp/dns/issues", - "source": "https://github.com/reactphp/dns/tree/v1.9.0" - }, - "funding": [ - { - "url": "https://github.com/WyriHaximus", - "type": "github" - }, - { - "url": "https://github.com/clue", - "type": "github" - } - ], - "time": "2021-12-20T08:46:54+00:00" - }, - { - "name": "react/event-loop", - "version": "v1.2.0", - "source": { - "type": "git", - "url": "https://github.com/reactphp/event-loop.git", - "reference": "be6dee480fc4692cec0504e65eb486e3be1aa6f2" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/reactphp/event-loop/zipball/be6dee480fc4692cec0504e65eb486e3be1aa6f2", - "reference": "be6dee480fc4692cec0504e65eb486e3be1aa6f2", - "shasum": "" - }, - "require": { - "php": ">=5.3.0" - }, - "require-dev": { - "phpunit/phpunit": "^9.3 || ^5.7 || ^4.8.35" - }, - "suggest": { - "ext-event": "~1.0 for ExtEventLoop", - "ext-pcntl": "For signal handling support when using the StreamSelectLoop", - "ext-uv": "* for ExtUvLoop" - }, - "type": "library", - "autoload": { - "psr-4": { - "React\\EventLoop\\": "src" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Christian Lück", - "email": "christian@clue.engineering", - "homepage": "https://clue.engineering/" - }, - { - "name": "Cees-Jan Kiewiet", - "email": "reactphp@ceesjankiewiet.nl", - "homepage": "https://wyrihaximus.net/" - }, - { - "name": "Jan Sorgalla", - "email": "jsorgalla@gmail.com", - "homepage": "https://sorgalla.com/" - }, - { - "name": "Chris Boden", - "email": "cboden@gmail.com", - "homepage": "https://cboden.dev/" - } - ], - "description": "ReactPHP's core reactor event loop that libraries can use for evented I/O.", - "keywords": [ - "asynchronous", - "event-loop" - ], - "support": { - "issues": "https://github.com/reactphp/event-loop/issues", - "source": "https://github.com/reactphp/event-loop/tree/v1.2.0" - }, - "funding": [ - { - "url": "https://github.com/WyriHaximus", - "type": "github" - }, - { - "url": "https://github.com/clue", - "type": "github" - } - ], - "time": "2021-07-11T12:31:24+00:00" - }, - { - "name": "react/http", - "version": "v1.6.0", - "source": { - "type": "git", - "url": "https://github.com/reactphp/http.git", - "reference": "59961cc4a5b14481728f07c591546be18fa3a5c7" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/reactphp/http/zipball/59961cc4a5b14481728f07c591546be18fa3a5c7", - "reference": "59961cc4a5b14481728f07c591546be18fa3a5c7", - "shasum": "" - }, - "require": { - "evenement/evenement": "^3.0 || ^2.0 || ^1.0", - "fig/http-message-util": "^1.1", - "php": ">=5.3.0", - "psr/http-message": "^1.0", - "react/event-loop": "^1.2", - "react/promise": "^2.3 || ^1.2.1", - "react/promise-stream": "^1.1", - "react/socket": "^1.9", - "react/stream": "^1.2", - "ringcentral/psr7": "^1.2" - }, - "require-dev": { - "clue/block-react": "^1.5", - "clue/http-proxy-react": "^1.7", - "clue/reactphp-ssh-proxy": "^1.3", - "clue/socks-react": "^1.3", - "phpunit/phpunit": "^9.3 || ^5.7 || ^4.8.35" - }, - "type": "library", - "autoload": { - "psr-4": { - "React\\Http\\": "src" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Christian Lück", - "email": "christian@clue.engineering", - "homepage": "https://clue.engineering/" - }, - { - "name": "Cees-Jan Kiewiet", - "email": "reactphp@ceesjankiewiet.nl", - "homepage": "https://wyrihaximus.net/" - }, - { - "name": "Jan Sorgalla", - "email": "jsorgalla@gmail.com", - "homepage": "https://sorgalla.com/" - }, - { - "name": "Chris Boden", - "email": "cboden@gmail.com", - "homepage": "https://cboden.dev/" - } - ], - "description": "Event-driven, streaming HTTP client and server implementation for ReactPHP", - "keywords": [ - "async", - "client", - "event-driven", - "http", - "http client", - "http server", - "https", - "psr-7", - "reactphp", - "server", - "streaming" - ], - "support": { - "issues": "https://github.com/reactphp/http/issues", - "source": "https://github.com/reactphp/http/tree/v1.6.0" - }, - "funding": [ - { - "url": "https://github.com/WyriHaximus", - "type": "github" - }, - { - "url": "https://github.com/clue", - "type": "github" - } - ], - "time": "2022-02-03T13:17:37+00:00" - }, - { - "name": "react/promise", - "version": "v2.9.0", - "source": { - "type": "git", - "url": "https://github.com/reactphp/promise.git", - "reference": "234f8fd1023c9158e2314fa9d7d0e6a83db42910" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/reactphp/promise/zipball/234f8fd1023c9158e2314fa9d7d0e6a83db42910", - "reference": "234f8fd1023c9158e2314fa9d7d0e6a83db42910", - "shasum": "" - }, - "require": { - "php": ">=5.4.0" - }, - "require-dev": { - "phpunit/phpunit": "^9.3 || ^5.7 || ^4.8.36" - }, - "type": "library", - "autoload": { - "files": [ - "src/functions_include.php" - ], - "psr-4": { - "React\\Promise\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Jan Sorgalla", - "email": "jsorgalla@gmail.com", - "homepage": "https://sorgalla.com/" - }, - { - "name": "Christian Lück", - "email": "christian@clue.engineering", - "homepage": "https://clue.engineering/" - }, - { - "name": "Cees-Jan Kiewiet", - "email": "reactphp@ceesjankiewiet.nl", - "homepage": "https://wyrihaximus.net/" - }, - { - "name": "Chris Boden", - "email": "cboden@gmail.com", - "homepage": "https://cboden.dev/" - } - ], - "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.9.0" - }, - "funding": [ - { - "url": "https://github.com/WyriHaximus", - "type": "github" - }, - { - "url": "https://github.com/clue", - "type": "github" - } - ], - "time": "2022-02-11T10:27:51+00:00" - }, - { - "name": "react/promise-stream", - "version": "v1.3.0", - "source": { - "type": "git", - "url": "https://github.com/reactphp/promise-stream.git", - "reference": "3ebd94fe0d8edbf44937948af28d02d5437e9949" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/reactphp/promise-stream/zipball/3ebd94fe0d8edbf44937948af28d02d5437e9949", - "reference": "3ebd94fe0d8edbf44937948af28d02d5437e9949", - "shasum": "" - }, - "require": { - "php": ">=5.3", - "react/promise": "^2.1 || ^1.2", - "react/stream": "^1.0 || ^0.7 || ^0.6 || ^0.5 || ^0.4.6" - }, - "require-dev": { - "clue/block-react": "^1.0", - "phpunit/phpunit": "^9.3 || ^5.7 || ^4.8.35", - "react/event-loop": "^1.0 || ^0.5 || ^0.4 || ^0.3", - "react/promise-timer": "^1.0" - }, - "type": "library", - "autoload": { - "files": [ - "src/functions_include.php" - ], - "psr-4": { - "React\\Promise\\Stream\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Christian Lück", - "email": "christian@clue.engineering", - "homepage": "https://clue.engineering/" - }, - { - "name": "Cees-Jan Kiewiet", - "email": "reactphp@ceesjankiewiet.nl", - "homepage": "https://wyrihaximus.net/" - }, - { - "name": "Jan Sorgalla", - "email": "jsorgalla@gmail.com", - "homepage": "https://sorgalla.com/" - }, - { - "name": "Chris Boden", - "email": "cboden@gmail.com", - "homepage": "https://cboden.dev/" - } - ], - "description": "The missing link between Promise-land and Stream-land for ReactPHP", - "homepage": "https://github.com/reactphp/promise-stream", - "keywords": [ - "Buffer", - "async", - "promise", - "reactphp", - "stream", - "unwrap" - ], - "support": { - "issues": "https://github.com/reactphp/promise-stream/issues", - "source": "https://github.com/reactphp/promise-stream/tree/v1.3.0" - }, - "funding": [ - { - "url": "https://github.com/WyriHaximus", - "type": "github" - }, - { - "url": "https://github.com/clue", - "type": "github" - } - ], - "time": "2021-10-18T10:47:09+00:00" - }, - { - "name": "react/promise-timer", - "version": "v1.8.0", - "source": { - "type": "git", - "url": "https://github.com/reactphp/promise-timer.git", - "reference": "0bbbcc79589e5bfdddba68a287f1cb805581a479" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/reactphp/promise-timer/zipball/0bbbcc79589e5bfdddba68a287f1cb805581a479", - "reference": "0bbbcc79589e5bfdddba68a287f1cb805581a479", - "shasum": "" - }, - "require": { - "php": ">=5.3", - "react/event-loop": "^1.2", - "react/promise": "^3.0 || ^2.7.0 || ^1.2.1" - }, - "require-dev": { - "phpunit/phpunit": "^9.3 || ^5.7 || ^4.8.35" - }, - "type": "library", - "autoload": { - "files": [ - "src/functions_include.php" - ], - "psr-4": { - "React\\Promise\\Timer\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Christian Lück", - "email": "christian@clue.engineering", - "homepage": "https://clue.engineering/" - }, - { - "name": "Cees-Jan Kiewiet", - "email": "reactphp@ceesjankiewiet.nl", - "homepage": "https://wyrihaximus.net/" - }, - { - "name": "Jan Sorgalla", - "email": "jsorgalla@gmail.com", - "homepage": "https://sorgalla.com/" - }, - { - "name": "Chris Boden", - "email": "cboden@gmail.com", - "homepage": "https://cboden.dev/" - } - ], - "description": "A trivial implementation of timeouts for Promises, built on top of ReactPHP.", - "homepage": "https://github.com/reactphp/promise-timer", - "keywords": [ - "async", - "event-loop", - "promise", - "reactphp", - "timeout", - "timer" - ], - "support": { - "issues": "https://github.com/reactphp/promise-timer/issues", - "source": "https://github.com/reactphp/promise-timer/tree/v1.8.0" - }, - "funding": [ - { - "url": "https://github.com/WyriHaximus", - "type": "github" - }, - { - "url": "https://github.com/clue", - "type": "github" - } - ], - "time": "2021-12-06T11:08:48+00:00" - }, - { - "name": "react/socket", - "version": "v1.11.0", - "source": { - "type": "git", - "url": "https://github.com/reactphp/socket.git", - "reference": "f474156aaab4f09041144fa8b57c7d70aed32a1c" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/reactphp/socket/zipball/f474156aaab4f09041144fa8b57c7d70aed32a1c", - "reference": "f474156aaab4f09041144fa8b57c7d70aed32a1c", - "shasum": "" - }, - "require": { - "evenement/evenement": "^3.0 || ^2.0 || ^1.0", - "php": ">=5.3.0", - "react/dns": "^1.8", - "react/event-loop": "^1.2", - "react/promise": "^2.6.0 || ^1.2.1", - "react/promise-timer": "^1.8", - "react/stream": "^1.2" - }, - "require-dev": { - "clue/block-react": "^1.5", - "phpunit/phpunit": "^9.3 || ^5.7 || ^4.8.35", - "react/promise-stream": "^1.2" - }, - "type": "library", - "autoload": { - "psr-4": { - "React\\Socket\\": "src" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Christian Lück", - "email": "christian@clue.engineering", - "homepage": "https://clue.engineering/" - }, - { - "name": "Cees-Jan Kiewiet", - "email": "reactphp@ceesjankiewiet.nl", - "homepage": "https://wyrihaximus.net/" - }, - { - "name": "Jan Sorgalla", - "email": "jsorgalla@gmail.com", - "homepage": "https://sorgalla.com/" - }, - { - "name": "Chris Boden", - "email": "cboden@gmail.com", - "homepage": "https://cboden.dev/" - } - ], - "description": "Async, streaming plaintext TCP/IP and secure TLS socket server and client connections for ReactPHP", - "keywords": [ - "Connection", - "Socket", - "async", - "reactphp", - "stream" - ], - "support": { - "issues": "https://github.com/reactphp/socket/issues", - "source": "https://github.com/reactphp/socket/tree/v1.11.0" - }, - "funding": [ - { - "url": "https://github.com/WyriHaximus", - "type": "github" - }, - { - "url": "https://github.com/clue", - "type": "github" - } - ], - "time": "2022-01-14T10:14:32+00:00" - }, - { - "name": "react/stream", - "version": "v1.2.0", - "source": { - "type": "git", - "url": "https://github.com/reactphp/stream.git", - "reference": "7a423506ee1903e89f1e08ec5f0ed430ff784ae9" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/reactphp/stream/zipball/7a423506ee1903e89f1e08ec5f0ed430ff784ae9", - "reference": "7a423506ee1903e89f1e08ec5f0ed430ff784ae9", - "shasum": "" - }, - "require": { - "evenement/evenement": "^3.0 || ^2.0 || ^1.0", - "php": ">=5.3.8", - "react/event-loop": "^1.2" - }, - "require-dev": { - "clue/stream-filter": "~1.2", - "phpunit/phpunit": "^9.3 || ^5.7 || ^4.8.35" - }, - "type": "library", - "autoload": { - "psr-4": { - "React\\Stream\\": "src" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Christian Lück", - "email": "christian@clue.engineering", - "homepage": "https://clue.engineering/" - }, - { - "name": "Cees-Jan Kiewiet", - "email": "reactphp@ceesjankiewiet.nl", - "homepage": "https://wyrihaximus.net/" - }, - { - "name": "Jan Sorgalla", - "email": "jsorgalla@gmail.com", - "homepage": "https://sorgalla.com/" - }, - { - "name": "Chris Boden", - "email": "cboden@gmail.com", - "homepage": "https://cboden.dev/" - } - ], - "description": "Event-driven readable and writable streams for non-blocking I/O in ReactPHP", - "keywords": [ - "event-driven", - "io", - "non-blocking", - "pipe", - "reactphp", - "readable", - "stream", - "writable" - ], - "support": { - "issues": "https://github.com/reactphp/stream/issues", - "source": "https://github.com/reactphp/stream/tree/v1.2.0" - }, - "funding": [ - { - "url": "https://github.com/WyriHaximus", - "type": "github" - }, - { - "url": "https://github.com/clue", - "type": "github" - } - ], - "time": "2021-07-11T12:37:55+00:00" - }, - { - "name": "ringcentral/psr7", - "version": "1.3.0", - "source": { - "type": "git", - "url": "https://github.com/ringcentral/psr7.git", - "reference": "360faaec4b563958b673fb52bbe94e37f14bc686" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/ringcentral/psr7/zipball/360faaec4b563958b673fb52bbe94e37f14bc686", - "reference": "360faaec4b563958b673fb52bbe94e37f14bc686", - "shasum": "" - }, - "require": { - "php": ">=5.3", - "psr/http-message": "~1.0" - }, - "provide": { - "psr/http-message-implementation": "1.0" - }, - "require-dev": { - "phpunit/phpunit": "~4.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0-dev" - } - }, - "autoload": { - "files": [ - "src/functions_include.php" - ], - "psr-4": { - "RingCentral\\Psr7\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Michael Dowling", - "email": "mtdowling@gmail.com", - "homepage": "https://github.com/mtdowling" - } - ], - "description": "PSR-7 message implementation", - "keywords": [ - "http", - "message", - "stream", - "uri" - ], - "support": { - "source": "https://github.com/ringcentral/psr7/tree/master" - }, - "time": "2018-05-29T20:21:04+00:00" - }, - { - "name": "symfony/console", - "version": "v5.4.5", - "source": { - "type": "git", - "url": "https://github.com/symfony/console.git", - "reference": "d8111acc99876953f52fe16d4c50eb60940d49ad" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/d8111acc99876953f52fe16d4c50eb60940d49ad", - "reference": "d8111acc99876953f52fe16d4c50eb60940d49ad", - "shasum": "" - }, - "require": { - "php": ">=7.2.5", - "symfony/deprecation-contracts": "^2.1|^3", - "symfony/polyfill-mbstring": "~1.0", - "symfony/polyfill-php73": "^1.9", - "symfony/polyfill-php80": "^1.16", - "symfony/service-contracts": "^1.1|^2|^3", - "symfony/string": "^5.1|^6.0" - }, - "conflict": { - "psr/log": ">=3", - "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|2.0" - }, - "require-dev": { - "psr/log": "^1|^2", - "symfony/config": "^4.4|^5.0|^6.0", - "symfony/dependency-injection": "^4.4|^5.0|^6.0", - "symfony/event-dispatcher": "^4.4|^5.0|^6.0", - "symfony/lock": "^4.4|^5.0|^6.0", - "symfony/process": "^4.4|^5.0|^6.0", - "symfony/var-dumper": "^4.4|^5.0|^6.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": "Eases the creation of beautiful and testable command line interfaces", - "homepage": "https://symfony.com", - "keywords": [ - "cli", - "command line", - "console", - "terminal" - ], - "support": { - "source": "https://github.com/symfony/console/tree/v5.4.5" - }, - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], - "time": "2022-02-24T12:45:35+00:00" - }, - { - "name": "symfony/deprecation-contracts", - "version": "v2.5.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/deprecation-contracts.git", - "reference": "6f981ee24cf69ee7ce9736146d1c57c2780598a8" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/6f981ee24cf69ee7ce9736146d1c57c2780598a8", - "reference": "6f981ee24cf69ee7ce9736146d1c57c2780598a8", - "shasum": "" - }, - "require": { - "php": ">=7.1" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "2.5-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/v2.5.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-07-12T14:48:14+00:00" - }, - { - "name": "symfony/polyfill-ctype", - "version": "v1.25.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/polyfill-ctype.git", - "reference": "30885182c981ab175d4d034db0f6f469898070ab" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/30885182c981ab175d4d034db0f6f469898070ab", - "reference": "30885182c981ab175d4d034db0f6f469898070ab", - "shasum": "" - }, - "require": { - "php": ">=7.1" - }, - "provide": { - "ext-ctype": "*" - }, - "suggest": { - "ext-ctype": "For best performance" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "1.23-dev" - }, - "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" - } - }, - "autoload": { - "files": [ - "bootstrap.php" - ], - "psr-4": { - "Symfony\\Polyfill\\Ctype\\": "" - } - }, - "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.25.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-10-20T20:35:02+00:00" - }, - { - "name": "symfony/polyfill-intl-grapheme", - "version": "v1.25.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/polyfill-intl-grapheme.git", - "reference": "81b86b50cf841a64252b439e738e97f4a34e2783" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/81b86b50cf841a64252b439e738e97f4a34e2783", - "reference": "81b86b50cf841a64252b439e738e97f4a34e2783", - "shasum": "" - }, - "require": { - "php": ">=7.1" - }, - "suggest": { - "ext-intl": "For best performance" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "1.23-dev" - }, - "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" - } - }, - "autoload": { - "files": [ - "bootstrap.php" - ], - "psr-4": { - "Symfony\\Polyfill\\Intl\\Grapheme\\": "" - } - }, - "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.25.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-11-23T21:10:46+00:00" - }, - { - "name": "symfony/polyfill-intl-normalizer", - "version": "v1.25.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/polyfill-intl-normalizer.git", - "reference": "8590a5f561694770bdcd3f9b5c69dde6945028e8" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/8590a5f561694770bdcd3f9b5c69dde6945028e8", - "reference": "8590a5f561694770bdcd3f9b5c69dde6945028e8", - "shasum": "" - }, - "require": { - "php": ">=7.1" - }, - "suggest": { - "ext-intl": "For best performance" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "1.23-dev" - }, - "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" - } - }, - "autoload": { - "files": [ - "bootstrap.php" - ], - "psr-4": { - "Symfony\\Polyfill\\Intl\\Normalizer\\": "" - }, - "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.25.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-02-19T12:13:01+00:00" - }, - { - "name": "symfony/polyfill-mbstring", - "version": "v1.25.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/polyfill-mbstring.git", - "reference": "0abb51d2f102e00a4eefcf46ba7fec406d245825" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/0abb51d2f102e00a4eefcf46ba7fec406d245825", - "reference": "0abb51d2f102e00a4eefcf46ba7fec406d245825", - "shasum": "" - }, - "require": { - "php": ">=7.1" - }, - "provide": { - "ext-mbstring": "*" - }, - "suggest": { - "ext-mbstring": "For best performance" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "1.23-dev" - }, - "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" - } - }, - "autoload": { - "files": [ - "bootstrap.php" - ], - "psr-4": { - "Symfony\\Polyfill\\Mbstring\\": "" - } - }, - "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.25.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-11-30T18:21:41+00:00" - }, - { - "name": "symfony/polyfill-php73", - "version": "v1.25.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/polyfill-php73.git", - "reference": "cc5db0e22b3cb4111010e48785a97f670b350ca5" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php73/zipball/cc5db0e22b3cb4111010e48785a97f670b350ca5", - "reference": "cc5db0e22b3cb4111010e48785a97f670b350ca5", - "shasum": "" - }, - "require": { - "php": ">=7.1" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "1.23-dev" - }, - "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" - } - }, - "autoload": { - "files": [ - "bootstrap.php" - ], - "psr-4": { - "Symfony\\Polyfill\\Php73\\": "" - }, - "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.25.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-06-05T21:20:04+00:00" - }, - { - "name": "symfony/polyfill-php80", - "version": "v1.25.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/polyfill-php80.git", - "reference": "4407588e0d3f1f52efb65fbe92babe41f37fe50c" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/4407588e0d3f1f52efb65fbe92babe41f37fe50c", - "reference": "4407588e0d3f1f52efb65fbe92babe41f37fe50c", - "shasum": "" - }, - "require": { - "php": ">=7.1" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "1.23-dev" - }, - "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" - } - }, - "autoload": { - "files": [ - "bootstrap.php" - ], - "psr-4": { - "Symfony\\Polyfill\\Php80\\": "" - }, - "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.25.0" - }, - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], - "time": "2022-03-04T08:16:47+00:00" - }, - { - "name": "symfony/process", - "version": "v5.4.5", - "source": { - "type": "git", - "url": "https://github.com/symfony/process.git", - "reference": "95440409896f90a5f85db07a32b517ecec17fa4c" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/process/zipball/95440409896f90a5f85db07a32b517ecec17fa4c", - "reference": "95440409896f90a5f85db07a32b517ecec17fa4c", - "shasum": "" - }, - "require": { - "php": ">=7.2.5", - "symfony/polyfill-php80": "^1.16" - }, - "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": "Executes commands in sub-processes", - "homepage": "https://symfony.com", - "support": { - "source": "https://github.com/symfony/process/tree/v5.4.5" - }, - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], - "time": "2022-01-30T18:16:22+00:00" - }, - { - "name": "symfony/service-contracts", - "version": "v2.5.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/service-contracts.git", - "reference": "1ab11b933cd6bc5464b08e81e2c5b07dec58b0fc" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/service-contracts/zipball/1ab11b933cd6bc5464b08e81e2c5b07dec58b0fc", - "reference": "1ab11b933cd6bc5464b08e81e2c5b07dec58b0fc", - "shasum": "" - }, - "require": { - "php": ">=7.2.5", - "psr/container": "^1.1", - "symfony/deprecation-contracts": "^2.1" - }, - "conflict": { - "ext-psr": "<1.1|>=2" - }, - "suggest": { - "symfony/service-implementation": "" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "2.5-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/v2.5.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-11-04T16:48:04+00:00" - }, - { - "name": "symfony/string", - "version": "v5.4.3", - "source": { - "type": "git", - "url": "https://github.com/symfony/string.git", - "reference": "92043b7d8383e48104e411bc9434b260dbeb5a10" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/string/zipball/92043b7d8383e48104e411bc9434b260dbeb5a10", - "reference": "92043b7d8383e48104e411bc9434b260dbeb5a10", - "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" - }, - "conflict": { - "symfony/translation-contracts": ">=3.0" - }, - "require-dev": { - "symfony/error-handler": "^4.4|^5.0|^6.0", - "symfony/http-client": "^4.4|^5.0|^6.0", - "symfony/translation-contracts": "^1.1|^2", - "symfony/var-exporter": "^4.4|^5.0|^6.0" - }, - "type": "library", - "autoload": { - "files": [ - "Resources/functions.php" - ], - "psr-4": { - "Symfony\\Component\\String\\": "" - }, - "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": "Provides an object-oriented API to strings and deals with bytes, UTF-8 code points and grapheme clusters in a unified way", - "homepage": "https://symfony.com", - "keywords": [ - "grapheme", - "i18n", - "string", - "unicode", - "utf-8", - "utf8" - ], - "support": { - "source": "https://github.com/symfony/string/tree/v5.4.3" - }, - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], - "time": "2022-01-02T09:53:40+00:00" - }, - { - "name": "symfony/yaml", - "version": "v5.4.3", - "source": { - "type": "git", - "url": "https://github.com/symfony/yaml.git", - "reference": "e80f87d2c9495966768310fc531b487ce64237a2" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/yaml/zipball/e80f87d2c9495966768310fc531b487ce64237a2", - "reference": "e80f87d2c9495966768310fc531b487ce64237a2", - "shasum": "" - }, - "require": { - "php": ">=7.2.5", - "symfony/deprecation-contracts": "^2.1|^3", - "symfony/polyfill-ctype": "^1.8" - }, - "conflict": { - "symfony/console": "<5.3" - }, - "require-dev": { - "symfony/console": "^5.3|^6.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": "Loads and dumps YAML files", - "homepage": "https://symfony.com", - "support": { - "source": "https://github.com/symfony/yaml/tree/v5.4.3" - }, - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], - "time": "2022-01-26T16:32:32+00:00" - } - ], - "packages-dev": [ - { - "name": "dealerdirect/phpcodesniffer-composer-installer", - "version": "v0.7.2", - "source": { - "type": "git", - "url": "https://github.com/Dealerdirect/phpcodesniffer-composer-installer.git", - "reference": "1c968e542d8843d7cd71de3c5c9c3ff3ad71a1db" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/Dealerdirect/phpcodesniffer-composer-installer/zipball/1c968e542d8843d7cd71de3c5c9c3ff3ad71a1db", - "reference": "1c968e542d8843d7cd71de3c5c9c3ff3ad71a1db", - "shasum": "" - }, - "require": { - "composer-plugin-api": "^1.0 || ^2.0", - "php": ">=5.3", - "squizlabs/php_codesniffer": "^2.0 || ^3.1.0 || ^4.0" - }, - "require-dev": { - "composer/composer": "*", - "php-parallel-lint/php-parallel-lint": "^1.3.1", - "phpcompatibility/php-compatibility": "^9.0" - }, - "type": "composer-plugin", - "extra": { - "class": "Dealerdirect\\Composer\\Plugin\\Installers\\PHPCodeSniffer\\Plugin" - }, - "autoload": { - "psr-4": { - "Dealerdirect\\Composer\\Plugin\\Installers\\PHPCodeSniffer\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Franck Nijhof", - "email": "franck.nijhof@dealerdirect.com", - "homepage": "http://www.frenck.nl", - "role": "Developer / IT Manager" - }, - { - "name": "Contributors", - "homepage": "https://github.com/Dealerdirect/phpcodesniffer-composer-installer/graphs/contributors" - } - ], - "description": "PHP_CodeSniffer Standards Composer Installer Plugin", - "homepage": "http://www.dealerdirect.com", - "keywords": [ - "PHPCodeSniffer", - "PHP_CodeSniffer", - "code quality", - "codesniffer", - "composer", - "installer", - "phpcbf", - "phpcs", - "plugin", - "qa", - "quality", - "standard", - "standards", - "style guide", - "stylecheck", - "tests" - ], - "support": { - "issues": "https://github.com/dealerdirect/phpcodesniffer-composer-installer/issues", - "source": "https://github.com/dealerdirect/phpcodesniffer-composer-installer" - }, - "time": "2022-02-04T12:51:07+00:00" - }, - { - "name": "doctrine/instantiator", - "version": "1.4.1", - "source": { - "type": "git", - "url": "https://github.com/doctrine/instantiator.git", - "reference": "10dcfce151b967d20fde1b34ae6640712c3891bc" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/doctrine/instantiator/zipball/10dcfce151b967d20fde1b34ae6640712c3891bc", - "reference": "10dcfce151b967d20fde1b34ae6640712c3891bc", - "shasum": "" - }, - "require": { - "php": "^7.1 || ^8.0" - }, - "require-dev": { - "doctrine/coding-standard": "^9", - "ext-pdo": "*", - "ext-phar": "*", - "phpbench/phpbench": "^0.16 || ^1", - "phpstan/phpstan": "^1.4", - "phpstan/phpstan-phpunit": "^1", - "phpunit/phpunit": "^7.5 || ^8.5 || ^9.5", - "vimeo/psalm": "^4.22" - }, - "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.1" - }, - "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": "2022-03-03T08:28:38+00:00" - }, - { - "name": "facade/ignition-contracts", - "version": "1.0.2", - "source": { - "type": "git", - "url": "https://github.com/facade/ignition-contracts.git", - "reference": "3c921a1cdba35b68a7f0ccffc6dffc1995b18267" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/facade/ignition-contracts/zipball/3c921a1cdba35b68a7f0ccffc6dffc1995b18267", - "reference": "3c921a1cdba35b68a7f0ccffc6dffc1995b18267", - "shasum": "" - }, - "require": { - "php": "^7.3|^8.0" - }, - "require-dev": { - "friendsofphp/php-cs-fixer": "^v2.15.8", - "phpunit/phpunit": "^9.3.11", - "vimeo/psalm": "^3.17.1" - }, - "type": "library", - "autoload": { - "psr-4": { - "Facade\\IgnitionContracts\\": "src" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Freek Van der Herten", - "email": "freek@spatie.be", - "homepage": "https://flareapp.io", - "role": "Developer" - } - ], - "description": "Solution contracts for Ignition", - "homepage": "https://github.com/facade/ignition-contracts", - "keywords": [ - "contracts", - "flare", - "ignition" - ], - "support": { - "issues": "https://github.com/facade/ignition-contracts/issues", - "source": "https://github.com/facade/ignition-contracts/tree/1.0.2" - }, - "time": "2020-10-16T08:27:54+00:00" - }, - { - "name": "filp/whoops", - "version": "2.14.5", - "source": { - "type": "git", - "url": "https://github.com/filp/whoops.git", - "reference": "a63e5e8f26ebbebf8ed3c5c691637325512eb0dc" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/filp/whoops/zipball/a63e5e8f26ebbebf8ed3c5c691637325512eb0dc", - "reference": "a63e5e8f26ebbebf8ed3c5c691637325512eb0dc", - "shasum": "" - }, - "require": { - "php": "^5.5.9 || ^7.0 || ^8.0", - "psr/log": "^1.0.1 || ^2.0 || ^3.0" - }, - "require-dev": { - "mockery/mockery": "^0.9 || ^1.0", - "phpunit/phpunit": "^4.8.36 || ^5.7.27 || ^6.5.14 || ^7.5.20 || ^8.5.8 || ^9.3.3", - "symfony/var-dumper": "^2.6 || ^3.0 || ^4.0 || ^5.0" - }, - "suggest": { - "symfony/var-dumper": "Pretty print complex values better with var-dumper available", - "whoops/soap": "Formats errors as SOAP responses" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.7-dev" - } - }, - "autoload": { - "psr-4": { - "Whoops\\": "src/Whoops/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Filipe Dobreira", - "homepage": "https://github.com/filp", - "role": "Developer" - } - ], - "description": "php error handling for cool kids", - "homepage": "https://filp.github.io/whoops/", - "keywords": [ - "error", - "exception", - "handling", - "library", - "throwable", - "whoops" - ], - "support": { - "issues": "https://github.com/filp/whoops/issues", - "source": "https://github.com/filp/whoops/tree/2.14.5" - }, - "funding": [ - { - "url": "https://github.com/denis-sokolov", - "type": "github" - } - ], - "time": "2022-01-07T12:00:00+00:00" - }, - { - "name": "myclabs/deep-copy", - "version": "1.11.0", - "source": { - "type": "git", - "url": "https://github.com/myclabs/DeepCopy.git", - "reference": "14daed4296fae74d9e3201d2c4925d1acb7aa614" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/14daed4296fae74d9e3201d2c4925d1acb7aa614", - "reference": "14daed4296fae74d9e3201d2c4925d1acb7aa614", - "shasum": "" - }, - "require": { - "php": "^7.1 || ^8.0" - }, - "conflict": { - "doctrine/collections": "<1.6.8", - "doctrine/common": "<2.13.3 || >=3,<3.2.2" - }, - "require-dev": { - "doctrine/collections": "^1.6.8", - "doctrine/common": "^2.13.3 || ^3.2.2", - "phpunit/phpunit": "^7.5.20 || ^8.5.23 || ^9.5.13" - }, - "type": "library", - "autoload": { - "files": [ - "src/DeepCopy/deep_copy.php" - ], - "psr-4": { - "DeepCopy\\": "src/DeepCopy/" - } - }, - "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.11.0" - }, - "funding": [ - { - "url": "https://tidelift.com/funding/github/packagist/myclabs/deep-copy", - "type": "tidelift" - } - ], - "time": "2022-03-03T13:19:32+00:00" - }, - { - "name": "nikic/php-parser", - "version": "v4.13.2", - "source": { - "type": "git", - "url": "https://github.com/nikic/PHP-Parser.git", - "reference": "210577fe3cf7badcc5814d99455df46564f3c077" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/210577fe3cf7badcc5814d99455df46564f3c077", - "reference": "210577fe3cf7badcc5814d99455df46564f3c077", - "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.13.2" - }, - "time": "2021-11-30T19:35:32+00:00" - }, - { - "name": "nunomaduro/collision", - "version": "v5.11.0", - "source": { - "type": "git", - "url": "https://github.com/nunomaduro/collision.git", - "reference": "8b610eef8582ccdc05d8f2ab23305e2d37049461" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/nunomaduro/collision/zipball/8b610eef8582ccdc05d8f2ab23305e2d37049461", - "reference": "8b610eef8582ccdc05d8f2ab23305e2d37049461", - "shasum": "" - }, - "require": { - "facade/ignition-contracts": "^1.0", - "filp/whoops": "^2.14.3", - "php": "^7.3 || ^8.0", - "symfony/console": "^5.0" - }, - "require-dev": { - "brianium/paratest": "^6.1", - "fideloper/proxy": "^4.4.1", - "fruitcake/laravel-cors": "^2.0.3", - "laravel/framework": "8.x-dev", - "nunomaduro/larastan": "^0.6.2", - "nunomaduro/mock-final-classes": "^1.0", - "orchestra/testbench": "^6.0", - "phpstan/phpstan": "^0.12.64", - "phpunit/phpunit": "^9.5.0" - }, - "type": "library", - "extra": { - "laravel": { - "providers": [ - "NunoMaduro\\Collision\\Adapters\\Laravel\\CollisionServiceProvider" - ] - } - }, - "autoload": { - "psr-4": { - "NunoMaduro\\Collision\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Nuno Maduro", - "email": "enunomaduro@gmail.com" - } - ], - "description": "Cli error handling for console/command-line PHP applications.", - "keywords": [ - "artisan", - "cli", - "command-line", - "console", - "error", - "handling", - "laravel", - "laravel-zero", - "php", - "symfony" - ], - "support": { - "issues": "https://github.com/nunomaduro/collision/issues", - "source": "https://github.com/nunomaduro/collision" - }, - "funding": [ - { - "url": "https://www.paypal.com/paypalme/enunomaduro", - "type": "custom" - }, - { - "url": "https://github.com/nunomaduro", - "type": "github" - }, - { - "url": "https://www.patreon.com/nunomaduro", - "type": "patreon" - } - ], - "time": "2022-01-10T16:22:52+00:00" - }, - { - "name": "pestphp/pest", - "version": "v1.21.2", - "source": { - "type": "git", - "url": "https://github.com/pestphp/pest.git", - "reference": "63f009fadf9b37f611fda43928d03336475d5d9f" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/pestphp/pest/zipball/63f009fadf9b37f611fda43928d03336475d5d9f", - "reference": "63f009fadf9b37f611fda43928d03336475d5d9f", - "shasum": "" - }, - "require": { - "nunomaduro/collision": "^5.10.0|^6.0", - "pestphp/pest-plugin": "^1.0.0", - "php": "^7.3 || ^8.0", - "phpunit/phpunit": "^9.5.5" - }, - "require-dev": { - "illuminate/console": "^8.47.0", - "illuminate/support": "^8.47.0", - "laravel/dusk": "^6.15.0", - "pestphp/pest-dev-tools": "dev-master", - "pestphp/pest-plugin-parallel": "^1.0" - }, - "bin": [ - "bin/pest" - ], - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.x-dev" - }, - "pest": { - "plugins": [ - "Pest\\Plugins\\Coverage", - "Pest\\Plugins\\Init", - "Pest\\Plugins\\Version", - "Pest\\Plugins\\Environment" - ] - }, - "laravel": { - "providers": [ - "Pest\\Laravel\\PestServiceProvider" - ] - } - }, - "autoload": { - "files": [ - "src/Functions.php", - "src/Pest.php" - ], - "psr-4": { - "Pest\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Nuno Maduro", - "email": "enunomaduro@gmail.com" - } - ], - "description": "An elegant PHP Testing Framework.", - "keywords": [ - "framework", - "pest", - "php", - "test", - "testing", - "unit" - ], - "support": { - "issues": "https://github.com/pestphp/pest/issues", - "source": "https://github.com/pestphp/pest/tree/v1.21.2" - }, - "funding": [ - { - "url": "https://www.paypal.com/paypalme/enunomaduro", - "type": "custom" - }, - { - "url": "https://github.com/lukeraymonddowning", - "type": "github" - }, - { - "url": "https://github.com/nunomaduro", - "type": "github" - }, - { - "url": "https://github.com/octoper", - "type": "github" - }, - { - "url": "https://github.com/olivernybroe", - "type": "github" - }, - { - "url": "https://github.com/owenvoke", - "type": "github" - }, - { - "url": "https://www.patreon.com/nunomaduro", - "type": "patreon" - } - ], - "time": "2022-03-05T19:34:40+00:00" - }, - { - "name": "pestphp/pest-plugin", - "version": "v1.0.0", - "source": { - "type": "git", - "url": "https://github.com/pestphp/pest-plugin.git", - "reference": "fc8519de148699fe612d9c669be60554cd2db4fa" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/pestphp/pest-plugin/zipball/fc8519de148699fe612d9c669be60554cd2db4fa", - "reference": "fc8519de148699fe612d9c669be60554cd2db4fa", - "shasum": "" - }, - "require": { - "composer-plugin-api": "^1.1 || ^2.0", - "php": "^7.3 || ^8.0" - }, - "conflict": { - "pestphp/pest": "<1.0" - }, - "require-dev": { - "composer/composer": "^1.10.19", - "pestphp/pest": "^1.0", - "pestphp/pest-dev-tools": "dev-master" - }, - "type": "composer-plugin", - "extra": { - "branch-alias": { - "dev-master": "1.x-dev" - }, - "class": "Pest\\Plugin\\Manager" - }, - "autoload": { - "psr-4": { - "Pest\\Plugin\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "description": "The Pest plugin manager", - "keywords": [ - "framework", - "manager", - "pest", - "php", - "plugin", - "test", - "testing", - "unit" - ], - "support": { - "source": "https://github.com/pestphp/pest-plugin/tree/v1.0.0" - }, - "funding": [ - { - "url": "https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=66BYDWAT92N6L", - "type": "custom" - }, - { - "url": "https://github.com/nunomaduro", - "type": "github" - }, - { - "url": "https://www.patreon.com/nunomaduro", - "type": "patreon" - } - ], - "time": "2021-01-03T15:53:42+00:00" - }, - { - "name": "phar-io/manifest", - "version": "2.0.3", - "source": { - "type": "git", - "url": "https://github.com/phar-io/manifest.git", - "reference": "97803eca37d319dfa7826cc2437fc020857acb53" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phar-io/manifest/zipball/97803eca37d319dfa7826cc2437fc020857acb53", - "reference": "97803eca37d319dfa7826cc2437fc020857acb53", - "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/2.0.3" - }, - "time": "2021-07-20T11:28:43+00:00" - }, - { - "name": "phar-io/version", - "version": "3.2.1", - "source": { - "type": "git", - "url": "https://github.com/phar-io/version.git", - "reference": "4f7fd7836c6f332bb2933569e566a0d6c4cbed74" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phar-io/version/zipball/4f7fd7836c6f332bb2933569e566a0d6c4cbed74", - "reference": "4f7fd7836c6f332bb2933569e566a0d6c4cbed74", - "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.2.1" - }, - "time": "2022-02-21T01:04:05+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.3.0", - "source": { - "type": "git", - "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git", - "reference": "622548b623e81ca6d78b721c5e029f4ce664f170" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/622548b623e81ca6d78b721c5e029f4ce664f170", - "reference": "622548b623e81ca6d78b721c5e029f4ce664f170", - "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", - "psalm/phar": "^4.8" - }, - "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/5.3.0" - }, - "time": "2021-10-19T17:43:47+00:00" - }, - { - "name": "phpdocumentor/type-resolver", - "version": "1.6.1", - "source": { - "type": "git", - "url": "https://github.com/phpDocumentor/TypeResolver.git", - "reference": "77a32518733312af16a44300404e945338981de3" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/77a32518733312af16a44300404e945338981de3", - "reference": "77a32518733312af16a44300404e945338981de3", - "shasum": "" - }, - "require": { - "php": "^7.2 || ^8.0", - "phpdocumentor/reflection-common": "^2.0" - }, - "require-dev": { - "ext-tokenizer": "*", - "psalm/phar": "^4.8" - }, - "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.6.1" - }, - "time": "2022-03-15T21:29:03+00:00" - }, - { - "name": "phpspec/prophecy", - "version": "v1.15.0", - "source": { - "type": "git", - "url": "https://github.com/phpspec/prophecy.git", - "reference": "bbcd7380b0ebf3961ee21409db7b38bc31d69a13" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phpspec/prophecy/zipball/bbcd7380b0ebf3961ee21409db7b38bc31d69a13", - "reference": "bbcd7380b0ebf3961ee21409db7b38bc31d69a13", - "shasum": "" - }, - "require": { - "doctrine/instantiator": "^1.2", - "php": "^7.2 || ~8.0, <8.2", - "phpdocumentor/reflection-docblock": "^5.2", - "sebastian/comparator": "^3.0 || ^4.0", - "sebastian/recursion-context": "^3.0 || ^4.0" - }, - "require-dev": { - "phpspec/phpspec": "^6.0 || ^7.0", - "phpunit/phpunit": "^8.0 || ^9.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.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/v1.15.0" - }, - "time": "2021-12-08T12:19:24+00:00" - }, - { - "name": "phpstan/phpdoc-parser", - "version": "1.4.2", - "source": { - "type": "git", - "url": "https://github.com/phpstan/phpdoc-parser.git", - "reference": "4cb3021a4e10ffe3d5f94a4c34cf4b3f6de2fa3d" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/4cb3021a4e10ffe3d5f94a4c34cf4b3f6de2fa3d", - "reference": "4cb3021a4e10ffe3d5f94a4c34cf4b3f6de2fa3d", - "shasum": "" - }, - "require": { - "php": "^7.2 || ^8.0" - }, - "require-dev": { - "php-parallel-lint/php-parallel-lint": "^1.2", - "phpstan/extension-installer": "^1.0", - "phpstan/phpstan": "^1.5", - "phpstan/phpstan-strict-rules": "^1.0", - "phpunit/phpunit": "^9.5", - "symfony/process": "^5.2" - }, - "type": "library", - "autoload": { - "psr-4": { - "PHPStan\\PhpDocParser\\": [ - "src/" - ] - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "description": "PHPDoc parser with support for nullable, intersection and generic types", - "support": { - "issues": "https://github.com/phpstan/phpdoc-parser/issues", - "source": "https://github.com/phpstan/phpdoc-parser/tree/1.4.2" - }, - "time": "2022-03-30T13:33:37+00:00" - }, - { - "name": "phpstan/phpstan", - "version": "1.4.10", - "source": { - "type": "git", - "url": "https://github.com/phpstan/phpstan.git", - "reference": "898c479c39caa727bedf4311dd294a8f4e250e72" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpstan/zipball/898c479c39caa727bedf4311dd294a8f4e250e72", - "reference": "898c479c39caa727bedf4311dd294a8f4e250e72", - "shasum": "" - }, - "require": { - "php": "^7.1|^8.0" - }, - "conflict": { - "phpstan/phpstan-shim": "*" - }, - "bin": [ - "phpstan", - "phpstan.phar" - ], - "type": "library", - "autoload": { - "files": [ - "bootstrap.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "description": "PHPStan - PHP Static Analysis Tool", - "support": { - "issues": "https://github.com/phpstan/phpstan/issues", - "source": "https://github.com/phpstan/phpstan/tree/1.4.10" - }, - "funding": [ - { - "url": "https://github.com/ondrejmirtes", - "type": "github" - }, - { - "url": "https://github.com/phpstan", - "type": "github" - }, - { - "url": "https://www.patreon.com/phpstan", - "type": "patreon" - }, - { - "url": "https://tidelift.com/funding/github/packagist/phpstan/phpstan", - "type": "tidelift" - } - ], - "time": "2022-03-14T10:25:45+00:00" - }, - { - "name": "phpunit/php-code-coverage", - "version": "9.2.15", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/php-code-coverage.git", - "reference": "2e9da11878c4202f97915c1cb4bb1ca318a63f5f" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/2e9da11878c4202f97915c1cb4bb1ca318a63f5f", - "reference": "2e9da11878c4202f97915c1cb4bb1ca318a63f5f", - "shasum": "" - }, - "require": { - "ext-dom": "*", - "ext-libxml": "*", - "ext-xmlwriter": "*", - "nikic/php-parser": "^4.13.0", - "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.15" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2022-03-07T09:28:20+00:00" - }, - { - "name": "phpunit/php-file-iterator", - "version": "3.0.6", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/php-file-iterator.git", - "reference": "cf1c2e7c203ac650e352f4cc675a7021e7d1b3cf" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/cf1c2e7c203ac650e352f4cc675a7021e7d1b3cf", - "reference": "cf1c2e7c203ac650e352f4cc675a7021e7d1b3cf", - "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.6" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2021-12-02T12:48:52+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.20", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "12bc8879fb65aef2138b26fc633cb1e3620cffba" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/12bc8879fb65aef2138b26fc633cb1e3620cffba", - "reference": "12bc8879fb65aef2138b26fc633cb1e3620cffba", - "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.3", - "phar-io/version": "^3.0.2", - "php": ">=7.3", - "phpspec/prophecy": "^1.12.1", - "phpunit/php-code-coverage": "^9.2.13", - "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": "^3.0", - "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": { - "files": [ - "src/Framework/Assert/Functions.php" - ], - "classmap": [ - "src/" - ] - }, - "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.20" - }, - "funding": [ - { - "url": "https://phpunit.de/sponsors.html", - "type": "custom" - }, - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2022-04-01T12:37:26+00:00" - }, - { - "name": "psr/log", - "version": "1.1.4", - "source": { - "type": "git", - "url": "https://github.com/php-fig/log.git", - "reference": "d49695b909c3b7628b6289db5479a1c204601f11" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/php-fig/log/zipball/d49695b909c3b7628b6289db5479a1c204601f11", - "reference": "d49695b909c3b7628b6289db5479a1c204601f11", - "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": "https://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.4" - }, - "time": "2021-05-03T11:20:27+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.4", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/exporter.git", - "reference": "65e8b7db476c5dd267e65eea9cab77584d3cfff9" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/65e8b7db476c5dd267e65eea9cab77584d3cfff9", - "reference": "65e8b7db476c5dd267e65eea9cab77584d3cfff9", - "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": "https://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.4" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2021-11-11T14:18:36+00:00" - }, - { - "name": "sebastian/global-state", - "version": "5.0.5", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/global-state.git", - "reference": "0ca8db5a5fc9c8646244e629625ac486fa286bf2" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/0ca8db5a5fc9c8646244e629625ac486fa286bf2", - "reference": "0ca8db5a5fc9c8646244e629625ac486fa286bf2", - "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.5" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2022-02-14T08:28:10+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": "3.0.0", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/type.git", - "reference": "b233b84bc4465aff7b57cf1c4bc75c86d00d6dad" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/b233b84bc4465aff7b57cf1c4bc75c86d00d6dad", - "reference": "b233b84bc4465aff7b57cf1c4bc75c86d00d6dad", - "shasum": "" - }, - "require": { - "php": ">=7.3" - }, - "require-dev": { - "phpunit/phpunit": "^9.5" - }, - "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": "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/3.0.0" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2022-03-15T09:54:48+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": "slevomat/coding-standard", - "version": "7.1", - "source": { - "type": "git", - "url": "https://github.com/slevomat/coding-standard.git", - "reference": "b521bd358b5f7a7d69e9637fd139e036d8adeb6f" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/slevomat/coding-standard/zipball/b521bd358b5f7a7d69e9637fd139e036d8adeb6f", - "reference": "b521bd358b5f7a7d69e9637fd139e036d8adeb6f", - "shasum": "" - }, - "require": { - "dealerdirect/phpcodesniffer-composer-installer": "^0.6.2 || ^0.7", - "php": "^7.2 || ^8.0", - "phpstan/phpdoc-parser": "^1.4.1", - "squizlabs/php_codesniffer": "^3.6.2" - }, - "require-dev": { - "phing/phing": "2.17.2", - "php-parallel-lint/php-parallel-lint": "1.3.2", - "phpstan/phpstan": "1.4.10|1.5.2", - "phpstan/phpstan-deprecation-rules": "1.0.0", - "phpstan/phpstan-phpunit": "1.0.0|1.1.0", - "phpstan/phpstan-strict-rules": "1.1.0", - "phpunit/phpunit": "7.5.20|8.5.21|9.5.19" - }, - "type": "phpcodesniffer-standard", - "extra": { - "branch-alias": { - "dev-master": "7.x-dev" - } - }, - "autoload": { - "psr-4": { - "SlevomatCodingStandard\\": "SlevomatCodingStandard" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "description": "Slevomat Coding Standard for PHP_CodeSniffer complements Consistence Coding Standard by providing sniffs with additional checks.", - "support": { - "issues": "https://github.com/slevomat/coding-standard/issues", - "source": "https://github.com/slevomat/coding-standard/tree/7.1" - }, - "funding": [ - { - "url": "https://github.com/kukulich", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/slevomat/coding-standard", - "type": "tidelift" - } - ], - "time": "2022-03-29T12:44:16+00:00" - }, - { - "name": "squizlabs/php_codesniffer", - "version": "3.6.2", - "source": { - "type": "git", - "url": "https://github.com/squizlabs/PHP_CodeSniffer.git", - "reference": "5e4e71592f69da17871dba6e80dd51bce74a351a" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/squizlabs/PHP_CodeSniffer/zipball/5e4e71592f69da17871dba6e80dd51bce74a351a", - "reference": "5e4e71592f69da17871dba6e80dd51bce74a351a", - "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": "2021-12-12T21:44:58+00:00" - }, - { - "name": "theseer/tokenizer", - "version": "1.2.1", - "source": { - "type": "git", - "url": "https://github.com/theseer/tokenizer.git", - "reference": "34a41e998c2183e22995f158c581e7b5e755ab9e" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/theseer/tokenizer/zipball/34a41e998c2183e22995f158c581e7b5e755ab9e", - "reference": "34a41e998c2183e22995f158c581e7b5e755ab9e", - "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/1.2.1" - }, - "funding": [ - { - "url": "https://github.com/theseer", - "type": "github" - } - ], - "time": "2021-07-28T10:34:58+00:00" - }, - { - "name": "webmozart/assert", - "version": "1.10.0", - "source": { - "type": "git", - "url": "https://github.com/webmozarts/assert.git", - "reference": "6964c76c7804814a842473e0c8fd15bab0f18e25" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/webmozarts/assert/zipball/6964c76c7804814a842473e0c8fd15bab0f18e25", - "reference": "6964c76c7804814a842473e0c8fd15bab0f18e25", - "shasum": "" - }, - "require": { - "php": "^7.2 || ^8.0", - "symfony/polyfill-ctype": "^1.8" - }, - "conflict": { - "phpstan/phpstan": "<0.12.20", - "vimeo/psalm": "<4.6.1 || 4.6.2" - }, - "require-dev": { - "phpunit/phpunit": "^8.5.13" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.10-dev" - } - }, - "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/webmozarts/assert/issues", - "source": "https://github.com/webmozarts/assert/tree/1.10.0" - }, - "time": "2021-03-09T10:59:23+00:00" - } - ], - "aliases": [], - "minimum-stability": "stable", - "stability-flags": [], - "prefer-stable": false, - "prefer-lowest": false, - "platform": { - "php": "^8.0|^7.3", - "ext-json": "*" - }, - "platform-dev": [], - "plugin-api-version": "2.2.0" -} diff --git a/dep b/dep new file mode 100755 index 000000000..ff8e03231 Binary files /dev/null and b/dep differ diff --git a/docs/KNOWN_BUGS.md b/docs/KNOWN_BUGS.md deleted file mode 100644 index 7319ad4c5..000000000 --- a/docs/KNOWN_BUGS.md +++ /dev/null @@ -1,57 +0,0 @@ -# Known Bugs - -## Ubuntu 14.04, Coreutils 8.21 - -There are known bug with relative symlinks `ln --relative`, which may fail rollback command. - -Add next line to _deploy.php_ file: - -```php -set('use_relative_symlink', false); -``` - -## OpenSSH_7.2p2 - -ControlPersist causes stderr to be left open until the master connection times out. - -* https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=714526 -* https://bugzilla.mindrot.org/show_bug.cgi?id=1988 - -## cURL 7.29.0 - -Certificate verification fails with multiple https urls. - -* https://bugzilla.redhat.com/show_bug.cgi?id=1241172 - -## Rsync (3.1.3) - -Artifact upload with `rsync` is interrupted after the first chunk of data upload. -``` -The command "rsync -azP -e 'ssh -A -p *** -o UserKnownHostsFile=/dev/null - -o StrictHostKeyChecking=no' 'artifacts/artifact.tar.gz' 'deploy@ssh.XXX.io:/srv/releases/2009076181'" failed. - -Exit Code: 255(Unknown error) - -Output: -================ -sending incremental file list -artifact.tar.gz - 32,768 0% 0.00kB/s 0:00:00 - -Error Output: -================ -client_loop: send disconnect: Broken pipe - -rsync: [sender] write error: Broken pipe (32) -``` - -In order to resolve (workaround) the issue, you need to add `--bwlimit=4096` to the list of options. - -Example: -```php -task('artifact:upload', function () { - upload(get('artifact_path'), '{{release_path}}', ['options' => ['--bwlimit=4096']]); -}); -``` - -The issue was also described in the [Github Action](https://github.com/deployphp/action/issues/35). \ No newline at end of file diff --git a/docs/UPGRADE.md b/docs/UPGRADE.md deleted file mode 100644 index a92e53dfb..000000000 --- a/docs/UPGRADE.md +++ /dev/null @@ -1,250 +0,0 @@ -# Upgrade from 6.x to 7.x - -## Step 1: Update deploy.php -1. Change config `hostname` to `alias`. -2. Change config `real_hostname` to `hostname`. -3. Change config `user` to `remote_user`. -4. Update `host()` definitions: - 1. Add `set` prefix to all setters: `identityFile` -> `setIdentityFile` or `set('identity_file')` - 2. Update `host(...)->addSshOption('UserKnownHostsFile', '/dev/null')` to `host(...)->setSshArguments(['-o UserKnownHostsFile=/dev/null']);` - 3. Replace _stage_ with labels, i.e. - ```php - host('deployer.org') - ->set('labels', ['stage' => 'prod']); - ``` - When deploying use instead of `dep deploy prod` use `dep deploy stage=prod`. - 4. `alias()` is deleted, `host()` itself sets alias and hostname, to override hostname use `setHostname()`. -5. Update `task()` definitions. - 1. Replace `onRoles()` with `select()`: - ```php - task(...) - ->select('stage=prod'); - ``` -6. Third party recipes now live inside main Deployer repo in _contrib_: - ```php - require 'contrib/rsync.php'; - ``` -7. Replace `inventory()` with `import()`. It now can import hosts, configs, tasks: - ```yaml - import: recipe/common.php - - config: - application: deployer - shared_dirs: - - uploads - - storage/logs/ - - storage/db - shared_files: - - .env - - config/test.yaml - keep_releases: 3 - http_user: false - - hosts: - prod: - local: true - - tasks: - deploy: - - deploy:prepare - - deploy:vendors - - deploy:publish - - deploy:vendors: - - run: 'cd {{release_path}} && echo {{bin/composer}} {{composer_options}} 2>&1' - ``` -8. Rename task `success` to `deploy:success` and `cleanup` to deploy:cleanup`. -9. Verbosity function (`isDebug()`, etc) deleted. Use `output()->isDebug()` instead. -10. runLocally() commands are executed relative to the recipe file directory. This behaviour can be overridden via an environment variable: - ``` - DEPLOYER_ROOT=. vendor/bin/dep taskname` - ``` -11. Replace `local()` tasks with combination of `once()` and `runLocally()` func. -12. Replace `locateBinaryPath()` with `which()` func. -13. Configuration property `default_stage` is not supported. - -## Step 2: Deploy - -Since the release history numbering is not compatible between v6 and v7, you need to specify the `release_name` manually for the first time. Otherwise you start with release 1. - -1. Find out next release name (ssh to the host, `ls` releases dir, find the biggest number). Example: `42`. -2. Deploy with release_name: - ``` - dep deploy -o release_name=43 - ``` - -:::note -In case a rollback is needed, manually change the `current` symlink: -``` -ln -nfs releases/42 current -``` -::: - -:::note -In case there are multiple hosts with different release names, you should create a `{{deploy_path}}/.dep/latest_release` file in each host with the current release number of that particular host. -::: - -## Other versions - -### Upgrade from 5.x to 6.x - -1. Changed branch option priority - - If you have host definition with `branch(...)` parameter, adding `--branch` option will not override it any more. - If no `branch(...)` parameter persists, branch will be fetched from current local git branch. - - ```php - host('prod') - ->set('branch', 'production') - ``` - - In order to return to old behavior add checking of `--branch` option. - - ```php - host('prod') - ->set('branch', function () { - return input()->getOption('branch') ?: 'production'; - }) - ``` - -2. Add `deploy:info` task to the beginning to `deploy` task. - -3. `run` returns string instead of `Deployer\Type\Result` - - Now `run` and `runLocally` returns `string` instead of `Deployer\Type\Result`. - Replace method calls as: - - * `run('command')->toString()` → `run('command')` - * `run('if command; then echo "true"; fi;')->toBool()` → `test('command')` - -4. `env_vars` renamed to `env` - - * `set('env_vars', 'FOO=bar');` → `set('env', ['FOO' => 'bar']);` - - If your are using Symfony recipe, then you need to change `env` setting: - - * `set('env', 'prod');` → `set('symfony_env', 'prod');` - -### Upgrade from 4.x to 5.x - -1. Servers to Hosts - - * `server($hostname)` to `host($hostname)`, and `server($name, $hostname)` to `host($name)->hostname($hostname)` - * `localServer($name)` to `localhost()` - * `cluster($name, $nodes, $port)` to `hosts(...$hodes)` - * `serverList($file)` to `inventory($file)` - - If you need to deploy to same server use [host aliases](https://deployer.org/docs/hosts#host-aliases): - - ```php - host('domain.com/green', 'domain.com/blue') - ->set('deploy_path', '~/{{hostname}}') - ... - ``` - - Or you can define different hosts with same hostname: - - ```php - host('production') - ->hostname('domain.com') - ->set('deploy_path', '~/production') - ... - - host('beta') - ->hostname('domain.com') - ->set('deploy_path', '~/beta') - ... - ``` - -2. Configuration options - - * Rename `{{server.name}}` to `{{hostname}}` - -3. DotArray syntax - - In v5 access to nested arrays in config via dot notation was removed. - If you was using it, consider to move to plain config options. - - Refactor this: - - ```php - set('a', ['b' => 1]); - - // ... - - get('a.b'); - ``` - - To: - - ```php - set('a_b', 1); - - // ... - - get('a_b'); - ``` - -4. Credentials - - Best practice in new v5 is to omit credentials for connection in `deploy.php` and write them in `~/.ssh/config` instead. - - * `identityFile($publicKeyFile,, $privateKeyFile, $passPhrase)` to `identityFile($privateKeyFile)` - * `pemFile($pemFile)` to `identityFile($pemFile)` - * `forwardAgent()` to `forwardAgent(true)` - -5. Tasks constraints - - * `onlyOn` to `onHosts` - * `onlyOnStage` to `onStage` - - -### Upgrade from 3.x to 4.x - -1. Namespace for functions - - Add to beginning of *deploy.php* next line: - - ```php - use function Deployer\{server, task, run, set, get, add, before, after}; - ``` - - If you are using PHP version less than 5.6, you can use this: - - ```php - namespace Deployer; - ``` - -2. `env()` to `set()`/`get()` - - Rename all calls `env($name, $value)` to `set($name, $value)`. - - Rename all rvalue `env($name)` to `get($name)`. - - Rename all `server(...)->env(...)` to `server(...)->set(...)`. - -3. Moved *NonFatalException* - - Rename `Deployer\Task\NonFatalException` to `Deployer\Exception\NonFatalException`. - -4. Prior release cleanup - - Due to changes in release management, the new cleanup task will ignore any prior releases deployed with 3.x. These will need to be manually removed after migrating to and successfully releasing via 4.x. - -### Upgrade from 2.x to 3.x - -1. ### `->path('...')` - - Replace your server paths configuration: - - ```php - server(...) - ->path(...); - ``` - - to: - - ```php - server(...) - ->env('deploy_path', '...'); - ``` diff --git a/docs/api.md b/docs/api.md deleted file mode 100644 index 168eea97b..000000000 --- a/docs/api.md +++ /dev/null @@ -1,562 +0,0 @@ - - - - -# API Reference - -## host() - -```php -host(string ...$hostname) -``` - -Defines a host or hosts. -```php -host('example.org'); -host('prod.example.org', 'staging.example.org'); -``` - -Inside task can be used to get `Host` instance of an alias. -```php -task('test', function () { - $port = host('example.org')->get('port'); -}); -``` - - - -## localhost() - -```php -localhost(string ...$hostnames) -``` - - - -## currentHost() - -```php -currentHost(): Host -``` - -Returns current host. - - -## select() - -```php -select(string $selector): array -``` - -Returns hosts based on provided selector. - -```php -on(select('stage=prod, role=db'), function (Host $host) { - ... -}); -``` - - - -## selectedHosts() - -```php -selectedHosts(): array -``` - -Returns array of hosts selected by user via CLI. - - - -## import() - -```php -import(string $file): void -``` - -Import other php or yaml recipes. - -```php -import('recipe/common.php'); -``` - -```php -import(__DIR__ . '/config/hosts.yaml'); -``` - - - -## desc() - -```php -desc(?string $title = null): ?string -``` - -Set task description. - - -## task() - -```php -task(string $name, $body = null): Task -``` - -Define a new task and save to tasks list. - -Alternatively get a defined task. - - - -| Argument | Type | Comment | -|---|---|---| -| `$name` | `string` | Name of current task. | -| `$body` | `callable():void` or `array` or `null` | Callable task, array of other tasks names or nothing to get a defined tasks | - -## before() - -```php -before(string $task, $do) -``` - -Call that task before specified task runs. - - - - -| Argument | Type | Comment | -|---|---|---| -| `$task` | `string` | The task before $that should be run. | -| `$do` | `string` or `callable():void` | The task to be run. | - -## after() - -```php -after(string $task, $do) -``` - -Call that task after specified task runs. - - - - -| Argument | Type | Comment | -|---|---|---| -| `$task` | `string` | The task after $that should be run. | -| `$do` | `string` or `callable():void` | The task to be run. | - -## fail() - -```php -fail(string $task, $do) -``` - -Setup which task run on failure of $task. -When called multiple times for a task, previous fail() definitions will be overridden. - - - - -| Argument | Type | Comment | -|---|---|---| -| `$task` | `string` | The task which need to fail so $that should be run. | -| `$do` | `string` or `callable():void` | The task to be run. | - -## option() - -```php -option(string $name, $shortcut = null, ?int $mode = null, string $description = '', $default = null): void -``` - -Add users options. - - - -| Argument | Type | Comment | -|---|---|---| -| `$name` | `string` | The option name | -| `$shortcut` | `string` or `array` or `null` | The shortcuts, can be null, a string of shortcuts delimited by | or an array of shortcuts | -| `$mode` | `int` or `null` | The option mode: One of the VALUE_* constants | -| `$description` | `string` | A description text | -| `$default` | `string` or `string[]` or `int` or `bool` or `null` | The default value (must be null for self::VALUE_NONE) | - -## cd() - -```php -cd(string $path): void -``` - -Change the current working directory. - - -## within() - -```php -within(string $path, callable $callback) -``` - -Execute a callback within a specific directory and revert back to the initial working directory. - - - -## run() - -```php -run(string $command, ?array $options = [], ?int $timeout = null, ?int $idle_timeout = null, ?string $secret = null, ?array $env = null, ?bool $real_time_output = false, ?bool $no_throw = false): string -``` - -Executes given command on remote host. - -Examples: - -```php -run('echo hello world'); -run('cd {{deploy_path}} && git status'); -run('password %secret%', secret: getenv('CI_SECRET')); -run('curl medv.io', timeout: 5); -``` - -```php -$path = run('readlink {{deploy_path}}/current'); -run("echo $path"); -``` - - - - -| Argument | Type | Comment | -|---|---|---| -| `$command` | `string` | Command to run on remote host. | -| `$options` | `array` or `null` | Array of options will override passed named arguments. | -| `$timeout` | `int` or `null` | Sets the process timeout (max. runtime). The timeout in seconds (default: 300 sec; see {{default_timeout}}, `null` to disable). | -| `$idle_timeout` | `int` or `null` | Sets the process idle timeout (max. time since last output) in seconds. | -| `$secret` | `string` or `null` | Placeholder `%secret%` can be used in command. Placeholder will be replaced with this value and will not appear in any logs. | -| `$env` | `array` or `null` | Array of environment variables: `run('echo $KEY', env: ['key' => 'value']);` | -| `$real_time_output` | `bool` or `null` | Print command output in real-time. | -| `$no_throw` | `bool` or `null` | Don't throw an exception of non-zero exit code. | - -## runLocally() - -```php -runLocally(string $command, ?array $options = [], ?int $timeout = null, ?int $idle_timeout = null, ?string $secret = null, ?array $env = null, ?string $shell = null): string -``` - -Execute commands on a local machine. - -Examples: - -```php -$user = runLocally('git config user.name'); -runLocally("echo $user"); -``` - - - - -| Argument | Type | Comment | -|---|---|---| -| `$command` | `string` | Command to run on localhost. | -| `$options` | `array` or `null` | Array of options will override passed named arguments. | -| `$timeout` | `int` or `null` | Sets the process timeout (max. runtime). The timeout in seconds (default: 300 sec, `null` to disable). | -| `$idle_timeout` | `int` or `null` | Sets the process idle timeout (max. time since last output) in seconds. | -| `$secret` | `string` or `null` | Placeholder `%secret%` can be used in command. Placeholder will be replaced with this value and will not appear in any logs. | -| `$env` | `array` or `null` | Array of environment variables: `runLocally('echo $KEY', env: ['key' => 'value']);` | -| `$shell` | `string` or `null` | Shell to run in. Default is `bash -s`. | - -## test() - -```php -test(string $command): bool -``` - -Run test command. -Example: - -```php -if (test('[ -d {{release_path}} ]')) { -... -} -``` - - - -## testLocally() - -```php -testLocally(string $command): bool -``` - -Run test command locally. -Example: - - testLocally('[ -d {{local_release_path}} ]') - - - -## on() - -```php -on($hosts, callable $callback): void -``` - -Iterate other hosts, allowing to call run a func in callback. - -```php -on(select('stage=prod, role=db'), function ($host) { - ... -}); -``` - -```php -on(host('example.org'), function ($host) { - ... -}); -``` - -```php -on(Deployer::get()->hosts, function ($host) { - ... -}); -``` - - - -## invoke() - -```php -invoke(string $taskName): void -``` - -Runs a task. -```php -invoke('deploy:symlink'); -``` - - - -## upload() - -```php -upload($source, string $destination, array $config = []): void -``` - -Upload file or directory to host. - -> You may have noticed that there is a trailing slash (/) at the end of the first argument in the above command, this is necessary to mean “the contents of build“. -> -> The alternative, without the trailing slash, would place build, including the directory, within public. This would create a hierarchy that looks like: {{release_path}}/public/build - - The `$config` array supports the following keys: - -- `flags` for overriding the default `-azP` passed to the `rsync` command -- `options` with additional flags passed directly to the `rsync` command -- `timeout` for `Process::fromShellCommandline()` (`null` by default) -- `progress_bar` to display upload/download progress -- `display_stats' to display rsync set of statistics - - - - -## download() - -```php -download(string $source, string $destination, array $config = []): void -``` - -Download file or directory from host - - - - -## info() - -```php -info(string $message): void -``` - -Writes an info message. - - -## warning() - -```php -warning(string $message): void -``` - -Writes an warning message. - - -## writeln() - -```php -writeln(string $message, int $options = 0): void -``` - -Writes a message to the output and adds a newline at the end. - - -## parse() - -```php -parse(string $value): string -``` - -Parse set values. - - -## set() - -```php -set(string $name, $value): void -``` - -Setup configuration option. - - -## add() - -```php -add(string $name, array $array): void -``` - -Merge new config params to existing config array. - - - -## get() - -```php -get(string $name, $default = null) -``` - -Get configuration value. - - - - -## has() - -```php -has(string $name): bool -``` - -Check if there is such configuration option. - - -## ask() - -```php -ask(string $message, ?string $default = null, ?array $autocomplete = null): ?string -``` - - - -## askChoice() - -```php -askChoice(string $message, array $availableChoices, $default = null, bool $multiselect = false) -``` - - - -## askConfirmation() - -```php -askConfirmation(string $message, bool $default = false): bool -``` - - - -## askHiddenResponse() - -```php -askHiddenResponse(string $message): string -``` - - - -## input() - -```php -input(): InputInterface -``` - - - -## output() - -```php -output(): OutputInterface -``` - - - -## commandExist() - -```php -commandExist(string $command): bool -``` - -Check if command exists - - - -## commandSupportsOption() - -```php -commandSupportsOption(string $command, string $option): bool -``` - - - -## which() - -```php -which(string $name): string -``` - - - -## remoteEnv() - -```php -remoteEnv(): array -``` - -Returns remote environments variables as an array. -```php -$remotePath = remoteEnv()['PATH']; -run('echo $PATH', env: ['PATH' => "/home/user/bin:$remotePath"]); -``` - - -## error() - -```php -error(string $message): Exception -``` - -Creates a new exception. - - -## timestamp() - -```php -timestamp(): string -``` - -Returns current timestamp in UTC timezone in ISO8601 format. - - -## fetch() - -```php -fetch(string $url, string $method = 'get', array $headers = [], ?string $body = null, ?array &$info = null, bool $nothrow = false): string -``` - -Example usage: -```php -$result = fetch('{{domain}}', info: $info); -var_dump($info['http_code'], $result); -``` - - diff --git a/docs/avoid-php-fpm-reloading.md b/docs/avoid-php-fpm-reloading.md deleted file mode 100644 index 7699378d6..000000000 --- a/docs/avoid-php-fpm-reloading.md +++ /dev/null @@ -1,54 +0,0 @@ -# Avoid PHP-FPM Reloading - -Deployer symlinks _current_ to latest release dir. - -``` -current -> releases/3/ -releases/ - 1/ - 2/ - 3/ -``` - -## The problem - -PHP Opcodes get cached. And if `SCRIPT_FILENAME` contains _current_ symlink, on -new deploy nothing updates. Usually, a solution is simple to reload **php-fpm** -after deploy, but such reload can lead to **dropped** or **failed** requests. -The correct fix is to configure your server set `SCRIPT_FILENAME` to a resolved path. -You can check your server configuration by printing `SCRIPT_FILENAME`. - -```php -echo $_SERVER['SCRIPT_FILENAME']; -``` - -If it prints something like `/home/deployer/example.com/current/index.php` with -_current_ in the path, your server configured incorrectly. - -## Fix for Nginx - -Nginx has special variable `$realpath_root`, use it to set up `SCRIPT_FILENAME`: - -```diff -location ~ \.php$ { - include fastcgi_params; - fastcgi_pass unix:/var/run/php/php-fpm.sock; -- fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; -+ fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name; -} -``` - -## Fix for Caddy - -:::tip -If you're already using servers provisioned by Deployer, you don't need to fix -anything, as everything is already configured properly. -::: - -Use `resolve_root_symlink`: - -``` -php_fastcgi * unix//run/php/php-fpm.sock { - resolve_root_symlink -} -``` diff --git a/docs/basics.md b/docs/basics.md deleted file mode 100644 index 87a0042cd..000000000 --- a/docs/basics.md +++ /dev/null @@ -1,233 +0,0 @@ -# Basics - -Deployer has two main concepts: [**hosts**](hosts.md) and [**tasks**](tasks.md). - -A **recipe** is a file containing definitions for **hosts** and **tasks**. - -Deployer CLI requires two arguments to run: a **task** to run and a **host** -or group of **hosts**. - -``` -$ dep deploy deployer.org - --- ------ ------------ - | | | - | | `--- The host - | `------------- The task - `------------------ The CLI -``` - -Then Deployer takes the given task, performs some preparation (described later), -and executes the task on all specified hosts. - -The `dep` CLI looks for `deploy.php` or `deploy.yaml` file in current directory. - -Or recipe can be specified explicitly via `-f` or `--file` option. -``` -$ dep --file=deploy.php deploy deployer.org -``` - -Let's write a recipe. - -```php -// We are going to use functions declared primarily in Deployer namespace, -// to simplify recipe we will use Deployer namespace too. Alternativly, -// you can import individual functions via "use function". -namespace Deployer; - -host('deployer.org'); - -task('my_task', function () { - run('whoami'); -}); -``` - -Let's try to run our task on deployer.org. - -``` -$ dep my_task -task my_task -$ -``` - -If no host provided, Deployer will show an interactive prompt for selecting hosts. -If your recipe contains only one host, Deployer will automatically choose it. -To select all hosts specify `all`. - -But where is our `whoami` command output? By default, Deployer runs with normal verbosity -level and shows only names of executed tasks. Let's increase verbosity to verbose, and -rerun our task. - -Add `-v` option to increase verbosity. Read more about [CLI usage](cli.md). - -``` -$ dep my_task -v -task my_task -[deployer.org] run whoami -[deployer.org] deployer -$ -``` - -Now let's add second host: - -```php -host('deployer.org'); -host('medv.io'); -``` - -How does Deployer know how to connect to a host? It uses same `~/.ssh/config` file as -the `ssh` command. Alternatively, you can specify [connection options](hosts.md) in recipe. - -Let's run `my_task` task on both hosts: - -``` -$ dep my_task -v all -task my_task -[deployer.org] run whoami -[medv.io] run whoami -[medv.io] anton -[deployer.org] deployer -``` - -Deployer runs a task in parallel on each host. This is why the output is mixed. We can -limit it to run only one host. - -``` -$ dep my_task -v all --limit 1 -task my_task -[deployer.org] run whoami -[deployer.org] deployer -[medv.io] run whoami -[medv.io] deployer -``` - -Limit level also possible to [specified per task](tasks.md). - -Each host has a configuration: a list of key-value pairs. Let's define our first -configuration option for both our hosts: - -```php -host('deployer.org') - ->set('my_config', 'foo'); -host('medv.io') - ->set('my_config', 'bar'); -``` - -In the task we can get current executing host with [currentHost](api.md#currenthost) function: - -```php -task('my_task', function () { - $myConfig = currentHost()->get('my_config'); - writeln("my_config: " . $myConfig); -}); -``` - -Or with [get](api.md#get) function: - -```diff -task('my_task', function () { -- $myConfig = currentHost()->get('my_config'); -+ $myConfig = get('my_config'); - writeln("my_config: " . $myConfig); -}); -``` - -Or via [parse](api.md#parse) function which replaces brackets `{{ ... }}` and value -with of config option. - -All functions (writeln, run, runLocally, cd, upload, etc) call **parse** function -internally. So you don't need to call **parse** function by your self. - -```diff -task('my_task', function () { -- $myConfig = get('my_config'); -- writeln("my_config: " . $myConfig); -+ writeln("my_config: {{my_config}}"); -}); -``` - -Let's try to run our task: - -``` -$ dep my_task all -task my_task -[deployer.org] my_config: foo -[medv.io] my_config: bar -``` - -Awesome! Each host configuration inherits global configuration. Let's refactor -our recipe to define one global config option: - -```php -set('my_config', 'global'); - -host('deployer.org'); -host('medv.io'); -``` - -The config option `my_config` will be equal to `global` on both hosts. - -Also, config option value can be specified as a callback, such callback -executed on first access and returned result saved in host configuration. - -```php -set('whoami', function () { - return run('whoami'); -}); - -task('my_task', function () { - writeln('Who am I? {{whoami}}'); -}); -``` - -Let's try to run it: - -``` -$ dep my_task all -task my_task -[deployer.org] Who am I? deployer -[medv.io] Who am I? anton -``` - -We can use this to create dynamic configuration which uses current host information. - -Only the first call will trigger the callback execution. All subsequent checks use saved value. - -Here is an example: - -```php -set('current_date', function () { - return run('date'); -}); - -task('my_task', function () { - writeln('What time is it? {{current_date}}'); - run('sleep 5'); - writeln('What time is it? {{current_date}}'); -}); -``` - -If we run my_task we will see that `date` is called only once on -`{{current_date}}` access. - -``` -$ dep my_task deployer.org -v -task my_task -[deployer.org] run date -[deployer.org] Wed 03 Nov 2021 01:16:53 PM UTC -[deployer.org] What time is it? Wed 03 Nov 2021 01:16:53 PM UTC -[deployer.org] run sleep 5 -[deployer.org] What time is it? Wed 03 Nov 2021 01:16:53 PM UTC -``` - -We can override a config option via CLI option `-o` like this: - -``` -$ dep my_task deployer.org -v -o current_date="I don't know" -task my_task -[deployer.org] What time is it? I don't know -[deployer.org] run sleep 5 -[deployer.org] What time is it? I don't know -``` - -Since the `current_date` config option is overridden there is no need to call the callback. -So there is no 'run date'. diff --git a/docs/ci-cd.md b/docs/ci-cd.md deleted file mode 100755 index f1b174013..000000000 --- a/docs/ci-cd.md +++ /dev/null @@ -1,96 +0,0 @@ -# CI/CD - -## GitHub Actions - -Use official [GitHub Action for Deployer](https://github.com/deployphp/action). - -Create `.github/workflows/deploy.yml` file with following content: - -```yaml -name: deploy - -on: - push: - branches: [ master ] - -concurrency: production_environment - -jobs: - deploy: - runs-on: ubuntu-latest - - steps: - - uses: actions/checkout@v2 - - - name: Setup PHP - uses: shivammathur/setup-php@v2 - with: - php-version: '8.0' - - - name: Deploy - uses: deployphp/action@v1 - with: - private-key: ${{ secrets.PRIVATE_KEY }} - dep: deploy -``` - -:::warning -The `concurrency: production_environment` is important as it prevents concurrent -deploys. -::: - -## GitLab CI/CD - -Set the following variables in GitLab project: - -- `SSH_KNOW_HOSTS`: Content of `~/.ssh/known_hosts` file. -The public SSH keys for a host may be obtained using the utility `ssh-keyscan`. -For example: `ssh-keyscan deployer.org`. -- `SSH_PRIVATE_KEY`: Private key for connecting to remote hosts. -To generate private key: `ssh-keygen -t ed25519 -C 'gitlab@deployer.org'`. - -Create .gitlab-ci.yml file with following content: - -```yml -stages: - - deploy - -deploy: - stage: deploy - image: - name: deployphp/deployer:7 - entrypoint: [""] - before_script: - - mkdir -p ~/.ssh - - eval $(ssh-agent -s) - - echo "$SSH_KNOWN_HOSTS" > ~/.ssh/known_hosts - - chmod 644 ~/.ssh/known_hosts - - echo "$SSH_PRIVATE_KEY" | tr -d '\r' | ssh-add - > /dev/null - script: - - dep deploy -vvv - resource_group: production - only: - - master -``` - -### Deployment concurrency - -Only one deployment job runs at a time with the [`resource_group` keyword](https://docs.gitlab.com/ee/ci/yaml/index.html#resource_group) in .gitlab-ci.yml. - -In addition, you can ensure that older deployment jobs are cancelled automatically when a newer deployment runs by enabling the [skip outdated deployment jobs](https://docs.gitlab.com/ee/ci/pipelines/settings.html#skip-outdated-deployment-jobs) feature. - -### Deploy secrets - -Is not recommended committing secrets in the repository, you could use a GitLab variable to store them. - -Many frameworks use dotenv to store secrets, let's create a GitLab file variable named `DOTENV`, so it can be deployed along with the code. - -Set up a deployer task to copy secrets to the server: - -```php -task('deploy:secrets', function () { - upload(getenv('DOTENV'), '{{deploy_path}}/shared/.env'); -}); -``` - -Run the task immediately after updating the code. diff --git a/docs/cli.md b/docs/cli.md deleted file mode 100755 index 886e8419b..000000000 --- a/docs/cli.md +++ /dev/null @@ -1,146 +0,0 @@ -# CLI Usage - -We recommend adding next alias to your .bashrc file: - -```bash -alias dep='vendor/bin/dep' -``` - -As well as installing completion script for Deployer, completion supports: -- tasks, -- options, -- host names, -- and configs. - -For example for macOS run next commands: - -```bash -brew install bash-completion -dep completion bash > /usr/local/etc/bash_completion.d/deployer -``` - -## Overriding configuration options - -For example, if your _deploy.php_ file contains this configuration: - -```php -set('ssh_multiplexing', false); -``` - -And you want to enable [ssh multiplexing](https://en.wikibooks.org/wiki/OpenSSH/Cookbook/Multiplexing) without modifying the recipe, you can pass the `-o` option to the `dep` command: - -``` -dep deploy -o ssh_multiplexing=true -``` - -To override multiple config options, you can pass multiple `-o` args: - -``` -dep deploy -o ssh_multiplexing=true -o branch=master -``` - -## Running arbitrary commands - -Run any command on one or more hosts: - -``` -dep run 'uptime -p' -``` - -## Tree command - -Deployer has group tasks and before/after hooks, so see task tree use **dep tree** command: - -``` -$ dep tree deploy -The task-tree for deploy: -└── deploy - ├── deploy:prepare - │ ├── deploy:info - │ ├── deploy:setup - │ ├── deploy:lock - │ ├── deploy:release - │ ├── deploy:update_code - │ ├── build // after deploy:update_code - │ ├── deploy:shared - │ └── deploy:writable - ├── deploy:vendors - ├── artisan:storage:link - ├── artisan:config:cache - ├── artisan:route:cache - ├── artisan:view:cache - ├── artisan:migrate - └── deploy:publish - ├── deploy:symlink - ├── deploy:unlock - ├── deploy:cleanup - └── deploy:success -``` - -## Execution plan - -Before executing tasks, Deployer needs to flatten task tree and to decide in which order it will be executing tasks -on which hosts. Use `--plan` option to output table with tasks/hosts: - -``` -$ dep deploy --plan all -┌──────────────────────┬──────────────────────┬──────────────────────┬──────────────────────┐ -│ prod01 │ prod02 │ prod03 │ prod04 │ -├──────────────────────┼──────────────────────┼──────────────────────┼──────────────────────┤ -│ deploy:info │ deploy:info │ deploy:info │ deploy:info │ -│ deploy:setup │ deploy:setup │ deploy:setup │ deploy:setup │ -│ deploy:lock │ deploy:lock │ deploy:lock │ deploy:lock │ -│ deploy:release │ deploy:release │ deploy:release │ deploy:release │ -│ deploy:update_code │ deploy:update_code │ deploy:update_code │ deploy:update_code │ -│ build │ build │ build │ build │ -│ deploy:shared │ deploy:shared │ deploy:shared │ deploy:shared │ -│ deploy:writable │ deploy:writable │ deploy:writable │ deploy:writable │ -│ deploy:vendors │ deploy:vendors │ deploy:vendors │ deploy:vendors │ -│ artisan:storage:link │ artisan:storage:link │ artisan:storage:link │ artisan:storage:link │ -│ artisan:config:cache │ artisan:config:cache │ artisan:config:cache │ artisan:config:cache │ -│ artisan:route:cache │ artisan:route:cache │ artisan:route:cache │ artisan:route:cache │ -│ artisan:view:cache │ artisan:view:cache │ artisan:view:cache │ artisan:view:cache │ -│ artisan:migrate │ artisan:migrate │ artisan:migrate │ artisan:migrate │ -│ deploy:symlink │ - │ - │ - │ -│ - │ deploy:symlink │ - │ - │ -│ - │ - │ deploy:symlink │ - │ -│ - │ - │ - │ deploy:symlink │ -│ deploy:unlock │ deploy:unlock │ deploy:unlock │ deploy:unlock │ -│ deploy:cleanup │ deploy:cleanup │ deploy:cleanup │ deploy:cleanup │ -│ deploy:success │ deploy:success │ deploy:success │ deploy:success │ -└──────────────────────┴──────────────────────┴──────────────────────┴──────────────────────┘ -``` - -The **deploy.php*: - -```php -host('prod[01:04]'); -task('deploy:symlink')->limit(1); -``` - -## The `runLocally` working dir - -By default `runLocally()` commands are executed relative to the recipe file directory. -This can be overridden globally by setting an environment variable: - -``` -DEPLOYER_ROOT=. dep taskname` -``` - -Alternatively the root directory can be overridden per command via the cwd configuration. - -```php -runLocally('ls', ['cwd' => '/root/directory']); -``` - -## Play blackjack - -> Yeah, well. I'm gonna go build my own theme park... with blackjack and hookers! -> -> In fact, forget the park! -> -> — Bender - -``` -dep blackjack -``` diff --git a/docs/contrib/bugsnag.md b/docs/contrib/bugsnag.md deleted file mode 100644 index 63db28444..000000000 --- a/docs/contrib/bugsnag.md +++ /dev/null @@ -1,42 +0,0 @@ - - - - -# bugsnag - -[Source](/contrib/bugsnag.php) - - - -Add to your _deploy.php_ - -```php -require 'contrib/bugsnag.php'; -``` - -## Configuration - -- *bugsnag_api_key* – the API Key associated with the project. Informs Bugsnag which project has been deployed. This is the only required field. -- *bugsnag_provider* – the name of your source control provider. Required when repository is supplied and only for on-premise services. -- *bugsnag_app_version* – the app version of the code you are currently deploying. Only set this if you tag your releases with semantic version numbers and deploy infrequently. (Optional.) - -## Usage - -Since you should only notify Bugsnag of a successful deployment, the `bugsnag:notify` task should be executed right at the end. - -```php -after('deploy', 'bugsnag:notify'); -``` - - - -## Tasks - -### bugsnag:notify -[Source](https://github.com/deployphp/deployer/blob/master/contrib/bugsnag.php#L28) - -Notifies Bugsnag of deployment. - - - - diff --git a/docs/contrib/cachetool.md b/docs/contrib/cachetool.md deleted file mode 100644 index b5eb136eb..000000000 --- a/docs/contrib/cachetool.md +++ /dev/null @@ -1,125 +0,0 @@ - - - - -# cachetool - -[Source](/contrib/cachetool.php) - - - -Add to your _deploy.php_ - -```php -require 'contrib/cachetool.php'; -``` - -## Configuration - -- **cachetool** *(optional)*: accepts a *string* with the unix socket or ip address to php-fpm. If `cachetool` is not given, then the application will look for a `cachetool.yml` file and read the configuration from there. - - ```php - set('cachetool', '/var/run/php-fpm.sock'); - // or - set('cachetool', '127.0.0.1:9000'); - ``` - -You can also specify different cachetool settings for each host: -```php -host('staging') - ->set('cachetool', '127.0.0.1:9000'); - -host('production') - ->set('cachetool', '/var/run/php-fpm.sock'); -``` - -By default, if no `cachetool` parameter is provided, this recipe will fallback to the global setting. - -If your deployment user does not have permission to access the php-fpm.sock, you can alternatively use -the web adapter that creates a temporary php file and makes a web request to it with a configuration like -```php -set('cachetool_args', '--web --web-path=./public --web-url=https://{{hostname}}'); -``` - -## Usage - -Since APCu and OPcache deal with compiling and caching files, they should be executed right after the symlink is created for the new release: - -```php -after('deploy:symlink', 'cachetool:clear:opcache'); -or -after('deploy:symlink', 'cachetool:clear:apcu'); -``` - -## Read more - -Read more information about cachetool on the website: -http://gordalina.github.io/cachetool/ - - -## Configuration -### cachetool -[Source](https://github.com/deployphp/deployer/blob/master/contrib/cachetool.php#L53) - - - - - -### cachetool_url -[Source](https://github.com/deployphp/deployer/blob/master/contrib/cachetool.php#L54) - - - -```php title="Default value" -'https://github.com/gordalina/cachetool/releases/download/7.0.0/cachetool.phar' -``` - - -### cachetool_args -[Source](https://github.com/deployphp/deployer/blob/master/contrib/cachetool.php#L55) - - - - - -### bin/cachetool -[Source](https://github.com/deployphp/deployer/blob/master/contrib/cachetool.php#L56) - - - - - -### cachetool_options -[Source](https://github.com/deployphp/deployer/blob/master/contrib/cachetool.php#L62) - - - - - - -## Tasks - -### cachetool:clear:opcache -[Source](https://github.com/deployphp/deployer/blob/master/contrib/cachetool.php#L79) - -Clears OPcode cache. - -Clear opcache cache - - -### cachetool:clear:apcu -[Source](https://github.com/deployphp/deployer/blob/master/contrib/cachetool.php#L87) - -Clears APCu system cache. - -Clear APCU cache - - -### cachetool:clear:stat -[Source](https://github.com/deployphp/deployer/blob/master/contrib/cachetool.php#L95) - -Clears file status and realpath caches. - -Clear file status cache, including the realpath cache - - diff --git a/docs/contrib/chatwork.md b/docs/contrib/chatwork.md deleted file mode 100644 index ac20ba087..000000000 --- a/docs/contrib/chatwork.md +++ /dev/null @@ -1,190 +0,0 @@ - - - - -# chatwork - -[Source](/contrib/chatwork.php) - - - -# Chatwork Recipe - -## Installing - 1. Create chatwork account by any manual in the internet - 2. Take chatwork token (Like: b29a700e2d15bef3f26ae6a5c142d1ea) and set `chatwork_token` parameter - 3. Take chatwork room id from url after clicked on the room, and set `chatwork_room_id` parameter - 4. If you want, you can edit `chatwork_notify_text`, `chatwork_success_text` or `chatwork_failure_text` - 5. Require chatwork recipe in your `deploy.php` file - -```php -# https://deployer.org/recipes.html - -require 'recipe/chatwork.php'; -``` - -Add hook on deploy: - -```php -before('deploy', 'chatwork:notify'); -``` - -## Configuration - -- `chatwork_token` – chatwork bot token, **required** -- `chatwork_room_id` — chatwork room to push messages to **required** -- `chatwork_notify_text` – notification message template - ``` - [info] - [title](*) Deployment Status: Deploying[/title] - Repo: {{repository}} - Branch: {{branch}} - Server: {{hostname}} - Release Path: {{release_path}} - Current Path: {{current_path}} - [/info] - ``` -- `chatwork_success_text` – success template, default: - ``` - [info] - [title](*) Deployment Status: Successfully[/title] - Repo: {{repository}} - Branch: {{branch}} - Server: {{hostname}} - Release Path: {{release_path}} - Current Path: {{current_path}} - [/info]" - ``` -- `chatwork_failure_text` – failure template, default: - ``` - [info] - [title](*) Deployment Status: Failed[/title] - Repo: {{repository}} - Branch: {{branch}} - Server: {{hostname}} - Release Path: {{release_path}} - Current Path: {{current_path}} - [/info]" - ``` - -## Tasks - -- `chatwork:notify` – send message to chatwork -- `chatwork:notify:success` – send success message to chatwork -- `chatwork:notify:failure` – send failure message to chatwork - -## Usage - -If you want to notify only about beginning of deployment add this line only: - -```php -before('deploy', 'chatwork:notify'); -``` - -If you want to notify about successful end of deployment add this too: - -```php -after('success', 'chatwork:notify:success'); -``` -If you want to notify about failed deployment add this too: - -```php -after('deploy:failed', 'chatwork:notify:failure'); -``` - - -## Configuration -### chatwork_token -[Source](https://github.com/deployphp/deployer/blob/master/contrib/chatwork.php#L91) - -Chatwork settings - - - -### chatwork_room_id -[Source](https://github.com/deployphp/deployer/blob/master/contrib/chatwork.php#L94) - - - - - -### chatwork_api -[Source](https://github.com/deployphp/deployer/blob/master/contrib/chatwork.php#L97) - - - - - -### chatwork_notify_text -[Source](https://github.com/deployphp/deployer/blob/master/contrib/chatwork.php#L102) - -The Messages - -```php title="Default value" -"[info]\n[title](*) Deployment Status: Deploying[/title]\nRepo: {{repository}}\nBranch: {{branch}}\nServer: {{hostname}}\nRelease Path: {{release_path}}\nCurrent Path: {{current_path}}\n[/info]" -``` - - -### chatwork_success_text -[Source](https://github.com/deployphp/deployer/blob/master/contrib/chatwork.php#L103) - - - -```php title="Default value" -"[info]\n[title](*) Deployment Status: Successfully[/title]\nRepo: {{repository}}\nBranch: {{branch}}\nServer: {{hostname}}\nRelease Path: {{release_path}}\nCurrent Path: {{current_path}}\n[/info]" -``` - - -### chatwork_failure_text -[Source](https://github.com/deployphp/deployer/blob/master/contrib/chatwork.php#L104) - - - -```php title="Default value" -"[info]\n[title](*) Deployment Status: Failed[/title]\nRepo: {{repository}}\nBranch: {{branch}}\nServer: {{hostname}}\nRelease Path: {{release_path}}\nCurrent Path: {{current_path}}\n[/info]" -``` - - - -## Tasks - -### chatwork_send_message -[Source](https://github.com/deployphp/deployer/blob/master/contrib/chatwork.php#L107) - - - -Helpers - - -### chatwork:test -[Source](https://github.com/deployphp/deployer/blob/master/contrib/chatwork.php#L116) - -Tests messages. - -Tasks - - -### chatwork:notify -[Source](https://github.com/deployphp/deployer/blob/master/contrib/chatwork.php#L127) - -Notifies Chatwork. - - - - -### chatwork:notify:success -[Source](https://github.com/deployphp/deployer/blob/master/contrib/chatwork.php#L142) - -Notifies Chatwork about deploy finish. - - - - -### chatwork:notify:failure -[Source](https://github.com/deployphp/deployer/blob/master/contrib/chatwork.php#L158) - -Notifies Chatwork about deploy failure. - - - - diff --git a/docs/contrib/cimonitor.md b/docs/contrib/cimonitor.md deleted file mode 100644 index 149937d00..000000000 --- a/docs/contrib/cimonitor.md +++ /dev/null @@ -1,215 +0,0 @@ - - - - -# cimonitor - -[Source](/contrib/cimonitor.php) - - - -# CIMonitor recipe - -Monitor your deployments on [CIMonitor](https://github.com/CIMonitor/CIMonitor). - -![CIMonitorGif](https://www.steefmin.xyz/deployer-example.gif) - -Require cimonitor recipe in your `deploy.php` file: - -```php -require 'contrib/cimonitor.php'; -``` - -Add tasks on deploy: - -```php -before('deploy', 'cimonitor:notify'); -after('deploy:success', 'cimonitor:notify:success'); -after('deploy:failed', 'cimonitor:notify:failure'); -``` - -## Configuration - -- `cimonitor_webhook` – CIMonitor server webhook url, **required** - ``` - set('cimonitor_webhook', 'https://cimonitor.enrise.com/webhook/deployer'); - ``` -- `cimonitor_title` – the title of application, default the username\reponame combination from `{{repository}}` - ``` - set('cimonitor_title', ''); - ``` -- `cimonitor_user` – User object with name and email, default gets information from `git config` - ``` - set('cimonitor_user', function () { - return [ - 'name' => 'John Doe', - 'email' => 'john@enrise.com', - ]; - }); - ``` - -Various cimonitor statusses are set, in case you want to change these yourselves. See the [CIMonitor documentation](https://cimonitor.readthedocs.io/en/latest/) for the usages of different states. - -## Usage - -If you want to notify only about beginning of deployment add this line only: - -```php -before('deploy', 'cimonitor:notify'); -``` - -If you want to notify about successful end of deployment add this too: - -```php -after('deploy:success', 'cimonitor:notify:success'); -``` - -If you want to notify about failed deployment add this too: - -```php -after('deploy:failed', 'cimonitor:notify:failure'); -``` - - -## Configuration -### cimonitor_title -[Source](https://github.com/deployphp/deployer/blob/master/contrib/cimonitor.php#L70) - -Title of project based on git repo - - - -### cimonitor_user -[Source](https://github.com/deployphp/deployer/blob/master/contrib/cimonitor.php#L75) - - - - - -### cimonitor_status_info -[Source](https://github.com/deployphp/deployer/blob/master/contrib/cimonitor.php#L83) - -CI monitor status states and job states - -```php title="Default value" -'info' -``` - - -### cimonitor_status_warning -[Source](https://github.com/deployphp/deployer/blob/master/contrib/cimonitor.php#L84) - - - -```php title="Default value" -'warning' -``` - - -### cimonitor_status_error -[Source](https://github.com/deployphp/deployer/blob/master/contrib/cimonitor.php#L85) - - - -```php title="Default value" -'error' -``` - - -### cimonitor_status_success -[Source](https://github.com/deployphp/deployer/blob/master/contrib/cimonitor.php#L86) - - - -```php title="Default value" -'success' -``` - - -### cimonitor_job_state_info -[Source](https://github.com/deployphp/deployer/blob/master/contrib/cimonitor.php#L87) - - - -```php title="Default value" -get('cimonitor_status_info') -``` - - -### cimonitor_job_state_pending -[Source](https://github.com/deployphp/deployer/blob/master/contrib/cimonitor.php#L88) - - - -```php title="Default value" -'pending' -``` - - -### cimonitor_job_state_running -[Source](https://github.com/deployphp/deployer/blob/master/contrib/cimonitor.php#L89) - - - -```php title="Default value" -'running' -``` - - -### cimonitor_job_state_warning -[Source](https://github.com/deployphp/deployer/blob/master/contrib/cimonitor.php#L90) - - - -```php title="Default value" -get('cimonitor_status_warning') -``` - - -### cimonitor_job_state_error -[Source](https://github.com/deployphp/deployer/blob/master/contrib/cimonitor.php#L91) - - - -```php title="Default value" -get('cimonitor_status_error') -``` - - -### cimonitor_job_state_success -[Source](https://github.com/deployphp/deployer/blob/master/contrib/cimonitor.php#L92) - - - -```php title="Default value" -get('cimonitor_status_success') -``` - - - -## Tasks - -### cimonitor:notify -[Source](https://github.com/deployphp/deployer/blob/master/contrib/cimonitor.php#L95) - -Notifies CIMonitor. - - - - -### cimonitor:notify:success -[Source](https://github.com/deployphp/deployer/blob/master/contrib/cimonitor.php#L121) - -Notifies CIMonitor about deploy finish. - - - - -### cimonitor:notify:failure -[Source](https://github.com/deployphp/deployer/blob/master/contrib/cimonitor.php#L149) - -Notifies CIMonitor about deploy failure. - - - - diff --git a/docs/contrib/cloudflare.md b/docs/contrib/cloudflare.md deleted file mode 100644 index 6fe5818f4..000000000 --- a/docs/contrib/cloudflare.md +++ /dev/null @@ -1,45 +0,0 @@ - - - - -# cloudflare - -[Source](/contrib/cloudflare.php) - - - -### Installing - -Add to your _deploy.php_ - -```php -require 'contrib/cloudflare.php'; -``` - -### Configuration - -- `cloudflare` – array with configuration for cloudflare - - `service_key` – Cloudflare Service Key. If this is not provided, use api_key and email. - - `api_key` – Cloudflare API key generated on the "My Account" page. - - `email` – Cloudflare Email address associated with your account. - - `domain` – The domain you want to clear - - `zone_id` – Cloudflare Zone ID (optional). - -### Usage - -Since the website should be built and some load is likely about to be applied to your server, this should be one of, -if not the, last tasks before cleanup - - - - -## Tasks - -### deploy:cloudflare -[Source](https://github.com/deployphp/deployer/blob/master/contrib/cloudflare.php#L29) - -Clears Cloudflare Cache. - - - - diff --git a/docs/contrib/cpanel.md b/docs/contrib/cpanel.md deleted file mode 100644 index a0beb1468..000000000 --- a/docs/contrib/cpanel.md +++ /dev/null @@ -1,179 +0,0 @@ - - - - -# cpanel - -[Source](/contrib/cpanel.php) - - - -### Installing - -Add to your _deploy.php_ - -```php -require 'contrib/cpanel.php'; -``` - -### Description -This is a recipe that uses the [cPanel 2 API](https://documentation.cPanel.net/display/DD/Guide+to+cPanel+API+2). - -Unfortunately the [UAPI](https://documentation.cPanel.net/display/DD/Guide+to+UAPI) that is recommended does not have support for creating addon domains. -The main idea behind is for staging purposes but I guess you can use it for other interesting concepts. - -The idea is, every branch possibly has its own staging domain/subdomain (staging-neat-feature.project.com) and database db_neat-feature_project so it can be tested. -This recipe can make the domain/subdomain and database creation part of the deployment process so you don't have to manually create them through an interface. - - -### Configuration -The example uses a .env file and Dotenv for configuration, but you can set the parameters as you wish -``` -set('cpanel', [ - 'host' => getenv('CPANEL_HOST'), - 'port' => getenv('CPANEL_PORT'), - 'username' => getenv('CPANEL_USERNAME'), - 'auth_type' => getenv('CPANEL_AUTH_TYPE'), - 'token' => getenv('CPANEL_TOKEN'), - 'user' => getenv('CPANEL_USER'), - 'db_user' => getenv('CPANEL_DB_USER'), - 'db_user_privileges' => getenv('CPANEL_DB_PRIVILEGES'), - 'timeout' => 500, - - 'allowInStage' => ['staging', 'beta', 'alpha'], - - 'create_domain_format' => '%s-%s-%s', - 'create_domain_values' => ['staging', 'master', get('application')], - 'subdomain_prefix' => substr(md5(get('application')), 0,4) . '-', - 'subdomain_suffix' => getenv('SUDOMAIN_SUFFIX'), - - - 'create_db_format' => '%s_%s-%s-%s', - 'create_db_values' => ['apps', 'staging','master', get('application')], - -]); -``` - -- `cpanel` – array with configuration for cPanel - - `username` – WHM account - - `user` – cPanel account that you want in charge of the domain - - `token` – WHM API token - - `create_domain_format` – Format for name creation of domain - - `create_domain_values` – The actual value reference for naming - - `subdomain_prefix` – cPanel has a weird way of dealing with addons and subdomains, you cannot create 2 addons with the same subdomain, so you need to change it in some way, example uses first 4 chars of md5(app_name) - - `subdomain_suffix` – cPanel has a weird way of dealing with addons and subdomains, so the suffix needs to be your main domain for that account for deletion purposes - - `addondir` – addon dir is different from the deploy path because cPanel "injects" /home/user/ into the path, so tilde cannot be used - - `allowInStage` – Define the stages that cPanel recipe actions are allowed in - - -#### .env file example -``` -CPANEL_HOST=xxx.xxx.xxx.xxx -CPANEL_PORT=2087 -CPANEL_USERNAME=root -CPANEL_TOKEN=xxxx -CPANEL_USER=xxx -CPANEL_AUTH_TYPE=hash -CPANEL_DB_USER=db_user -CPANEL_DB_PRIVILEGES="ALL PRIVILEGES" -SUDOMAIN_SUFFIX=.mymaindomain.com - -``` - -### Tasks - -- `cpanel:createaddondomain` Creates an addon domain -- `cpanel:deleteaddondomain` Removes an addon domain -- `cpanel:createdb` Creates a new database - -### Usage - -A complete example with configs, staging and deployment - -``` -load(); // this is used just so an .env file can be used for credentials - -require 'cpanel.php'; - - -Project name -set('application', 'myproject.com'); -Project repository -set('repository', 'git@github.com:myorg/myproject.com'); - - - - - -set('cpanel', [ - 'host' => getenv('CPANEL_HOST'), - 'port' => getenv('CPANEL_PORT'), - 'username' => getenv('CPANEL_USERNAME'), - 'auth_type' => getenv('CPANEL_AUTH_TYPE'), - 'token' => getenv('CPANEL_TOKEN'), - 'user' => getenv('CPANEL_USER'), - 'db_user' => getenv('CPANEL_DB_USER'), - 'db_user_privileges' => getenv('CPANEL_DB_PRIVILEGES'), - 'timeout' => 500, - 'allowInStage' => ['staging', 'beta', 'alpha'], - - 'create_domain_format' => '%s-%s-%s', - 'create_domain_values' => ['staging', 'master', get('application')], - 'subdomain_prefix' => substr(md5(get('application')), 0,4) . '-', - 'subdomain_suffix' => getenv('SUDOMAIN_SUFFIX'), - - - 'create_db_format' => '%s_%s-%s-%s', - 'create_db_values' => ['apps', 'staging','master', get('application')], - -]); - -host('myproject.com') - ->stage('staging') - ->set('cpanel_createdb', vsprintf(get('cpanel')['create_db_format'], get('cpanel')['create_db_values'])) - ->set('branch', 'dev-branch') - ->set('deploy_path', '~/staging/' . vsprintf(get('cpanel')['create_domain_format'], get('cpanel')['create_domain_values'])) - ->set('addondir', 'staging/' . vsprintf(get('cpanel')['create_domain_format'], get('cpanel')['create_domain_values'])); -Tasks -task('build', function () { - run('cd {{release_path}} && build'); -}); - -after('deploy:prepare', 'cpanel:createaddondomain'); -after('deploy:prepare', 'cpanel:createdb'); -``` - - - -## Tasks - -### cpanel:createdb -[Source](https://github.com/deployphp/deployer/blob/master/contrib/cpanel.php#L203) - -Creates database though CPanel API. - - - - -### cpanel:createaddondomain -[Source](https://github.com/deployphp/deployer/blob/master/contrib/cpanel.php#L231) - -Creates addon domain though CPanel API. - - - - -### cpanel:deleteaddondomain -[Source](https://github.com/deployphp/deployer/blob/master/contrib/cpanel.php#L254) - -Deletes addon domain though CPanel API. - - - - diff --git a/docs/contrib/crontab.md b/docs/contrib/crontab.md deleted file mode 100644 index ccc8987e2..000000000 --- a/docs/contrib/crontab.md +++ /dev/null @@ -1,58 +0,0 @@ - - - - -# crontab - -[Source](/contrib/crontab.php) - - - -Recipe for adding crontab jobs. - -It checks for duplicates by the command part of the job. Changing the schedule will update the crontab. So when you change the command part you have to manually remove the old one. Use `crontab -e` on the server to remove it. - -## Configuration - -- *crontab:jobs* - An array of strings with crontab lines. - -## Usage - -```php -require 'contrib/crontab.php'; - -after('deploy:success', 'crontab:sync'); - -add('crontab:jobs', [ - '* * * * * cd {{current_path}} && {{bin/php}} artisan schedule:run >> /dev/null 2>&1', -]); -``` - - -## Configuration -### bin/crontab -[Source](https://github.com/deployphp/deployer/blob/master/contrib/crontab.php#L26) - -Get path to bin - - - - -## Tasks - -### crontab:load -[Source](https://github.com/deployphp/deployer/blob/master/contrib/crontab.php#L31) - -Loads crontab. - - - - -### crontab:sync -[Source](https://github.com/deployphp/deployer/blob/master/contrib/crontab.php#L56) - -Sync crontab jobs. - - - - diff --git a/docs/contrib/directadmin.md b/docs/contrib/directadmin.md deleted file mode 100644 index 27a8e8fc4..000000000 --- a/docs/contrib/directadmin.md +++ /dev/null @@ -1,87 +0,0 @@ - - - - -# directadmin - -[Source](/contrib/directadmin.php) - - - -### Installing - -Add to your _deploy.php_ - -```php -require 'contrib/directadmin.php'; -``` - -### Configuration -- `directadmin` – array with configuration for DirectAdmin - - `host` – DirectAdmin host - - `port` – DirectAdmin port (default: 2222, not required) - - `scheme` – DirectAdmin scheme (default: http, not required) - - `username` – DirectAdmin username - - `password` – DirectAdmin password (it is recommended to use login keys!) - - `db_user` – Database username (required when using directadmin:createdb or directadmin:deletedb) - - `db_name` – Database namse (required when using directadmin:createdb) - - `db_password` – Database password (required when using directadmin:createdb) - - `domain_name` – Domain to create, delete or edit (required when using directadmin:createdomain, directadmin:deletedomain, directadmin:symlink-private-html or directadmin:php-version) - - `domain_ssl` – Enable SSL, options: ON/OFF, default: ON (optional when using directadmin:createdb) - - `domain_cgi` – Enable CGI, options: ON/OFF, default: ON (optional when using directadmin:createdb) - - `domain_php` – Enable PHP, options: ON/OFF, default: ON (optional when using directadmin:createdb) - - `domain_php_version` – Domain PHP Version, default: 1 (required when using directadmin:php-version) - - - - -## Tasks - -### directadmin:createdb -[Source](https://github.com/deployphp/deployer/blob/master/contrib/directadmin.php#L82) - -Creates a database on DirectAdmin. - - - - -### directadmin:deletedb -[Source](https://github.com/deployphp/deployer/blob/master/contrib/directadmin.php#L102) - -Deletes a database on DirectAdmin. - - - - -### directadmin:createdomain -[Source](https://github.com/deployphp/deployer/blob/master/contrib/directadmin.php#L117) - -Creates a domain on DirectAdmin. - - - - -### directadmin:deletedomain -[Source](https://github.com/deployphp/deployer/blob/master/contrib/directadmin.php#L135) - -Deletes a domain on DirectAdmin. - - - - -### directadmin:symlink-private-html -[Source](https://github.com/deployphp/deployer/blob/master/contrib/directadmin.php#L151) - -Symlink your private_html to public_html. - - - - -### directadmin:php-version -[Source](https://github.com/deployphp/deployer/blob/master/contrib/directadmin.php#L167) - -Changes the PHP version from a domain. - - - - diff --git a/docs/contrib/discord.md b/docs/contrib/discord.md deleted file mode 100644 index 8d84503ee..000000000 --- a/docs/contrib/discord.md +++ /dev/null @@ -1,144 +0,0 @@ - - - - -# discord - -[Source](/contrib/discord.php) - - - -## Installing - -Require discord recipe in your `deploy.php` file: - -```php -require 'contrib/discord.php'; -``` - -Add hook on deploy: - -```php -before('deploy', 'discord:notify'); -``` - -## Configuration - -- `discord_channel` – Discord channel ID, **required** -- `discord_token` – Discord channel token, **required** - -- `discord_notify_text` – notification message template, markdown supported, default: - ```markdown - :​information_source: **{{user}}** is deploying branch `{{branch}}` to _{{target}}_ - ``` -- `discord_success_text` – success template, default: - ```markdown - :​white_check_mark: Branch `{{branch}}` deployed to _{{target}}_ successfully - ``` -- `discord_failure_text` – failure template, default: - ```markdown - :​no_entry_sign: Branch `{{branch}}` has failed to deploy to _{{target}}_ - -## Usage - -If you want to notify only about beginning of deployment add this line only: - -```php -before('deploy', 'discord:notify'); -``` - -If you want to notify about successful end of deployment add this too: - -```php -after('deploy:success', 'discord:notify:success'); -``` - -If you want to notify about failed deployment add this too: - -```php -after('deploy:failed', 'discord:notify:failure'); -``` - - -## Configuration -### discord_webhook -[Source](https://github.com/deployphp/deployer/blob/master/contrib/discord.php#L59) - - - - - -### discord_notify_text -[Source](https://github.com/deployphp/deployer/blob/master/contrib/discord.php#L64) - -Deploy messages - - - -### discord_success_text -[Source](https://github.com/deployphp/deployer/blob/master/contrib/discord.php#L69) - - - - - -### discord_failure_text -[Source](https://github.com/deployphp/deployer/blob/master/contrib/discord.php#L74) - - - - - -### discord_message -[Source](https://github.com/deployphp/deployer/blob/master/contrib/discord.php#L81) - -The message - -```php title="Default value" -'discord_notify_text' -``` - - - -## Tasks - -### discord_send_message -[Source](https://github.com/deployphp/deployer/blob/master/contrib/discord.php#L84) - - - -Helpers - - -### discord:test -[Source](https://github.com/deployphp/deployer/blob/master/contrib/discord.php#L92) - -Tests messages. - -Tasks - - -### discord:notify -[Source](https://github.com/deployphp/deployer/blob/master/contrib/discord.php#L103) - -Notifies Discord. - - - - -### discord:notify:success -[Source](https://github.com/deployphp/deployer/blob/master/contrib/discord.php#L111) - -Notifies Discord about deploy finish. - - - - -### discord:notify:failure -[Source](https://github.com/deployphp/deployer/blob/master/contrib/discord.php#L119) - -Notifies Discord about deploy failure. - - - - diff --git a/docs/contrib/grafana.md b/docs/contrib/grafana.md deleted file mode 100644 index f39f1970f..000000000 --- a/docs/contrib/grafana.md +++ /dev/null @@ -1,58 +0,0 @@ - - - - -# grafana - -[Source](/contrib/grafana.php) - - - -## Installing - -Add to your _deploy.php_ - -```php -require 'contrib/grafana.php'; -``` - -## Configuration options - -- **url** *(required)*: the URL to the creates annotation api endpoint. -- **token** *(required)*: authentication token. Can be created at Grafana Console. -- **time** *(optional)* – set deploy time of annotation. specify epoch milliseconds. (Defaults is set to the current time in epoch milliseconds.) -- **tags** *(optional)* – set tag of annotation. -- **text** *(optional)* – set text of annotation. (Defaults is set to "Deployed " + git log -n 1 --format="%h") - -```php -deploy.php - -set('grafana', [ - 'token' => 'eyJrIj...', - 'url' => 'http://grafana/api/annotations', - 'tags' => ['deploy', 'production'], -]); - -``` - -## Usage - -If you want to create annotation about successful end of deployment. - -```php -after('deploy:success', 'grafana:annotation'); -``` - - - - -## Tasks - -### grafana:annotation -[Source](https://github.com/deployphp/deployer/blob/master/contrib/grafana.php#L45) - -Creates Grafana annotation of deployment. - - - - diff --git a/docs/contrib/hangouts.md b/docs/contrib/hangouts.md deleted file mode 100644 index 0bac12b49..000000000 --- a/docs/contrib/hangouts.md +++ /dev/null @@ -1,128 +0,0 @@ - - - - -# hangouts - -[Source](/contrib/hangouts.php) - - - -Require the Google Hangouts Chat recipe in your `deploy.php` file: - -```php -require 'contrib/chat.php'; -``` - -Add hook on deploy: - -```php -before('deploy', 'chat:notify'); -``` - -## Configuration - -- `chat_webhook` – chat incoming webhook url, **required** -- `chat_title` – the title of your notification card, default `{{application}}` -- `chat_subtitle` – the subtitle of your card, default `{{hostname}}` -- `chat_favicon` – an image for the header of your card, default `http://{{hostname}}/favicon.png` -- `chat_line1` – first line of the text in your card, default: `{{branch}}` -- `chat_line2` – second line of the text in your card, default: `{{stage}}` - -## Usage - -If you want to notify only about beginning of deployment add this line only: - -```php -before('deploy', 'chat:notify'); -``` - -If you want to notify about successful end of deployment add this too: - -```php -after('deploy:success', 'chat:notify:success'); -``` - -If you want to notify about failed deployment add this too: - -```php -after('deploy:failed', 'chat:notify:failure'); -``` - - - -## Configuration -### chat_title -[Source](https://github.com/deployphp/deployer/blob/master/contrib/hangouts.php#L50) - -Title of project - - - -### chat_subtitle -[Source](https://github.com/deployphp/deployer/blob/master/contrib/hangouts.php#L54) - - - -```php title="Default value" -get('hostname') -``` - - -### favicon -[Source](https://github.com/deployphp/deployer/blob/master/contrib/hangouts.php#L57) - -If 'favicon' is set Google Hangouts Chat will decorate your card with an image. - -```php title="Default value" -'http://{{hostname}}/favicon.png' -``` - - -### chat_line1 -[Source](https://github.com/deployphp/deployer/blob/master/contrib/hangouts.php#L60) - -Deploy messages - -```php title="Default value" -'{{branch}}' -``` - - -### chat_line2 -[Source](https://github.com/deployphp/deployer/blob/master/contrib/hangouts.php#L61) - - - -```php title="Default value" -'{{stage}}' -``` - - - -## Tasks - -### chat:notify -[Source](https://github.com/deployphp/deployer/blob/master/contrib/hangouts.php#L64) - -Notifies Google Hangouts Chat. - - - - -### chat:notify:success -[Source](https://github.com/deployphp/deployer/blob/master/contrib/hangouts.php#L106) - -Notifies Google Hangouts Chat about deploy finish. - - - - -### chat:notify:failure -[Source](https://github.com/deployphp/deployer/blob/master/contrib/hangouts.php#L148) - -Notifies Google Hangouts Chat about deploy failure. - - - - diff --git a/docs/contrib/hipchat.md b/docs/contrib/hipchat.md deleted file mode 100644 index 60771f21e..000000000 --- a/docs/contrib/hipchat.md +++ /dev/null @@ -1,89 +0,0 @@ - - - - -# hipchat - -[Source](/contrib/hipchat.php) - - - -## Installing - -Add to your _deploy.php_ - -```php -require 'contrib/hipchat.php'; -``` - -## Configuration - -- `hipchat_token` – Hipchat V1 auth token -- `hipchat_room_id` – Room ID or name -- `hipchat_message` – Deploy message, default is `_{{user}}_ deploying `{{branch}}` to *{{target}}*` -- `hipchat_from` – Default to target -- `hipchat_color` – Message color, default is **green** -- `hipchat_url` – The URL to the message endpoint, default is https://api.hipchat.com/v1/rooms/message - -## Usage - -Since you should only notify Hipchat room of a successful deployment, the `hipchat:notify` task should be executed right at the end. - -```php -after('deploy', 'hipchat:notify'); -``` - - - -## Configuration -### hipchat_color -[Source](https://github.com/deployphp/deployer/blob/master/contrib/hipchat.php#L33) - - - -```php title="Default value" -'green' -``` - - -### hipchat_from -[Source](https://github.com/deployphp/deployer/blob/master/contrib/hipchat.php#L34) - - - -```php title="Default value" -'{{target}}' -``` - - -### hipchat_message -[Source](https://github.com/deployphp/deployer/blob/master/contrib/hipchat.php#L35) - - - -```php title="Default value" -'_{{user}}_ deploying `{{branch}}` to *{{target}}*' -``` - - -### hipchat_url -[Source](https://github.com/deployphp/deployer/blob/master/contrib/hipchat.php#L36) - - - -```php title="Default value" -'https://api.hipchat.com/v1/rooms/message' -``` - - - -## Tasks - -### hipchat:notify -[Source](https://github.com/deployphp/deployer/blob/master/contrib/hipchat.php#L39) - -Notifies Hipchat channel of deployment. - - - - diff --git a/docs/contrib/ispmanager.md b/docs/contrib/ispmanager.md deleted file mode 100644 index b0717f5cc..000000000 --- a/docs/contrib/ispmanager.md +++ /dev/null @@ -1,241 +0,0 @@ - - - - -# ispmanager - -[Source](/contrib/ispmanager.php) - - - -This recipe for work with ISPManager Lite panel by API. - - -## Configuration -### ispmanager_owner -[Source](https://github.com/deployphp/deployer/blob/master/contrib/ispmanager.php#L10) - - - -```php title="Default value" -'www-root' -``` - - -### ispmanager_doc_root -[Source](https://github.com/deployphp/deployer/blob/master/contrib/ispmanager.php#L11) - - - -```php title="Default value" -'/var/www/' . get('ispmanager_owner') . '/data/' -``` - - -### ispmanager -[Source](https://github.com/deployphp/deployer/blob/master/contrib/ispmanager.php#L14) - -ISPManager default configuration - -```php title="Default value" -[ - 'api' => [ - 'dsn' => 'https://root:password@localhost:1500/ispmgr', - 'secure' => true, - ], - 'createDomain' => NULL, - 'updateDomain' => NULL, - 'deleteDomain' => NULL, - 'createDatabase' => NULL, - 'deleteDatabase' => NULL, - 'phpSelect' => NULL, - 'createAlias' => NULL, - 'deleteAlias' => NULL, -] -``` - - -### vhost -[Source](https://github.com/deployphp/deployer/blob/master/contrib/ispmanager.php#L30) - -Vhost default configuration - -```php title="Default value" -[ - 'name' => '{{domain}}', - 'php_enable' => 'on', - 'aliases' => 'www.{{domain}}', - 'home' => 'www/{{domain}}', - 'owner' => get('ispmanager_owner'), - 'email' => 'webmaster@{{domain}}', - 'charset' => 'off', - 'dirindex' => 'index.php uploaded.html', - 'ssi' => 'on', - 'php' => 'on', - 'php_mode' => 'php_mode_mod', - 'basedir' => 'on', - 'php_apache_version' => 'native', - 'cgi' => 'off', - 'log_access' => 'on', - 'log_error' => 'on', -] -``` - - -### ispmanager_session -[Source](https://github.com/deployphp/deployer/blob/master/contrib/ispmanager.php#L50) - -Storage - - - -### ispmanager_databases -[Source](https://github.com/deployphp/deployer/blob/master/contrib/ispmanager.php#L51) - - - -```php title="Default value" -[ - 'servers' => [], - 'hosts' => [], - 'dblist' => [], -] -``` - - -### ispmanager_domains -[Source](https://github.com/deployphp/deployer/blob/master/contrib/ispmanager.php#L57) - - - - - -### ispmanager_phplist -[Source](https://github.com/deployphp/deployer/blob/master/contrib/ispmanager.php#L58) - - - - - -### ispmanager_aliaslist -[Source](https://github.com/deployphp/deployer/blob/master/contrib/ispmanager.php#L59) - - - - - - -## Tasks - -### ispmanager:init -[Source](https://github.com/deployphp/deployer/blob/master/contrib/ispmanager.php#L62) - -Installs ispmanager. - - - - -### ispmanager:db-server-list -[Source](https://github.com/deployphp/deployer/blob/master/contrib/ispmanager.php#L85) - -Takes database servers list. - - - - -### ispmanager:db-list -[Source](https://github.com/deployphp/deployer/blob/master/contrib/ispmanager.php#L122) - -Takes databases list. - - - - -### ispmanager:domain-list -[Source](https://github.com/deployphp/deployer/blob/master/contrib/ispmanager.php#L144) - -Takes domain list. - - - - -### ispmanager:db-create -[Source](https://github.com/deployphp/deployer/blob/master/contrib/ispmanager.php#L160) - -Creates new database. - - - - -### ispmanager:db-delete -[Source](https://github.com/deployphp/deployer/blob/master/contrib/ispmanager.php#L230) - -Deletes database. - - - - -### ispmanager:domain-create -[Source](https://github.com/deployphp/deployer/blob/master/contrib/ispmanager.php#L281) - -Creates new domain. - - - - -### ispmanager:get-php-list -[Source](https://github.com/deployphp/deployer/blob/master/contrib/ispmanager.php#L327) - -Gets allowed PHP modes and versions. - - - - -### ispmanager:print-php-list -[Source](https://github.com/deployphp/deployer/blob/master/contrib/ispmanager.php#L373) - -Prints allowed PHP modes and versions. - - - - -### ispmanager:domain-php-select -[Source](https://github.com/deployphp/deployer/blob/master/contrib/ispmanager.php#L411) - -Switches PHP version for domain. - - - - -### ispmanager:domain-alias-create -[Source](https://github.com/deployphp/deployer/blob/master/contrib/ispmanager.php#L480) - -Creates new domain alias. - - - - -### ispmanager:domain-alias-delete -[Source](https://github.com/deployphp/deployer/blob/master/contrib/ispmanager.php#L549) - -Deletes domain alias. - - - - -### ispmanager:domain-delete -[Source](https://github.com/deployphp/deployer/blob/master/contrib/ispmanager.php#L617) - -Deletes domain. - - - - -### ispmanager:process -[Source](https://github.com/deployphp/deployer/blob/master/contrib/ispmanager.php#L664) - -Auto task processing. - - - - diff --git a/docs/contrib/mattermost.md b/docs/contrib/mattermost.md deleted file mode 100644 index bec6c1422..000000000 --- a/docs/contrib/mattermost.md +++ /dev/null @@ -1,208 +0,0 @@ - - - - -# mattermost - -[Source](/contrib/mattermost.php) - - - -## Installing - -Create a Mattermost incoming webhook, through the administration panel. - -Require the new recipe into your `deploy.php` - -```php -require 'contrib/mattermost.php'; -``` - -Add hook on deploy: - -``` -before('deploy', 'mattermost:notify'); -``` - -## Configuration - - - `mattermost_webhook` - incoming mattermost webook **required** - ``` - set('mattermost_webook', 'https://{your-mattermost-site}/hooks/xxx-generatedkey-xxx'); - ``` - - - `mattermost_channel` - overrides the channel the message posts in - ``` - set('mattermost_channel', 'town-square'); - ``` - - - `mattermost_username` - overrides the username the message posts as - ``` - set('mattermost_username', 'deployer'); - ``` - - - `mattermost_icon_url` - overrides the profile picture the message posts with - ``` - set('mattermost_icon_url', 'https://domain.com/your-icon.png'); - ``` - - - `mattermost_text` - notification message - ``` - set('mattermost_text', '_{{user}}_ deploying `{{branch}}` to **{{target}}**'); - ``` - - - `mattermost_success_text` – success template, default: - ``` - set('mattermost_success_text', 'Deploy to **{{target}}** successful {{mattermost_success_emoji}}'); - ``` - - - `mattermost_failure_text` – failure template, default: - ``` - set('mattermost_failure_text', 'Deploy to **{{target}}** failed {{mattermost_failure_emoji}}'); - ``` - - - `mattermost_success_emoji` – emoji added at the end of success text - - `mattermost_failure_emoji` – emoji added at the end of failure text - - For detailed information about Mattermost hooks see: https://developers.mattermost.com/integrate/incoming-webhooks/ - -## Usage - -If you want to notify only about beginning of deployment add this line only: - -```php -before('deploy', 'mattermost:notify'); -``` - -If you want to notify about successful end of deployment add this too: - -```php -after('deploy:success', 'mattermost:notify:success'); -``` - -If you want to notify about failed deployment add this too: - -```php -after('deploy:failed', 'mattermost:notify:failure'); -``` - - - -## Configuration -### mattermost_webhook -[Source](https://github.com/deployphp/deployer/blob/master/contrib/mattermost.php#L86) - - - -```php title="Default value" -null -``` - - -### mattermost_channel -[Source](https://github.com/deployphp/deployer/blob/master/contrib/mattermost.php#L87) - - - -```php title="Default value" -null -``` - - -### mattermost_username -[Source](https://github.com/deployphp/deployer/blob/master/contrib/mattermost.php#L88) - - - -```php title="Default value" -'deployer' -``` - - -### mattermost_icon_url -[Source](https://github.com/deployphp/deployer/blob/master/contrib/mattermost.php#L89) - - - -```php title="Default value" -null -``` - - -### mattermost_success_emoji -[Source](https://github.com/deployphp/deployer/blob/master/contrib/mattermost.php#L91) - - - -```php title="Default value" -':​white_check_mark:' -``` - - -### mattermost_failure_emoji -[Source](https://github.com/deployphp/deployer/blob/master/contrib/mattermost.php#L92) - - - -```php title="Default value" -':​x:' -``` - - -### mattermost_text -[Source](https://github.com/deployphp/deployer/blob/master/contrib/mattermost.php#L94) - - - -```php title="Default value" -'_{{user}}_ deploying `{{branch}}` to **{{target}}**' -``` - - -### mattermost_success_text -[Source](https://github.com/deployphp/deployer/blob/master/contrib/mattermost.php#L95) - - - -```php title="Default value" -'Deploy to **{{target}}** successful {{mattermost_success_emoji}}' -``` - - -### mattermost_failure_text -[Source](https://github.com/deployphp/deployer/blob/master/contrib/mattermost.php#L96) - - - -```php title="Default value" -'Deploy to **{{target}}** failed {{mattermost_failure_emoji}}' -``` - - - -## Tasks - -### mattermost:notify -[Source](https://github.com/deployphp/deployer/blob/master/contrib/mattermost.php#L99) - -Notifies mattermost. - - - - -### mattermost:notify:success -[Source](https://github.com/deployphp/deployer/blob/master/contrib/mattermost.php#L120) - -Notifies mattermost about deploy finish. - - - - -### mattermost:notify:failure -[Source](https://github.com/deployphp/deployer/blob/master/contrib/mattermost.php#L141) - -Notifies mattermost about deploy failure. - - - - diff --git a/docs/contrib/ms-teams.md b/docs/contrib/ms-teams.md deleted file mode 100644 index bc2b0eda4..000000000 --- a/docs/contrib/ms-teams.md +++ /dev/null @@ -1,176 +0,0 @@ - - - - -# ms-teams - -[Source](/contrib/ms-teams.php) - - - -## Installing - -Require ms-teams recipe in your `deploy.php` file: - -Setup: -1. Open MS Teams -2. Navigate to Teams section -3. Select existing or create new team -4. Select existing or create new channel -5. Hover over channel to get tree dots, click, in menu select "Connectors" -6. Search for and configure "Incoming Webhook" -7. Confirm/create and copy your Webhook URL -8. Setup deploy.php - Add in header: -```php -require 'contrib/ms-teams.php'; -set('teams_webhook', 'https://outlook.office.com/webhook/...'); -``` -Add in content: -```php -before('deploy', 'teams:notify'); -after('deploy:success', 'teams:notify:success'); -after('deploy:failed', 'teams:notify:failure'); -``` -9.) Sip your coffee - -## Configuration - -- `teams_webhook` – teams incoming webhook url, **required** - ``` - set('teams_webhook', 'https://outlook.office.com/webhook/...'); - ``` -- `teams_title` – the title of application, default `{{application}}` -- `teams_text` – notification message template, markdown supported - ``` - set('teams_text', '_{{user}}_ deploying `{{branch}}` to *{{target}}*'); - ``` -- `teams_success_text` – success template, default: - ``` - set('teams_success_text', 'Deploy to *{{target}}* successful'); - ``` -- `teams_failure_text` – failure template, default: - ``` - set('teams_failure_text', 'Deploy to *{{target}}* failed'); - ``` - -- `teams_color` – color's attachment -- `teams_success_color` – success color's attachment -- `teams_failure_color` – failure color's attachment - -## Usage - -If you want to notify only about beginning of deployment add this line only: - -```php -before('deploy', 'teams:notify'); -``` - -If you want to notify about successful end of deployment add this too: - -```php -after('deploy:success', 'teams:notify:success'); -``` - -If you want to notify about failed deployment add this too: - -```php -after('deploy:failed', 'teams:notify:failure'); -``` - - -## Configuration -### teams_title -[Source](https://github.com/deployphp/deployer/blob/master/contrib/ms-teams.php#L78) - -Title of project - - - -### teams_text -[Source](https://github.com/deployphp/deployer/blob/master/contrib/ms-teams.php#L83) - -Deploy message - -```php title="Default value" -'_{{user}}_ deploying `{{branch}}` to *{{target}}*' -``` - - -### teams_success_text -[Source](https://github.com/deployphp/deployer/blob/master/contrib/ms-teams.php#L84) - - - -```php title="Default value" -'Deploy to *{{target}}* successful' -``` - - -### teams_failure_text -[Source](https://github.com/deployphp/deployer/blob/master/contrib/ms-teams.php#L85) - - - -```php title="Default value" -'Deploy to *{{target}}* failed' -``` - - -### teams_color -[Source](https://github.com/deployphp/deployer/blob/master/contrib/ms-teams.php#L88) - -Color of attachment - -```php title="Default value" -'#4d91f7' -``` - - -### teams_success_color -[Source](https://github.com/deployphp/deployer/blob/master/contrib/ms-teams.php#L89) - - - -```php title="Default value" -'#00c100' -``` - - -### teams_failure_color -[Source](https://github.com/deployphp/deployer/blob/master/contrib/ms-teams.php#L90) - - - -```php title="Default value" -'#ff0909' -``` - - - -## Tasks - -### teams:notify -[Source](https://github.com/deployphp/deployer/blob/master/contrib/ms-teams.php#L93) - -Notifies Teams. - - - - -### teams:notify:success -[Source](https://github.com/deployphp/deployer/blob/master/contrib/ms-teams.php#L107) - -Notifies Teams about deploy finish. - - - - -### teams:notify:failure -[Source](https://github.com/deployphp/deployer/blob/master/contrib/ms-teams.php#L121) - -Notifies Teams about deploy failure. - - - - diff --git a/docs/contrib/newrelic.md b/docs/contrib/newrelic.md deleted file mode 100644 index f23ddf50f..000000000 --- a/docs/contrib/newrelic.md +++ /dev/null @@ -1,67 +0,0 @@ - - - - -# newrelic - -[Source](/contrib/newrelic.php) - - - -## Installing - -Add to your _deploy.php_ - -```php -require 'contrib/newrelic.php'; -``` - -## Configuration - -- `newrelic_app_id` – newrelic's app id -- `newrelic_api_key` – newrelic's api key -- `newrelic_description` – message to send - -## Usage - -Since you should only notify New Relic of a successful deployment, the `newrelic:notify` task should be executed right at the end. - -```php -after('deploy', 'newrelic:notify'); -``` - - - -## Configuration -### newrelic_app_id -[Source](https://github.com/deployphp/deployer/blob/master/contrib/newrelic.php#L30) - - - - - -### newrelic_description -[Source](https://github.com/deployphp/deployer/blob/master/contrib/newrelic.php#L34) - - - - - -### newrelic_revision -[Source](https://github.com/deployphp/deployer/blob/master/contrib/newrelic.php#L38) - - - - - - -## Tasks - -### newrelic:notify -[Source](https://github.com/deployphp/deployer/blob/master/contrib/newrelic.php#L43) - -Notifies New Relic of deployment. - - - - diff --git a/docs/contrib/npm.md b/docs/contrib/npm.md deleted file mode 100644 index f91f81799..000000000 --- a/docs/contrib/npm.md +++ /dev/null @@ -1,53 +0,0 @@ - - - - -# npm - -[Source](/contrib/npm.php) - - - -## Installing - -Add to your _deploy.php_ - -```php -require 'contrib/npm.php'; -``` - -## Configuration - -- `bin/npm` *(optional)*: set npm binary, automatically detected otherwise. - -## Usage - -```php -after('deploy:update_code', 'npm:install'); -``` - - - -## Configuration -### bin/npm -[Source](https://github.com/deployphp/deployer/blob/master/contrib/npm.php#L24) - - - - - - -## Tasks - -### npm:install -[Source](https://github.com/deployphp/deployer/blob/master/contrib/npm.php#L34) - -Installs npm packages. - -Uses `npm ci` command. This command is similar to npm install, -except it's meant to be used in automated environments such as -test platforms, continuous integration, and deployment -- or -any situation where you want to make sure you're doing a clean -install of your dependencies. - - diff --git a/docs/contrib/phinx.md b/docs/contrib/phinx.md deleted file mode 100644 index 7e7d8a8d3..000000000 --- a/docs/contrib/phinx.md +++ /dev/null @@ -1,117 +0,0 @@ - - - - -# phinx - -[Source](/contrib/phinx.php) - - - -## Installing - -Add to your _deploy.php_ - -```php -require 'contrib/phinx.php'; -``` - -## Configuration options - -All options are in the config parameter `phinx` specified as an array (instead of the `phinx_path` variable). -All parameters are *optional*, but you can specify them with a dictionary (to change all parameters) -or by deployer dot notation (to change one option). - -### Phinx params - -- `phinx.environment` -- `phinx.date` -- `phinx.configuration` N.B. current directory is the project directory -- `phinx.target` -- `phinx.seed` -- `phinx.parser` -- `phinx.remove-all` (pass empty string as value) - -### Phinx path params - -- `phinx_path` Specify phinx path (by default phinx is searched for in $PATH, ./vendor/bin and ~/.composer/vendor/bin) - -### Example of usage - -```php -$phinx_env_vars = [ - 'environment' => 'development', - 'configuration' => './migration/.phinx.yml', - 'target' => '20120103083322', - 'remove-all' => '', -]; - -set('phinx_path', '/usr/local/phinx/bin/phinx'); -set('phinx', $phinx_env_vars); - -after('cleanup', 'phinx:migrate'); - -or set it for a specific server -host('dev') - ->user('user') - ->set('deploy_path', '/var/www') - ->set('phinx', $phinx_env_vars) - ->set('phinx_path', ''); -``` - -## Suggested Usage - -You can run all tasks before or after any -tasks (but you need to specify external configs for phinx). -If you use internal configs (which are in your project) you need -to run it after the `deploy:update_code` task is completed. - -## Read more - -For further reading see [phinx.org](https://phinx.org). Complete descriptions of all possible options can be found on the [commands page](http://docs.phinx.org/en/latest/commands.html). - - - -## Configuration -### bin/phinx -[Source](https://github.com/deployphp/deployer/blob/master/contrib/phinx.php#L87) - -Path to Phinx - - - - -## Tasks - -### phinx:migrate -[Source](https://github.com/deployphp/deployer/blob/master/contrib/phinx.php#L154) - -Migrats database with phinx. - - - - -### phinx:rollback -[Source](https://github.com/deployphp/deployer/blob/master/contrib/phinx.php#L176) - -Rollbacks database migrations with phinx. - - - - -### phinx:seed -[Source](https://github.com/deployphp/deployer/blob/master/contrib/phinx.php#L198) - -Seeds database with phinx. - - - - -### phinx:breakpoint -[Source](https://github.com/deployphp/deployer/blob/master/contrib/phinx.php#L219) - -Sets a migrations breakpoint with phinx. - - - - diff --git a/docs/contrib/php-fpm.md b/docs/contrib/php-fpm.md deleted file mode 100644 index ff7c5b611..000000000 --- a/docs/contrib/php-fpm.md +++ /dev/null @@ -1,75 +0,0 @@ - - - - -# php-fpm - -[Source](/contrib/php-fpm.php) - - - -## Installing - -:::caution -Do **not** reload php-fpm. Some user requests could fail or not complete in the -process of reloading. - -Instead, configure your server [properly](https://ï.at/avoid-php-fpm-reloading). If you're using Deployer's provision -recipe, it's already configured the right way and no php-fpm reload is needed. -::: - -Add to your _deploy.php_ - -```php -require 'contrib/php-fpm.php'; -``` - -## Configuration - -- `php_fpm_version` – The PHP-fpm version. For example: `8.0`. -- `php_fpm_service` – The full name of the PHP-fpm service. Defaults to `php{{php_fpm_version}}-fpm`. -- `php_fpm_command` – The command to run to reload PHP-fpm. Defaults to `sudo systemctl reload {{php_fpm_service}}`. - -## Usage - -Start by explicitely providing the current version of PHP-version using the `php_fpm_version`. -Alternatively, you may use any of the options above to configure how PHP-fpm should reload. - -Then, add the `php-fpm:reload` task at the end of your deployments by using the `after` method like so. - -```php -set('php_fpm_version', '8.0'); -after('deploy', 'php-fpm:reload'); -``` - - - -## Configuration -### php_fpm_version -[Source](https://github.com/deployphp/deployer/blob/master/contrib/php-fpm.php#L41) - -Automatically detects by using [bin/php](/docs/recipe/common.md#bin/php). - - - -### php_fpm_service -[Source](https://github.com/deployphp/deployer/blob/master/contrib/php-fpm.php#L45) - - - -```php title="Default value" -'php{{php_fpm_version}}-fpm' -``` - - - -## Tasks - -### php-fpm:reload -[Source](https://github.com/deployphp/deployer/blob/master/contrib/php-fpm.php#L48) - -Reloads the php-fpm service. - - - - diff --git a/docs/contrib/rabbit.md b/docs/contrib/rabbit.md deleted file mode 100644 index 0ee070317..000000000 --- a/docs/contrib/rabbit.md +++ /dev/null @@ -1,69 +0,0 @@ - - - - -# rabbit - -[Source](/contrib/rabbit.php) - - - -### Installing - -```php -deploy.php - -require 'recipe/rabbit.php'; -``` - -### Configuration options - -- **rabbit** *(required)*: accepts an *array* with the connection information to [rabbitmq](http://www.rabbitmq.com) server token and team name. - - -You can provide also other configuration options: - - - *host* - default is localhost - - *port* - default is 5672 - - *username* - default is *guest* - - *password* - default is *guest* - - *channel* - no default value, need to be specified via config - - *message* - default is **Deployment to '{$host}' on *{$prod}* was successful\n($releasePath)** - - *vhost* - default is - - -```php -deploy.php - -set('rabbit', [ - 'host' => 'localhost', - 'port' => '5672', - 'username' => 'guest', - 'password' => 'guest', - 'channel' => 'notify-channel', - 'vhost' => '/my-app' -]); -``` - -### Suggested Usage - -Since you should only notify RabbitMQ channel of a successful deployment, the `deploy:rabbit` task should be executed right at the end. - -```php -deploy.php - -before('deploy:end', 'deploy:rabbit'); -``` - - - -## Tasks - -### deploy:rabbit -[Source](https://github.com/deployphp/deployer/blob/master/contrib/rabbit.php#L58) - -Notifies RabbitMQ channel about deployment. - - - - diff --git a/docs/contrib/raygun.md b/docs/contrib/raygun.md deleted file mode 100644 index 8cbfd824b..000000000 --- a/docs/contrib/raygun.md +++ /dev/null @@ -1,48 +0,0 @@ - - - - -# raygun - -[Source](/contrib/raygun.php) - - - -## Installing - -Add to your _deploy.php_ - -```php -require 'contrib/raygun.php'; -``` - -## Configuration - -- `raygun_api_key` – the API key of your Raygun application -- `raygun_version` – the version of your application that this deployment is releasing -- `raygun_owner_name` – the name of the person creating this deployment -- `raygun_email` – the email of the person creating this deployment -- `raygun_comment` – the deployment notes -- `raygun_scm_identifier` – the commit that this deployment was built off -- `raygun_scm_type` - the source control system you use - -## Usage - -To notify Raygun of a successful deployment, you can use the 'raygun:notify' task after a deployment. - -```php -after('deploy', 'raygun:notify'); -``` - - - -## Tasks - -### raygun:notify -[Source](https://github.com/deployphp/deployer/blob/master/contrib/raygun.php#L34) - -Notifies Raygun of deployment. - - - - diff --git a/docs/contrib/rocketchat.md b/docs/contrib/rocketchat.md deleted file mode 100644 index aea126371..000000000 --- a/docs/contrib/rocketchat.md +++ /dev/null @@ -1,229 +0,0 @@ - - - - -# rocketchat - -[Source](/contrib/rocketchat.php) - - - -## Installing - -Create a RocketChat incoming webhook, through the administration panel. - -Require the new recipe into your `deploy.php` - -```php -require 'contrib/rocketchat.php'; -``` - -Add hook on deploy: - -``` -before('deploy', 'rocketchat:notify'); -``` - -## Configuration - - - `rocketchat_webhook` - incoming rocketchat webook **required** - ``` - set('rocketchat_webook', 'https://rocketchat.yourcompany.com/hooks/XXXXX'); - ``` - - - `rocketchat_title` - the title of the application, defaults to `{{application}}` - - `rocketchat_text` - notification message - ``` - set('rocketchat_text', '_{{user}}_ deploying {{branch}} to {{target}}'); - ``` - - - `rocketchat_success_text` – success template, default: - ``` - set('rocketchat_success_text', 'Deploy to *{{target}}* successful'); - ``` - - `rocketchat_failure_text` – failure template, default: - ``` - set('rocketchat_failure_text', 'Deploy to *{{target}}* failed'); - ``` - - - `rocketchat_color` – color's attachment - - `rocketchat_success_color` – success color's attachment - - `rocketchat_failure_color` – failure color's attachment - -## Usage - -If you want to notify only about beginning of deployment add this line only: - -```php -before('deploy', 'rocketchat:notify'); -``` - -If you want to notify about successful end of deployment add this too: - -```php -after('deploy:success', 'rocketchat:notify:success'); -``` - -If you want to notify about failed deployment add this too: - -```php -after('deploy:failed', 'rocketchat:notify:failure'); -``` - - - -## Configuration -### rockchat_title -[Source](https://github.com/deployphp/deployer/blob/master/contrib/rocketchat.php#L70) - - - - - -### rocketchat_icon_emoji -[Source](https://github.com/deployphp/deployer/blob/master/contrib/rocketchat.php#L74) - - - -```php title="Default value" -':robot:' -``` - - -### rocketchat_icon_url -[Source](https://github.com/deployphp/deployer/blob/master/contrib/rocketchat.php#L75) - - - -```php title="Default value" -null -``` - - -### rocketchat_channel -[Source](https://github.com/deployphp/deployer/blob/master/contrib/rocketchat.php#L77) - - - -```php title="Default value" -null -``` - - -### rocketchat_room_id -[Source](https://github.com/deployphp/deployer/blob/master/contrib/rocketchat.php#L78) - - - -```php title="Default value" -null -``` - - -### rocketchat_username -[Source](https://github.com/deployphp/deployer/blob/master/contrib/rocketchat.php#L79) - - - -```php title="Default value" -null -``` - - -### rocketchat_webhook -[Source](https://github.com/deployphp/deployer/blob/master/contrib/rocketchat.php#L80) - - - -```php title="Default value" -null -``` - - -### rocketchat_color -[Source](https://github.com/deployphp/deployer/blob/master/contrib/rocketchat.php#L82) - - - -```php title="Default value" -'#000000' -``` - - -### rocketchat_success_color -[Source](https://github.com/deployphp/deployer/blob/master/contrib/rocketchat.php#L83) - - - -```php title="Default value" -'#00c100' -``` - - -### rocketchat_failure_color -[Source](https://github.com/deployphp/deployer/blob/master/contrib/rocketchat.php#L84) - - - -```php title="Default value" -'#ff0909' -``` - - -### rocketchat_text -[Source](https://github.com/deployphp/deployer/blob/master/contrib/rocketchat.php#L86) - - - -```php title="Default value" -'_{{user}}_ deploying `{{branch}}` to *{{target}}*' -``` - - -### rocketchat_success_text -[Source](https://github.com/deployphp/deployer/blob/master/contrib/rocketchat.php#L87) - - - -```php title="Default value" -'Deploy to *{{target}}* successful' -``` - - -### rocketchat_failure_text -[Source](https://github.com/deployphp/deployer/blob/master/contrib/rocketchat.php#L88) - - - -```php title="Default value" -'Deploy to *{{target}}* failed' -``` - - - -## Tasks - -### rocketchat:notify -[Source](https://github.com/deployphp/deployer/blob/master/contrib/rocketchat.php#L91) - -Notifies RocketChat. - - - - -### rocketchat:notify:success -[Source](https://github.com/deployphp/deployer/blob/master/contrib/rocketchat.php#L121) - -Notifies RocketChat about deploy finish. - - - - -### rocketchat:notify:failure -[Source](https://github.com/deployphp/deployer/blob/master/contrib/rocketchat.php#L151) - -Notifies RocketChat about deploy failure. - - - - diff --git a/docs/contrib/rollbar.md b/docs/contrib/rollbar.md deleted file mode 100644 index cdb657eb1..000000000 --- a/docs/contrib/rollbar.md +++ /dev/null @@ -1,59 +0,0 @@ - - - - -# rollbar - -[Source](/contrib/rollbar.php) - - - -## Installing - -Add to your _deploy.php_ - -```php -require 'contrib/rollbar.php'; -``` - -## Configuration - -- `rollbar_token` – access token to rollbar api -- `rollbar_comment` – comment about deploy, default to - ```php - set('rollbar_comment', '_{{user}}_ deploying `{{branch}}` to *{{target}}*'); - ``` -- `rollbar_username` – rollbar user name - -## Usage - -Since you should only notify Rollbar channel of a successful deployment, the `rollbar:notify` task should be executed right at the end. - -```php -after('deploy', 'rollbar:notify'); -``` - - - -## Configuration -### rollbar_comment -[Source](https://github.com/deployphp/deployer/blob/master/contrib/rollbar.php#L33) - - - -```php title="Default value" -'_{{user}}_ deploying `{{branch}}` to *{{target}}*' -``` - - - -## Tasks - -### rollbar:notify -[Source](https://github.com/deployphp/deployer/blob/master/contrib/rollbar.php#L36) - -Notifies Rollbar of deployment. - - - - diff --git a/docs/contrib/rsync.md b/docs/contrib/rsync.md deleted file mode 100644 index 01cdf40dd..000000000 --- a/docs/contrib/rsync.md +++ /dev/null @@ -1,221 +0,0 @@ - - - - -# rsync - -[Source](/contrib/rsync.php) - - - -## IMPORTANT - -This must not be confused with `/src/Utility/Rsync.php`, deployer's built-in rsync. Their configuration options are also very different, read carefully below. - -## Installing - -Add to your _deploy.php_ - -```php -require 'contrib/rsync.php'; -``` - -## Configuration options - -- **rsync**: Accepts an array with following rsync options (all are optional and defaults are ok): - - *exclude*: accepts an *array* with patterns to be excluded from sending to server - - *exclude-file*: accepts a *string* containing absolute path to file, which contains exclude patterns - - *include*: accepts an *array* with patterns to be included in sending to server - - *include-file*: accepts a *string* containing absolute path to file, which contains include patterns - - *filter*: accepts an *array* of rsync filter rules - - *filter-file*: accepts a *string* containing merge-file filename. - - *filter-perdir*: accepts a *string* containing merge-file filename to be scanned and merger per each directory in rsync list on files to send - - *flags*: accepts a *string* of flags to set when calling rsync command. Please **avoid** flags that accept params, and use *options* instead. - - *options*: accepts an *array* of options to set when calling rsync command. **DO NOT** prefix options with `--` as it's automatically added. - - *timeout*: accepts an *int* defining timeout for rsync command to run locally. - -### Sample Configuration: - -Following is default configuration. By default rsync ignores only git dir and `deploy.php` file. - -```php -deploy.php - -set('rsync',[ - 'exclude' => [ - '.git', - 'deploy.php', - ], - 'exclude-file' => false, - 'include' => [], - 'include-file' => false, - 'filter' => [], - 'filter-file' => false, - 'filter-perdir'=> false, - 'flags' => 'rz', // Recursive, with compress - 'options' => ['delete'], - 'timeout' => 60, -]); -``` - -If You have multiple excludes, You can put them in file and reference that instead. If You use `deploy:rsync_warmup` You could set additional options that could speed-up and/or affect way things are working. For example: - -```php -deploy.php - -set('rsync',[ - 'exclude' => ['excludes_file'], - 'exclude-file' => '/tmp/localdeploys/excludes_file', //Use absolute path to avoid possible rsync problems - 'include' => [], - 'include-file' => false, - 'filter' => [], - 'filter-file' => false, - 'filter-perdir' => false, - 'flags' => 'rzcE', // Recursive, with compress, check based on checksum rather than time/size, preserve Executable flag - 'options' => ['delete', 'delete-after', 'force'], //Delete after successful transfer, delete even if deleted dir is not empty - 'timeout' => 3600, //for those huge repos or crappy connection -]); -``` - - -### Parameter - -- **rsync_src**: per-host rsync source. This can be server, stage or whatever-dependent. By default it's set to current directory -- **rsync_dest**: per-host rsync destination. This can be server, stage or whatever-dependent. by default it's equivalent to release deploy destination. - -### Sample configurations: - -This is default configuration: - -```php -set('rsync_src', __DIR__); -set('rsync_dest','{{release_path}}'); -``` - -If You use local deploy recipe You can set src to local release: - -```php -host('hostname') - ->hostname('10.10.10.10') - ->port(22) - ->set('deploy_path','/your/remote/path/app') - ->set('rsync_src', '/your/local/path/app') - ->set('rsync_dest','{{release_path}}'); -``` - -## Usage - -- `rsync` task - - Set `rsync_src` to locally cloned repository and rsync to `rsync_dest`. Then set this task instead of `deploy:update_code` in Your `deploy` task if Your hosting provider does not allow git. - -- `rsync:warmup` task - - If Your deploy task looks like: - - ```php - task('deploy', [ - 'deploy:prepare', - 'deploy:release', - 'rsync', - 'deploy:vendors', - 'deploy:symlink', - ])->desc('Deploy your project'); - ``` - - And Your `rsync_dest` is set to `{{release_path}}` then You could add this task to run before `rsync` task or after `deploy:release`, whatever is more convenient. - - - -## Configuration -### rsync -[Source](https://github.com/deployphp/deployer/blob/master/contrib/rsync.php#L127) - - - -```php title="Default value" -[ - 'exclude' => [ - '.git', - 'deploy.php', - ], - 'exclude-file' => false, - 'include' => [], - 'include-file' => false, - 'filter' => [], - 'filter-file' => false, - 'filter-perdir' => false, - 'flags' => 'rz', - 'options' => ['delete'], - 'timeout' => 300, -] -``` - - -### rsync_src -[Source](https://github.com/deployphp/deployer/blob/master/contrib/rsync.php#L143) - - - -```php title="Default value" -__DIR__ -``` - - -### rsync_dest -[Source](https://github.com/deployphp/deployer/blob/master/contrib/rsync.php#L144) - - - -```php title="Default value" -'{{release_path}}' -``` - - -### rsync_excludes -[Source](https://github.com/deployphp/deployer/blob/master/contrib/rsync.php#L146) - - - - - -### rsync_includes -[Source](https://github.com/deployphp/deployer/blob/master/contrib/rsync.php#L161) - - - - - -### rsync_filter -[Source](https://github.com/deployphp/deployer/blob/master/contrib/rsync.php#L176) - - - - - -### rsync_options -[Source](https://github.com/deployphp/deployer/blob/master/contrib/rsync.php#L194) - - - - - - -## Tasks - -### rsync:warmup -[Source](https://github.com/deployphp/deployer/blob/master/contrib/rsync.php#L206) - -Warmups remote Rsync target. - - - - -### rsync -[Source](https://github.com/deployphp/deployer/blob/master/contrib/rsync.php#L221) - -Rsync local->remote. - - - - diff --git a/docs/contrib/sentry.md b/docs/contrib/sentry.md deleted file mode 100644 index 6fc37d867..000000000 --- a/docs/contrib/sentry.md +++ /dev/null @@ -1,73 +0,0 @@ - - - - -# sentry - -[Source](/contrib/sentry.php) - - - -### Installing - -```php -deploy.php - -require 'contrib/sentry.php'; -``` - -### Configuration options - -- **organization** *(required)*: the slug of the organization the release belongs to. -- **projects** *(required)*: array of slugs of the projects to create a release for. -- **token** *(required)*: authentication token. Can be created at [https://sentry.io/settings/account/api/auth-tokens/] -- **version** *(required)* – a version identifier for this release. -Can be a version number, a commit hash etc. (Defaults is set to git log -n 1 --format="%h".) -- **version_prefix** *(optional)* - a string prefixed to version. -Releases are global per organization so indipentent projects needs to prefix version number with unique string to avoid conflicts -- **environment** *(optional)* - the environment you’re deploying to. By default framework's environment is used. -For example for symfony, *symfony_env* configuration is read otherwise defaults to 'prod'. -- **ref** *(optional)* – an optional commit reference. This is useful if a tagged version has been provided. -- **refs** *(optional)* - array to indicate the start and end commits for each repository included in a release. -Head commits must include parameters *repository* and *commit*) (the HEAD sha). -They can optionally include *previousCommit* (the sha of the HEAD of the previous release), -which should be specified if this is the first time you’ve sent commit data. -- **commits** *(optional)* - array commits data to be associated with the release. -Commits must include parameters *id* (the sha of the commit), and can optionally include *repository*, -*message*, *author_name*, *author_email* and *timestamp*. By default will send all new commits, -unless it's a first release, then only first 200 will be sent. -- **url** *(optional)* – a URL that points to the release. This can be the path to an online interface to the sourcecode for instance. -- **date_released** *(optional)* – date that indicates when the release went live. If not provided the current time is assumed. -- **sentry_server** *(optional)* – sentry server (if you host it yourself). defaults to hosted sentry service. -- **date_deploy_started** *(optional)* - date that indicates when the deploy started. Defaults to current time. -- **date_deploy_finished** *(optional)* - date that indicates when the deploy ended. If not provided, the current time is used. -- **deploy_name** *(optional)* - name of the deploy -- **git_version_command** *(optional)* - the command that retrieves the git version information (Defaults is set to git log -n 1 --format="%h", other options are git describe --tags --abbrev=0) - -```php -deploy.php - -set('sentry', [ - 'organization' => 'exampleorg', - 'projects' => [ - 'exampleproj' - ], - 'token' => 'd47828...', - 'version' => '0.0.1', - -]); -``` - -### Suggested Usage - -Since you should only notify Sentry of a successful deployment, the deploy:sentry task should be executed right at the end. - -```php -deploy.php - -after('deploy', 'deploy:sentry'); -``` - - - - diff --git a/docs/contrib/slack.md b/docs/contrib/slack.md deleted file mode 100644 index 5a2da2906..000000000 --- a/docs/contrib/slack.md +++ /dev/null @@ -1,217 +0,0 @@ - - - - -# slack - -[Source](/contrib/slack.php) - - - -## Installing - -Add to Slack - -Require slack recipe in your `deploy.php` file: - -```php -require 'contrib/slack.php'; -``` - -Add hook on deploy: - -```php -before('deploy', 'slack:notify'); -``` - -## Configuration - -- `slack_webhook` – slack incoming webhook url, **required** - ``` - set('slack_webhook', 'https://hooks.slack.com/...'); - ``` -- `slack_channel` - channel to send notification to. The default is the channel configured in the webhook -- `slack_title` – the title of application, default `{{application}}` -- `slack_text` – notification message template, markdown supported - ``` - set('slack_text', '_{{user}}_ deploying `{{branch}}` to *{{target}}*'); - ``` -- `slack_success_text` – success template, default: - ``` - set('slack_success_text', 'Deploy to *{{target}}* successful'); - ``` -- `slack_failure_text` – failure template, default: - ``` - set('slack_failure_text', 'Deploy to *{{target}}* failed'); - ``` - -- `slack_color` – color's attachment -- `slack_success_color` – success color's attachment -- `slack_failure_color` – failure color's attachment -- `slack_fields` - set attachments fields for pretty output in Slack, default: - ``` - set('slack_fields', []); - ``` - -## Usage - -If you want to notify only about beginning of deployment add this line only: - -```php -before('deploy', 'slack:notify'); -``` - -If you want to notify about successful end of deployment add this too: - -```php -after('deploy:success', 'slack:notify:success'); -``` - -If you want to notify about failed deployment add this too: - -```php -after('deploy:failed', 'slack:notify:failure'); -``` - - - -## Configuration -### slack_channel -[Source](https://github.com/deployphp/deployer/blob/master/contrib/slack.php#L74) - -Channel to publish to, when false the default channel the webhook will be used - -```php title="Default value" -false -``` - - -### slack_title -[Source](https://github.com/deployphp/deployer/blob/master/contrib/slack.php#L77) - -Title of project - - - -### slack_text -[Source](https://github.com/deployphp/deployer/blob/master/contrib/slack.php#L82) - -Deploy message - -```php title="Default value" -'_{{user}}_ deploying `{{target}}` to *{{hostname}}*' -``` - - -### slack_success_text -[Source](https://github.com/deployphp/deployer/blob/master/contrib/slack.php#L83) - - - -```php title="Default value" -'Deploy to *{{target}}* successful' -``` - - -### slack_failure_text -[Source](https://github.com/deployphp/deployer/blob/master/contrib/slack.php#L84) - - - -```php title="Default value" -'Deploy to *{{target}}* failed' -``` - - -### slack_rollback_text -[Source](https://github.com/deployphp/deployer/blob/master/contrib/slack.php#L85) - - - -```php title="Default value" -'_{{user}}_ rolled back changes on *{{target}}*' -``` - - -### slack_fields -[Source](https://github.com/deployphp/deployer/blob/master/contrib/slack.php#L86) - - - - - -### slack_color -[Source](https://github.com/deployphp/deployer/blob/master/contrib/slack.php#L89) - -Color of attachment - -```php title="Default value" -'#4d91f7' -``` - - -### slack_success_color -[Source](https://github.com/deployphp/deployer/blob/master/contrib/slack.php#L90) - - - -```php title="Default value" -'#00c100' -``` - - -### slack_failure_color -[Source](https://github.com/deployphp/deployer/blob/master/contrib/slack.php#L91) - - - -```php title="Default value" -'#ff0909' -``` - - -### slack_rollback_color -[Source](https://github.com/deployphp/deployer/blob/master/contrib/slack.php#L92) - - - -```php title="Default value" -'#eba211' -``` - - - -## Tasks - -### slack:notify -[Source](https://github.com/deployphp/deployer/blob/master/contrib/slack.php#L104) - -Notifies Slack. - - - - -### slack:notify:success -[Source](https://github.com/deployphp/deployer/blob/master/contrib/slack.php#L123) - -Notifies Slack about deploy finish. - - - - -### slack:notify:failure -[Source](https://github.com/deployphp/deployer/blob/master/contrib/slack.php#L143) - -Notifies Slack about deploy failure. - - - - -### slack:notify:rollback -[Source](https://github.com/deployphp/deployer/blob/master/contrib/slack.php#L162) - -Notifies Slack about rollback. - - - - diff --git a/docs/contrib/telegram.md b/docs/contrib/telegram.md deleted file mode 100644 index 683cd9e36..000000000 --- a/docs/contrib/telegram.md +++ /dev/null @@ -1,141 +0,0 @@ - - - - -# telegram - -[Source](/contrib/telegram.php) - - - -## Installing - 1. Create telegram bot with [BotFather](https://t.me/BotFather) and grab the token provided - 2. Send `/start` to your bot and open https://api.telegram.org/bot{$TELEGRAM_TOKEN_HERE}/getUpdates - 3. Take chat_id from response -Require telegram recipe in your `deploy.php` file: - -```php -require 'contrib/telegram.php'; -``` - -Add hook on deploy: - -```php -before('deploy', 'telegram:notify'); -``` - -## Configuration - -- `telegram_token` – telegram bot token, **required** -- `telegram_chat_id` — chat ID to push messages to -- `telegram_proxy` - proxy connection string in [CURLOPT_PROXY](https://curl.haxx.se/libcurl/c/CURLOPT_PROXY.html) form like: - ``` - http://proxy:80 - socks5://user:password@host:3128 - ``` -- `telegram_title` – the title of application, default `{{application}}` -- `telegram_text` – notification message template - ``` - _{{user}}_ deploying `{{branch}}` to *{{target}}* - ``` -- `telegram_success_text` – success template, default: - ``` - Deploy to *{{target}}* successful - - ``` -- `telegram_failure_text` – failure template, default: - ``` - Deploy to *{{target}}* failed - ``` - -## Usage - -If you want to notify only about beginning of deployment add this line only: - -```php -before('deploy', 'telegram:notify'); -``` - -If you want to notify about successful end of deployment add this too: - -```php -after('deploy:success', 'telegram:notify:success'); -``` -If you want to notify about failed deployment add this too: - -```php -after('deploy:failed', 'telegram:notify:failure'); - - - - -## Configuration -### telegram_title -[Source](https://github.com/deployphp/deployer/blob/master/contrib/telegram.php#L67) - -Title of project - - - -### telegram_token -[Source](https://github.com/deployphp/deployer/blob/master/contrib/telegram.php#L72) - -Telegram settings - - - -### telegram_chat_id -[Source](https://github.com/deployphp/deployer/blob/master/contrib/telegram.php#L75) - - - - - -### telegram_url -[Source](https://github.com/deployphp/deployer/blob/master/contrib/telegram.php#L78) - - - - - -### telegram_text -[Source](https://github.com/deployphp/deployer/blob/master/contrib/telegram.php#L83) - -Deploy message - -```php title="Default value" -'_{{user}}_ deploying `{{branch}}` to *{{target}}*' -``` - - -### telegram_success_text -[Source](https://github.com/deployphp/deployer/blob/master/contrib/telegram.php#L84) - - - -```php title="Default value" -'Deploy to *{{target}}* successful' -``` - - -### telegram_failure_text -[Source](https://github.com/deployphp/deployer/blob/master/contrib/telegram.php#L85) - - - -```php title="Default value" -'Deploy to *{{target}}* failed' -``` - - - -## Tasks - -### telegram:notify -[Source](https://github.com/deployphp/deployer/blob/master/contrib/telegram.php#L89) - -Notifies Telegram. - - - - diff --git a/docs/contrib/webpack_encore.md b/docs/contrib/webpack_encore.md deleted file mode 100644 index 7223deb87..000000000 --- a/docs/contrib/webpack_encore.md +++ /dev/null @@ -1,66 +0,0 @@ - - - - -# webpack_encore - -[Source](/contrib/webpack_encore.php) - -* Requires - * [npm](/docs/contrib/npm.md) - * [yarn](/docs/contrib/yarn.md) - - -## Installing - -Add to your _deploy.php_ - -```php -require 'contrib/webpack_encore.php'; -``` - -## Configuration - -- **webpack_encore/package_manager** *(optional)*: set yarn or npm. We try to find if yarn or npm is available and used. - -## Usage - -```php -For Yarn -after('deploy:update_code', 'yarn:install'); -For npm -after('deploy:update_code', 'npm:install'); - -after('deploy:update_code', 'webpack_encore:build'); -``` - - -## Configuration -### webpack_encore/package_manager -[Source](https://github.com/deployphp/deployer/blob/master/contrib/webpack_encore.php#L31) - - - - - -### webpack_encore/env -[Source](https://github.com/deployphp/deployer/blob/master/contrib/webpack_encore.php#L39) - - - -```php title="Default value" -'production' -``` - - - -## Tasks - -### webpack_encore:build -[Source](https://github.com/deployphp/deployer/blob/master/contrib/webpack_encore.php#L42) - -Runs webpack encore build. - - - - diff --git a/docs/contrib/workplace.md b/docs/contrib/workplace.md deleted file mode 100644 index c5a03a86b..000000000 --- a/docs/contrib/workplace.md +++ /dev/null @@ -1,148 +0,0 @@ - - - - -# workplace - -[Source](/contrib/workplace.php) - - - -## Installing - -This recipes works with Custom Integrations and Publishing Bots. - -Require the new recipe into your `deploy.php` - -```php -require 'contrib/workplace.php'; -``` - -Add hook on deploy: - -``` -before('deploy', 'workplace:notify'); -``` - -## Configuration - - - `workplace_webhook` - incoming workplace webhook **required** - ``` - // With custom integration - set('workplace_webhook', 'https://graph.facebook.com//feed?access_token='); - - // With publishing bot - set('workplace_webhook', 'https://graph.facebook.com/v3.0/group/feed?access_token='); - - // Use markdown on message - set('workplace_webhook', 'https://graph.facebook.com//feed?access_token=&formatting=MARKDOWN'); - ``` - - - `workplace_text` - notification message - ``` - set('workplace_text', '_{{user}}_ deploying `{{branch}}` to *{{target}}*'); - ``` - - - `workplace_success_text` – success template, default: - ``` - set('workplace_success_text', 'Deploy to *{{target}}* successful'); - ``` - - `workplace_failure_text` – failure template, default: - ``` - set('workplace_failure_text', 'Deploy to *{{target}}* failed'); - ``` - - `workplace_edit_post` – whether to create a new post for deploy result, or edit the first one created, default creates a new post: - ``` - set('workplace_edit_post', false); - ``` - -## Usage - -If you want to notify only about beginning of deployment add this line only: - -```php -before('deploy', 'workplace:notify'); -``` - -If you want to notify about successful end of deployment add this too: - -```php -after('deploy:success', 'workplace:notify:success'); -``` - -If you want to notify about failed deployment add this too: - -```php -after('deploy:failed', 'workplace:notify:failure'); -``` - - - -## Configuration -### workplace_text -[Source](https://github.com/deployphp/deployer/blob/master/contrib/workplace.php#L77) - -Deploy message - -```php title="Default value" -'_{{user}}_ deploying `{{branch}}` to *{{target}}*' -``` - - -### workplace_success_text -[Source](https://github.com/deployphp/deployer/blob/master/contrib/workplace.php#L78) - - - -```php title="Default value" -'Deploy to *{{target}}* successful' -``` - - -### workplace_failure_text -[Source](https://github.com/deployphp/deployer/blob/master/contrib/workplace.php#L79) - - - -```php title="Default value" -'Deploy to *{{target}}* failed' -``` - - -### workplace_edit_post -[Source](https://github.com/deployphp/deployer/blob/master/contrib/workplace.php#L82) - -By default, create a new post for every message - -```php title="Default value" -false -``` - - - -## Tasks - -### workplace:notify -[Source](https://github.com/deployphp/deployer/blob/master/contrib/workplace.php#L85) - -Notifies Workplace. - - - - -### workplace:notify:success -[Source](https://github.com/deployphp/deployer/blob/master/contrib/workplace.php#L109) - -Notifies Workplace about deploy finish. - - - - -### workplace:notify:failure -[Source](https://github.com/deployphp/deployer/blob/master/contrib/workplace.php#L120) - -Notifies Workplace about deploy failure. - - - - diff --git a/docs/contrib/yammer.md b/docs/contrib/yammer.md deleted file mode 100644 index db2b40690..000000000 --- a/docs/contrib/yammer.md +++ /dev/null @@ -1,142 +0,0 @@ - - - - -# yammer - -[Source](/contrib/yammer.php) - - - -# Yammer recipe - -## Installing - -Require yammer recipe in your `deploy.php` file: - -```php -require 'contrib/yammer.php'; -``` - -Add hook on deploy: - -```php -before('deploy', 'yammer:notify'); -``` - -## Configuration - -- `yammer_url` – The URL to the message endpoint, default is https://www.yammer.com/api/v1/messages.json -- `yammer_token` *(required)* – Yammer auth token -- `yammer_group_id` *(required)* - Group ID -- `yammer_title` – the title of application, default `{{application}}` -- `yammer_body` – notification message template, default: - ``` - {{user}} deploying {{branch}} to {{target}} - ``` -- `yammer_success_body` – success template, default: - ``` - Deploy to {{target}} successful - ``` -- `yammer_failure_body` – failure template, default: - ``` - Deploy to {{target}} failed - ``` - -## Usage - -If you want to notify only about beginning of deployment add this line only: - -```php -before('deploy', 'yammer:notify'); -``` - -If you want to notify about successful end of deployment add this too: - -```php -after('deploy:success', 'yammer:notify:success'); -``` - -If you want to notify about failed deployment add this too: - -```php -after('deploy:failed', 'yammer:notify:failure'); -``` - - - -## Configuration -### yammer_url -[Source](https://github.com/deployphp/deployer/blob/master/contrib/yammer.php#L63) - - - -```php title="Default value" -'https://www.yammer.com/api/v1/messages.json' -``` - - -### yammer_title -[Source](https://github.com/deployphp/deployer/blob/master/contrib/yammer.php#L66) - -Title of project - - - -### yammer_body -[Source](https://github.com/deployphp/deployer/blob/master/contrib/yammer.php#L71) - -Deploy message - -```php title="Default value" -'{{user}} deploying {{branch}} to {{target}}' -``` - - -### yammer_success_body -[Source](https://github.com/deployphp/deployer/blob/master/contrib/yammer.php#L72) - - - -```php title="Default value" -'Deploy to {{target}} successful' -``` - - -### yammer_failure_body -[Source](https://github.com/deployphp/deployer/blob/master/contrib/yammer.php#L73) - - - -```php title="Default value" -'Deploy to {{target}} failed' -``` - - - -## Tasks - -### yammer:notify -[Source](https://github.com/deployphp/deployer/blob/master/contrib/yammer.php#L76) - -Notifies Yammer. - - - - -### yammer:notify:success -[Source](https://github.com/deployphp/deployer/blob/master/contrib/yammer.php#L95) - -Notifies Yammer about deploy finish. - - - - -### yammer:notify:failure -[Source](https://github.com/deployphp/deployer/blob/master/contrib/yammer.php#L114) - -Notifies Yammer about deploy failure. - - - - diff --git a/docs/contrib/yarn.md b/docs/contrib/yarn.md deleted file mode 100644 index 470cabb2f..000000000 --- a/docs/contrib/yarn.md +++ /dev/null @@ -1,48 +0,0 @@ - - - - -# yarn - -[Source](/contrib/yarn.php) - - - -## Installing - -Add to your _deploy.php_ - -```php -require 'contrib/yarn.php'; -``` - -## Configuration - -- **bin/yarn** *(optional)*: set Yarn binary, automatically detected otherwise. - -## Usage - -```php -after('deploy:update_code', 'yarn:install'); -``` - - -## Configuration -### bin/yarn -[Source](https://github.com/deployphp/deployer/blob/master/contrib/yarn.php#L23) - - - - - - -## Tasks - -### yarn:install -[Source](https://github.com/deployphp/deployer/blob/master/contrib/yarn.php#L29) - -Installs Yarn packages. - -In there is a {{previous_release}}, node_modules will be copied from it before installing deps with yarn. - - diff --git a/docs/getting-started.md b/docs/getting-started.md deleted file mode 100755 index 02ed1709e..000000000 --- a/docs/getting-started.md +++ /dev/null @@ -1,138 +0,0 @@ -# Getting Started - -In this tutorial we will cover: -- Setting up a new host with provision recipe. -- Configuring a deployment and perfoming our first deploy. - -Tutorial duration: **5 min** - -First, [install the Deployer](installation.md): - -Now lets cd into the project and run the following command: - -```sh -dep init -``` - -Deployer will ask you a few question and after finishing you will have a -**deploy.php** or **deploy.yaml** file. This is our deployment recipe. -It contains hosts, tasks and requires other recipes. All framework recipes -that come with Deployer are based on the [common](recipe/common.md) recipe. - -## Provision - -:::note -If you already have a configured webserver you may skip to -[deployment](#deploy). -::: - -Let's create a new VPS on Linode, DigitalOcean, Vultr, AWS, GCP, etc. - -Make sure the image is **Ubuntu 20.04 LTS** as this version is supported via -Deployer [provision](recipe/provision.md) recipe. - -:::tip -Configure Reverse DNS or RDNS on your server. This will allow you to ssh into -server using the domain name instead of the IP address. -::: - -Our **deploy.php** recipe contains host definition with few important params: - - `remote_user` user's name for ssh connection, - - `deploy_path` host's path where we are going to deploy. - -```php -host('example.org') - ->set('remote_user', 'deployer') - ->set('deploy_path', '~/example'); -``` - -To connect to remote host we need to specify identity key or private key. -We can add our identity key directly into host definition, but better to put it -in **~/.ssh/config** file: - -``` -Host * - IdentityFile ~/.ssh/id_rsa -``` - -Now let's provision our server. As our host doesn't have user name `deployer`, but -only `root` user. We going to override `remote_user` for provision via `-o remote_user=root`. - -```sh -dep provision -o remote_user=root -``` -:::tip -If your server doesn't have a `root` user but your remote user can use `sudo` to become root, then use: - -```sh -dep provision -o become=root -``` -::: - -Deployer will ask you a few questions during provisioning: php version, -database type, etc. You can specify it also in directly in recipe. - -Provision recipe going to do: -- Update and upgrade all Ubuntu packages to latest versions, -- Install all needed packages for our website (acl, npm, git, etc), -- Install php with all needed extensions, -- Install and configure the database, -- Install Caddy webserver and configure our website with SSL certificate, -- Configure ssh and firewall, -- Setup **deployer** user. - -Provisioning will take around **5 minutes** and will install everything we need to run a -website. It will also setup a `deployer` user, which we will need to use to ssh to our -host. A new website will be configured at [deploy_path](recipe/common.md#deploy_path). - -After we have configured the webserver, let's deploy the project. - -## Deploy - -To deploy the project: - -```sh -dep deploy -``` - -If deploy failed, Deployer will print error message and command what was unsuccessful. -Most likely we need to configure correct database credentials in _.env_ file or similar. - -Ssh to the host, for example, for editing _.env_ file: - -```sh -dep ssh -``` - -After everything is configured properly we can resume our deployment from the place it stopped (But this is not required, we can just start a new deploy): - -``` -dep deploy --start-from deploy:migrate -``` - -Now let's add a build step on our host: -```php -task('build', function () { - cd('{{release_path}}'); - run('npm install'); - run('npm run prod'); -}); - -after('deploy:update_code', 'build'); -``` - -Deployer has a useful task for examining what is currently deployed. - -``` -$ dep releases -task releases -+---------------------+--------- deployer.org -------+--------+-----------+ -| Date (UTC) | Release | Author | Target | Commit | -+---------------------+-------------+----------------+--------+-----------+ -| 2021-11-05 14:00:22 | 1 (current) | Anton Medvedev | HEAD | 943ded2be | -+---------------------+-------------+----------------+--------+-----------+ -``` - -:::tip -During development, the [dep push](recipe/deploy/push.md) task maybe useful. -::: diff --git a/docs/hosts.md b/docs/hosts.md deleted file mode 100644 index 7a16f0e83..000000000 --- a/docs/hosts.md +++ /dev/null @@ -1,184 +0,0 @@ -# Hosts - -To define a new host use the [host()](api.md#host) function. Deployer keeps a list of -all defined hosts in the `Deployer::get()->hosts` collection. - -```php -host('example.org'); -``` - -Each host contains it's own configuration key-value pairs. The [host()](api.md#host) -call defines two important configs: **alias** and **hostname**. - -- **hostname** - used when connecting to remote host. -- **alias** - used as a key in `Deployer::get()->hosts` collection. - -```php -task('test', function () { - writeln('The {{alias}} is {{hostname}}'); -}); -``` - -``` -$ dep test -[example.org] The example.org is example.org -``` - -We can override hostname via `set()` method: - -```php -host('example.org') - ->set('hostname', 'example.cloud.google.com'); -``` - -The hostname will be used for the ssh connection, but the host will be referred -by its alias when running Deployer. - -``` -$ dep test -[example.org] The example.org is example.cloud.google.com -``` - -Another important ssh connection parameter is `remote_user`. - -```php -host('example.org') - ->set('hostname', 'example.cloud.google.com') - ->set('remote_user', 'deployer'); -``` - -Now Deployer will connect using something like -`ssh deployer@example.cloud.google.com` to establishing connection. - -Also, Deployer's `Host` class has special setter methods (for better IDE -autocompletion). - -```php -host('example.org') - ->setHostname('example.cloud.google.com') - ->setRemoteUser('deployer'); -``` - -## Host config - -### `alias` - -The identifier used to identify a host. -You can use actual hostname or something like `prod` or `staging`. - -### `hostname` - -Deployer uses this config for actual ssh connection. - -### `remote_user` - -Deployer uses this config for actual ssh connection. If not specified, -Deployer will be using `RemoteUser` from **~/.ssh/config** file, or current -OS username. - -### `port` - -Port of remote ssh server to connect to. Default is `22`. - -### `config_file` - -Default is `~/.ssh/config`. - -:::info Config file -It is a good practice to keep connection parameters out of `deploy.php` file, as -they can change depending on where the deploy is executed from. Only specify -`hostname` and `remote_user` and other keep in `~/.ssh/config`: - -``` -Host * - IdentityFile ~/.ssh/id_rsa -``` -::: - -### `identity_file` - -For example, `~/.ssh/id_rsa`. - -### `forward_agent` - -Default is `true`. - -### `ssh_multiplexing` - -Default is `true`. - -### `shell` - -Default is `bash -ls`. - -### `deploy_path` - -For example, `~/myapp`. - -### `labels` - -Key-value pairs for host selector. - -### `ssh_arguments` - -For example, `['-o UserKnownHostsFile=/dev/null']` - -### `ssh_control_path` - -Default is `~/.ssh/%C`. - -If **CI** env is present, default value is `/dev/shm/%C`. - -## Multiple hosts - -You can pass multiple hosts to the host function: - -```php -host('example.org', 'deployer.org', ...) - ->setRemoteUser('anton'); -``` - -## Host ranges - -If you have a lot of hosts following similar patterns, you can describe them -like this rather than listing each hostname: - -```php -host('www[01:50].example.org'); -``` - -For numeric patterns, leading zeros can be included or removed, as desired. -Ranges are inclusive. - -You can also define alphabetic ranges: - -```php -host('db[a:f].example.org'); -``` - -## Localhost - -The [localhost()](api.md#localhost) function defines a special local host. -Deployer will not connect to this host, but will execute commands locally instead. - -```php -localhost(); // Alias and hostname will be "localhost". -localhost('ci'); // Alias is "ci", hostname is "localhost". -``` - -## YAML Inventory - -You can use the [import()](api.md#import) function to keep host definitions in a -separate file. For example, *inventory.yaml*. - -```php title="deploy.php" -import('inventory.yaml'); -``` - -```yaml title="inventory.yaml" -hosts: - example.org: - remote_user: deployer - deployer.org: - remote_user: deployer -``` diff --git a/docs/installation.md b/docs/installation.md deleted file mode 100755 index 2aaf6bb00..000000000 --- a/docs/installation.md +++ /dev/null @@ -1,29 +0,0 @@ -# Installation - -To install Deployer, run next command in your project dir: -``` -composer require --dev deployer/deployer -``` - -To initialize deployer in you project run: - -``` -vendor/bin/dep init -``` - -:::tip Bash integration -Add next alias to your _.bashrc_ file: - -```bash -alias dep='vendor/bin/dep' -``` - -Deployer comes with autocomplete support for task names, options, and hosts. - -Run the next command to add bash completion support: -``` -dep completion bash > /etc/bash_completion.d/deployer -``` - -Make sure what your _.bashrc_ file includes generated file in some way. -::: diff --git a/docs/recipe/cakephp.md b/docs/recipe/cakephp.md deleted file mode 100644 index aca08f31f..000000000 --- a/docs/recipe/cakephp.md +++ /dev/null @@ -1,77 +0,0 @@ - - - - -# cakephp - -[Source](/recipe/cakephp.php) - -* Requires - * [common](/docs/recipe/common.md) - -## Configuration -### shared_dirs -[Source](https://github.com/deployphp/deployer/blob/master/recipe/cakephp.php#L13) - -Overrides [shared_dirs](/docs/recipe/deploy/shared.md#shared_dirs) from `recipe/deploy/shared.php`. - -CakePHP 4 Project Template shared dirs - -```php title="Default value" -[ - 'logs', - 'tmp', -] -``` - - -### shared_files -[Source](https://github.com/deployphp/deployer/blob/master/recipe/cakephp.php#L19) - -Overrides [shared_files](/docs/recipe/deploy/shared.md#shared_files) from `recipe/deploy/shared.php`. - -CakePHP 4 Project Template shared files - -```php title="Default value" -[ - 'config/.env', - 'config/app.php', -] -``` - - - -## Tasks - -### deploy:init -[Source](https://github.com/deployphp/deployer/blob/master/recipe/cakephp.php#L27) - - - -Create plugins' symlinks - - -### deploy:run_migrations -[Source](https://github.com/deployphp/deployer/blob/master/recipe/cakephp.php#L34) - - - -Run migrations - - -### deploy -[Source](https://github.com/deployphp/deployer/blob/master/recipe/cakephp.php#L42) - - - -Main task - - -This task is group task which contains next tasks: -* [deploy:prepare](/docs/recipe/common.md#deployprepare) -* [deploy:vendors](/docs/recipe/deploy/vendors.md#deployvendors) -* [deploy:init](/docs/recipe/cakephp.md#deployinit) -* [deploy:run_migrations](/docs/recipe/cakephp.md#deployrun_migrations) -* [deploy:publish](/docs/recipe/common.md#deploypublish) - - diff --git a/docs/recipe/codeigniter.md b/docs/recipe/codeigniter.md deleted file mode 100644 index 87cf5843e..000000000 --- a/docs/recipe/codeigniter.md +++ /dev/null @@ -1,53 +0,0 @@ - - - - -# codeigniter - -[Source](/recipe/codeigniter.php) - -* Requires - * [common](/docs/recipe/common.md) - -## Configuration -### shared_dirs -[Source](https://github.com/deployphp/deployer/blob/master/recipe/codeigniter.php#L9) - -Overrides [shared_dirs](/docs/recipe/deploy/shared.md#shared_dirs) from `recipe/deploy/shared.php`. - -CodeIgniter shared dirs - -```php title="Default value" -['application/cache', 'application/logs'] -``` - - -### writable_dirs -[Source](https://github.com/deployphp/deployer/blob/master/recipe/codeigniter.php#L12) - -Overrides [writable_dirs](/docs/recipe/deploy/writable.md#writable_dirs) from `recipe/deploy/writable.php`. - -CodeIgniter writable dirs - -```php title="Default value" -['application/cache', 'application/logs'] -``` - - - -## Tasks - -### deploy -[Source](https://github.com/deployphp/deployer/blob/master/recipe/codeigniter.php#L18) - -Deploys your project. - -Main task - - -This task is group task which contains next tasks: -* [deploy:prepare](/docs/recipe/common.md#deployprepare) -* [deploy:vendors](/docs/recipe/deploy/vendors.md#deployvendors) -* [deploy:publish](/docs/recipe/common.md#deploypublish) - - diff --git a/docs/recipe/common.md b/docs/recipe/common.md deleted file mode 100644 index 976e7a9ad..000000000 --- a/docs/recipe/common.md +++ /dev/null @@ -1,220 +0,0 @@ - - - - -# common - -[Source](/recipe/common.php) - -* Requires - * [provision](/docs/recipe/provision.md) - * [check_remote](/docs/recipe/deploy/check_remote.md) - * [cleanup](/docs/recipe/deploy/cleanup.md) - * [clear_paths](/docs/recipe/deploy/clear_paths.md) - * [copy_dirs](/docs/recipe/deploy/copy_dirs.md) - * [info](/docs/recipe/deploy/info.md) - * [lock](/docs/recipe/deploy/lock.md) - * [push](/docs/recipe/deploy/push.md) - * [release](/docs/recipe/deploy/release.md) - * [rollback](/docs/recipe/deploy/rollback.md) - * [setup](/docs/recipe/deploy/setup.md) - * [shared](/docs/recipe/deploy/shared.md) - * [symlink](/docs/recipe/deploy/symlink.md) - * [update_code](/docs/recipe/deploy/update_code.md) - * [vendors](/docs/recipe/deploy/vendors.md) - * [writable](/docs/recipe/deploy/writable.md) - -## Configuration -### user -[Source](https://github.com/deployphp/deployer/blob/master/recipe/common.php#L29) - -Name of current user who is running deploy. -If not set will try automatically get git user name, -otherwise output of `whoami` command. - - - -### keep_releases -[Source](https://github.com/deployphp/deployer/blob/master/recipe/common.php#L46) - -Number of releases to preserve in releases folder. - -```php title="Default value" -10 -``` - - -### repository -[Source](https://github.com/deployphp/deployer/blob/master/recipe/common.php#L49) - -Repository to deploy. - - - -### default_timeout -[Source](https://github.com/deployphp/deployer/blob/master/recipe/common.php#L54) - -Default timeout for `run()` and `runLocally()` functions. - -Set to `null` to disable timeout. - -```php title="Default value" -300 -``` - - -### env -[Source](https://github.com/deployphp/deployer/blob/master/recipe/common.php#L70) - -Remote environment variables. -```php -set('env', [ - 'KEY' => 'something', -]); -``` - -It is possible to override it per `run()` call. - -```php -run('echo $KEY', env: ['KEY' => 'over']); -``` - - - -### dotenv -[Source](https://github.com/deployphp/deployer/blob/master/recipe/common.php#L79) - -Path to `.env` file which will be used as environment variables for each command per `run()`. - -```php -set('dotenv', '{{current_path}}/.env'); -``` - -```php title="Default value" -false -``` - - -### deploy_path -[Source](https://github.com/deployphp/deployer/blob/master/recipe/common.php#L89) - -The deploy path. - -For example can be set for a bunch of host once as: -```php -set('deploy_path', '~/{{alias}}'); -``` - - - -### current_path -[Source](https://github.com/deployphp/deployer/blob/master/recipe/common.php#L99) - -Return current release path. Default to [deploy_path](/docs/recipe/common.md#deploy_path)/`current`. -```php -set('current_path', '/var/public_html'); -``` - -```php title="Default value" -'{{deploy_path}}/current' -``` - - -### bin/php -[Source](https://github.com/deployphp/deployer/blob/master/recipe/common.php#L102) - -Path to the `php` bin. - - - -### bin/git -[Source](https://github.com/deployphp/deployer/blob/master/recipe/common.php#L110) - -Path to the `git` bin. - - - -### use_relative_symlink -[Source](https://github.com/deployphp/deployer/blob/master/recipe/common.php#L116) - -Should [bin/symlink](/docs/recipe/common.md#bin/symlink) use `--relative` option or not. Will detect -automatically. - - - -### bin/symlink -[Source](https://github.com/deployphp/deployer/blob/master/recipe/common.php#L121) - -Path to the `ln` bin. With predefined options `-nfs`. - - - -### sudo_askpass -[Source](https://github.com/deployphp/deployer/blob/master/recipe/common.php#L128) - -Path to a file which will store temp script with sudo password. -Defaults to `.dep/sudo_pass`. This script is only temporary and will be deleted after -sudo command executed. - - - - -## Tasks - -### deploy:prepare -[Source](https://github.com/deployphp/deployer/blob/master/recipe/common.php#L137) - -Prepares a new release. - - - - -This task is group task which contains next tasks: -* [deploy:info](/docs/recipe/deploy/info.md#deployinfo) -* [deploy:setup](/docs/recipe/deploy/setup.md#deploysetup) -* [deploy:lock](/docs/recipe/deploy/lock.md#deploylock) -* [deploy:release](/docs/recipe/deploy/release.md#deployrelease) -* [deploy:update_code](/docs/recipe/deploy/update_code.md#deployupdate_code) -* [deploy:shared](/docs/recipe/deploy/shared.md#deployshared) -* [deploy:writable](/docs/recipe/deploy/writable.md#deploywritable) - - -### deploy:publish -[Source](https://github.com/deployphp/deployer/blob/master/recipe/common.php#L148) - -Publishes the release. - - - - -This task is group task which contains next tasks: -* [deploy:symlink](/docs/recipe/deploy/symlink.md#deploysymlink) -* [deploy:unlock](/docs/recipe/deploy/lock.md#deployunlock) -* [deploy:cleanup](/docs/recipe/deploy/cleanup.md#deploycleanup) -* [deploy:success](/docs/recipe/common.md#deploysuccess) - - -### deploy:success -[Source](https://github.com/deployphp/deployer/blob/master/recipe/common.php#L158) - - - -Prints success message - - -### deploy:failed -[Source](https://github.com/deployphp/deployer/blob/master/recipe/common.php#L167) - - - -Hook on deploy failure. - - -### logs:app -[Source](https://github.com/deployphp/deployer/blob/master/recipe/common.php#L177) - -Shows application logs. - -Follows latest application logs. - - diff --git a/docs/recipe/composer.md b/docs/recipe/composer.md deleted file mode 100644 index 90fd8e08c..000000000 --- a/docs/recipe/composer.md +++ /dev/null @@ -1,28 +0,0 @@ - - - - -# composer - -[Source](/recipe/composer.php) - -* Requires - * [common](/docs/recipe/common.md) - - -## Tasks - -### deploy -[Source](https://github.com/deployphp/deployer/blob/master/recipe/composer.php#L9) - -Deploys your project. - - - - -This task is group task which contains next tasks: -* [deploy:prepare](/docs/recipe/common.md#deployprepare) -* [deploy:vendors](/docs/recipe/deploy/vendors.md#deployvendors) -* [deploy:publish](/docs/recipe/common.md#deploypublish) - - diff --git a/docs/recipe/contao.md b/docs/recipe/contao.md deleted file mode 100644 index 7a807575f..000000000 --- a/docs/recipe/contao.md +++ /dev/null @@ -1,115 +0,0 @@ - - - - -# contao - -[Source](/recipe/contao.php) - -* Requires - * [symfony](/docs/recipe/symfony.md) - -## Configuration -### public_path -[Source](https://github.com/deployphp/deployer/blob/master/recipe/contao.php#L11) - -Overrides [public_path](/docs/recipe/provision/website.md#public_path) from `recipe/provision/website.php`. - -The public path is the path to be set as DocumentRoot and is defined in the `composer.json` of the project -but defaults to `public` from Contao 5.0 on. -This path is relative from the [current_path](/docs/recipe/common.md#current_path), see [`recipe/provision/website.php`](/docs/recipe/provision/website.php#public_path). - - - -### bin/console -[Source](https://github.com/deployphp/deployer/blob/master/recipe/contao.php#L29) - -Overrides [bin/console](/docs/recipe/symfony.md#bin/console) from `recipe/symfony.php`. - - - - - -### contao_version -[Source](https://github.com/deployphp/deployer/blob/master/recipe/contao.php#L33) - - - - - - -## Tasks - -### contao:migrate -[Source](https://github.com/deployphp/deployer/blob/master/recipe/contao.php#L47) - -Run Contao migrations. - -This task updates the database. A database backup is saved automatically as a default. - -To automatically drop the obsolete database structures, you can override the task as follows: - -```php -task('contao:migrate', function () { - run('{{bin/php}} {{bin/console}} contao:migrate --with-deletes {{console_options}}'); -}); -``` - - -### contao:manager:download -[Source](https://github.com/deployphp/deployer/blob/master/recipe/contao.php#L53) - -Download the Contao Manager. - -Downloads the `contao-manager.phar.php` into the public path. - - -### contao:install:lock -[Source](https://github.com/deployphp/deployer/blob/master/recipe/contao.php#L59) - -Lock the Contao Install Tool. - -Locks the Contao install tool which is useful if you don't use it. - - -### contao:manager:lock -[Source](https://github.com/deployphp/deployer/blob/master/recipe/contao.php#L65) - -Lock the Contao Manager. - -Locks the Contao Manager which is useful if you only need the API of the Manager rather than the UI. - - -### contao:maintenance:enable -[Source](https://github.com/deployphp/deployer/blob/master/recipe/contao.php#L71) - -Enable maintenance mode. - - - - -### contao:maintenance:disable -[Source](https://github.com/deployphp/deployer/blob/master/recipe/contao.php#L86) - -Disable maintenance mode. - - - - -### deploy -[Source](https://github.com/deployphp/deployer/blob/master/recipe/contao.php#L98) - -Deploy the project. - - - - -This task is group task which contains next tasks: -* [deploy:prepare](/docs/recipe/common.md#deployprepare) -* [deploy:vendors](/docs/recipe/deploy/vendors.md#deployvendors) -* [contao:maintenance:enable](/docs/recipe/contao.md#contaomaintenanceenable) -* [contao:migrate](/docs/recipe/contao.md#contaomigrate) -* [contao:maintenance:disable](/docs/recipe/contao.md#contaomaintenancedisable) -* [deploy:publish](/docs/recipe/common.md#deploypublish) - - diff --git a/docs/recipe/deploy/check_remote.md b/docs/recipe/deploy/check_remote.md deleted file mode 100644 index 81410caf2..000000000 --- a/docs/recipe/deploy/check_remote.md +++ /dev/null @@ -1,21 +0,0 @@ - - - - -# check_remote - -[Source](/recipe/deploy/check_remote.php) - - - -## Tasks - -### deploy:check_remote -[Source](https://github.com/deployphp/deployer/blob/master/recipe/deploy/check_remote.php#L10) - -Checks remote head. - -Cancel deployment if there would be no change to the codebase. -This avoids unnecessary releases if the latest commit has already been deployed. - - diff --git a/docs/recipe/deploy/cleanup.md b/docs/recipe/deploy/cleanup.md deleted file mode 100644 index b797d1911..000000000 --- a/docs/recipe/deploy/cleanup.md +++ /dev/null @@ -1,31 +0,0 @@ - - - - -# cleanup - -[Source](/recipe/deploy/cleanup.php) - - -## Configuration -### cleanup_use_sudo -[Source](https://github.com/deployphp/deployer/blob/master/recipe/deploy/cleanup.php#L5) - -Use sudo in deploy:cleanup task for rm command. - -```php title="Default value" -false -``` - - - -## Tasks - -### deploy:cleanup -[Source](https://github.com/deployphp/deployer/blob/master/recipe/deploy/cleanup.php#L8) - -Cleanup old releases. - - - - diff --git a/docs/recipe/deploy/clear_paths.md b/docs/recipe/deploy/clear_paths.md deleted file mode 100644 index e335f457a..000000000 --- a/docs/recipe/deploy/clear_paths.md +++ /dev/null @@ -1,38 +0,0 @@ - - - - -# clear_paths - -[Source](/recipe/deploy/clear_paths.php) - - -## Configuration -### clear_paths -[Source](https://github.com/deployphp/deployer/blob/master/recipe/deploy/clear_paths.php#L5) - -List of paths to remove from [release_path](/docs/recipe/deploy/release.md#release_path). - - - -### clear_use_sudo -[Source](https://github.com/deployphp/deployer/blob/master/recipe/deploy/clear_paths.php#L8) - -Use sudo for deploy:clear_path task? - -```php title="Default value" -false -``` - - - -## Tasks - -### deploy:clear_paths -[Source](https://github.com/deployphp/deployer/blob/master/recipe/deploy/clear_paths.php#L11) - -Cleanup files and/or directories. - - - - diff --git a/docs/recipe/deploy/copy_dirs.md b/docs/recipe/deploy/copy_dirs.md deleted file mode 100644 index 3570adf58..000000000 --- a/docs/recipe/deploy/copy_dirs.md +++ /dev/null @@ -1,29 +0,0 @@ - - - - -# copy_dirs - -[Source](/recipe/deploy/copy_dirs.php) - - -## Configuration -### copy_dirs -[Source](https://github.com/deployphp/deployer/blob/master/recipe/deploy/copy_dirs.php#L6) - -List of dirs to copy between releases. -For example you can copy `node_modules` to speedup npm install. - - - - -## Tasks - -### deploy:copy_dirs -[Source](https://github.com/deployphp/deployer/blob/master/recipe/deploy/copy_dirs.php#L9) - -Copies directories. - - - - diff --git a/docs/recipe/deploy/info.md b/docs/recipe/deploy/info.md deleted file mode 100644 index e52a2012b..000000000 --- a/docs/recipe/deploy/info.md +++ /dev/null @@ -1,20 +0,0 @@ - - - - -# info - -[Source](/recipe/deploy/info.php) - - - -## Tasks - -### deploy:info -[Source](https://github.com/deployphp/deployer/blob/master/recipe/deploy/info.php#L5) - -Displays info about deployment. - - - - diff --git a/docs/recipe/deploy/lock.md b/docs/recipe/deploy/lock.md deleted file mode 100644 index 382c050ad..000000000 --- a/docs/recipe/deploy/lock.md +++ /dev/null @@ -1,36 +0,0 @@ - - - - -# lock - -[Source](/recipe/deploy/lock.php) - - - -## Tasks - -### deploy:lock -[Source](https://github.com/deployphp/deployer/blob/master/recipe/deploy/lock.php#L7) - -Locks deploy. - - - - -### deploy:unlock -[Source](https://github.com/deployphp/deployer/blob/master/recipe/deploy/lock.php#L20) - -Unlocks deploy. - - - - -### deploy:is_locked -[Source](https://github.com/deployphp/deployer/blob/master/recipe/deploy/lock.php#L25) - -Checks if deploy is locked. - - - - diff --git a/docs/recipe/deploy/push.md b/docs/recipe/deploy/push.md deleted file mode 100644 index 5953a53c0..000000000 --- a/docs/recipe/deploy/push.md +++ /dev/null @@ -1,22 +0,0 @@ - - - - -# push - -[Source](/recipe/deploy/push.php) - - - -## Tasks - -### push -[Source](https://github.com/deployphp/deployer/blob/master/recipe/deploy/push.php#L8) - -Pushes local changes to remote host. - -Creates patch of local changes and pushes them on host. -And applies to current_path. Push can be done many times. -The task purpose to be used only for development. - - diff --git a/docs/recipe/deploy/release.md b/docs/recipe/deploy/release.md deleted file mode 100644 index 9e9b8ba4d..000000000 --- a/docs/recipe/deploy/release.md +++ /dev/null @@ -1,82 +0,0 @@ - - - - -# release - -[Source](/recipe/deploy/release.php) - - -## Configuration -### release_name -[Source](https://github.com/deployphp/deployer/blob/master/recipe/deploy/release.php#L8) - -The name of the release. - - - -### releases_log -[Source](https://github.com/deployphp/deployer/blob/master/recipe/deploy/release.php#L16) - -Holds releases log from `.dep/releases_log` file. - - - -### releases_list -[Source](https://github.com/deployphp/deployer/blob/master/recipe/deploy/release.php#L31) - -Return list of release names on host. - - - -### release_path -[Source](https://github.com/deployphp/deployer/blob/master/recipe/deploy/release.php#L58) - -Return release path. - - - -### release_revision -[Source](https://github.com/deployphp/deployer/blob/master/recipe/deploy/release.php#L69) - -Current release revision. Usually a git hash. - - - -### release_or_current_path -[Source](https://github.com/deployphp/deployer/blob/master/recipe/deploy/release.php#L75) - -Return the release path during a deployment -but fallback to the current path otherwise. - - - - -## Tasks - -### deploy:release -[Source](https://github.com/deployphp/deployer/blob/master/recipe/deploy/release.php#L82) - -Prepares release. - -Clean up unfinished releases and prepare next release - - -### releases -[Source](https://github.com/deployphp/deployer/blob/master/recipe/deploy/release.php#L149) - -Shows releases list. - -Example output: -``` -+---------------------+------example.org ------------+--------+-----------+ -| Date (UTC) | Release | Author | Target | Commit | -+---------------------+-------------+----------------+--------+-----------+ -| 2021-11-06 20:51:45 | 1 | Anton Medvedev | HEAD | 34d24192e | -| 2021-11-06 21:00:50 | 2 (bad) | Anton Medvedev | HEAD | 392948a40 | -| 2021-11-06 23:19:20 | 3 | Anton Medvedev | HEAD | a4057a36c | -| 2021-11-06 23:24:30 | 4 (current) | Anton Medvedev | HEAD | s3wa45ca6 | -+---------------------+-------------+----------------+--------+-----------+ -``` - - diff --git a/docs/recipe/deploy/rollback.md b/docs/recipe/deploy/rollback.md deleted file mode 100644 index 273ec04c9..000000000 --- a/docs/recipe/deploy/rollback.md +++ /dev/null @@ -1,46 +0,0 @@ - - - - -# rollback - -[Source](/recipe/deploy/rollback.php) - - -## Configuration -### rollback_candidate -[Source](https://github.com/deployphp/deployer/blob/master/recipe/deploy/rollback.php#L19) - -Rollback candidate automatically will be automatically chosen by -looking at output of `ls` command and content of `.dep/releases_log`. - -If rollback candidate marked as **BAD_RELEASE**, it will be skipped. - -:::tip -You can override rollback candidate via: -``` -dep rollback -o rollback_candidate=123 -``` -::: - - - - -## Tasks - -### rollback -[Source](https://github.com/deployphp/deployer/blob/master/recipe/deploy/rollback.php#L62) - -Rollbacks to the previous release. - -Uses [rollback_candidate](/docs/recipe/deploy/rollback.md#rollback_candidate) for symlinking. Current release will be marked as -bad by creating file **BAD_RELEASE** with timestamp and [user](/docs/recipe/common.md#user). - -:::warning -You can always manually symlink [current_path](/docs/recipe/common.md#current_path) to proper release. -``` -dep run '{{bin/symlink}} releases/123 {{current_path}}' -``` -::: - - diff --git a/docs/recipe/deploy/setup.md b/docs/recipe/deploy/setup.md deleted file mode 100644 index 0af45460d..000000000 --- a/docs/recipe/deploy/setup.md +++ /dev/null @@ -1,20 +0,0 @@ - - - - -# setup - -[Source](/recipe/deploy/setup.php) - - - -## Tasks - -### deploy:setup -[Source](https://github.com/deployphp/deployer/blob/master/recipe/deploy/setup.php#L5) - -Prepares host for deploy. - - - - diff --git a/docs/recipe/deploy/shared.md b/docs/recipe/deploy/shared.md deleted file mode 100644 index 57dafc1ca..000000000 --- a/docs/recipe/deploy/shared.md +++ /dev/null @@ -1,43 +0,0 @@ - - - - -# shared - -[Source](/recipe/deploy/shared.php) - - -## Configuration -### shared_dirs -[Source](https://github.com/deployphp/deployer/blob/master/recipe/deploy/shared.php#L12) - -List of dirs what will be shared between releases. -Each release will have symlink to those dirs stored in [deploy_path](/docs/recipe/common.md#deploy_path)/shared dir. -```php -set('shared_dirs', ['storage']); -``` - - - -### shared_files -[Source](https://github.com/deployphp/deployer/blob/master/recipe/deploy/shared.php#L19) - -List of files what will be shared between releases. -Each release will have symlink to those files stored in [deploy_path](/docs/recipe/common.md#deploy_path)/shared dir. -```php -set('shared_files', ['.env']); -``` - - - - -## Tasks - -### deploy:shared -[Source](https://github.com/deployphp/deployer/blob/master/recipe/deploy/shared.php#L22) - -Creates symlinks for shared files and dirs. - - - - diff --git a/docs/recipe/deploy/symlink.md b/docs/recipe/deploy/symlink.md deleted file mode 100644 index 6e97eac1c..000000000 --- a/docs/recipe/deploy/symlink.md +++ /dev/null @@ -1,28 +0,0 @@ - - - - -# symlink - -[Source](/recipe/deploy/symlink.php) - - -## Configuration -### use_atomic_symlink -[Source](https://github.com/deployphp/deployer/blob/master/recipe/deploy/symlink.php#L5) - -Use mv -T if available. Will check automatically. - - - - -## Tasks - -### deploy:symlink -[Source](https://github.com/deployphp/deployer/blob/master/recipe/deploy/symlink.php#L10) - -Creates symlink to release. - - - - diff --git a/docs/recipe/deploy/update_code.md b/docs/recipe/deploy/update_code.md deleted file mode 100644 index 8d191aa4a..000000000 --- a/docs/recipe/deploy/update_code.md +++ /dev/null @@ -1,82 +0,0 @@ - - - - -# update_code - -[Source](/recipe/deploy/update_code.php) - - -## Configuration -### branch -[Source](https://github.com/deployphp/deployer/blob/master/recipe/deploy/update_code.php#L11) - -Determines which branch to deploy. Can be overridden with CLI option `--branch`. -If not specified, will get current git HEAD branch as default branch to deploy. - -```php title="Default value" -'HEAD' -``` - - -### target -[Source](https://github.com/deployphp/deployer/blob/master/recipe/deploy/update_code.php#L18) - -The deploy target: a branch, a tag or a revision. - - - -### update_code_strategy -[Source](https://github.com/deployphp/deployer/blob/master/recipe/deploy/update_code.php#L47) - -Sets deploy:update_code strategy. -Can be one of: -- archive -- clone (if you need `.git` dir in your [release_path](/docs/recipe/deploy/release.md#release_path)) - -```php title="Default value" -'archive' -``` - - -### git_ssh_command -[Source](https://github.com/deployphp/deployer/blob/master/recipe/deploy/update_code.php#L53) - -Sets environment variable _GIT_SSH_COMMAND_ for `git clone` command. -If `StrictHostKeyChecking` flag is set to `accept-new` then ssh will -automatically add new host keys to the user known hosts files, but -will not permit connections to hosts with changed host keys. - -```php title="Default value" -'ssh -o StrictHostKeyChecking=accept-new' -``` - - -### sub_directory -[Source](https://github.com/deployphp/deployer/blob/master/recipe/deploy/update_code.php#L65) - -Specifies a sub directory within the repository to deploy. -Works only when [`update_code_strategy`](#update_code_strategy) is set to `archive` (default). - -Example: - - set value to `src` if you want to deploy the folder that lives at `/src/api`. - - set value to `src/api` if you want to deploy the folder that lives at `/src/api`. - -Note: do not use a leading `/`! - -```php title="Default value" -false -``` - - - -## Tasks - -### deploy:update_code -[Source](https://github.com/deployphp/deployer/blob/master/recipe/deploy/update_code.php#L71) - -Updates code. - -Update code at [release_path](/docs/recipe/deploy/release.md#release_path) on host. - - diff --git a/docs/recipe/deploy/vendors.md b/docs/recipe/deploy/vendors.md deleted file mode 100644 index 34c1c5f37..000000000 --- a/docs/recipe/deploy/vendors.md +++ /dev/null @@ -1,50 +0,0 @@ - - - - -# vendors - -[Source](/recipe/deploy/vendors.php) - - -## Configuration -### composer_action -[Source](https://github.com/deployphp/deployer/blob/master/recipe/deploy/vendors.php#L4) - - - -```php title="Default value" -'install' -``` - - -### composer_options -[Source](https://github.com/deployphp/deployer/blob/master/recipe/deploy/vendors.php#L6) - - - -```php title="Default value" -'--verbose --prefer-dist --no-progress --no-interaction --no-dev --optimize-autoloader' -``` - - -### bin/composer -[Source](https://github.com/deployphp/deployer/blob/master/recipe/deploy/vendors.php#L11) - -Returns Composer binary path in found. Otherwise try to install latest -composer version to `.dep/composer.phar`. To use specific composer version -download desired phar and place it at `.dep/composer.phar`. - - - - -## Tasks - -### deploy:vendors -[Source](https://github.com/deployphp/deployer/blob/master/recipe/deploy/vendors.php#L27) - -Installs vendors. - - - - diff --git a/docs/recipe/deploy/writable.md b/docs/recipe/deploy/writable.md deleted file mode 100644 index a81187d8c..000000000 --- a/docs/recipe/deploy/writable.md +++ /dev/null @@ -1,88 +0,0 @@ - - - - -# writable - -[Source](/recipe/deploy/writable.php) - - -## Configuration -### http_user -[Source](https://github.com/deployphp/deployer/blob/master/recipe/deploy/writable.php#L8) - - - - - -### http_group -[Source](https://github.com/deployphp/deployer/blob/master/recipe/deploy/writable.php#L25) - -Used to make a writable directory by a server. -Used in `chgrp` mode of [writable_mode](/docs/recipe/deploy/writable.md#writable_mode) only. -Attempts automatically to detect http user in process list. - - - -### writable_dirs -[Source](https://github.com/deployphp/deployer/blob/master/recipe/deploy/writable.php#L40) - -List of writable dirs. - - - -### writable_mode -[Source](https://github.com/deployphp/deployer/blob/master/recipe/deploy/writable.php#L47) - -One of: -- chown -- chgrp -- chmod -- acl - -```php title="Default value" -'acl' -``` - - -### writable_use_sudo -[Source](https://github.com/deployphp/deployer/blob/master/recipe/deploy/writable.php#L50) - -Using sudo in writable commands? - -```php title="Default value" -false -``` - - -### writable_recursive -[Source](https://github.com/deployphp/deployer/blob/master/recipe/deploy/writable.php#L53) - -Use recursive mode (-R)? - -```php title="Default value" -false -``` - - -### writable_chmod_mode -[Source](https://github.com/deployphp/deployer/blob/master/recipe/deploy/writable.php#L56) - -The chmod mode. - -```php title="Default value" -'0755' -``` - - - -## Tasks - -### deploy:writable -[Source](https://github.com/deployphp/deployer/blob/master/recipe/deploy/writable.php#L59) - -Makes writable dirs. - - - - diff --git a/docs/recipe/drupal7.md b/docs/recipe/drupal7.md deleted file mode 100644 index 1de18af15..000000000 --- a/docs/recipe/drupal7.md +++ /dev/null @@ -1,96 +0,0 @@ - - - - -# drupal7 - -[Source](/recipe/drupal7.php) - -* Requires - * [common](/docs/recipe/common.md) - -## Configuration -### drupal_site -[Source](https://github.com/deployphp/deployer/blob/master/recipe/drupal7.php#L14) - -Set Drupal 7 site. Change if you use different site - -```php title="Default value" -'default' -``` - - -### shared_dirs -[Source](https://github.com/deployphp/deployer/blob/master/recipe/drupal7.php#L17) - -Overrides [shared_dirs](/docs/recipe/deploy/shared.md#shared_dirs) from `recipe/deploy/shared.php`. - -Drupal 7 shared dirs - -```php title="Default value" -[ - 'sites/{{drupal_site}}/files', -] -``` - - -### shared_files -[Source](https://github.com/deployphp/deployer/blob/master/recipe/drupal7.php#L22) - -Overrides [shared_files](/docs/recipe/deploy/shared.md#shared_files) from `recipe/deploy/shared.php`. - -Drupal 7 shared files - -```php title="Default value" -[ - 'sites/{{drupal_site}}/settings.php', -] -``` - - -### writable_dirs -[Source](https://github.com/deployphp/deployer/blob/master/recipe/drupal7.php#L27) - -Overrides [writable_dirs](/docs/recipe/deploy/writable.md#writable_dirs) from `recipe/deploy/writable.php`. - -Drupal 7 writable dirs - -```php title="Default value" -[ - 'sites/{{drupal_site}}/files', -] -``` - - - -## Tasks - -### deploy -[Source](https://github.com/deployphp/deployer/blob/master/recipe/drupal7.php#L8) - - - - - - -This task is group task which contains next tasks: -* [deploy:prepare](/docs/recipe/common.md#deployprepare) -* [deploy:publish](/docs/recipe/common.md#deploypublish) - - -### drupal:settings -[Source](https://github.com/deployphp/deployer/blob/master/recipe/drupal7.php#L33) - - - -Create and upload Drupal 7 settings.php using values from secrets - - -### drupal:upload_files -[Source](https://github.com/deployphp/deployer/blob/master/recipe/drupal7.php#L75) - - - -Upload Drupal 7 files folder - - diff --git a/docs/recipe/drupal8.md b/docs/recipe/drupal8.md deleted file mode 100644 index d20c81cfb..000000000 --- a/docs/recipe/drupal8.md +++ /dev/null @@ -1,81 +0,0 @@ - - - - -# drupal8 - -[Source](/recipe/drupal8.php) - -* Requires - * [common](/docs/recipe/common.md) - -## Configuration -### drupal_site -[Source](https://github.com/deployphp/deployer/blob/master/recipe/drupal8.php#L14) - -Set drupal site. Change if you use different site - -```php title="Default value" -'default' -``` - - -### shared_dirs -[Source](https://github.com/deployphp/deployer/blob/master/recipe/drupal8.php#L18) - -Overrides [shared_dirs](/docs/recipe/deploy/shared.md#shared_dirs) from `recipe/deploy/shared.php`. - -Drupal 8 shared dirs - -```php title="Default value" -[ - 'sites/{{drupal_site}}/files', -] -``` - - -### shared_files -[Source](https://github.com/deployphp/deployer/blob/master/recipe/drupal8.php#L23) - -Overrides [shared_files](/docs/recipe/deploy/shared.md#shared_files) from `recipe/deploy/shared.php`. - -Drupal 8 shared files - -```php title="Default value" -[ - 'sites/{{drupal_site}}/settings.php', - 'sites/{{drupal_site}}/services.yml', -] -``` - - -### writable_dirs -[Source](https://github.com/deployphp/deployer/blob/master/recipe/drupal8.php#L29) - -Overrides [writable_dirs](/docs/recipe/deploy/writable.md#writable_dirs) from `recipe/deploy/writable.php`. - -Drupal 8 Writable dirs - -```php title="Default value" -[ - 'sites/{{drupal_site}}/files', -] -``` - - - -## Tasks - -### deploy -[Source](https://github.com/deployphp/deployer/blob/master/recipe/drupal8.php#L8) - - - - - - -This task is group task which contains next tasks: -* [deploy:prepare](/docs/recipe/common.md#deployprepare) -* [deploy:publish](/docs/recipe/common.md#deploypublish) - - diff --git a/docs/recipe/flow_framework.md b/docs/recipe/flow_framework.md deleted file mode 100644 index 754098de0..000000000 --- a/docs/recipe/flow_framework.md +++ /dev/null @@ -1,83 +0,0 @@ - - - - -# flow_framework - -[Source](/recipe/flow_framework.php) - -* Requires - * [common](/docs/recipe/common.md) - -## Configuration -### flow_context -[Source](https://github.com/deployphp/deployer/blob/master/recipe/flow_framework.php#L9) - -Flow-Framework application-context - -```php title="Default value" -'Production' -``` - - -### flow_command -[Source](https://github.com/deployphp/deployer/blob/master/recipe/flow_framework.php#L12) - -Flow-Framework cli-command - -```php title="Default value" -'flow' -``` - - -### shared_dirs -[Source](https://github.com/deployphp/deployer/blob/master/recipe/flow_framework.php#L15) - -Overrides [shared_dirs](/docs/recipe/deploy/shared.md#shared_dirs) from `recipe/deploy/shared.php`. - -Flow-Framework shared directories - -```php title="Default value" -[ - 'Data/Persistent', - 'Data/Logs', - 'Configuration/{{flow_context}}' -] -``` - - - -## Tasks - -### deploy:run_migrations -[Source](https://github.com/deployphp/deployer/blob/master/recipe/flow_framework.php#L25) - -Applies database migrations. - -Apply database migrations - - -### deploy:publish_resources -[Source](https://github.com/deployphp/deployer/blob/master/recipe/flow_framework.php#L33) - -Publishes resources. - -Publish resources - - -### deploy -[Source](https://github.com/deployphp/deployer/blob/master/recipe/flow_framework.php#L41) - -Deploys your project. - -Main task - - -This task is group task which contains next tasks: -* [deploy:prepare](/docs/recipe/common.md#deployprepare) -* [deploy:vendors](/docs/recipe/deploy/vendors.md#deployvendors) -* [deploy:run_migrations](/docs/recipe/flow_framework.md#deployrun_migrations) -* [deploy:publish_resources](/docs/recipe/flow_framework.md#deploypublish_resources) -* [deploy:publish](/docs/recipe/common.md#deploypublish) - - diff --git a/docs/recipe/fuelphp.md b/docs/recipe/fuelphp.md deleted file mode 100644 index b5416c2f1..000000000 --- a/docs/recipe/fuelphp.md +++ /dev/null @@ -1,43 +0,0 @@ - - - - -# fuelphp - -[Source](/recipe/fuelphp.php) - -* Requires - * [common](/docs/recipe/common.md) - -## Configuration -### shared_dirs -[Source](https://github.com/deployphp/deployer/blob/master/recipe/fuelphp.php#L9) - -Overrides [shared_dirs](/docs/recipe/deploy/shared.md#shared_dirs) from `recipe/deploy/shared.php`. - -FuelPHP 1.x shared dirs - -```php title="Default value" -[ - 'fuel/app/cache', 'fuel/app/logs', -] -``` - - - -## Tasks - -### deploy -[Source](https://github.com/deployphp/deployer/blob/master/recipe/fuelphp.php#L17) - -Deploys your project. - -Main task - - -This task is group task which contains next tasks: -* [deploy:prepare](/docs/recipe/common.md#deployprepare) -* [deploy:vendors](/docs/recipe/deploy/vendors.md#deployvendors) -* [deploy:publish](/docs/recipe/common.md#deploypublish) - - diff --git a/docs/recipe/joomla.md b/docs/recipe/joomla.md deleted file mode 100644 index bfbc871ca..000000000 --- a/docs/recipe/joomla.md +++ /dev/null @@ -1,64 +0,0 @@ - - - - -# joomla - -[Source](/recipe/joomla.php) - -* Requires - * [common](/docs/recipe/common.md) - -## Configuration -### shared_files -[Source](https://github.com/deployphp/deployer/blob/master/recipe/joomla.php#L8) - -Overrides [shared_files](/docs/recipe/deploy/shared.md#shared_files) from `recipe/deploy/shared.php`. - - - -```php title="Default value" -['configuration.php'] -``` - - -### shared_dirs -[Source](https://github.com/deployphp/deployer/blob/master/recipe/joomla.php#L9) - -Overrides [shared_dirs](/docs/recipe/deploy/shared.md#shared_dirs) from `recipe/deploy/shared.php`. - - - -```php title="Default value" -['images'] -``` - - -### writable_dirs -[Source](https://github.com/deployphp/deployer/blob/master/recipe/joomla.php#L10) - -Overrides [writable_dirs](/docs/recipe/deploy/writable.md#writable_dirs) from `recipe/deploy/writable.php`. - - - -```php title="Default value" -['images'] -``` - - - -## Tasks - -### deploy -[Source](https://github.com/deployphp/deployer/blob/master/recipe/joomla.php#L13) - -Deploys your project. - - - - -This task is group task which contains next tasks: -* [deploy:prepare](/docs/recipe/common.md#deployprepare) -* [deploy:publish](/docs/recipe/common.md#deploypublish) - - diff --git a/docs/recipe/laravel.md b/docs/recipe/laravel.md deleted file mode 100644 index 5a4d32018..000000000 --- a/docs/recipe/laravel.md +++ /dev/null @@ -1,386 +0,0 @@ - - - - -# laravel - -[Source](/recipe/laravel.php) - -* Requires - * [common](/docs/recipe/common.md) - -## Configuration -### shared_dirs -[Source](https://github.com/deployphp/deployer/blob/master/recipe/laravel.php#L8) - -Overrides [shared_dirs](/docs/recipe/deploy/shared.md#shared_dirs) from `recipe/deploy/shared.php`. - - - -```php title="Default value" -['storage'] -``` - - -### shared_files -[Source](https://github.com/deployphp/deployer/blob/master/recipe/laravel.php#L9) - -Overrides [shared_files](/docs/recipe/deploy/shared.md#shared_files) from `recipe/deploy/shared.php`. - - - -```php title="Default value" -['.env'] -``` - - -### writable_dirs -[Source](https://github.com/deployphp/deployer/blob/master/recipe/laravel.php#L10) - -Overrides [writable_dirs](/docs/recipe/deploy/writable.md#writable_dirs) from `recipe/deploy/writable.php`. - - - -```php title="Default value" -[ - 'bootstrap/cache', - 'storage', - 'storage/app', - 'storage/app/public', - 'storage/framework', - 'storage/framework/cache', - 'storage/framework/sessions', - 'storage/framework/views', - 'storage/logs', -] -``` - - -### log_files -[Source](https://github.com/deployphp/deployer/blob/master/recipe/laravel.php#L21) - - - -```php title="Default value" -'storage/logs/*.log' -``` - - -### laravel_version -[Source](https://github.com/deployphp/deployer/blob/master/recipe/laravel.php#L22) - - - - - - -## Tasks - -### artisan:down -[Source](https://github.com/deployphp/deployer/blob/master/recipe/laravel.php#L89) - -Puts the application into maintenance / demo mode. - - - - -### artisan:up -[Source](https://github.com/deployphp/deployer/blob/master/recipe/laravel.php#L92) - -Brings the application out of maintenance mode. - - - - -### artisan:​key:generate -[Source](https://github.com/deployphp/deployer/blob/master/recipe/laravel.php#L99) - -Sets the application key. - - - - -### artisan:passport:keys -[Source](https://github.com/deployphp/deployer/blob/master/recipe/laravel.php#L102) - -Creates the encryption keys for API authentication. - - - - -### artisan:db:seed -[Source](https://github.com/deployphp/deployer/blob/master/recipe/laravel.php#L109) - -Seeds the database with records. - - - - -### artisan:migrate -[Source](https://github.com/deployphp/deployer/blob/master/recipe/laravel.php#L112) - -Runs the database migrations. - - - - -### artisan:migrate:fresh -[Source](https://github.com/deployphp/deployer/blob/master/recipe/laravel.php#L115) - -Drops all tables and re-run all migrations. - - - - -### artisan:migrate:rollback -[Source](https://github.com/deployphp/deployer/blob/master/recipe/laravel.php#L118) - -Rollbacks the last database migration. - - - - -### artisan:migrate:status -[Source](https://github.com/deployphp/deployer/blob/master/recipe/laravel.php#L121) - -Shows the status of each migration. - - - - -### artisan:cache:clear -[Source](https://github.com/deployphp/deployer/blob/master/recipe/laravel.php#L128) - -Flushes the application cache. - - - - -### artisan:config:cache -[Source](https://github.com/deployphp/deployer/blob/master/recipe/laravel.php#L131) - -Creates a cache file for faster configuration loading. - - - - -### artisan:config:clear -[Source](https://github.com/deployphp/deployer/blob/master/recipe/laravel.php#L134) - -Removes the configuration cache file. - - - - -### artisan:event:cache -[Source](https://github.com/deployphp/deployer/blob/master/recipe/laravel.php#L137) - -Discovers and cache the application\'s events and listeners. - - - - -### artisan:event:clear -[Source](https://github.com/deployphp/deployer/blob/master/recipe/laravel.php#L140) - -Clears all cached events and listeners. - - - - -### artisan:event:list -[Source](https://github.com/deployphp/deployer/blob/master/recipe/laravel.php#L143) - -Lists the application\'s events and listeners. - - - - -### artisan:optimize -[Source](https://github.com/deployphp/deployer/blob/master/recipe/laravel.php#L146) - -Cache the framework bootstrap files. - - - - -### artisan:optimize:clear -[Source](https://github.com/deployphp/deployer/blob/master/recipe/laravel.php#L149) - -Removes the cached bootstrap files. - - - - -### artisan:route:cache -[Source](https://github.com/deployphp/deployer/blob/master/recipe/laravel.php#L152) - -Creates a route cache file for faster route registration. - - - - -### artisan:route:clear -[Source](https://github.com/deployphp/deployer/blob/master/recipe/laravel.php#L155) - -Removes the route cache file. - - - - -### artisan:route:list -[Source](https://github.com/deployphp/deployer/blob/master/recipe/laravel.php#L158) - -Lists all registered routes. - - - - -### artisan:storage:link -[Source](https://github.com/deployphp/deployer/blob/master/recipe/laravel.php#L161) - -Creates the symbolic links configured for the application. - - - - -### artisan:view:cache -[Source](https://github.com/deployphp/deployer/blob/master/recipe/laravel.php#L164) - -Compiles all of the application\'s Blade templates. - - - - -### artisan:view:clear -[Source](https://github.com/deployphp/deployer/blob/master/recipe/laravel.php#L167) - -Clears all compiled view files. - - - - -### artisan:queue:failed -[Source](https://github.com/deployphp/deployer/blob/master/recipe/laravel.php#L174) - -Lists all of the failed queue jobs. - - - - -### artisan:queue:flush -[Source](https://github.com/deployphp/deployer/blob/master/recipe/laravel.php#L177) - -Flushes all of the failed queue jobs. - - - - -### artisan:queue:restart -[Source](https://github.com/deployphp/deployer/blob/master/recipe/laravel.php#L180) - -Restarts queue worker daemons after their current job. - - - - -### artisan:horizon -[Source](https://github.com/deployphp/deployer/blob/master/recipe/laravel.php#L183) - -Starts a master supervisor in the foreground. - - - - -### artisan:horizon:clear -[Source](https://github.com/deployphp/deployer/blob/master/recipe/laravel.php#L186) - -Deletes all of the jobs from the specified queue. - - - - -### artisan:horizon:continue -[Source](https://github.com/deployphp/deployer/blob/master/recipe/laravel.php#L189) - -Instructs the master supervisor to continue processing jobs. - - - - -### artisan:horizon:list -[Source](https://github.com/deployphp/deployer/blob/master/recipe/laravel.php#L192) - -Lists all of the deployed machines. - - - - -### artisan:horizon:pause -[Source](https://github.com/deployphp/deployer/blob/master/recipe/laravel.php#L195) - -Pauses the master supervisor. - - - - -### artisan:horizon:purge -[Source](https://github.com/deployphp/deployer/blob/master/recipe/laravel.php#L198) - -Terminates any rogue Horizon processes. - - - - -### artisan:horizon:status -[Source](https://github.com/deployphp/deployer/blob/master/recipe/laravel.php#L201) - -Gets the current status of Horizon. - - - - -### artisan:horizon:terminate -[Source](https://github.com/deployphp/deployer/blob/master/recipe/laravel.php#L204) - -Terminates the master supervisor so it can be restarted. - - - - -### artisan:​telescope:clear -[Source](https://github.com/deployphp/deployer/blob/master/recipe/laravel.php#L211) - -Clears all entries from Telescope. - - - - -### artisan:​telescope:prune -[Source](https://github.com/deployphp/deployer/blob/master/recipe/laravel.php#L214) - -Prunes stale entries from the Telescope database. - - - - -### deploy -[Source](https://github.com/deployphp/deployer/blob/master/recipe/laravel.php#L220) - -Deploys your project. - -Main deploy task. - - -This task is group task which contains next tasks: -* [deploy:prepare](/docs/recipe/common.md#deployprepare) -* [deploy:vendors](/docs/recipe/deploy/vendors.md#deployvendors) -* [artisan:storage:link](/docs/recipe/laravel.md#artisanstoragelink) -* [artisan:config:cache](/docs/recipe/laravel.md#artisanconfigcache) -* [artisan:route:cache](/docs/recipe/laravel.md#artisanroutecache) -* [artisan:view:cache](/docs/recipe/laravel.md#artisanviewcache) -* [artisan:event:cache](/docs/recipe/laravel.md#artisaneventcache) -* [artisan:migrate](/docs/recipe/laravel.md#artisanmigrate) -* [deploy:publish](/docs/recipe/common.md#deploypublish) - - diff --git a/docs/recipe/magento.md b/docs/recipe/magento.md deleted file mode 100644 index f4cce52fe..000000000 --- a/docs/recipe/magento.md +++ /dev/null @@ -1,81 +0,0 @@ - - - - -# magento - -[Source](/recipe/magento.php) - -* Requires - * [common](/docs/recipe/common.md) - -## Configuration -### shared_dirs -[Source](https://github.com/deployphp/deployer/blob/master/recipe/magento.php#L13) - -Overrides [shared_dirs](/docs/recipe/deploy/shared.md#shared_dirs) from `recipe/deploy/shared.php`. - -Magento shared dirs - -```php title="Default value" -['var', 'media'] -``` - - -### shared_files -[Source](https://github.com/deployphp/deployer/blob/master/recipe/magento.php#L16) - -Overrides [shared_files](/docs/recipe/deploy/shared.md#shared_files) from `recipe/deploy/shared.php`. - -Magento shared files - -```php title="Default value" -['app/etc/local.xml'] -``` - - -### writable_dirs -[Source](https://github.com/deployphp/deployer/blob/master/recipe/magento.php#L19) - -Overrides [writable_dirs](/docs/recipe/deploy/writable.md#writable_dirs) from `recipe/deploy/writable.php`. - -Magento writable dirs - -```php title="Default value" -['var', 'media'] -``` - - - -## Tasks - -### deploy:cache:clear -[Source](https://github.com/deployphp/deployer/blob/master/recipe/magento.php#L25) - -Clears cache. - -Clear cache - - -### deploy:clear_version -[Source](https://github.com/deployphp/deployer/blob/master/recipe/magento.php#L32) - - - -Remove files that can be used to compromise Magento - - -### deploy -[Source](https://github.com/deployphp/deployer/blob/master/recipe/magento.php#L46) - -Deploys your project. - -Main task - - -This task is group task which contains next tasks: -* [deploy:prepare](/docs/recipe/common.md#deployprepare) -* [deploy:cache:clear](/docs/recipe/magento.md#deploycacheclear) -* [deploy:publish](/docs/recipe/common.md#deploypublish) - - diff --git a/docs/recipe/magento2.md b/docs/recipe/magento2.md deleted file mode 100644 index aaea6bf9e..000000000 --- a/docs/recipe/magento2.md +++ /dev/null @@ -1,266 +0,0 @@ - - - - -# magento2 - -[Source](/recipe/magento2.php) - -* Requires - * [common](/docs/recipe/common.md) - -## Configuration -### static_content_locales -[Source](https://github.com/deployphp/deployer/blob/master/recipe/magento2.php#L20) - -By default setup:static-content:deploy uses `en_US`. -To change that, simply put `set('static_content_locales', 'en_US de_DE');` -in you deployer script. - -```php title="Default value" -'en_US' -``` - - -### magento_themes -[Source](https://github.com/deployphp/deployer/blob/master/recipe/magento2.php#L26) - -You can also set the themes to run against. By default it'll deploy -all themes - `add('magento_themes', ['Magento/luma', 'Magento/backend']);` - -```php title="Default value" -[ - -] -``` - - -### static_content_jobs -[Source](https://github.com/deployphp/deployer/blob/master/recipe/magento2.php#L34) - -Also set the number of conccurent jobs to run. The default is 1 -Update using: `set('static_content_jobs', '1');` - -```php title="Default value" -'1' -``` - - -### content_version -[Source](https://github.com/deployphp/deployer/blob/master/recipe/magento2.php#L36) - - - - - -### shared_files -[Source](https://github.com/deployphp/deployer/blob/master/recipe/magento2.php#L40) - -Overrides [shared_files](/docs/recipe/deploy/shared.md#shared_files) from `recipe/deploy/shared.php`. - - - -```php title="Default value" -[ - 'app/etc/env.php', - 'var/.maintenance.ip', -] -``` - - -### shared_dirs -[Source](https://github.com/deployphp/deployer/blob/master/recipe/magento2.php#L44) - -Overrides [shared_dirs](/docs/recipe/deploy/shared.md#shared_dirs) from `recipe/deploy/shared.php`. - - - -```php title="Default value" -[ - 'var/composer_home', - 'var/log', - 'var/export', - 'var/report', - 'var/import', - 'var/import_history', - 'var/session', - 'var/importexport', - 'var/backups', - 'var/tmp', - 'pub/sitemap', - 'pub/media' -] -``` - - -### writable_dirs -[Source](https://github.com/deployphp/deployer/blob/master/recipe/magento2.php#L58) - -Overrides [writable_dirs](/docs/recipe/deploy/writable.md#writable_dirs) from `recipe/deploy/writable.php`. - - - -```php title="Default value" -[ - 'var', - 'pub/static', - 'pub/media', - 'generated' -] -``` - - -### clear_paths -[Source](https://github.com/deployphp/deployer/blob/master/recipe/magento2.php#L64) - -Overrides [clear_paths](/docs/recipe/deploy/clear_paths.md#clear_paths) from `recipe/deploy/clear_paths.php`. - - - -```php title="Default value" -[ - 'generated/*', - 'pub/static/_cache/*', - 'var/generation/*', - 'var/cache/*', - 'var/page_cache/*', - 'var/view_preprocessed/*' -] -``` - - -### magento_version -[Source](https://github.com/deployphp/deployer/blob/master/recipe/magento2.php#L73) - - - - - -### maintenance_mode_status_active -[Source](https://github.com/deployphp/deployer/blob/master/recipe/magento2.php#L80) - - - - - -### enable_zerodowntime -[Source](https://github.com/deployphp/deployer/blob/master/recipe/magento2.php#L87) - -Deploy without setting maintenance mode if possible - -```php title="Default value" -true -``` - - - -## Tasks - -### magento:compile -[Source](https://github.com/deployphp/deployer/blob/master/recipe/magento2.php#L91) - -Compiles magento di. - -Tasks - - -### magento:deploy:assets -[Source](https://github.com/deployphp/deployer/blob/master/recipe/magento2.php#L98) - -Deploys assets. - - - - -### magento:sync:content_version -[Source](https://github.com/deployphp/deployer/blob/master/recipe/magento2.php#L111) - -Syncs content version. - - - - -### magento:maintenance:enable -[Source](https://github.com/deployphp/deployer/blob/master/recipe/magento2.php#L121) - -Enables maintenance mode. - - - - -### magento:maintenance:disable -[Source](https://github.com/deployphp/deployer/blob/master/recipe/magento2.php#L126) - -Disables maintenance mode. - - - - -### magento:config:import -[Source](https://github.com/deployphp/deployer/blob/master/recipe/magento2.php#L131) - -Config Import. - - - - -### magento:upgrade:db -[Source](https://github.com/deployphp/deployer/blob/master/recipe/magento2.php#L166) - -Upgrades magento database. - - - - -### magento:cache:flush -[Source](https://github.com/deployphp/deployer/blob/master/recipe/magento2.php#L193) - -Flushes Magento Cache. - - - - -### deploy:magento -[Source](https://github.com/deployphp/deployer/blob/master/recipe/magento2.php#L198) - -Magento2 deployment operations. - - - - -This task is group task which contains next tasks: -* [magento:build](/docs/recipe/magento2.md#magentobuild) -* [magento:config:import](/docs/recipe/magento2.md#magentoconfigimport) -* [magento:upgrade:db](/docs/recipe/magento2.md#magentoupgradedb) -* [magento:cache:flush](/docs/recipe/magento2.md#magentocacheflush) - - -### magento:build -[Source](https://github.com/deployphp/deployer/blob/master/recipe/magento2.php#L206) - -Magento2 build operations. - - - - -This task is group task which contains next tasks: -* [magento:compile](/docs/recipe/magento2.md#magentocompile) -* [magento:deploy:assets](/docs/recipe/magento2.md#magentodeployassets) - - -### deploy -[Source](https://github.com/deployphp/deployer/blob/master/recipe/magento2.php#L212) - -Deploys your project. - - - - -This task is group task which contains next tasks: -* [deploy:prepare](/docs/recipe/common.md#deployprepare) -* [deploy:vendors](/docs/recipe/deploy/vendors.md#deployvendors) -* [deploy:clear_paths](/docs/recipe/deploy/clear_paths.md#deployclear_paths) -* [deploy:magento](/docs/recipe/magento2.md#deploymagento) -* [deploy:publish](/docs/recipe/common.md#deploypublish) - - diff --git a/docs/recipe/pimcore.md b/docs/recipe/pimcore.md deleted file mode 100644 index 1e1f90977..000000000 --- a/docs/recipe/pimcore.md +++ /dev/null @@ -1,51 +0,0 @@ - - - - -# pimcore - -[Source](/recipe/pimcore.php) - -* Requires - * [symfony](/docs/recipe/symfony.md) - - -## Tasks - -### pimcore:rebuild-classes -[Source](https://github.com/deployphp/deployer/blob/master/recipe/pimcore.php#L15) - -Rebuilds Pimcore Classes. - - - - -### pimcore:custom-layouts-rebuild -[Source](https://github.com/deployphp/deployer/blob/master/recipe/pimcore.php#L20) - -Creates Custom Layouts. - - - - -### pimcore:cache_clear -[Source](https://github.com/deployphp/deployer/blob/master/recipe/pimcore.php#L25) - -Removes cache. - - - - -### pimcore:deploy -[Source](https://github.com/deployphp/deployer/blob/master/recipe/pimcore.php#L29) - - - - - - -This task is group task which contains next tasks: -* [pimcore:rebuild-classes](/docs/recipe/pimcore.md#pimcorerebuild-classes) -* [pimcore:custom-layouts-rebuild](/docs/recipe/pimcore.md#pimcorecustom-layouts-rebuild) - - diff --git a/docs/recipe/prestashop.md b/docs/recipe/prestashop.md deleted file mode 100644 index 3437b77c8..000000000 --- a/docs/recipe/prestashop.md +++ /dev/null @@ -1,90 +0,0 @@ - - - - -# prestashop - -[Source](/recipe/prestashop.php) - -* Requires - * [common](/docs/recipe/common.md) - -## Configuration -### shared_files -[Source](https://github.com/deployphp/deployer/blob/master/recipe/prestashop.php#L8) - -Overrides [shared_files](/docs/recipe/deploy/shared.md#shared_files) from `recipe/deploy/shared.php`. - - - -```php title="Default value" -[ - 'config/settings.inc.php', - '.htaccess', -] -``` - - -### shared_dirs -[Source](https://github.com/deployphp/deployer/blob/master/recipe/prestashop.php#L12) - -Overrides [shared_dirs](/docs/recipe/deploy/shared.md#shared_dirs) from `recipe/deploy/shared.php`. - - - -```php title="Default value" -[ - 'img', - 'log', - 'download', - 'upload', - 'translations', - 'mails', - 'themes/default-bootstrap/lang', - 'themes/default-bootstrap/mails', - 'themes/default-bootstrap/pdf/lang', -] -``` - - -### writable_dirs -[Source](https://github.com/deployphp/deployer/blob/master/recipe/prestashop.php#L23) - -Overrides [writable_dirs](/docs/recipe/deploy/writable.md#writable_dirs) from `recipe/deploy/writable.php`. - - - -```php title="Default value" -[ - 'img', - 'log', - 'cache', - 'download', - 'upload', - 'translations', - 'mails', - 'themes/default-bootstrap/lang', - 'themes/default-bootstrap/mails', - 'themes/default-bootstrap/pdf/lang', - 'themes/default-bootstrap/cache', -] -``` - - - -## Tasks - -### deploy -[Source](https://github.com/deployphp/deployer/blob/master/recipe/prestashop.php#L38) - -Deploys your project. - - - - -This task is group task which contains next tasks: -* [deploy:prepare](/docs/recipe/common.md#deployprepare) -* [deploy:vendors](/docs/recipe/deploy/vendors.md#deployvendors) -* [deploy:publish](/docs/recipe/common.md#deploypublish) - - diff --git a/docs/recipe/provision.md b/docs/recipe/provision.md deleted file mode 100644 index 68d50f6ca..000000000 --- a/docs/recipe/provision.md +++ /dev/null @@ -1,150 +0,0 @@ - - - - -# provision - -[Source](/recipe/provision.php) - -* Requires - * [databases](/docs/recipe/provision/databases.md) - * [nodejs](/docs/recipe/provision/nodejs.md) - * [php](/docs/recipe/provision/php.md) - * [website](/docs/recipe/provision/website.md) - -## Configuration -### lsb_release -[Source](https://github.com/deployphp/deployer/blob/master/recipe/provision.php#L15) - -Name of lsb_release like: focal, bionic, etc. -As only Ubuntu 20.04 LTS is supported for provision should be the `focal`. - - - -### sudo_password -[Source](https://github.com/deployphp/deployer/blob/master/recipe/provision.php#L216) - - - - - -### ssh_copy_id -[Source](https://github.com/deployphp/deployer/blob/master/recipe/provision.php#L222) - -Specify which key to copy to server. -Set to `false` to disable copy of key. - -```php title="Default value" -'~/.ssh/id_rsa.pub' -``` - - - -## Tasks - -### provision -[Source](https://github.com/deployphp/deployer/blob/master/recipe/provision.php#L20) - -Provision the server. - - - - -This task is group task which contains next tasks: -* [provision:check](/docs/recipe/provision.md#provisioncheck) -* [provision:configure](/docs/recipe/provision.md#provisionconfigure) -* [provision:update](/docs/recipe/provision.md#provisionupdate) -* [provision:upgrade](/docs/recipe/provision.md#provisionupgrade) -* [provision:install](/docs/recipe/provision.md#provisioninstall) -* [provision:ssh](/docs/recipe/provision.md#provisionssh) -* [provision:firewall](/docs/recipe/provision.md#provisionfirewall) -* [provision:deployer](/docs/recipe/provision.md#provisiondeployer) -* [provision:server](/docs/recipe/provision.md#provisionserver) -* [provision:php](/docs/recipe/provision/php.md#provisionphp) -* [provision:databases](/docs/recipe/provision/databases.md#provisiondatabases) -* [provision:composer](/docs/recipe/provision/php.md#provisioncomposer) -* [provision:npm](/docs/recipe/provision/nodejs.md#provisionnpm) -* [provision:website](/docs/recipe/provision/website.md#provisionwebsite) -* [provision:verify](/docs/recipe/provision.md#provisionverify) - - -### provision:check -[Source](https://github.com/deployphp/deployer/blob/master/recipe/provision.php#L39) - -Checks pre-required state. - - - - -### provision:configure -[Source](https://github.com/deployphp/deployer/blob/master/recipe/provision.php#L59) - -Collects required params. - - - - -### provision:update -[Source](https://github.com/deployphp/deployer/blob/master/recipe/provision.php#L82) - -Adds repositories and update. - - - - -### provision:upgrade -[Source](https://github.com/deployphp/deployer/blob/master/recipe/provision.php#L104) - -Upgrades all packages. - - - - -### provision:install -[Source](https://github.com/deployphp/deployer/blob/master/recipe/provision.php#L111) - -Installs packages. - - - - -### provision:server -[Source](https://github.com/deployphp/deployer/blob/master/recipe/provision.php#L145) - -Configures a server. - - - - -### provision:ssh -[Source](https://github.com/deployphp/deployer/blob/master/recipe/provision.php#L206) - -Configures the ssh. - - - - -### provision:deployer -[Source](https://github.com/deployphp/deployer/blob/master/recipe/provision.php#L225) - -Setups a deployer user. - - - - -### provision:firewall -[Source](https://github.com/deployphp/deployer/blob/master/recipe/provision.php#L272) - -Setups a firewall. - - - - -### provision:verify -[Source](https://github.com/deployphp/deployer/blob/master/recipe/provision.php#L280) - -Verifies what provision was successful. - - - - diff --git a/docs/recipe/provision/databases.md b/docs/recipe/provision/databases.md deleted file mode 100644 index f1cd0391b..000000000 --- a/docs/recipe/provision/databases.md +++ /dev/null @@ -1,73 +0,0 @@ - - - - -# databases - -[Source](/recipe/provision/databases.php) - - -## Configuration -### db_type -[Source](https://github.com/deployphp/deployer/blob/master/recipe/provision/databases.php#L4) - - - - - -### db_name -[Source](https://github.com/deployphp/deployer/blob/master/recipe/provision/databases.php#L14) - - - - - -### db_user -[Source](https://github.com/deployphp/deployer/blob/master/recipe/provision/databases.php#L18) - - - - - -### db_password -[Source](https://github.com/deployphp/deployer/blob/master/recipe/provision/databases.php#L22) - - - - - - -## Tasks - -### provision:databases -[Source](https://github.com/deployphp/deployer/blob/master/recipe/provision/databases.php#L27) - -Provision databases. - - - - -### provision:mysql -[Source](https://github.com/deployphp/deployer/blob/master/recipe/provision/databases.php#L37) - -Provision MySQL. - - - - -### provision:mariadb -[Source](https://github.com/deployphp/deployer/blob/master/recipe/provision/databases.php#L48) - -Provision MariaDB. - - - - -### provision:postgresql -[Source](https://github.com/deployphp/deployer/blob/master/recipe/provision/databases.php#L59) - -Provision PostgreSQL. - - - - diff --git a/docs/recipe/provision/nodejs.md b/docs/recipe/provision/nodejs.md deleted file mode 100644 index 1b93833e0..000000000 --- a/docs/recipe/provision/nodejs.md +++ /dev/null @@ -1,31 +0,0 @@ - - - - -# nodejs - -[Source](/recipe/provision/nodejs.php) - - -## Configuration -### nodejs_version -[Source](https://github.com/deployphp/deployer/blob/master/recipe/provision/nodejs.php#L5) - -Node.js version from https://github.com/nodesource/distributions. - -```php title="Default value" -'node_16.x' -``` - - - -## Tasks - -### provision:npm -[Source](https://github.com/deployphp/deployer/blob/master/recipe/provision/nodejs.php#L8) - -Installs npm packages. - - - - diff --git a/docs/recipe/provision/php.md b/docs/recipe/provision/php.md deleted file mode 100644 index a196f8799..000000000 --- a/docs/recipe/provision/php.md +++ /dev/null @@ -1,44 +0,0 @@ - - - - -# php - -[Source](/recipe/provision/php.php) - - -## Configuration -### php_version -[Source](https://github.com/deployphp/deployer/blob/master/recipe/provision/php.php#L4) - - - - - - -## Tasks - -### provision:php -[Source](https://github.com/deployphp/deployer/blob/master/recipe/provision/php.php#L9) - -Installs PHP packages. - - - - -### logs:php-fpm -[Source](https://github.com/deployphp/deployer/blob/master/recipe/provision/php.php#L60) - -Shows php-fpm logs. - - - - -### provision:composer -[Source](https://github.com/deployphp/deployer/blob/master/recipe/provision/php.php#L65) - -Installs Composer. - - - - diff --git a/docs/recipe/provision/website.md b/docs/recipe/provision/website.md deleted file mode 100644 index c453f6f66..000000000 --- a/docs/recipe/provision/website.md +++ /dev/null @@ -1,51 +0,0 @@ - - - - -# website - -[Source](/recipe/provision/website.php) - - -## Configuration -### domain -[Source](https://github.com/deployphp/deployer/blob/master/recipe/provision/website.php#L4) - - - - - -### public_path -[Source](https://github.com/deployphp/deployer/blob/master/recipe/provision/website.php#L8) - - - - - - -## Tasks - -### provision:website -[Source](https://github.com/deployphp/deployer/blob/master/recipe/provision/website.php#L13) - -Provision website. - - - - -### logs:caddy -[Source](https://github.com/deployphp/deployer/blob/master/recipe/provision/website.php#L82) - -Shows caddy logs. - - - - -### logs:caddy:syslog -[Source](https://github.com/deployphp/deployer/blob/master/recipe/provision/website.php#L87) - -Shows caddy syslog. - - - - diff --git a/docs/recipe/shopware.md b/docs/recipe/shopware.md deleted file mode 100644 index 38beeac8d..000000000 --- a/docs/recipe/shopware.md +++ /dev/null @@ -1,212 +0,0 @@ - - - - -# shopware - -[Source](/recipe/shopware.php) - -* Requires - * [common](/docs/recipe/common.md) - - -## Usage - -Add {{repository}} to your _deploy.php_ file: - -```php -set('repository', 'git@github.com:shopware/production.git'); -``` - -:::note -Please remember that the installation must be modified so that it can be -[build without database](https://developer.shopware.com/docs/guides/hosting/installation-updates/deployments/build-w-o-db#compiling-the-storefront-without-database). -::: - - -## Configuration -### default_timeout -[Source](https://github.com/deployphp/deployer/blob/master/recipe/shopware.php#L23) - -Overrides [default_timeout](/docs/recipe/common.md#default_timeout) from `recipe/common.php`. - - - - - -### shared_files -[Source](https://github.com/deployphp/deployer/blob/master/recipe/shopware.php#L26) - -Overrides [shared_files](/docs/recipe/deploy/shared.md#shared_files) from `recipe/deploy/shared.php`. - -These files are shared among all releases. - -```php title="Default value" -[ - '.env', - 'install.lock', - 'public/.htaccess', - 'public/.user.ini', -] -``` - - -### shared_dirs -[Source](https://github.com/deployphp/deployer/blob/master/recipe/shopware.php#L34) - -Overrides [shared_dirs](/docs/recipe/deploy/shared.md#shared_dirs) from `recipe/deploy/shared.php`. - -These directories are shared among all releases. - -```php title="Default value" -[ - 'config/jwt', - 'files', - 'var/log', - 'public/media', - 'public/thumbnail', - 'public/sitemap', -] -``` - - -### writable_dirs -[Source](https://github.com/deployphp/deployer/blob/master/recipe/shopware.php#L45) - -Overrides [writable_dirs](/docs/recipe/deploy/writable.md#writable_dirs) from `recipe/deploy/writable.php`. - -These directories are made writable (the definition of "writable" requires attention). -Please note that the files in `config/jwt/*` receive special attention in the `sw:writable:jwt` task. - -```php title="Default value" -[ - 'config/jwt', - 'custom/plugins', - 'files', - 'public/bundles', - 'public/css', - 'public/fonts', - 'public/js', - 'public/media', - 'public/sitemap', - 'public/theme', - 'public/thumbnail', - 'var', -] -``` - - - -## Tasks - -### sw:cache:clear -[Source](https://github.com/deployphp/deployer/blob/master/recipe/shopware.php#L61) - - - -This task remotely executes the `cache:clear` console command on the target server. - - -### sw:cache:warmup -[Source](https://github.com/deployphp/deployer/blob/master/recipe/shopware.php#L67) - - - -This task remotely executes the cache warmup console commands on the target server, so that the first user, who -visits the website, doesn't have to wait for the cache to be built up. - - -### sw:database:migrate -[Source](https://github.com/deployphp/deployer/blob/master/recipe/shopware.php#L73) - - - -This task remotely executes the `database:migrate` console command on the target server. - - -### sw:plugin:refresh -[Source](https://github.com/deployphp/deployer/blob/master/recipe/shopware.php#L77) - - - - - - -### sw:plugin:update:all -[Source](https://github.com/deployphp/deployer/blob/master/recipe/shopware.php#L113) - - - - - - -### sw:writable:jwt -[Source](https://github.com/deployphp/deployer/blob/master/recipe/shopware.php#L123) - - - - - - -### sw:deploy -[Source](https://github.com/deployphp/deployer/blob/master/recipe/shopware.php#L130) - - - -Grouped SW deploy tasks. - - -This task is group task which contains next tasks: -* [sw:database:migrate](/docs/recipe/shopware.md#swdatabasemigrate) -* [sw:plugin:refresh](/docs/recipe/shopware.md#swpluginrefresh) -* [sw:cache:clear](/docs/recipe/shopware.md#swcacheclear) -* [sw:plugin:update:all](/docs/recipe/shopware.md#swpluginupdateall) -* [sw:cache:clear](/docs/recipe/shopware.md#swcacheclear) - - -### deploy -[Source](https://github.com/deployphp/deployer/blob/master/recipe/shopware.php#L139) - -Deploys your project. - - - - -This task is group task which contains next tasks: -* [deploy:prepare](/docs/recipe/common.md#deployprepare) -* [sw:deploy](/docs/recipe/shopware.md#swdeploy) -* [deploy:clear_paths](/docs/recipe/deploy/clear_paths.md#deployclear_paths) -* [sw:cache:warmup](/docs/recipe/shopware.md#swcachewarmup) -* [sw:writable:jwt](/docs/recipe/shopware.md#swwritablejwt) -* [deploy:publish](/docs/recipe/common.md#deploypublish) - - -### sw-build-without-db:get-remote-config -[Source](https://github.com/deployphp/deployer/blob/master/recipe/shopware.php#L149) - - - - - - -### sw-build-without-db:build -[Source](https://github.com/deployphp/deployer/blob/master/recipe/shopware.php#L175) - - - - - - -### sw-build-without-db -[Source](https://github.com/deployphp/deployer/blob/master/recipe/shopware.php#L179) - - - - - - -This task is group task which contains next tasks: -* [sw-build-without-db:get-remote-config](/docs/recipe/shopware.md#sw-build-without-dbget-remote-config) -* [sw-build-without-db:build](/docs/recipe/shopware.md#sw-build-without-dbbuild) - - diff --git a/docs/recipe/silverstripe.md b/docs/recipe/silverstripe.md deleted file mode 100644 index ba9ae3b3c..000000000 --- a/docs/recipe/silverstripe.md +++ /dev/null @@ -1,88 +0,0 @@ - - - - -# silverstripe - -[Source](/recipe/silverstripe.php) - -* Requires - * [common](/docs/recipe/common.md) - -## Configuration -### shared_assets -[Source](https://github.com/deployphp/deployer/blob/master/recipe/silverstripe.php#L12) - - - - - -### shared_dirs -[Source](https://github.com/deployphp/deployer/blob/master/recipe/silverstripe.php#L21) - -Overrides [shared_dirs](/docs/recipe/deploy/shared.md#shared_dirs) from `recipe/deploy/shared.php`. - -Silverstripe shared dirs - -```php title="Default value" -[ - '{{shared_assets}}' -] -``` - - -### writable_dirs -[Source](https://github.com/deployphp/deployer/blob/master/recipe/silverstripe.php#L26) - -Overrides [writable_dirs](/docs/recipe/deploy/writable.md#writable_dirs) from `recipe/deploy/writable.php`. - -Silverstripe writable dirs - -```php title="Default value" -[ - '{{shared_assets}}' -] -``` - - -### silverstripe_cli_script -[Source](https://github.com/deployphp/deployer/blob/master/recipe/silverstripe.php#L31) - -Silverstripe cli script - - - - -## Tasks - -### silverstripe:build -[Source](https://github.com/deployphp/deployer/blob/master/recipe/silverstripe.php#L47) - -Runs /dev/build. - -Helper tasks - - -### silverstripe:buildflush -[Source](https://github.com/deployphp/deployer/blob/master/recipe/silverstripe.php#L52) - -Runs /dev/build?flush=all. - - - - -### deploy -[Source](https://github.com/deployphp/deployer/blob/master/recipe/silverstripe.php#L60) - -Deploys your project. - -Main task - - -This task is group task which contains next tasks: -* [deploy:prepare](/docs/recipe/common.md#deployprepare) -* [deploy:vendors](/docs/recipe/deploy/vendors.md#deployvendors) -* [silverstripe:buildflush](/docs/recipe/silverstripe.md#silverstripebuildflush) -* [deploy:publish](/docs/recipe/common.md#deploypublish) - - diff --git a/docs/recipe/statamic.md b/docs/recipe/statamic.md deleted file mode 100644 index 769ae3de9..000000000 --- a/docs/recipe/statamic.md +++ /dev/null @@ -1,176 +0,0 @@ - - - - -# statamic - -[Source](/recipe/statamic.php) - -* Requires - * [laravel](/docs/recipe/laravel.md) - -## Configuration -### statamic_version -[Source](https://github.com/deployphp/deployer/blob/master/recipe/statamic.php#L15) - - - - - - -## Tasks - -### statamic:addons:discover -[Source](https://github.com/deployphp/deployer/blob/master/recipe/statamic.php#L26) - -Rebuilds the cached addon package manifest. - - - - -### statamic:assets:generate-presets -[Source](https://github.com/deployphp/deployer/blob/master/recipe/statamic.php#L33) - -Generates asset preset manipulations. - - - - -### statamic:assets:meta -[Source](https://github.com/deployphp/deployer/blob/master/recipe/statamic.php#L36) - -Generates asset metadata files. - - - - -### statamic:git:commit -[Source](https://github.com/deployphp/deployer/blob/master/recipe/statamic.php#L43) - -Git add and commit tracked content. - - - - -### statamic:glide:clear -[Source](https://github.com/deployphp/deployer/blob/master/recipe/statamic.php#L50) - -Clears the Glide image cache. - - - - -### statamic:responsive:generate -[Source](https://github.com/deployphp/deployer/blob/master/recipe/statamic.php#L57) - -Generates responsive images. - - - - -### statamic:responsive:regenerate -[Source](https://github.com/deployphp/deployer/blob/master/recipe/statamic.php#L60) - -Regenerate responsive images. - - - - -### statamic:search:insert -[Source](https://github.com/deployphp/deployer/blob/master/recipe/statamic.php#L67) - -Inserts an item into its search indexes. - - - - -### statamic:search:update -[Source](https://github.com/deployphp/deployer/blob/master/recipe/statamic.php#L70) - -Update a search index. - - - - -### statamic:stache:clear -[Source](https://github.com/deployphp/deployer/blob/master/recipe/statamic.php#L77) - -Clears the "Stache" cache. - - - - -### statamic:stache:doctor -[Source](https://github.com/deployphp/deployer/blob/master/recipe/statamic.php#L80) - -Diagnose any problems with the Stache. - - - - -### statamic:stache:refresh -[Source](https://github.com/deployphp/deployer/blob/master/recipe/statamic.php#L83) - -Clears and rebuild the "Stache" cache. - - - - -### statamic:stache:warm -[Source](https://github.com/deployphp/deployer/blob/master/recipe/statamic.php#L86) - -Builds the "Stache" cache. - - - - -### statamic:static:clear -[Source](https://github.com/deployphp/deployer/blob/master/recipe/statamic.php#L93) - -Clears the static page cache. - - - - -### statamic:static:warm -[Source](https://github.com/deployphp/deployer/blob/master/recipe/statamic.php#L96) - -Warms the static cache by visiting all URLs. - - - - -### statamic:support:details -[Source](https://github.com/deployphp/deployer/blob/master/recipe/statamic.php#L103) - -Outputs details helpful for support requests. - - - - -### statamic:updates:run -[Source](https://github.com/deployphp/deployer/blob/master/recipe/statamic.php#L110) - -Runs update scripts from specific version. - - - - -### deploy -[Source](https://github.com/deployphp/deployer/blob/master/recipe/statamic.php#L118) - -Deploys your project. - - - - -This task is group task which contains next tasks: -* [deploy:prepare](/docs/recipe/common.md#deployprepare) -* [deploy:vendors](/docs/recipe/deploy/vendors.md#deployvendors) -* [artisan:storage:link](/docs/recipe/laravel.md#artisanstoragelink) -* [artisan:cache:clear](/docs/recipe/laravel.md#artisancacheclear) -* [statamic:stache:clear](/docs/recipe/statamic.md#statamicstacheclear) -* [statamic:stache:warm](/docs/recipe/statamic.md#statamicstachewarm) -* [deploy:publish](/docs/recipe/common.md#deploypublish) - - diff --git a/docs/recipe/sulu.md b/docs/recipe/sulu.md deleted file mode 100644 index 1b9b75970..000000000 --- a/docs/recipe/sulu.md +++ /dev/null @@ -1,46 +0,0 @@ - - - - -# sulu - -[Source](/recipe/sulu.php) - -* Requires - * [symfony](/docs/recipe/symfony.md) - -## Configuration -### bin/websiteconsole -[Source](https://github.com/deployphp/deployer/blob/master/recipe/sulu.php#L12) - - - - - - -## Tasks - -### phpcr:migrate -[Source](https://github.com/deployphp/deployer/blob/master/recipe/sulu.php#L17) - -Migrates PHPCR. - - - - -### deploy:website:cache:clear -[Source](https://github.com/deployphp/deployer/blob/master/recipe/sulu.php#L22) - -Clears cache. - - - - -### deploy:website:cache:warmup -[Source](https://github.com/deployphp/deployer/blob/master/recipe/sulu.php#L27) - -Warmups cache. - - - - diff --git a/docs/recipe/symfony.md b/docs/recipe/symfony.md deleted file mode 100644 index db34c525c..000000000 --- a/docs/recipe/symfony.md +++ /dev/null @@ -1,137 +0,0 @@ - - - - -# symfony - -[Source](/recipe/symfony.php) - -* Requires - * [common](/docs/recipe/common.md) - -## Configuration -### symfony_version -[Source](https://github.com/deployphp/deployer/blob/master/recipe/symfony.php#L8) - - - - - -### shared_dirs -[Source](https://github.com/deployphp/deployer/blob/master/recipe/symfony.php#L14) - -Overrides [shared_dirs](/docs/recipe/deploy/shared.md#shared_dirs) from `recipe/deploy/shared.php`. - - - -```php title="Default value" -[ - 'var/log', -] -``` - - -### shared_files -[Source](https://github.com/deployphp/deployer/blob/master/recipe/symfony.php#L18) - -Overrides [shared_files](/docs/recipe/deploy/shared.md#shared_files) from `recipe/deploy/shared.php`. - - - -```php title="Default value" -[ - '.env.local' -] -``` - - -### writable_dirs -[Source](https://github.com/deployphp/deployer/blob/master/recipe/symfony.php#L22) - -Overrides [writable_dirs](/docs/recipe/deploy/writable.md#writable_dirs) from `recipe/deploy/writable.php`. - - - -```php title="Default value" -[ - 'var', - 'var/cache', - 'var/log', - 'var/sessions', -] -``` - - -### migrations_config -[Source](https://github.com/deployphp/deployer/blob/master/recipe/symfony.php#L29) - - - - - -### doctrine_schema_validate_config -[Source](https://github.com/deployphp/deployer/blob/master/recipe/symfony.php#L31) - - - - - -### bin/console -[Source](https://github.com/deployphp/deployer/blob/master/recipe/symfony.php#L33) - - - -```php title="Default value" -'{{bin/php}} {{release_or_current_path}}/bin/console' -``` - - -### console_options -[Source](https://github.com/deployphp/deployer/blob/master/recipe/symfony.php#L35) - - - - - - -## Tasks - -### database:migrate -[Source](https://github.com/deployphp/deployer/blob/master/recipe/symfony.php#L40) - -Migrates database. - - - - -### doctrine:schema:validate -[Source](https://github.com/deployphp/deployer/blob/master/recipe/symfony.php#L50) - -Validate the Doctrine mapping files. - - - - -### deploy:cache:clear -[Source](https://github.com/deployphp/deployer/blob/master/recipe/symfony.php#L55) - -Clears cache. - - - - -### deploy -[Source](https://github.com/deployphp/deployer/blob/master/recipe/symfony.php#L64) - -Deploys project. - - - - -This task is group task which contains next tasks: -* [deploy:prepare](/docs/recipe/common.md#deployprepare) -* [deploy:vendors](/docs/recipe/deploy/vendors.md#deployvendors) -* [deploy:cache:clear](/docs/recipe/symfony.md#deploycacheclear) -* [deploy:publish](/docs/recipe/common.md#deploypublish) - - diff --git a/docs/recipe/typo3.md b/docs/recipe/typo3.md deleted file mode 100644 index 8c85e5e51..000000000 --- a/docs/recipe/typo3.md +++ /dev/null @@ -1,86 +0,0 @@ - - - - -# typo3 - -[Source](/recipe/typo3.php) - -* Requires - * [common](/docs/recipe/common.md) - -## Configuration -### typo3_webroot -[Source](https://github.com/deployphp/deployer/blob/master/recipe/typo3.php#L11) - -DocumentRoot / WebRoot for the TYPO3 installation - -```php title="Default value" -'Web' -``` - - -### shared_dirs -[Source](https://github.com/deployphp/deployer/blob/master/recipe/typo3.php#L26) - -Overrides [shared_dirs](/docs/recipe/deploy/shared.md#shared_dirs) from `recipe/deploy/shared.php`. - -Shared directories - -```php title="Default value" -[ - '{{typo3_webroot}}/fileadmin', - '{{typo3_webroot}}/typo3temp', - '{{typo3_webroot}}/uploads' -] -``` - - -### shared_files -[Source](https://github.com/deployphp/deployer/blob/master/recipe/typo3.php#L35) - -Overrides [shared_files](/docs/recipe/deploy/shared.md#shared_files) from `recipe/deploy/shared.php`. - -Shared files - -```php title="Default value" -[ - '{{typo3_webroot}}/.htaccess' -] -``` - - -### writable_dirs -[Source](https://github.com/deployphp/deployer/blob/master/recipe/typo3.php#L42) - -Overrides [writable_dirs](/docs/recipe/deploy/writable.md#writable_dirs) from `recipe/deploy/writable.php`. - -Writeable directories - -```php title="Default value" -[ - '{{typo3_webroot}}/fileadmin', - '{{typo3_webroot}}/typo3temp', - '{{typo3_webroot}}/typo3conf', - '{{typo3_webroot}}/uploads' -] -``` - - - -## Tasks - -### deploy -[Source](https://github.com/deployphp/deployer/blob/master/recipe/typo3.php#L17) - -Deploys your project. - -Main TYPO3 task - - -This task is group task which contains next tasks: -* [deploy:prepare](/docs/recipe/common.md#deployprepare) -* [deploy:vendors](/docs/recipe/deploy/vendors.md#deployvendors) -* [deploy:publish](/docs/recipe/common.md#deploypublish) - - diff --git a/docs/recipe/wordpress.md b/docs/recipe/wordpress.md deleted file mode 100644 index 4b28a589d..000000000 --- a/docs/recipe/wordpress.md +++ /dev/null @@ -1,64 +0,0 @@ - - - - -# wordpress - -[Source](/recipe/wordpress.php) - -* Requires - * [common](/docs/recipe/common.md) - -## Configuration -### shared_files -[Source](https://github.com/deployphp/deployer/blob/master/recipe/wordpress.php#L8) - -Overrides [shared_files](/docs/recipe/deploy/shared.md#shared_files) from `recipe/deploy/shared.php`. - - - -```php title="Default value" -['wp-config.php'] -``` - - -### shared_dirs -[Source](https://github.com/deployphp/deployer/blob/master/recipe/wordpress.php#L9) - -Overrides [shared_dirs](/docs/recipe/deploy/shared.md#shared_dirs) from `recipe/deploy/shared.php`. - - - -```php title="Default value" -['wp-content/uploads'] -``` - - -### writable_dirs -[Source](https://github.com/deployphp/deployer/blob/master/recipe/wordpress.php#L10) - -Overrides [writable_dirs](/docs/recipe/deploy/writable.md#writable_dirs) from `recipe/deploy/writable.php`. - - - -```php title="Default value" -['wp-content/uploads'] -``` - - - -## Tasks - -### deploy -[Source](https://github.com/deployphp/deployer/blob/master/recipe/wordpress.php#L13) - -Deploys your project. - - - - -This task is group task which contains next tasks: -* [deploy:prepare](/docs/recipe/common.md#deployprepare) -* [deploy:publish](/docs/recipe/common.md#deploypublish) - - diff --git a/docs/recipe/yii.md b/docs/recipe/yii.md deleted file mode 100644 index fba2df59c..000000000 --- a/docs/recipe/yii.md +++ /dev/null @@ -1,53 +0,0 @@ - - - - -# yii - -[Source](/recipe/yii.php) - -* Requires - * [common](/docs/recipe/common.md) - -## Configuration -### shared_dirs -[Source](https://github.com/deployphp/deployer/blob/master/recipe/yii.php#L9) - -Overrides [shared_dirs](/docs/recipe/deploy/shared.md#shared_dirs) from `recipe/deploy/shared.php`. - -Yii shared dirs - -```php title="Default value" -['runtime'] -``` - - -### writable_dirs -[Source](https://github.com/deployphp/deployer/blob/master/recipe/yii.php#L12) - -Overrides [writable_dirs](/docs/recipe/deploy/writable.md#writable_dirs) from `recipe/deploy/writable.php`. - -Yii writable dirs - -```php title="Default value" -['runtime'] -``` - - - -## Tasks - -### deploy -[Source](https://github.com/deployphp/deployer/blob/master/recipe/yii.php#L18) - -Deploys your project. - -Main task - - -This task is group task which contains next tasks: -* [deploy:prepare](/docs/recipe/common.md#deployprepare) -* [deploy:vendors](/docs/recipe/deploy/vendors.md#deployvendors) -* [deploy:publish](/docs/recipe/common.md#deploypublish) - - diff --git a/docs/recipe/zend_framework.md b/docs/recipe/zend_framework.md deleted file mode 100644 index e3391befc..000000000 --- a/docs/recipe/zend_framework.md +++ /dev/null @@ -1,28 +0,0 @@ - - - - -# zend_framework - -[Source](/recipe/zend_framework.php) - -* Requires - * [common](/docs/recipe/common.md) - - -## Tasks - -### deploy -[Source](https://github.com/deployphp/deployer/blob/master/recipe/zend_framework.php#L12) - -Deploys your project. - -Main task - - -This task is group task which contains next tasks: -* [deploy:prepare](/docs/recipe/common.md#deployprepare) -* [deploy:vendors](/docs/recipe/deploy/vendors.md#deployvendors) -* [deploy:publish](/docs/recipe/common.md#deploypublish) - - diff --git a/docs/sidebar.js b/docs/sidebar.js deleted file mode 100644 index 6c9281922..000000000 --- a/docs/sidebar.js +++ /dev/null @@ -1,26 +0,0 @@ -module.exports = [ - 'installation', - 'getting-started', - 'basics', - { - type: 'category', - label: 'Main Concepts', - items: [ - 'hosts', - 'tasks', - ], - }, - 'ci-cd', - 'yaml', - 'cli', - 'api', - { - type: 'category', - label: 'Other', - items: [ - 'avoid-php-fpm-reloading', - 'UPGRADE', - 'KNOWN_BUGS', - ], - }, -] diff --git a/docs/tasks.md b/docs/tasks.md deleted file mode 100644 index 9657178e9..000000000 --- a/docs/tasks.md +++ /dev/null @@ -1,135 +0,0 @@ -# Tasks - -Define a tasks by using the [task](api.md#task) function. Also, you can give a description -for a task with the [desc](api.md#desc) function called before _task_: - -```php -desc('My task'); -task('my_task', function () { - .... -}); -``` - -To get the task or override task config call the _task_ function without second argument: - -```php -task('my_task')->disable(); -``` - - -## Task config - -### desc() - -Sets task's description. - -```php -task('deploy', function () { - // ... -})->desc('Task description'); -``` - -Same as using [desc()](api.md#desc) func helper: - -```php -desc('Task description'); -task('deploy', function () { - // ... -}); -``` - -### once() - -Sets the task to run only on one of selected hosts. - -### oncePerNode() - -Sets the task to run only on **one node** of selected hosts. - -Node determined by [hostname](hosts.md#hostname). For example a few different -hosts can be deploying to one physical machine (uniq hostname). - -```php -host('foo')->setHostname('example.com'); -host('bar')->setHostname('example.com'); -host('pro')->setHostname('another.com'); - -task('apt:update', function () { - // This task will be executed twise, only on "foo" and "pro" hosts. - run('apt-get update'); -})->oncePerNode(); -``` - -### hidden() - -Hides task from CLI usage page. - -### addBefore() - -Adds before hook to the task. - -### addAfter() - -Adds after hook to the task. - -### limit() - -Limits number of hosts the task will be executed in parallel. - -Default is unlimited (runs the task on all host in parallel). - -### select() - -Sets task's host selector. - -### addSelector() - -Adds task's selector. - -### verbose() - -Makes task always verbose. As if `-v` option persists. - -### disable() - -Disables the task. Task will not be executed. - -### enable() - -Enables the task. - - -## Task grouping - -You can combine tasks in groups: - -```php -task('deploy', [ - 'deploy:prepare', - 'deploy:update_code', - 'deploy:vendors', - 'deploy:symlink', - 'cleanup' -]); -``` - -## Task hooks - -You can define tasks to be run before or after specific tasks. - -```php -task('deploy:done', function () { - write('Deploy done!'); -}); - -after('deploy', 'deploy:done'); -``` - -After the `deploy` task executed, `deploy:done` will be triggered. - -:::note -You can see which hooks is enabled via **dep tree** command. -``` -dep tree deploy -``` -::: diff --git a/docs/yaml.md b/docs/yaml.md deleted file mode 100644 index dfaba6ffd..000000000 --- a/docs/yaml.md +++ /dev/null @@ -1,31 +0,0 @@ -# YAML - -Deployer supports recipes written in YAML. For validating structure, Deployer uses -JSON Schema declared in [schema.json](https://github.com/deployphp/deployer/blob/master/src/schema.json). - -Here is an example of YAML recipe: - -```yaml -import: - - recipe/laravel.php - -config: - repository: 'git@github.com:example/example.com.git' - remote_user: deployer - -hosts: - example.com: - deploy_path: '~/example' - -tasks: - build: - - cd: '{{release_path}}' - - run: 'npm run build' - -after: - deploy:failed: deploy:unlock -``` - -YAML recipes can include recipes written in PHP. For example, some tasks maybe written in PHP and imported in YAML. - -Also, other way around is possible: import YAML recipe from PHP. Use [import()](api.md#import) function for that. diff --git a/recipe/cakephp.php b/recipe/cakephp.php deleted file mode 100644 index 451d1a995..000000000 --- a/recipe/cakephp.php +++ /dev/null @@ -1,48 +0,0 @@ -desc('Initialization'); - -/** - * Run migrations - */ -task('deploy:run_migrations', function () { - run('{{bin/php}} {{release_or_current_path}}/bin/cake.php migrations migrate --no-lock'); - run('{{bin/php}} {{release_or_current_path}}/bin/cake.php schema_cache build'); -})->desc('Run migrations'); - -/** - * Main task - */ -task('deploy', [ - 'deploy:prepare', - 'deploy:vendors', - 'deploy:init', - 'deploy:run_migrations', - 'deploy:publish', -])->desc('Deploy your project'); diff --git a/recipe/codeigniter.php b/recipe/codeigniter.php deleted file mode 100644 index 086271152..000000000 --- a/recipe/codeigniter.php +++ /dev/null @@ -1,22 +0,0 @@ - 'something', - * ]); - * ``` - * - * It is possible to override it per `run()` call. - * - * ```php - * run('echo $KEY', env: ['KEY' => 'over']); - * ``` - */ -set('env', []); - -/** - * Path to `.env` file which will be used as environment variables for each command per `run()`. - * - * ```php - * set('dotenv', '{{current_path}}/.env'); - * ``` - */ -set('dotenv', false); - -/** - * The deploy path. - * - * For example can be set for a bunch of host once as: - * ```php - * set('deploy_path', '~/{{alias}}'); - * ``` - */ -set('deploy_path', function () { - throw new ConfigurationException('Please, specify `deploy_path`.'); -}); - -/** - * Return current release path. Default to {{deploy_path}}/`current`. - * ```php - * set('current_path', '/var/public_html'); - * ``` - */ -set('current_path', '{{deploy_path}}/current'); - -// Path to the `php` bin. -set('bin/php', function () { - if (currentHost()->hasOwn('php_version')) { - return '/usr/bin/php{{php_version}}'; - } - return which('php'); -}); - -// Path to the `git` bin. -set('bin/git', function () { - return which('git'); -}); - -// Should {{bin/symlink}} use `--relative` option or not. Will detect -// automatically. -set('use_relative_symlink', function () { - return commandSupportsOption('ln', '--relative'); -}); - -// Path to the `ln` bin. With predefined options `-nfs`. -set('bin/symlink', function () { - return get('use_relative_symlink') ? 'ln -nfs --relative' : 'ln -nfs'; -}); - -// Path to a file which will store temp script with sudo password. -// Defaults to `.dep/sudo_pass`. This script is only temporary and will be deleted after -// sudo command executed. -set('sudo_askpass', function () { - if (test('[ -d {{deploy_path}}/.dep ]')) { - return '{{deploy_path}}/.dep/sudo_pass'; - } else { - return '/tmp/dep_sudo_pass'; - } -}); - -desc('Prepares a new release'); -task('deploy:prepare', [ - 'deploy:info', - 'deploy:setup', - 'deploy:lock', - 'deploy:release', - 'deploy:update_code', - 'deploy:shared', - 'deploy:writable', -]); - -desc('Publishes the release'); -task('deploy:publish', [ - 'deploy:symlink', - 'deploy:unlock', - 'deploy:cleanup', - 'deploy:success', -]); - -/** - * Prints success message - */ -task('deploy:success', function () { - info('successfully deployed!'); -}) - ->hidden(); - - -/** - * Hook on deploy failure. - */ -task('deploy:failed', function () { -}) - ->hidden(); - -fail('deploy', 'deploy:failed'); - -/** - * Follows latest application logs. - */ -desc('Shows application logs'); -task('logs:app', function () { - if (!has('log_files')) { - warning("Please, specify \"log_files\" option."); - return; - } - cd('{{current_path}}'); - run('tail -f {{log_files}}'); -})->verbose(); diff --git a/recipe/composer.php b/recipe/composer.php deleted file mode 100644 index 4021b3c60..000000000 --- a/recipe/composer.php +++ /dev/null @@ -1,13 +0,0 @@ - contao-manager/login.lock'); -}); - -desc('Enable maintenance mode'); -task('contao:maintenance:enable', function () { - // Enable maintenance mode in both the current and release build, so that the maintenance mode will be enabled - // for the current installation before the symlink changes and the new installation after the symlink changed. - foreach (array_unique([parse('{{current_path}}'), parse('{{release_or_current_path}}')]) as $path) { - // The current path might not be present during first deploy. - if (!test("[ -d $path ]")) { - continue; - } - - cd($path); - run('{{bin/console}} contao:maintenance-mode enable {{console_options}}'); - } -}); - -desc('Disable maintenance mode'); -task('contao:maintenance:disable', function () { - foreach (array_unique([parse('{{current_path}}'), parse('{{release_or_current_path}}')]) as $path) { - if (!test("[ -d $path ]")) { - continue; - } - - cd($path); - run('{{bin/console}} contao:maintenance-mode disable {{console_options}}'); - } -}); - -desc('Deploy the project'); -task('deploy', [ - 'deploy:prepare', - 'deploy:vendors', - 'contao:maintenance:enable', - 'contao:migrate', - 'contao:maintenance:disable', - 'deploy:publish', -]); diff --git a/recipe/deploy/check_remote.php b/recipe/deploy/check_remote.php deleted file mode 100644 index 350680b6a..000000000 --- a/recipe/deploy/check_remote.php +++ /dev/null @@ -1,49 +0,0 @@ -getOption('revision'); - - if (!$targetRevision) { - $ref = 'HEAD'; - $opt = ''; - if ($tag = input()->getOption('tag')) { - $ref = $tag; - $opt = '--tags'; - } elseif ($branch = get('branch')) { - $ref = $branch; - $opt = '--heads'; - } - $remoteLs = runLocally("git ls-remote $opt $repository $ref"); - if (strstr($remoteLs, "\n")) { - throw new Exception("Could not determine target revision. '$ref' matched multiple commits."); - } - if (!$remoteLs) { - throw new Exception("Could not resolve a revision from '$ref'."); - } - $targetRevision = substr($remoteLs, 0, strpos($remoteLs, "\t")); - } - - // Compare commit hashes. We use strpos to support short versions. - $targetRevision = trim($targetRevision); - $lastDeployedRevision = run('cat {{current_path}}/REVISION'); - if ($targetRevision && strpos($lastDeployedRevision, $targetRevision) === 0) { - throw new GracefulShutdownException("Already up-to-date."); - } - - info("deployed different version"); -}); diff --git a/recipe/deploy/cleanup.php b/recipe/deploy/cleanup.php deleted file mode 100644 index dfc6fe0cc..000000000 --- a/recipe/deploy/cleanup.php +++ /dev/null @@ -1,20 +0,0 @@ - 0) { - foreach (array_slice($releases, $keep) as $release) { - run("$sudo rm -rf {{deploy_path}}/releases/$release"); - } - } -}); diff --git a/recipe/deploy/clear_paths.php b/recipe/deploy/clear_paths.php deleted file mode 100644 index 938f3da5f..000000000 --- a/recipe/deploy/clear_paths.php +++ /dev/null @@ -1,24 +0,0 @@ -{{target}}"); -}); diff --git a/recipe/deploy/lock.php b/recipe/deploy/lock.php deleted file mode 100644 index f436ab728..000000000 --- a/recipe/deploy/lock.php +++ /dev/null @@ -1,32 +0,0 @@ - {{deploy_path}}/.dep/deploy.lock"); - if ($locked === '+locked') { - $lockedUser = run("cat {{deploy_path}}/.dep/deploy.lock"); - throw new GracefulShutdownException( - "Deploy locked by $lockedUser.\n" . - "Execute \"deploy:unlock\" task to unlock." - ); - } -}); - -desc('Unlocks deploy'); -task('deploy:unlock', function () { - run("rm -f {{deploy_path}}/.dep/deploy.lock");//always success -}); - -desc('Checks if deploy is locked'); -task('deploy:is_locked', function () { - $locked = test("[ -f {{deploy_path}}/.dep/deploy.lock ]"); - if ($locked) { - $lockedUser = run("cat {{deploy_path}}/.dep/deploy.lock"); - throw new GracefulShutdownException("Deploy is locked by $lockedUser."); - } - info('Deploy is unlocked.'); -}); diff --git a/recipe/deploy/push.php b/recipe/deploy/push.php deleted file mode 100644 index 1c51a90f5..000000000 --- a/recipe/deploy/push.php +++ /dev/null @@ -1,24 +0,0 @@ - false, 'options' => ['--relative']] - ); - - // Mark this release as dirty. - run("echo '{{user}}' > {{current_path}}/DIRTY_RELEASE"); -}); diff --git a/recipe/deploy/release.php b/recipe/deploy/release.php deleted file mode 100644 index ed09bbd00..000000000 --- a/recipe/deploy/release.php +++ /dev/null @@ -1,194 +0,0 @@ -= 0; --$i) { - $release = $releasesLog[$i]['release_name']; - if (in_array($release, $ll, true)) { - $releases[] = $release; - } - } - return $releases; -}); - -// Return release path. -set('release_path', function () { - $releaseExists = test('[ -h {{deploy_path}}/release ]'); - if ($releaseExists) { - $link = run("readlink {{deploy_path}}/release"); - return substr($link, 0, 1) === '/' ? $link : get('deploy_path') . '/' . $link; - } else { - throw new Exception(parse('The "release_path" ({{deploy_path}}/release) does not exist.')); - } -}); - -// Current release revision. Usually a git hash. -set('release_revision', function () { - return run('cat {{release_path}}/REVISION'); -}); - -// Return the release path during a deployment -// but fallback to the current path otherwise. -set('release_or_current_path', function () { - $releaseExists = test('[ -h {{deploy_path}}/release ]'); - return $releaseExists ? get('release_path') : get('current_path'); -}); - -// Clean up unfinished releases and prepare next release -desc('Prepares release'); -task('deploy:release', function () { - cd('{{deploy_path}}'); - - // Clean up if there is unfinished release. - if (test('[ -h release ]')) { - run('rm -rf "$(readlink release)"'); // Delete release. - run('rm release'); // Delete symlink. - } - - // We need to get releases_list at same point as release_name, - // as standard release_name's implementation depends on it and, - // if user overrides it, we need to get releases_list manually. - $releasesList = get('releases_list'); - $releaseName = get('release_name'); - $releasePath = "releases/$releaseName"; - - // Check what there is no such release path. - if (test("[ -d $releasePath ]")) { - throw new Exception("Release name \"$releaseName\" already exists.\nRelease name can be overridden via:\n dep deploy -o release_name=$releaseName"); - } - - // Save release_name. - if (is_numeric($releaseName) && is_integer(intval($releaseName))) { - run("echo $releaseName > .dep/latest_release"); - } - - // Metainfo. - $timestamp = timestamp(); - $metainfo = [ - 'created_at' => $timestamp, - 'release_name' => $releaseName, - 'user' => get('user'), - 'target' => get('target'), - ]; - - // Save metainfo about release. - $json = json_encode($metainfo); - run("echo '$json' >> .dep/releases_log"); - - // Make new release. - run("mkdir -p $releasePath"); - run("{{bin/symlink}} $releasePath {{deploy_path}}/release"); - - // Add to releases list. - array_unshift($releasesList, $releaseName); - set('releases_list', $releasesList); - - // Set previous_release. - if (isset($releasesList[1])) { - set('previous_release', "{{deploy_path}}/releases/{$releasesList[1]}"); - } -}); - -desc('Shows releases list'); -/* - * Example output: - * ``` - * +---------------------+------example.org ------------+--------+-----------+ - * | Date (UTC) | Release | Author | Target | Commit | - * +---------------------+-------------+----------------+--------+-----------+ - * | 2021-11-06 20:51:45 | 1 | Anton Medvedev | HEAD | 34d24192e | - * | 2021-11-06 21:00:50 | 2 (bad) | Anton Medvedev | HEAD | 392948a40 | - * | 2021-11-06 23:19:20 | 3 | Anton Medvedev | HEAD | a4057a36c | - * | 2021-11-06 23:24:30 | 4 (current) | Anton Medvedev | HEAD | s3wa45ca6 | - * +---------------------+-------------+----------------+--------+-----------+ - * ``` - */ -task('releases', function () { - cd('{{deploy_path}}'); - - $releasesLog = get('releases_log'); - $currentRelease = basename(run('readlink {{current_path}}')); - $releasesList = get('releases_list'); - - $table = []; - $tz = !empty(getenv('TIMEZONE')) ? getenv('TIMEZONE') : date_default_timezone_get(); - - foreach ($releasesLog as &$metainfo) { - $date = \DateTime::createFromFormat(\DateTimeInterface::ISO8601, $metainfo['created_at']); - $date->setTimezone(new \DateTimeZone($tz)); - $status = $release = $metainfo['release_name']; - if (in_array($release, $releasesList, true)) { - if (test("[ -f releases/$release/BAD_RELEASE ]")) { - $status = "$release (bad)"; - } else if (test("[ -f releases/$release/DIRTY_RELEASE ]")) { - $status = "$release (dirty)"; - } else { - $status = "$release"; - } - } - if ($release === $currentRelease) { - $status .= ' (current)'; - } - try { - $revision = run("cat releases/$release/REVISION"); - } catch (\Throwable $e) { - $revision = 'unknown'; - } - $table[] = [ - $date->format("Y-m-d H:i:s"), - $status, - $metainfo['user'], - $metainfo['target'], - $revision, - ]; - } - - (new Table(output())) - ->setHeaderTitle(currentHost()->getAlias()) - ->setHeaders(["Date ($tz)", 'Release', 'Author', 'Target', 'Commit']) - ->setRows($table) - ->render(); -}); diff --git a/recipe/deploy/rollback.php b/recipe/deploy/rollback.php deleted file mode 100644 index b851e0a4f..000000000 --- a/recipe/deploy/rollback.php +++ /dev/null @@ -1,90 +0,0 @@ -$currentRelease."); - - if (!test("[ -d releases/$candidate ]")) { - throw new \RuntimeException(parse("Release \"$candidate\" not found in \"{{deploy_path}}/releases\".")); - } - if (test("[ -f releases/$candidate/BAD_RELEASE ]")) { - writeln("Candidate $candidate marked as bad release."); - if (!askConfirmation("Continue rollback to $candidate?")) { - writeln('Rollback aborted.'); - return; - } - } - writeln("Rolling back to $candidate release."); - - // Symlink to old release. - run("{{bin/symlink}} releases/$candidate {{current_path}}"); - - // Mark release as bad. - $timestamp = timestamp(); - run("echo '$timestamp,{{user}}' > releases/$currentRelease/BAD_RELEASE"); - - writeln("rollback to release $candidate was successful"); -}); diff --git a/recipe/deploy/setup.php b/recipe/deploy/setup.php deleted file mode 100644 index 84f1839c7..000000000 --- a/recipe/deploy/setup.php +++ /dev/null @@ -1,20 +0,0 @@ -getVerbosity() === OutputInterface::VERBOSITY_DEBUG ? 'v' : ''; - - foreach (get('shared_dirs') as $dir) { - // Make sure all path without tailing slash. - $dir = trim($dir, '/'); - - // Check if shared dir does not exist. - if (!test("[ -d $sharedPath/$dir ]")) { - // Create shared dir if it does not exist. - run("mkdir -p $sharedPath/$dir"); - // If release contains shared dir, copy that dir from release to shared. - if (test("[ -d $(echo {{release_path}}/$dir) ]")) { - run("cp -r$copyVerbosity {{release_path}}/$dir $sharedPath/" . dirname($dir)); - } - } - - // Remove from source. - run("rm -rf {{release_path}}/$dir"); - - // Create path to shared dir in release dir if it does not exist. - // Symlink will not create the path and will fail otherwise. - run("mkdir -p `dirname {{release_path}}/$dir`"); - - // Symlink shared dir to release dir - run("{{bin/symlink}} $sharedPath/$dir {{release_path}}/$dir"); - } - - foreach (get('shared_files') as $file) { - $dirname = dirname(parse($file)); - - // Create dir of shared file if not existing - if (!test("[ -d $sharedPath/$dirname ]")) { - run("mkdir -p $sharedPath/$dirname"); - } - - // Check if shared file does not exist in shared. - // and file exist in release - if (!test("[ -f $sharedPath/$file ]") && test("[ -f {{release_path}}/$file ]")) { - // Copy file in shared dir if not present - run("cp -r$copyVerbosity {{release_path}}/$file $sharedPath/$file"); - } - - // Remove from source. - run("if [ -f $(echo {{release_path}}/$file) ]; then rm -rf {{release_path}}/$file; fi"); - - // Ensure dir is available in release - run("if [ ! -d $(echo {{release_path}}/$dirname) ]; then mkdir -p {{release_path}}/$dirname;fi"); - - // Touch shared - run("[ -f $sharedPath/$file ] || touch $sharedPath/$file"); - - // Symlink shared dir to release dir - run("{{bin/symlink}} $sharedPath/$file {{release_path}}/$file"); - } -}); diff --git a/recipe/deploy/symlink.php b/recipe/deploy/symlink.php deleted file mode 100644 index e59bc8d18..000000000 --- a/recipe/deploy/symlink.php +++ /dev/null @@ -1,20 +0,0 @@ -hasOption('branch') && !empty(input()->getOption('branch'))) { - $target = input()->getOption('branch'); - } - if (input()->hasOption('tag') && !empty(input()->getOption('tag'))) { - $target = input()->getOption('tag'); - } - if (input()->hasOption('revision') && !empty(input()->getOption('revision'))) { - $target = input()->getOption('revision'); - } - - if (empty($target)) { - $target = "HEAD"; - } - return $target; -}); - -// Sets deploy:update_code strategy. -// Can be one of: -// - archive -// - clone (if you need `.git` dir in your {{release_path}}) -set('update_code_strategy', 'archive'); - -// Sets environment variable _GIT_SSH_COMMAND_ for `git clone` command. -// If `StrictHostKeyChecking` flag is set to `accept-new` then ssh will -// automatically add new host keys to the user known hosts files, but -// will not permit connections to hosts with changed host keys. -set('git_ssh_command', 'ssh -o StrictHostKeyChecking=accept-new'); - -/** - * Specifies a sub directory within the repository to deploy. - * Works only when [`update_code_strategy`](#update_code_strategy) is set to `archive` (default). - * - * Example: - * - set value to `src` if you want to deploy the folder that lives at `/src/api`. - * - set value to `src/api` if you want to deploy the folder that lives at `/src/api`. - * - * Note: do not use a leading `/`! - */ -set('sub_directory', false); - -/** - * Update code at {{release_path}} on host. - */ -desc('Updates code'); -task('deploy:update_code', function () { - $git = get('bin/git'); - $repository = get('repository'); - $target = get('target'); - - $targetWithDir = $target; - if (!empty(get('sub_directory'))) { - $targetWithDir .= ':{{sub_directory}}'; - } - - $bare = parse('{{deploy_path}}/.dep/repo'); - $env = [ - 'GIT_TERMINAL_PROMPT' => '0', - 'GIT_SSH_COMMAND' => get('git_ssh_command') - ]; - - start: - // Clone the repository to a bare repo. - run("[ -d $bare ] || mkdir -p $bare"); - run("[ -f $bare/HEAD ] || $git clone --mirror $repository $bare 2>&1", ['env' => $env]); - - cd($bare); - - // If remote url changed, drop `.dep/repo` and reinstall. - if (run("$git config --get remote.origin.url") !== $repository) { - cd('{{deploy_path}}'); - run("rm -rf $bare"); - goto start; - } - - run("$git remote update 2>&1", ['env' => $env]); - - // Copy to release_path. - if (get('update_code_strategy') === 'archive') { - run("$git archive $targetWithDir | tar -x -f - -C {{release_path}} 2>&1"); - } else if (get('update_code_strategy') === 'clone') { - cd('{{release_path}}'); - run("$git clone -l $bare ."); - run("$git checkout --force $target"); - } else { - throw new ConfigurationException(parse("Unknown `update_code_strategy` option: {{update_code_strategy}}.")); - } - - // Save git revision in REVISION file. - $rev = escapeshellarg(run("$git rev-list $target -1")); - run("echo $rev > {{release_path}}/REVISION"); -}); diff --git a/recipe/deploy/vendors.php b/recipe/deploy/vendors.php deleted file mode 100644 index b7c8f9a06..000000000 --- a/recipe/deploy/vendors.php +++ /dev/null @@ -1,32 +0,0 @@ -&1'); -}); diff --git a/recipe/deploy/writable.php b/recipe/deploy/writable.php deleted file mode 100644 index 07bcc28b2..000000000 --- a/recipe/deploy/writable.php +++ /dev/null @@ -1,134 +0,0 @@ -&1; true"), '+a') !== false) { - // Try OS-X specific setting of access-rights - - run("$sudo chmod +a \"$httpUser allow delete,write,append,file_inherit,directory_inherit\" $dirs"); - run("$sudo chmod +a \"$remoteUser allow delete,write,append,file_inherit,directory_inherit\" $dirs"); - } elseif (commandExist('setfacl')) { - $setFaclUsers = "-m u:\"$httpUser\":rwX"; - // Check if remote user exists, before adding it to setfacl - $remoteUserExists = test("id -u $remoteUser &>/dev/null 2>&1 || exit 0"); - if ($remoteUserExists === true) { - $setFaclUsers .= " -m u:$remoteUser:rwX"; - } - if (empty($sudo)) { - // When running without sudo, exception may be thrown - // if executing setfacl on files created by http user (in directory that has been setfacl before). - // These directories/files should be skipped. - // Now, we will check each directory for ACL and only setfacl for which has not been set before. - $writeableDirs = get('writable_dirs'); - foreach ($writeableDirs as $dir) { - // Check if ACL has been set or not - $hasfacl = run("getfacl -p $dir | grep \"^user:$httpUser:.*w\" | wc -l"); - // Set ACL for directory if it has not been set before - if (!$hasfacl) { - run("setfacl -L $recursive $setFaclUsers $dir"); - run("setfacl -dL $recursive $setFaclUsers $dir"); - } - } - } else { - run("$sudo setfacl -L $recursive $setFaclUsers $dirs"); - run("$sudo setfacl -dL $recursive $setFaclUsers $dirs"); - } - } else { - $alias = currentHost()->getAlias(); - throw new \RuntimeException("Can't set writable dirs with ACL.\nInstall ACL with next command:\ndep run 'sudo apt-get install acl' -- $alias"); - } - } else { - throw new \RuntimeException("Unknown writable_mode `$mode`."); - } -}); diff --git a/recipe/drupal7.php b/recipe/drupal7.php deleted file mode 100644 index aea108ef8..000000000 --- a/recipe/drupal7.php +++ /dev/null @@ -1,79 +0,0 @@ - $value) { - $keys = []; - for ($i = $iterator->getDepth(); $i > 0; $i --) { - $keys[] = $iterator->getSubIterator($i - 1)->key(); - } - $keys[] = $key; - - $replacements['{{' . implode('.', $keys) . '}}'] = $value; - } - - //Create settings from template - $settings = file_get_contents($template); - - $settings = strtr($settings, $replacements); - - writeln('settings.php created successfully'); - - $tmpFilename = tempnam(sys_get_temp_dir(), 'tmp_settings_'); - file_put_contents($tmpFilename, $settings); - - upload($tmpFilename, '{{deploy_path}}/shared/sites/{{drupal_site}}/settings.php'); - - unlink($tmpFilename); - } -}); - -//Upload Drupal 7 files folder -task('drupal:upload_files', function () { - if (askConfirmation('Are you sure?')) { - upload('sites/{{drupal_site}}/files', '{{deploy_path}}/shared/sites/{{drupal_site}}/files'); - } -}); diff --git a/recipe/drupal8.php b/recipe/drupal8.php deleted file mode 100644 index 77c4190ec..000000000 --- a/recipe/drupal8.php +++ /dev/null @@ -1,31 +0,0 @@ - #.#: The minimum Laravel version required (included). - * - 'max' => #.#: The maximum Laravel version required (included). - * - 'skipIfNoEnv': Skip and warn the user if `.env` file is inexistant or empty. - * - 'failIfNoEnv': Fail the command if `.env` file is inexistant or empty. - * - 'showOutput': Show the output of the command if given. - * - * @param string $command The artisan command (with cli options if any). - * @param array $options The options that define the behaviour of the command. - * @return callable A function that can be used as a task. - */ -function artisan($command, $options = []) -{ - return function () use ($command, $options) { - - // Ensure the artisan command is available on the current version. - $versionTooEarly = array_key_exists('min', $options) - && laravel_version_compare($options['min'], '<'); - - $versionTooLate = array_key_exists('max', $options) - && laravel_version_compare($options['max'], '>'); - - if ($versionTooEarly || $versionTooLate) { - return; - } - - // Ensure we warn or fail when a command relies on the ".env" file. - if (in_array('failIfNoEnv', $options) && !test('[ -s {{release_or_current_path}}/.env ]')) { - throw new \Exception('Your .env file is empty! Cannot proceed.'); - } - - if (in_array('skipIfNoEnv', $options) && !test('[ -s {{release_or_current_path}}/.env ]')) { - warning("Your .env file is empty! Skipping..."); - return; - } - - $artisan = '{{release_or_current_path}}/artisan'; - - // Run the artisan command. - $output = run("{{bin/php}} $artisan $command"); - - // Output the results when appropriate. - if (in_array('showOutput', $options)) { - writeln("$output"); - } - }; -} - -function laravel_version_compare($version, $comparator) -{ - return version_compare(get('laravel_version'), $version, $comparator); -} - -/* - * Maintenance mode. - */ - -desc('Puts the application into maintenance / demo mode'); -task('artisan:down', artisan('down', ['showOutput'])); - -desc('Brings the application out of maintenance mode'); -task('artisan:up', artisan('up', ['showOutput'])); - -/* - * Generate keys. - */ - -desc('Sets the application key'); -task('artisan:key:generate', artisan('key:generate')); - -desc('Creates the encryption keys for API authentication'); -task('artisan:passport:keys', artisan('passport:keys')); - -/* - * Database and migrations. - */ - -desc('Seeds the database with records'); -task('artisan:db:seed', artisan('db:seed --force', ['showOutput'])); - -desc('Runs the database migrations'); -task('artisan:migrate', artisan('migrate --force', ['skipIfNoEnv'])); - -desc('Drops all tables and re-run all migrations'); -task('artisan:migrate:fresh', artisan('migrate:fresh --force')); - -desc('Rollbacks the last database migration'); -task('artisan:migrate:rollback', artisan('migrate:rollback --force', ['showOutput'])); - -desc('Shows the status of each migration'); -task('artisan:migrate:status', artisan('migrate:status', ['showOutput'])); - -/* - * Cache and optimizations. - */ - -desc('Flushes the application cache'); -task('artisan:cache:clear', artisan('cache:clear')); - -desc('Creates a cache file for faster configuration loading'); -task('artisan:config:cache', artisan('config:cache')); - -desc('Removes the configuration cache file'); -task('artisan:config:clear', artisan('config:clear')); - -desc('Discovers and cache the application\'s events and listeners'); -task('artisan:event:cache', artisan('event:cache', ['min' => '5.8.9'])); - -desc('Clears all cached events and listeners'); -task('artisan:event:clear', artisan('event:clear', ['min' => '5.8.9'])); - -desc('Lists the application\'s events and listeners'); -task('artisan:event:list', artisan('event:list', ['showOutput', 'min' => '5.8.9'])); - -desc('Cache the framework bootstrap files'); -task('artisan:optimize', artisan('optimize')); - -desc('Removes the cached bootstrap files'); -task('artisan:optimize:clear', artisan('optimize:clear')); - -desc('Creates a route cache file for faster route registration'); -task('artisan:route:cache', artisan('route:cache')); - -desc('Removes the route cache file'); -task('artisan:route:clear', artisan('route:clear')); - -desc('Lists all registered routes'); -task('artisan:route:list', artisan('route:list', ['showOutput'])); - -desc('Creates the symbolic links configured for the application'); -task('artisan:storage:link', artisan('storage:link', ['min' => 5.3])); - -desc('Compiles all of the application\'s Blade templates'); -task('artisan:view:cache', artisan('view:cache', ['min' => 5.6])); - -desc('Clears all compiled view files'); -task('artisan:view:clear', artisan('view:clear')); - -/** - * Queue and Horizon. - */ - -desc('Lists all of the failed queue jobs'); -task('artisan:queue:failed', artisan('queue:failed', ['showOutput'])); - -desc('Flushes all of the failed queue jobs'); -task('artisan:queue:flush', artisan('queue:flush')); - -desc('Restarts queue worker daemons after their current job'); -task('artisan:queue:restart', artisan('queue:restart')); - -desc('Starts a master supervisor in the foreground'); -task('artisan:horizon', artisan('horizon')); - -desc('Deletes all of the jobs from the specified queue'); -task('artisan:horizon:clear', artisan('horizon:clear --force')); - -desc('Instructs the master supervisor to continue processing jobs'); -task('artisan:horizon:continue', artisan('horizon:continue')); - -desc('Lists all of the deployed machines'); -task('artisan:horizon:list', artisan('horizon:list', ['showOutput'])); - -desc('Pauses the master supervisor'); -task('artisan:horizon:pause', artisan('horizon:pause')); - -desc('Terminates any rogue Horizon processes'); -task('artisan:horizon:purge', artisan('horizon:purge')); - -desc('Gets the current status of Horizon'); -task('artisan:horizon:status', artisan('horizon:status', ['showOutput'])); - -desc('Terminates the master supervisor so it can be restarted'); -task('artisan:horizon:terminate', artisan('horizon:terminate')); - -/* - * Telescope. - */ - -desc('Clears all entries from Telescope'); -task('artisan:telescope:clear', artisan('telescope:clear')); - -desc('Prunes stale entries from the Telescope database'); -task('artisan:telescope:prune', artisan('telescope:prune')); - -/** - * Main deploy task. - */ -desc('Deploys your project'); -task('deploy', [ - 'deploy:prepare', - 'deploy:vendors', - 'artisan:storage:link', - 'artisan:config:cache', - 'artisan:route:cache', - 'artisan:view:cache', - 'artisan:event:cache', - 'artisan:migrate', - 'deploy:publish', -]); diff --git a/recipe/magento.php b/recipe/magento.php deleted file mode 100644 index d07221998..000000000 --- a/recipe/magento.php +++ /dev/null @@ -1,50 +0,0 @@ -cleanCache();\""); -}); - -/** - * Remove files that can be used to compromise Magento - */ -task('deploy:clear_version', function () { - run("rm -f {{release_or_current_path}}/LICENSE.html"); - run("rm -f {{release_or_current_path}}/LICENSE.txt"); - run("rm -f {{release_or_current_path}}/LICENSE_AFL.txt"); - run("rm -f {{release_or_current_path}}/RELEASE_NOTES.txt"); -})->hidden(); - -after('deploy:update_code', 'deploy:clear_version'); - - -/** - * Main task - */ -desc('Deploys your project'); -task('deploy', [ - 'deploy:prepare', - 'deploy:cache:clear', - 'deploy:publish', -]); diff --git a/recipe/magento2.php b/recipe/magento2.php deleted file mode 100644 index fc705f0b8..000000000 --- a/recipe/magento2.php +++ /dev/null @@ -1,220 +0,0 @@ - 0) { - foreach (get('magento_themes') as $theme) { - $themesToCompile .= ' -t ' . $theme; - } - } - - run("{{bin/php}} {{release_or_current_path}}/bin/magento setup:static-content:deploy --content-version={{content_version}} {{static_content_locales}} $themesToCompile -j {{static_content_jobs}}"); -}); - -desc('Syncs content version'); -task('magento:sync:content_version', function () { - $timestamp = time(); - on(select('all'), function (Host $host) use ($timestamp) { - $host->set('content_version', $timestamp); - }); -})->once(); - -before('magento:deploy:assets', 'magento:sync:content_version'); - -desc('Enables maintenance mode'); -task('magento:maintenance:enable', function () { - run("if [ -d $(echo {{current_path}}) ]; then {{bin/php}} {{current_path}}/bin/magento maintenance:enable; fi"); -}); - -desc('Disables maintenance mode'); -task('magento:maintenance:disable', function () { - run("if [ -d $(echo {{current_path}}) ]; then {{bin/php}} {{current_path}}/bin/magento maintenance:disable; fi"); -}); - -desc('Config Import'); -task('magento:config:import', function () { - $configImportNeeded = false; - - if(version_compare(get('magento_version'), '2.2.0', '<')) { - //app:config:import command does not exist in 2.0.x and 2.1.x branches - $configImportNeeded = false; - } elseif(version_compare(get('magento_version'), '2.2.4', '<')) { - //app:config:status command does not exist until 2.2.4, so proceed with config:import in every deploy - $configImportNeeded = true; - } else { - try { - run('{{bin/php}} {{release_or_current_path}}/bin/magento app:config:status'); - } catch (RunException $e) { - if ($e->getExitCode() == CONFIG_IMPORT_NEEDED_EXIT_CODE) { - $configImportNeeded = true; - } else { - throw $e; - } - } - } - - if ($configImportNeeded) { - if (get('enable_zerodowntime') && !get('maintenance_mode_status_active')) { - invoke('magento:maintenance:enable'); - } - - run('{{bin/php}} {{release_or_current_path}}/bin/magento app:config:import --no-interaction'); - - if (get('enable_zerodowntime') && !get('maintenance_mode_status_active')) { - invoke('magento:maintenance:disable'); - } - } -}); - -desc('Upgrades magento database'); -task('magento:upgrade:db', function () { - $databaseUpgradeNeeded = false; - - try { - run('{{bin/php}} {{release_or_current_path}}/bin/magento setup:db:status'); - } catch (RunException $e) { - if ($e->getExitCode() == DB_UPDATE_NEEDED_EXIT_CODE) { - $databaseUpgradeNeeded = true; - } else { - throw $e; - } - } - - if ($databaseUpgradeNeeded) { - if (get('enable_zerodowntime') && !get('maintenance_mode_status_active')) { - invoke('magento:maintenance:enable'); - } - - run("{{bin/php}} {{release_or_current_path}}/bin/magento setup:upgrade --keep-generated --no-interaction"); - - if (get('enable_zerodowntime') && !get('maintenance_mode_status_active')) { - invoke('magento:maintenance:disable'); - } - } -}); - -desc('Flushes Magento Cache'); -task('magento:cache:flush', function () { - run("{{bin/php}} {{release_or_current_path}}/bin/magento cache:flush"); -}); - -desc('Magento2 deployment operations'); -task('deploy:magento', [ - 'magento:build', - 'magento:config:import', - 'magento:upgrade:db', - 'magento:cache:flush', -]); - -desc('Magento2 build operations'); -task('magento:build', [ - 'magento:compile', - 'magento:deploy:assets', -]); - -desc('Deploys your project'); -task('deploy', [ - 'deploy:prepare', - 'deploy:vendors', - 'deploy:clear_paths', - 'deploy:magento', - 'deploy:publish', -]); - -after('deploy:failed', 'magento:maintenance:disable'); diff --git a/recipe/pimcore.php b/recipe/pimcore.php deleted file mode 100644 index 3d4c5cc0d..000000000 --- a/recipe/pimcore.php +++ /dev/null @@ -1,35 +0,0 @@ - $name, 'VERSION_ID' => $version] = parse_ini_string($release); - if ($name !== 'Ubuntu' || $version !== '20.04') { - warning('!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!'); - warning('!! !!'); - warning('!! Only Ubuntu 20.04 LTS supported! !!'); - warning('!! !!'); - warning('!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!'); - } -})->oncePerNode(); - -desc('Collects required params'); -task('provision:configure', function () { - $params = [ - 'sudo_password', - 'domain', - 'public_path', - 'php_version', - 'db_type', - 'db_user', - 'db_name', - 'db_password', - ]; - $code = "\n\n host('{{alias}}')"; - foreach ($params as $name) { - $code .= "\n ->set('$name', '…')"; - } - $code .= ";\n\n"; - writeln($code); - foreach ($params as $name) { - get($name); - } -}); - -desc('Adds repositories and update'); -task('provision:update', function () { - // PHP - run('apt-add-repository ppa:ondrej/php -y', ['env' => ['DEBIAN_FRONTEND' => 'noninteractive']]); - - // Caddy - run("curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/gpg.key' > /etc/apt/trusted.gpg.d/caddy-stable.asc"); - run("curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt' > /etc/apt/sources.list.d/caddy-stable.list"); - - // Nodejs - $keyring = '/usr/share/keyrings/nodesource.gpg'; - run("curl -fsSL https://deb.nodesource.com/gpgkey/nodesource.gpg.key | gpg --dearmor | sudo tee '$keyring' >/dev/null"); - run("gpg --no-default-keyring --keyring '$keyring' --list-keys"); - run("echo 'deb [signed-by=$keyring] https://deb.nodesource.com/{{nodejs_version}} {{lsb_release}} main' | sudo tee /etc/apt/sources.list.d/nodesource.list"); - run("echo 'deb-src [signed-by=$keyring] https://deb.nodesource.com/{{nodejs_version}} {{lsb_release}} main' | sudo tee -a /etc/apt/sources.list.d/nodesource.list"); - - // Update - run('apt-get update', ['env' => ['DEBIAN_FRONTEND' => 'noninteractive']]); -}) - ->oncePerNode() - ->verbose(); - -desc('Upgrades all packages'); -task('provision:upgrade', function () { - run('apt-get upgrade -y', ['env' => ['DEBIAN_FRONTEND' => 'noninteractive'], 'timeout' => 900]); -}) - ->oncePerNode() - ->verbose(); - -desc('Installs packages'); -task('provision:install', function () { - $packages = [ - 'acl', - 'apt-transport-https', - 'build-essential', - 'caddy', - 'curl', - 'debian-archive-keyring', - 'debian-keyring', - 'fail2ban', - 'gcc', - 'git', - 'libmcrypt4', - 'libpcre3-dev', - 'libsqlite3-dev', - 'make', - 'ncdu', - 'nodejs', - 'pkg-config', - 'python', - 'redis', - 'sendmail', - 'sqlite3', - 'ufw', - 'unzip', - 'uuid-runtime', - 'whois', - ]; - run('apt-get install -y ' . implode(' ', $packages), ['env' => ['DEBIAN_FRONTEND' => 'noninteractive'], 'timeout' => 900]); -}) - ->verbose() - ->oncePerNode(); - -desc('Configures a server'); -task('provision:server', function () { - run('usermod -a -G www-data caddy'); - $html = <<<'HTML' - - - - - - 404 Not Found - - - -
- - Deployer - - - - - - - -

Not Found

-

The requested URL was not found on this server.

-
- - -HTML; - run("mkdir -p /var/dep/html"); - run("echo $'$html' > /var/dep/html/404.html"); -})->oncePerNode(); - -desc('Configures the ssh'); -task('provision:ssh', function () { - run("sed -i 's/PasswordAuthentication .*/PasswordAuthentication no/' /etc/ssh/sshd_config"); - run('ssh-keygen -A'); - run('service ssh restart'); - if (test('[ ! -d /root/.ssh ]')) { - run('mkdir -p /root/.ssh'); - run('touch /root/.ssh/authorized_keys'); - } -})->oncePerNode(); - -set('sudo_password', function () { - return askHiddenResponse(' Password for sudo: '); -}); - -// Specify which key to copy to server. -// Set to `false` to disable copy of key. -set('ssh_copy_id', '~/.ssh/id_rsa.pub'); - -desc('Setups a deployer user'); -task('provision:deployer', function () { - if (test('id deployer >/dev/null 2>&1')) { - // TODO: Check what created deployer user configured correctly. - // TODO: Update sudo_password of deployer user. - // TODO: Copy ssh_copy_id to deployer ssh dir. - info('deployer user already exist'); - } else { - run('useradd deployer'); - run('mkdir -p /home/deployer/.ssh'); - run('mkdir -p /home/deployer/.deployer'); - run('adduser deployer sudo'); - - run('chsh -s /bin/bash deployer'); - run('cp /root/.profile /home/deployer/.profile'); - run('cp /root/.bashrc /home/deployer/.bashrc'); - - // Make color prompt. - run("sed -i 's/#force_color_prompt=yes/force_color_prompt=yes/' /home/deployer/.bashrc"); - - $password = run("mkpasswd -m sha-512 '%secret%'", ['secret' => get('sudo_password')]); - run("usermod --password '%secret%' deployer", ['secret' => $password]); - - if (!empty(get('ssh_copy_id'))) { - $file = parse_home_dir(get('ssh_copy_id')); - if (!file_exists($file)) { - info('Configure path to your public key.'); - writeln(""); - writeln(" set('ssh_copy_id', '~/.ssh/id_rsa.pub');"); - writeln(""); - $file = ask(' Specify path to your public ssh key: ', '~/.ssh/id_rsa.pub'); - } - run('echo "$KEY" >> /root/.ssh/authorized_keys', ['env' => ['KEY' => file_get_contents(parse_home_dir($file))]]); - } - run('cp /root/.ssh/authorized_keys /home/deployer/.ssh/authorized_keys'); - run('ssh-keygen -f /home/deployer/.ssh/id_rsa -t rsa -N ""'); - - run('chown -R deployer:deployer /home/deployer'); - run('chmod -R 755 /home/deployer'); - run('chmod 700 /home/deployer/.ssh/id_rsa'); - - run('usermod -a -G www-data deployer'); - run('usermod -a -G caddy deployer'); - run('groups deployer'); - } -})->oncePerNode(); - -desc('Setups a firewall'); -task('provision:firewall', function () { - run('ufw allow 22'); - run('ufw allow 80'); - run('ufw allow 443'); - run('ufw --force enable'); -})->oncePerNode(); - -desc('Verifies what provision was successful'); -task('provision:verify', function () { - fetch('{{domain}}', 'get', [], null, $info, true); - if ($info['http_code'] === 404) { - info("provisioned successfully!"); - } -}); diff --git a/recipe/provision/databases.php b/recipe/provision/databases.php deleted file mode 100644 index 7b7d026f6..000000000 --- a/recipe/provision/databases.php +++ /dev/null @@ -1,63 +0,0 @@ -limit(1); - -desc('Provision MySQL'); -task('provision:mysql', function () { - run('apt-get install -y mysql-server', ['env' => ['DEBIAN_FRONTEND' => 'noninteractive'], 'timeout' => 900]); - run("mysql --user=\"root\" -e \"CREATE USER IF NOT EXISTS '{{db_user}}'@'0.0.0.0' IDENTIFIED BY '%secret%';\"", ['secret' => get('db_password')]); - run("mysql --user=\"root\" -e \"CREATE USER IF NOT EXISTS '{{db_user}}'@'%' IDENTIFIED BY '%secret%';\"", ['secret' => get('db_password')]); - run("mysql --user=\"root\" -e \"GRANT ALL PRIVILEGES ON *.* TO '{{db_user}}'@'0.0.0.0' WITH GRANT OPTION;\""); - run("mysql --user=\"root\" -e \"GRANT ALL PRIVILEGES ON *.* TO '{{db_user}}'@'%' WITH GRANT OPTION;\""); - run("mysql --user=\"root\" -e \"FLUSH PRIVILEGES;\""); - run("mysql --user=\"root\" -e \"CREATE DATABASE IF NOT EXISTS {{db_name}} character set UTF8mb4 collate utf8mb4_bin;\""); -}); - -desc('Provision MariaDB'); -task('provision:mariadb', function () { - run('apt-get install -y mariadb-server', ['env' => ['DEBIAN_FRONTEND' => 'noninteractive'], 'timeout' => 900]); - run("mysql --user=\"root\" -e \"CREATE USER IF NOT EXISTS '{{db_user}}'@'0.0.0.0' IDENTIFIED BY '%secret%';\"", ['secret' => get('db_password')]); - run("mysql --user=\"root\" -e \"CREATE USER IF NOT EXISTS '{{db_user}}'@'%' IDENTIFIED BY '%secret%';\"", ['secret' => get('db_password')]); - run("mysql --user=\"root\" -e \"GRANT ALL PRIVILEGES ON *.* TO '{{db_user}}'@'0.0.0.0' WITH GRANT OPTION;\""); - run("mysql --user=\"root\" -e \"GRANT ALL PRIVILEGES ON *.* TO '{{db_user}}'@'%' WITH GRANT OPTION;\""); - run("mysql --user=\"root\" -e \"FLUSH PRIVILEGES;\""); - run("mysql --user=\"root\" -e \"CREATE DATABASE IF NOT EXISTS {{db_name}} character set UTF8mb4 collate utf8mb4_bin;\""); -}); - -desc('Provision PostgreSQL'); -task('provision:postgresql', function () { - run('apt-get install -y postgresql postgresql-contrib', ['env' => ['DEBIAN_FRONTEND' => 'noninteractive'], 'timeout' => 900]); - run('sudo -u postgres createuser deployer'); - run('sudo -u postgres createdb deployer'); -}); diff --git a/recipe/provision/nodejs.php b/recipe/provision/nodejs.php deleted file mode 100644 index 4a33c115d..000000000 --- a/recipe/provision/nodejs.php +++ /dev/null @@ -1,12 +0,0 @@ -oncePerNode(); diff --git a/recipe/provision/php.php b/recipe/provision/php.php deleted file mode 100644 index d107e284a..000000000 --- a/recipe/provision/php.php +++ /dev/null @@ -1,69 +0,0 @@ - ['DEBIAN_FRONTEND' => 'noninteractive']]); - - // Configure PHP-CLI - run("sudo sed -i 's/error_reporting = .*/error_reporting = E_ALL/' /etc/php/$version/cli/php.ini"); - run("sudo sed -i 's/display_errors = .*/display_errors = On/' /etc/php/$version/cli/php.ini"); - run("sudo sed -i 's/memory_limit = .*/memory_limit = 512M/' /etc/php/$version/cli/php.ini"); - run("sudo sed -i 's/;date.timezone.*/date.timezone = UTC/' /etc/php/$version/cli/php.ini"); - - // Configure PHP-FPM - run("sed -i 's/error_reporting = .*/error_reporting = E_ALL/' /etc/php/$version/fpm/php.ini"); - run("sed -i 's/display_errors = .*/display_errors = On/' /etc/php/$version/fpm/php.ini"); - run("sed -i 's/memory_limit = .*/memory_limit = 512M/' /etc/php/$version/fpm/php.ini"); - run("sed -i 's/;date.timezone.*/date.timezone = UTC/' /etc/php/$version/fpm/php.ini"); - run("sed -i 's/;cgi.fix_pathinfo=1/cgi.fix_pathinfo=0/' /etc/php/$version/fpm/php.ini"); - - // Configure FPM Pool - run("sed -i 's/;request_terminate_timeout = .*/request_terminate_timeout = 60/' /etc/php/$version/fpm/pool.d/www.conf"); - run("sed -i 's/;catch_workers_output = .*/catch_workers_output = yes/' /etc/php/$version/fpm/pool.d/www.conf"); - run("sed -i 's/;php_flag\[display_errors\] = .*/php_flag[display_errors] = yes/' /etc/php/$version/fpm/pool.d/www.conf"); - run("sed -i 's/;php_admin_value\[error_log\] = .*/php_admin_value[error_log] = \/var\/log\/fpm-php.www.log/' /etc/php/$version/fpm/pool.d/www.conf"); - run("sed -i 's/;php_admin_flag\[log_errors\] = .*/php_admin_flag[log_errors] = on/' /etc/php/$version/fpm/pool.d/www.conf"); - - // Configure PHP sessions directory - run('chmod 733 /var/lib/php/sessions'); - run('chmod +t /var/lib/php/sessions'); -}) - ->verbose() - ->limit(1); - -desc('Shows php-fpm logs'); -task('logs:php-fpm', function () { - run('tail -f /var/log/fpm-php.www.log'); -})->verbose(); - -desc('Installs Composer'); -task('provision:composer', function () { - run('curl -sS https://getcomposer.org/installer | php'); - run('mv composer.phar /usr/local/bin/composer'); -})->oncePerNode(); - diff --git a/recipe/provision/website.php b/recipe/provision/website.php deleted file mode 100644 index 380b77786..000000000 --- a/recipe/provision/website.php +++ /dev/null @@ -1,90 +0,0 @@ - Caddyfile.new"); - $diff = run('diff -U5 --color=always Caddyfile Caddyfile.new', ['no_throw' => true]); - if (empty($diff)) { - run('rm Caddyfile.new'); - } else { - info('Found Caddyfile changes'); - writeln("\n" . $diff); - $answer = askChoice(' Which Caddyfile to save? ', ['old', 'new'], 0); - if ($answer === 'old') { - run('rm Caddyfile.new'); - } else { - run('mv Caddyfile.new Caddyfile'); - } - } - } else { - run("echo $'$caddyfile' > Caddyfile"); - } - - set('remote_user', 'root'); - if (!test("grep -q 'import $deployPath/Caddyfile' /etc/caddy/Caddyfile")) { - run("echo 'import $deployPath/Caddyfile' >> /etc/caddy/Caddyfile"); - } - run('service caddy reload'); - - info("Website $domain configured!"); -})->limit(1); - -desc('Shows caddy logs'); -task('logs:caddy', function () { - run('tail -f {{deploy_path}}/log/access.log'); -})->verbose(); - -desc('Shows caddy syslog'); -task('logs:caddy:syslog', function () { - run('sudo journalctl -u caddy -f'); -})->verbose(); - diff --git a/recipe/shopware.php b/recipe/shopware.php deleted file mode 100644 index 46f3a0ee8..000000000 --- a/recipe/shopware.php +++ /dev/null @@ -1,184 +0,0 @@ -Running plugin update for " . $plugin['Plugin'] . "\n"); - run("cd {{release_path}} && bin/console plugin:update " . $plugin['Plugin']); - } - } -}); - -task('sw:writable:jwt', static function () { - run('cd {{release_path}} && chmod -R 660 config/jwt/*'); -}); - -/** - * Grouped SW deploy tasks. - */ -task('sw:deploy', [ - 'sw:database:migrate', - 'sw:plugin:refresh', - 'sw:cache:clear', - 'sw:plugin:update:all', - 'sw:cache:clear', -]); - -desc('Deploys your project'); -task('deploy', [ - 'deploy:prepare', - 'sw:deploy', - 'deploy:clear_paths', - 'sw:cache:warmup', - 'sw:writable:jwt', - 'deploy:publish', -]); - - -task('sw-build-without-db:get-remote-config', static function () { - if (!test('[ -d {{current_path}} ]')) { - return; - } - within('{{deploy_path}}/current', function () { - run('./bin/console bundle:dump'); - download('{{deploy_path}}/current/var/plugins.json', './var/'); - - run('./bin/console theme:dump'); - download('{{deploy_path}}/current/files/theme-config', './files/'); - - // Temporary workaround to remove absolute file paths in Shopware <6.4.6.0 - // See: - // - https://github.com/shopware/platform/commit/01c8ff86c7d8d3bee1888a26c24c9dc9b4529cbc - // - https://issues.shopware.com/issues/NEXT-17720 - // - https://github.com/deployphp/deployer/issues/2754 - $deployPath = get('deploy_path'); - if (substr($deployPath, -1, 1) !== '/') { - $deployPath .= '/'; - } - $deployPath .= 'releases/[0-9a-zA-Z]*/'; - $escapedDeployPath = str_replace('/', '\\\\/', $deployPath); - runLocally("sed -iE 's#${escapedDeployPath}##g' files/theme-config/* || true"); - }); -}); - -task('sw-build-without-db:build', static function () { - runLocally('CI=1 SHOPWARE_SKIP_BUNDLE_DUMP=1 ./bin/build.sh'); -}); - -task('sw-build-without-db', [ - 'sw-build-without-db:get-remote-config', - 'sw-build-without-db:build', -]); - -before('deploy:update_code', 'sw-build-without-db'); diff --git a/recipe/silverstripe.php b/recipe/silverstripe.php deleted file mode 100644 index edde919c1..000000000 --- a/recipe/silverstripe.php +++ /dev/null @@ -1,65 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Deployer\Collection; - -use Countable; -use IteratorAggregate; - -class Collection implements Countable, IteratorAggregate -{ - /** - * @var array - */ - protected $values = []; - - public function all(): array - { - return $this->values; - } - - /** - * @return mixed - */ - public function get(string $name) - { - if ($this->has($name)) { - return $this->values[$name]; - } else { - $this->throwNotFound($name); - } - } - - public function has(string $name): bool - { - return array_key_exists($name, $this->values); - } - - /** - * @param mixed $object - */ - public function set(string $name, $object) - { - $this->values[$name] = $object; - } - - public function remove(string $name): void - { - if ($this->has($name)) { - unset($this->values[$name]); - } else { - $this->throwNotFound($name); - } - } - - public function count(): int - { - return count($this->values); - } - - public function select(callable $callback): array - { - $values = []; - - foreach ($this->values as $key => $value) { - if ($callback($value, $key)) { - $values[$key] = $value; - } - } - - return $values; - } - - /** - * @return \ArrayIterator|\Traversable - */ - #[\ReturnTypeWillChange] - public function getIterator() - { - return new \ArrayIterator($this->values); - } - - protected function throwNotFound(string $name): void - { - throw new \InvalidArgumentException("Element \"$name\" not found in collection."); - } -} diff --git a/src/Command/BlackjackCommand.php b/src/Command/BlackjackCommand.php deleted file mode 100644 index 52317c53a..000000000 --- a/src/Command/BlackjackCommand.php +++ /dev/null @@ -1,392 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Deployer\Command; - -use Symfony\Component\Console\Command\Command; -use Symfony\Component\Console\Input\InputInterface as Input; -use Symfony\Component\Console\Output\OutputInterface as Output; -use Symfony\Component\Console\Question\ChoiceQuestion; -use Symfony\Component\Console\Style\SymfonyStyle; -use function Deployer\Support\array_flatten; - -class BlackjackCommand extends Command -{ - use CommandCommon; - - /** - * @var Input - */ - private $input; - - /** - * @var Output - */ - private $output; - - public function __construct() - { - parent::__construct('blackjack'); - $this->setDescription('Play blackjack'); - } - - protected function execute(Input $input, Output $output): int - { - $this->input = $input; - $this->output = $output; - $this->telemetry(); - $io = new SymfonyStyle($this->input, $this->output); - - if (getenv('COLORTERM') === 'truecolor') { - $this->print("\x1b[38;2;255;95;109m╭\x1b[39m\x1b[38;2;255;95;107m─\x1b[39m\x1b[38;2;255;96;106m─\x1b[39m\x1b[38;2;255;96;104m─\x1b[39m\x1b[38;2;255;96;103m─\x1b[39m\x1b[38;2;255;97;101m─\x1b[39m\x1b[38;2;255;97;100m─\x1b[39m\x1b[38;2;255;97;99m─\x1b[39m\x1b[38;2;255;98;97m─\x1b[39m\x1b[38;2;255;100;98m─\x1b[39m\x1b[38;2;255;102;98m─\x1b[39m\x1b[38;2;255;104;98m─\x1b[39m\x1b[38;2;255;106;99m─\x1b[39m\x1b[38;2;255;108;99m─\x1b[39m\x1b[38;2;255;110;99m─\x1b[39m\x1b[38;2;255;112;100m─\x1b[39m\x1b[38;2;255;114;100m─\x1b[39m\x1b[38;2;255;116;100m─\x1b[39m\x1b[38;2;255;118;100m─\x1b[39m\x1b[38;2;255;120;101m─\x1b[39m\x1b[38;2;255;122;101m─\x1b[39m\x1b[38;2;255;124;101m─\x1b[39m\x1b[38;2;255;126;102m╮\x1b[39m"); - $this->print("\x1b[38;2;255;128;102m│\x1b[39m \x1b[38;2;255;130;102m│\x1b[39m"); - $this->print("\x1b[38;2;255;132;103m│\x1b[39m \x1b[38;2;255;134;103mW\x1b[39m\x1b[38;2;255;136;103me\x1b[39m\x1b[38;2;255;138;104ml\x1b[39m\x1b[38;2;255;140;104mc\x1b[39m\x1b[38;2;255;142;104mo\x1b[39m\x1b[38;2;255;144;104mm\x1b[39m\x1b[38;2;255;146;105me\x1b[39m\x1b[38;2;255;148;105m!\x1b[39m \x1b[38;2;255;150;105m│\x1b[39m"); - $this->print("\x1b[38;2;255;152;106m│\x1b[39m \x1b[38;2;255;153;106m│\x1b[39m"); - $this->print("\x1b[38;2;255;155;106m╰\x1b[39m\x1b[38;2;255;157;107m─\x1b[39m\x1b[38;2;255;159;107m─\x1b[39m\x1b[38;2;255;161;107m─\x1b[39m\x1b[38;2;255;163;108m─\x1b[39m\x1b[38;2;255;165;108m─\x1b[39m\x1b[38;2;255;166;108m─\x1b[39m\x1b[38;2;255;168;108m─\x1b[39m\x1b[38;2;255;170;109m─\x1b[39m\x1b[38;2;255;172;109m─\x1b[39m\x1b[38;2;255;174;109m─\x1b[39m\x1b[38;2;255;176;110m─\x1b[39m\x1b[38;2;255;177;110m─\x1b[39m\x1b[38;2;255;179;110m─\x1b[39m\x1b[38;2;255;181;111m─\x1b[39m\x1b[38;2;255;183;111m─\x1b[39m\x1b[38;2;255;185;111m─\x1b[39m\x1b[38;2;255;186;111m─\x1b[39m\x1b[38;2;255;188;112m─\x1b[39m\x1b[38;2;255;190;112m─\x1b[39m\x1b[38;2;255;192;112m─\x1b[39m\x1b[38;2;255;193;113m─\x1b[39m\x1b[38;2;255;195;113m╯\x1b[0m"); - } else { - $this->print("╭─────────────────────╮"); - $this->print("│ │"); - $this->print("│ Welcome! │"); - $this->print("│ │"); - $this->print("╰─────────────────────╯"); - } - - $money = 100; - - if (md5(strval(getenv('MONEY'))) === '5a7c2f336d0cc43b68951e75cdffe333') { - $money += 25; - $this->print('You got an extra $25.'); - } else if (md5(strval(getenv('MONEY'))) === '530029252abcbda4a2a2069036ccc7fc') { - $money += 100; - $this->print('You got an extra $100.'); - } else if (md5(strval(getenv('MONEY'))) === '1aa827a06ecbfa5d6fa7c62ad245f3a3') { - $money = 100000; - } - - $hasWatch = true; - $orderWhiskey = false; - $whiskeyLevel = 0; - - $deck = $this->newDeck(); - $graveyard = []; - $dealersHand = []; - $playersHand = []; - shuffle($deck); - $deal = function () use (&$deck, &$graveyard) { - if (count($deck) == 0) { - shuffle($graveyard); - $deck = $graveyard; - $graveyard = []; - } - return array_pop($deck); - }; - - start: - $this->print("You have $$money."); - if ($money > 0) { - $bet = (int)$io->ask('Your bet', '5'); - if ($bet <= 0) goto start; - if ($bet > $money) goto start; - } else if ($hasWatch) { - $answer = $io->askQuestion(new ChoiceQuestion('?', ['leave', '- Here, take my watch! [$25]'], 0)); - if ($answer == 'leave') { - goto leave; - } else { - $hasWatch = false; - $money = 25; - $bet = 25; - } - } else { - goto leave; - } - - $graveyard = array_merge($graveyard, $dealersHand); - $dealersHand = []; - $dealersHand[] = $deal(); - $this->print("Dealers hand:"); - $this->printHand($dealersHand); - - $graveyard = array_merge($graveyard, $playersHand); - $playersHand = []; - $playersHand[] = $deal(); - $playersHand[] = $deal(); - $this->print("Your hand:"); - $this->printHand($playersHand, 2); - - while (true) { - $question = new ChoiceQuestion('Your turn', ['hit', 'stand'], 0); - $answer = $io->askQuestion($question); - - if ($answer === 'hit') { - $playersHand[] = $deal(); - usleep(200000); - } - - if ($answer === 'stand') { - break; - } - - $this->printHand($playersHand); - $handValue = self::handValue($playersHand); - - if ($handValue > 21) { - $this->print("You got $handValue."); - $this->print("Bust!"); - $this->print("-$$bet"); - $money -= $bet; - goto nextRound; - } - } - - $this->printHand($dealersHand); - $this->print("Dealer: " . self::handValue($dealersHand)); - sleep(1); - - while (self::handValue($dealersHand) <= 17) { - $dealersHand[] = $deal(); - $this->printHand($dealersHand); - $this->print("Dealer: " . self::handValue($dealersHand)); - sleep(1); - } - - $d = self::handValue($dealersHand); - $p = self::handValue($playersHand); - $this->print("You got $p and dealer $d."); - - if ($d > 21 || $p > $d) { - $this->print("You won!"); - $this->print("+$$bet"); - $money += $bet; - } else if ($p < $d) { - $this->print("You lose!"); - $this->print("-$$bet"); - $money -= $bet; - } else { - $this->print("Push!"); - } - - nextRound: - $choices = ['continue', 'leave']; - if ($orderWhiskey) { - $orderWhiskey = false; - $whiskeyLevel = 4; - $this->print(); - $this->print('The waitress brought whiskey and says:'); - $this->print(' - Your whiskey, sir.'); - if ($money >= 5) { - array_push($choices, 'tip the waitress [$5]'); - } - } else if ($money >= 5) { - array_push($choices, 'order whiskey [$5]'); - } - - if ($whiskeyLevel > 0) { - $this->printWhiskey($whiskeyLevel); - $whiskeyLevel--; - } - $answer = $io->askQuestion(new ChoiceQuestion('?', $choices, 0)); - - if ($answer == 'leave') { - goto leave; - } else if ($money >= 5 && $answer == 'order whiskey [$5]') { - $orderWhiskey = true; - $this->print('You say:'); - $this->print(' - Whiskey, please.'); - $money -= 5; - } else if ($money >= 5 && $answer == 'tip the waitress [$5]') { - $this->print('The waitress says:'); - $this->print(' - Thank you, sir!'); - $money -= 5; - } - $this->print(); - $this->print("=====> Next round <====="); - goto start; - - leave: - if ($money >= 5) { - $answer = $io->ask('Leave a $5 tip to the dealer?', 'yes'); - if ($answer === 'yes') { - $this->print("You can leave a tip here:"); - $this->print(); - $this->print("- https://github.com/sponsors/antonmedv"); - $this->print("- https://paypal.me/antonmedv"); - $this->print(); - } - } - $this->print('Thanks for playing, Come again!'); - return 0; - } - - private function newDeck(): array - { - $deck = []; - foreach (['♠', '♣', '♥', '♦'] as $suit) { - for ($i = 2; $i <= 10; $i++) { - $deck[] = [strval($i), $suit]; - } - $deck[] = ['J', $suit]; - $deck[] = ['Q', $suit]; - $deck[] = ['K', $suit]; - $deck[] = ['A', $suit]; - } - return $deck; - } - - public static function handValue(array $hand): int - { - $aces = 0; - $value = 0; - foreach ($hand as list($rank)) { - switch ($rank) { - case '2': - $value += 2; - break; - case '3': - $value += 3; - break; - case '4': - $value += 4; - break; - case '5': - $value += 5; - break; - case '6': - $value += 6; - break; - case '7': - $value += 7; - break; - case '8': - $value += 8; - break; - case '9': - $value += 9; - break; - case '10': - case 'J': - case 'Q': - case 'K': - $value += 10; - break; - case 'A': - $aces++; - break; - } - } - $variants = [$value]; - while ($aces-- > 0) { - $variants = array_flatten(array_map(function ($v) { - return [$v + 1, $v + 11]; - }, $variants)); - } - $sum = $variants[0]; - for ($i = 1; $i < count($variants); $i++) { - if ($variants[$i] <= 21) { - $sum = $variants[$i]; - } else { - break; - } - } - return $sum; - } - - private function print(string $text = "") - { - $this->output->writeln(" $text"); - } - - private function printHand(array $hand, int $offset = 1) - { - $cards = []; - for ($i = 0; $i < count($hand) - $offset; $i++) { - list($rank) = $hand[$i]; - $cards[] = [ - "┌───", - "│" . str_pad($rank, 3), - "│ ", - "│ ", - "│ ", - "│ ", - "└───", - ]; - } - - for (; $i < count($hand); $i++) { - list($rank, $suit) = $hand[$i]; - $cards[] = [ - "┌───────┐", - "│" . str_pad($rank, 7) . "│", - "│ │", - "│ " . $suit . " │", - "│ │", - "│" . str_pad($rank, 7, " ", STR_PAD_LEFT) . "│", - "└───────┘", - ]; - } - - for ($i = 0; $i < 7; $i++) { - $this->output->write(" "); - foreach ($cards as $lines) { - $this->output->write($lines[$i]); - } - $this->output->write("\n"); - } - } - - private function printWhiskey(int $whiskeyLevel) - { - if ($whiskeyLevel == 4) { - echo << - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Deployer\Command; - -use Deployer\Deployer; -use Deployer\Support\Reporter; - -trait CommandCommon -{ - /** - * Collecting anonymous stat helps Deployer team improve developer experience. - * If you are not comfortable with this, you will always be able to disable this - * by setting DO_NOT_TRACK environment variable to `1`. - * @codeCoverageIgnore - */ - protected function telemetry(array $data = []): void - { - if (getenv('DO_NOT_TRACK') === 'true') { - return; - } - try { - Reporter::report(array_merge([ - 'command_name' => $this->getName(), - 'deployer_version' => DEPLOYER_VERSION, - 'deployer_phar' => Deployer::isPharArchive(), - 'php_version' => phpversion(), - 'os' => defined('PHP_OS_FAMILY') ? PHP_OS_FAMILY : (stristr(PHP_OS, 'DAR') ? 'OSX' : (stristr(PHP_OS, 'WIN') ? 'WIN' : (stristr(PHP_OS, 'LINUX') ? 'LINUX' : PHP_OS))), - ], $data)); - } catch (\Throwable $e) { - return; - } - } - -} diff --git a/src/Command/ConfigCommand.php b/src/Command/ConfigCommand.php deleted file mode 100644 index 8aee286ff..000000000 --- a/src/Command/ConfigCommand.php +++ /dev/null @@ -1,77 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Deployer\Command; - -use Deployer\Deployer; -use Deployer\Exception\WillAskUser; -use Deployer\Task\Context; -use Symfony\Component\Console\Input\InputInterface as Input; -use Symfony\Component\Console\Input\InputOption; -use Symfony\Component\Console\Output\NullOutput; -use Symfony\Component\Console\Output\OutputInterface as Output; -use Symfony\Component\Yaml\Yaml; - -class ConfigCommand extends SelectCommand -{ - public function __construct(Deployer $deployer) - { - parent::__construct('config', $deployer); - $this->setDescription('Get all configuration options for hosts'); - } - - protected function configure() - { - parent::configure(); - $this->addOption('format', null, InputOption::VALUE_OPTIONAL, 'The output format (json, yaml)', 'yaml'); - $this->getDefinition()->getArgument('selector')->setDefault(['all']); - } - - protected function execute(Input $input, Output $output): int - { - $this->deployer->input = $input; - $this->deployer->output = new NullOutput(); - $hosts = $this->selectHosts($input, $output); - $data = []; - $keys = $this->deployer->config->keys(); - define('DEPLOYER_NO_ASK', true); - foreach ($hosts as $host) { - Context::push(new Context($host)); - $values = []; - foreach ($keys as $key) { - try { - $values[$key] = $host->get($key); - } catch (WillAskUser $exception) { - $values[$key] = ['ask' => $exception->getMessage()]; - } catch (\Throwable $exception) { - $values[$key] = ['error' => $exception->getMessage()]; - } - } - foreach ($host->config()->persist() as $k => $v) { - $values[$k] = $v; - } - ksort($values); - $data[$host->getAlias()] = $values; - Context::pop(); - } - $format = $input->getOption('format'); - switch ($format) { - case 'json': - $output->writeln(json_encode($data, JSON_PRETTY_PRINT)); - break; - - case 'yaml': - $output->write(Yaml::dump($data)); - break; - - default: - throw new \Exception("Unknown format: $format."); - } - return 0; - } -} diff --git a/src/Command/CustomOption.php b/src/Command/CustomOption.php deleted file mode 100644 index f51af8d77..000000000 --- a/src/Command/CustomOption.php +++ /dev/null @@ -1,50 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Deployer\Command; - -use Deployer\Host\Host; - -trait CustomOption -{ - /** - * @param Host[] $hosts - * @param string[] $options - */ - protected function applyOverrides(array $hosts, array $options) - { - $override = []; - foreach ($options as $option) { - list($name, $value) = explode('=', $option); - $value = $this->castValueToPhpType(trim($value)); - $override[trim($name)] = $value; - } - - foreach ($hosts as $host) { - foreach ($override as $key => $value) { - $host->set($key, $value); - } - } - } - - /** - * @param mixed $value - * @return bool|mixed - */ - protected function castValueToPhpType($value) - { - switch ($value) { - case 'true': - return true; - case 'false': - return false; - default: - return $value; - } - } -} diff --git a/src/Command/InitCommand.php b/src/Command/InitCommand.php deleted file mode 100644 index 6d98e5bb9..000000000 --- a/src/Command/InitCommand.php +++ /dev/null @@ -1,258 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Deployer\Command; - -use Symfony\Component\Console\Command\Command; -use Symfony\Component\Console\Input\InputInterface; -use Symfony\Component\Console\Input\InputOption; -use Symfony\Component\Console\Output\OutputInterface; -use Symfony\Component\Console\Style\SymfonyStyle; -use Symfony\Component\Process\Exception\RuntimeException; -use Symfony\Component\Process\PhpProcess; -use Symfony\Component\Process\Process; - -class InitCommand extends Command -{ - use CommandCommon; - - protected function configure() - { - $this - ->setName('init') - ->setDescription('Initialize deployer in your project') - ->addOption('path', 'p', InputOption::VALUE_OPTIONAL, 'Recipe path'); - } - - protected function execute(InputInterface $input, OutputInterface $output): int - { - if (getenv('COLORTERM') === 'truecolor') { - $output->write(<<write(<<getOption('path'); - - $language = $io->choice('Select recipe language', ['php', 'yaml'], 'php'); - if (empty($recipePath)) { - $recipePath = "deploy.$language"; - } - - // Avoid accidentally override of existing file. - if (file_exists($recipePath)) { - $io->warning("$recipePath already exists"); - if (!$io->confirm("Do you want to override the existing file?", false)) { - $io->block('👍🏻'); - exit(1); - } - } - - // Template - $template = $io->choice('Select project template', $this->recipes(), 'common'); - - // Repo - $default = ''; - try { - $process = Process::fromShellCommandline('git remote get-url origin'); - $default = $process->mustRun()->getOutput(); - $default = trim($default); - } catch (RuntimeException $e) { - } - $repository = $io->ask('Repository', $default); - - // Guess host - if (preg_match('/github.com:(?[A-Za-z0-9_.\-]+)\//', $repository, $m)) { - $org = $m['org']; - $tempHostFile = tempnam(sys_get_temp_dir(), 'temp-host-file'); - $php = new PhpProcess(<<blog, PHP_URL_HOST); -file_put_contents('$tempHostFile', \$host); -EOF - ); - $php->start(); - } - - // Project - $default = ''; - try { - $process = Process::fromShellCommandline('basename "$PWD"'); - $default = $process->mustRun()->getOutput(); - $default = trim($default); - } catch (RuntimeException $e) { - } - $project = $io->ask('Project name', $default); - - // Hosts - $host = null; - if (isset($tempHostFile)) { - $host = file_get_contents($tempHostFile); - } - $hostsString = $io->ask('Hosts (comma separated)', $host); - if ($hostsString !== null) { - $hosts = explode(',', $hostsString); - } else { - $hosts = []; - } - - file_put_contents($recipePath, $this->$language($template, $project, $repository, $hosts)); - - $this->telemetry(); - $output->writeln(sprintf( - 'Successfully created %s', - $recipePath - )); - return 0; - } - - private function php(string $template, string $project, string $repository, array $hosts): string - { - $h = ""; - foreach ($hosts as $host) { - $h .= "host('{$host}')\n" . - " ->set('remote_user', 'deployer')\n" . - " ->set('deploy_path', '~/{$project}');\n"; - } - - return <<getAdditionalConfigs($template); - - return <<isDot()) { - continue; - } - if ($fileinfo->isDir()) { - continue; - } - - $recipe = pathinfo($fileinfo->getFilename(), PATHINFO_FILENAME); - - if ($recipe === 'README') { - continue; - } - - $recipes[] = $recipe; - } - - sort($recipes); - return $recipes; - } -} diff --git a/src/Command/MainCommand.php b/src/Command/MainCommand.php deleted file mode 100644 index 567ba6ed6..000000000 --- a/src/Command/MainCommand.php +++ /dev/null @@ -1,234 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Deployer\Command; - -use Deployer\Configuration\Configuration; -use Deployer\Deployer; -use Deployer\Exception\Exception; -use Deployer\Exception\GracefulShutdownException; -use Deployer\Executor\Planner; -use Deployer\Utility\Httpie; -use Symfony\Component\Console\Completion\CompletionInput; -use Symfony\Component\Console\Completion\CompletionSuggestions; -use Symfony\Component\Console\Input\InputInterface as Input; -use Symfony\Component\Console\Input\InputOption as Option; -use Symfony\Component\Console\Output\OutputInterface as Output; -use function Deployer\Support\find_config_line; -use function Deployer\warning; - -class MainCommand extends SelectCommand -{ - use CustomOption; - use CommandCommon; - - public function __construct(string $name, ?string $description, Deployer $deployer) - { - parent::__construct($name, $deployer); - if ($description) { - $this->setDescription($description); - } - } - - protected function configure() - { - parent::configure(); - - // Add global options defined with `option()` func. - $this->getDefinition()->addOptions($this->deployer->inputDefinition->getOptions()); - - $this->addOption( - 'option', - 'o', - Option::VALUE_REQUIRED | Option::VALUE_IS_ARRAY, - 'Set configuration option' - ); - $this->addOption( - 'limit', - 'l', - Option::VALUE_REQUIRED, - 'How many tasks to run in parallel?' - ); - $this->addOption( - 'no-hooks', - null, - Option::VALUE_NONE, - 'Run tasks without after/before hooks' - ); - $this->addOption( - 'plan', - null, - Option::VALUE_NONE, - 'Show execution plan' - ); - $this->addOption( - 'start-from', - null, - Option::VALUE_REQUIRED, - 'Start execution from this task' - ); - $this->addOption( - 'log', - null, - Option::VALUE_REQUIRED, - 'Write log to a file' - ); - $this->addOption( - 'profile', - null, - Option::VALUE_REQUIRED, - 'Write profile to a file' - ); - } - - protected function execute(Input $input, Output $output): int - { - $this->deployer->input = $input; - $this->deployer->output = $output; - $this->deployer['log'] = $input->getOption('log'); - $this->telemetry([ - 'project_hash' => empty($this->deployer->config['repository']) ? null : sha1($this->deployer->config['repository']), - 'hosts_count' => $this->deployer->hosts->count(), - 'recipes' => $this->deployer->config->get('recipes', []), - ]); - - $hosts = $this->selectHosts($input, $output); - $this->applyOverrides($hosts, $input->getOption('option')); - - // Save selected_hosts for selectedHosts() func. - $hostsAliases = []; - foreach ($hosts as $host) { - $hostsAliases[] = $host->getAlias(); - } - // Save selected_hosts per each host, and not globally. Otherwise it will - // not be accessible for workers. - foreach ($hosts as $host) { - $host->set('selected_hosts', $hostsAliases); - } - - $plan = $input->getOption('plan') ? new Planner($output, $hosts) : null; - - $this->deployer->scriptManager->setHooksEnabled(!$input->getOption('no-hooks')); - $startFrom = $input->getOption('start-from'); - if ($startFrom && !$this->deployer->tasks->has($startFrom)) { - throw new Exception("Task $startFrom does not exist."); - } - $skippedTasks = []; - $tasks = $this->deployer->scriptManager->getTasks($this->getName(), $startFrom, $skippedTasks); - - if (empty($tasks)) { - throw new Exception('No task will be executed, because the selected hosts do not meet the conditions of the tasks'); - } - - if (!$plan) { - $this->checkUpdates(); - $this->validateConfig(); - $this->deployer->server->start(); - - if (!empty($skippedTasks)) { - foreach ($skippedTasks as $taskName) { - $output->writeln("skip $taskName"); - } - } - } - $exitCode = $this->deployer->master->run($tasks, $hosts, $plan); - - if ($plan) { - $plan->render(); - return 0; - } - - if ($exitCode === 0) { - $this->showBanner(); - return 0; - } - if ($exitCode === GracefulShutdownException::EXIT_CODE) { - return 1; - } - - // Check if we have tasks to execute on failure. - if ($this->deployer['fail']->has($this->getName())) { - $taskName = $this->deployer['fail']->get($this->getName()); - $tasks = $this->deployer->scriptManager->getTasks($taskName); - $this->deployer->master->run($tasks, $hosts); - } - - return $exitCode; - } - - private function checkUpdates() - { - try { - fwrite(STDERR, Httpie::get('https://deployer.org/check-updates/' . DEPLOYER_VERSION)->send()); - } catch (\Throwable $e) { - // Meh - } - } - - private function showBanner() - { - try { - $withColors = getenv('COLORTERM') === 'truecolor' ? '_with_colors' : ''; - fwrite(STDERR, Httpie::get("https://deployer.org/banners/" . $this->getName() . $withColors)->send()); - } catch (\Throwable $e) { - // Meh - } - } - - private function validateConfig(): void - { - if (!defined('DEPLOYER_DEPLOY_FILE')) { - return; - } - $validate = function (Configuration $configA, Configuration $configB): void { - $keysA = array_keys($configA->ownValues()); - $keysB = array_keys($configB->ownValues()); - for ($i = 0; $i < count($keysA); $i++) { - for ($j = $i + 1; $j < count($keysB); $j++) { - $a = $keysA[$i]; - $b = $keysB[$j]; - if (levenshtein($a, $b) == 1) { - $source = file_get_contents(DEPLOYER_DEPLOY_FILE); - $code = ''; - foreach (find_config_line($source, $a) as list($n, $line)) { - $code .= " $n: " . str_replace($a, "$a", $line) . "\n"; - } - foreach (find_config_line($source, $b) as list($n, $line)) { - $code .= " $n: " . str_replace($b, "$b", $line) . "\n"; - } - if (!empty($code)) { - warning(<<$a" or "$b"? - - $code - AAA - ); - } - } - } - } - }; - - $validate($this->deployer->config, $this->deployer->config); - foreach ($this->deployer->hosts as $host) { - $validate($host->config(), $this->deployer->config); - } - } - - public function complete(CompletionInput $input, CompletionSuggestions $suggestions): void - { - parent::complete($input, $suggestions); - if ($input->mustSuggestOptionValuesFor('start-from')) { - $taskNames = []; - foreach ($this->deployer->scriptManager->getTasks($this->getName()) as $task) { - $taskNames[] = $task->getName(); - } - $suggestions->suggestValues($taskNames); - } - } -} diff --git a/src/Command/RunCommand.php b/src/Command/RunCommand.php deleted file mode 100644 index 8b60f68c4..000000000 --- a/src/Command/RunCommand.php +++ /dev/null @@ -1,88 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Deployer\Command; - -use Deployer\Deployer; -use Deployer\Task\Context; -use Deployer\Task\Task; -use Symfony\Component\Console\Input\InputArgument; -use Symfony\Component\Console\Input\InputInterface as Input; -use Symfony\Component\Console\Input\InputOption as Option; -use Symfony\Component\Console\Output\OutputInterface as Output; -use function Deployer\cd; -use function Deployer\get; -use function Deployer\has; -use function Deployer\run; -use function Deployer\test; - -class RunCommand extends SelectCommand -{ - use CustomOption; - - public function __construct(Deployer $deployer) - { - parent::__construct('run', $deployer); - $this->setDescription('Run any arbitrary command on hosts'); - } - - protected function configure() - { - $this->addArgument( - 'command-to-run', - InputArgument::REQUIRED, - 'Command to run on a remote host' - ); - parent::configure(); - $this->addOption( - 'option', - 'o', - Option::VALUE_REQUIRED | Option::VALUE_IS_ARRAY, - 'Set configuration option' - ); - $this->addOption( - 'timeout', - 't', - Option::VALUE_REQUIRED, - 'Command timeout in seconds' - ); - } - - protected function execute(Input $input, Output $output): int - { - $this->deployer->input = $input; - $this->deployer->output = $output; - - $command = $input->getArgument('command-to-run') ?? ''; - $hosts = $this->selectHosts($input, $output); - $this->applyOverrides($hosts, $input->getOption('option')); - - $task = new Task($command, function () use ($input, $command) { - if (has('current_path')) { - $path = get('current_path'); - if (test("[ -d $path ]")) { - cd($path); - } - } - run($command, [ - 'real_time_output' => true, - 'timeout' => intval($input->getOption('timeout')), - ]); - }); - - foreach ($hosts as $host) { - try { - $task->run(new Context($host)); - } catch (\Throwable $exception) { - $this->deployer->messenger->renderException($exception, $host); - } - } - - return 0; - } -} diff --git a/src/Command/SelectCommand.php b/src/Command/SelectCommand.php deleted file mode 100644 index 34c2ff31e..000000000 --- a/src/Command/SelectCommand.php +++ /dev/null @@ -1,120 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Deployer\Command; - -use Deployer\Deployer; -use Deployer\Exception\ConfigurationException; -use Deployer\Exception\Exception; -use Deployer\Host\Host; -use Symfony\Component\Console\Command\Command; -use Symfony\Component\Console\Completion\CompletionInput; -use Symfony\Component\Console\Completion\CompletionSuggestions; -use Symfony\Component\Console\Formatter\OutputFormatterStyle; -use Symfony\Component\Console\Helper\QuestionHelper; -use Symfony\Component\Console\Input\InputArgument; -use Symfony\Component\Console\Input\InputInterface as Input; -use Symfony\Component\Console\Output\OutputInterface as Output; -use Symfony\Component\Console\Question\ChoiceQuestion; - -abstract class SelectCommand extends Command -{ - /** - * @var Deployer - */ - protected $deployer; - - public function __construct(string $name, Deployer $deployer) - { - $this->deployer = $deployer; - parent::__construct($name); - } - - protected function configure() - { - $this->addArgument('selector', InputArgument::OPTIONAL | InputArgument::IS_ARRAY, 'Host selector'); - } - - /** - * @return Host[] - */ - protected function selectHosts(Input $input, Output $output): array - { - $output->getFormatter()->setStyle('success', new OutputFormatterStyle('green')); - if (!$output->isDecorated() && !defined('NO_ANSI')) { - define('NO_ANSI', 'true'); - } - $selector = $input->getArgument('selector'); - $selectExpression = is_array($selector) ? implode(',', $selector) : $selector; - - if (empty($selectExpression)) { - if (count($this->deployer->hosts) === 0) { - throw new ConfigurationException("No host configured.\nSpecify at least one host: `localhost();`."); - } else if (count($this->deployer->hosts) === 1) { - $hosts = $this->deployer->hosts->all(); - } else if ($input->isInteractive()) { - $hostsAliases = []; - foreach ($this->deployer->hosts as $host) { - $hostsAliases[] = $host->getAlias(); - } - /** @var QuestionHelper $helper */ - $helper = $this->getHelper('question'); - $question = new ChoiceQuestion( - 'Select hosts: (comma separated)', - $hostsAliases - ); - $question->setMultiselect(true); - $question->setErrorMessage('There is no "%s" host.'); - $answer = $helper->ask($input, $output, $question); - $answer = array_unique($answer); - $hosts = $this->deployer->hosts->select(function (Host $host) use ($answer) { - return in_array($host->getAlias(), $answer, true); - }); - } - } else { - $hosts = $this->deployer->selector->select($selectExpression); - } - - if (empty($hosts)) { - $message = 'No host selected.'; - if (!empty($selectExpression)) { - $message .= " Please, check your selector:\n\n $selectExpression"; - } - throw new Exception($message); - } - - return $hosts; - } - - public function complete(CompletionInput $input, CompletionSuggestions $suggestions): void - { - parent::complete($input, $suggestions); - if ($input->mustSuggestArgumentValuesFor('selector')) { - $selectors = ['all']; - $configs = []; - foreach ($this->deployer->hosts as $host) { - $configs[$host->getAlias()] = $host->config()->persist(); - } - foreach ($configs as $alias => $c) { - $selectors[] = $alias; - foreach ($c['labels'] ?? [] as $label => $value) { - $selectors[] = "$label=$value"; - } - } - $selectors = array_unique($selectors); - $suggestions->suggestValues($selectors); - } - if ($input->mustSuggestOptionValuesFor('option')) { - $values = []; - foreach ($this->deployer->config->keys() as $key) { - $values[] = $key . '='; - } - $suggestions->suggestValues($values); - } - } -} diff --git a/src/Command/SshCommand.php b/src/Command/SshCommand.php deleted file mode 100644 index df324c384..000000000 --- a/src/Command/SshCommand.php +++ /dev/null @@ -1,111 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Deployer\Command; - -use Deployer\Component\Ssh\Client; -use Deployer\Deployer; -use Deployer\Host\Localhost; -use Deployer\Task\Context; -use Symfony\Component\Console\Command\Command; -use Symfony\Component\Console\Completion\CompletionInput; -use Symfony\Component\Console\Completion\CompletionSuggestions; -use Symfony\Component\Console\Input\InputArgument; -use Symfony\Component\Console\Input\InputInterface; -use Symfony\Component\Console\Output\OutputInterface; -use Symfony\Component\Console\Question\ChoiceQuestion; - -/** - * @codeCoverageIgnore - */ -class SshCommand extends Command -{ - use CommandCommon; - - /** - * @var Deployer - */ - private $deployer; - - public function __construct(Deployer $deployer) - { - parent::__construct('ssh'); - $this->setDescription('Connect to host through ssh'); - $this->deployer = $deployer; - } - - protected function configure() - { - $this->addArgument( - 'hostname', - InputArgument::OPTIONAL, - 'Hostname' - ); - } - - protected function execute(InputInterface $input, OutputInterface $output): int - { - $this->telemetry(); - $hostname = $input->getArgument('hostname'); - if (!empty($hostname)) { - $host = $this->deployer->hosts->get($hostname); - } else { - $hostsAliases = []; - foreach ($this->deployer->hosts as $host) { - if ($host instanceof Localhost) { - continue; - } - $hostsAliases[] = $host->getAlias(); - } - - if (count($hostsAliases) === 0) { - $output->writeln('No remote hosts.'); - return 2; // Because there are no hosts. - } - - if (count($hostsAliases) === 1) { - $host = current($this->deployer->hosts->all()); - } else { - $helper = $this->getHelper('question'); - $question = new ChoiceQuestion( - 'Select host:', - $hostsAliases - ); - $question->setErrorMessage('There is no "%s" host.'); - - $hostname = $helper->ask($input, $output, $question); - $host = $this->deployer->hosts->get($hostname); - } - } - - $shell_path = 'exec $SHELL -l'; - if ($host->has('shell_path')) { - $shell_path = 'exec ' . $host->get('shell_path') . ' -l'; - } - - Context::push(new Context($host)); - $host->setSshMultiplexing(false); - $options = $host->connectionOptionsString(); - $deployPath = $host->get('deploy_path', '~'); - - if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') { - passthru("ssh -t $options {$host->connectionString()} \"cd $deployPath/current 2>/dev/null || cd $deployPath; $shell_path\""); - } else { - passthru("ssh -t $options {$host->connectionString()} 'cd $deployPath/current 2>/dev/null || cd $deployPath; $shell_path'"); - } - return 0; - } - - public function complete(CompletionInput $input, CompletionSuggestions $suggestions): void - { - parent::complete($input, $suggestions); - if ($input->mustSuggestArgumentValuesFor('hostname')) { - $suggestions->suggestValues(array_keys($this->deployer->hosts->all())); - } - } -} diff --git a/src/Command/TreeCommand.php b/src/Command/TreeCommand.php deleted file mode 100644 index 3357dd889..000000000 --- a/src/Command/TreeCommand.php +++ /dev/null @@ -1,178 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Deployer\Command; - -use Deployer\Deployer; -use Deployer\Task\GroupTask; -use Symfony\Component\Console\Command\Command; -use Symfony\Component\Console\Completion\CompletionInput; -use Symfony\Component\Console\Completion\CompletionSuggestions; -use Symfony\Component\Console\Input\InputArgument; -use Symfony\Component\Console\Input\InputInterface as Input; -use Symfony\Component\Console\Output\OutputInterface as Output; - -class TreeCommand extends Command -{ - /** - * @var Output - */ - protected $output; - /** - * @var Deployer - */ - private $deployer; - /** - * @var array - */ - private $tree; - /** - * @var int - */ - private $depth = 0; - /** - * @var array - */ - private $openGroupDepths = []; - - public function __construct(Deployer $deployer) - { - parent::__construct('tree'); - $this->setDescription('Display the task-tree for a given task'); - $this->deployer = $deployer; - $this->tree = []; - } - - protected function configure() - { - $this->addArgument( - 'task', - InputArgument::REQUIRED, - 'Task to display the tree for' - ); - } - - protected function execute(Input $input, Output $output): int - { - $this->output = $output; - - $rootTaskName = $input->getArgument('task'); - - $this->buildTree($rootTaskName); - $this->outputTree($rootTaskName); - return 0; - } - - private function buildTree(string $taskName) - { - $this->createTreeFromTaskName($taskName, '', true); - } - - private function createTreeFromTaskName(string $taskName, string $postfix = '', bool $isLast = false) - { - $task = $this->deployer->tasks->get($taskName); - - if (!$task->isEnabled()) { - if (empty($postfix)) { - $postfix = ' // disabled'; - } else { - $postfix .= '; disabled'; - } - } - - if ($task->getBefore()) { - $beforePostfix = sprintf(" // before %s", $task->getName()); - - foreach ($task->getBefore() as $beforeTask) { - $this->createTreeFromTaskName($beforeTask, $beforePostfix); - } - } - - if ($task instanceof GroupTask) { - $isLast = $isLast && empty($task->getAfter()); - - $this->addTaskToTree($task->getName() . $postfix, $isLast); - - if (!$isLast) { - $this->openGroupDepths[] = $this->depth; - } - - $this->depth++; - - $taskGroup = $task->getGroup(); - foreach ($taskGroup as $subtask) { - $isLastSubtask = $subtask === end($taskGroup); - $this->createTreeFromTaskName($subtask, '', $isLastSubtask); - } - - if (!$isLast) { - array_pop($this->openGroupDepths); - } - - $this->depth--; - } else { - $this->addTaskToTree($task->getName() . $postfix, $isLast); - } - - if ($task->getAfter()) { - $afterPostfix = sprintf(" // after %s", $task->getName()); - - foreach ($task->getAfter() as $afterTask) { - $this->createTreeFromTaskName($afterTask, $afterPostfix); - } - } - } - - private function addTaskToTree(string $taskName, bool $isLast = false) - { - $this->tree[] = [ - 'taskName' => $taskName, - 'depth' => $this->depth, - 'isLast' => $isLast, - 'openDepths' => $this->openGroupDepths - ]; - } - - private function outputTree(string $taskName) - { - $this->output->writeln("The task-tree for $taskName:"); - - /** - * @var int number of spaces for each depth increase - */ - $REPEAT_COUNT = 4; - - foreach ($this->tree as $treeItem) { - $depth = $treeItem['depth']; - - $startSymbol = $treeItem['isLast'] || $treeItem === end($this->tree) ? '└' : '├'; - - $prefix = ''; - - for ($i = 0; $i < $depth; $i++) { - if (in_array($i, $treeItem['openDepths'])) { - $prefix .= '│' . str_repeat(' ', $REPEAT_COUNT - 1); - } else { - $prefix .= str_repeat(' ', $REPEAT_COUNT); - } - } - - $prefix .= $startSymbol . '──'; - - $this->output->writeln(sprintf('%s %s', $prefix, $treeItem['taskName'])); - } - } - - public function complete(CompletionInput $input, CompletionSuggestions $suggestions): void - { - parent::complete($input, $suggestions); - if ($input->mustSuggestArgumentValuesFor('task')) { - $suggestions->suggestValues(array_keys($this->deployer->tasks->all())); - } - } -} diff --git a/src/Command/WorkerCommand.php b/src/Command/WorkerCommand.php deleted file mode 100644 index b62954ba2..000000000 --- a/src/Command/WorkerCommand.php +++ /dev/null @@ -1,57 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Deployer\Command; - -use Deployer\Deployer; -use Deployer\Executor\Worker; -use Deployer\Host\Localhost; -use Symfony\Component\Console\Input\InputInterface; -use Symfony\Component\Console\Input\InputOption as Option; -use Symfony\Component\Console\Output\OutputInterface; -use function Deployer\localhost; - -class WorkerCommand extends MainCommand -{ - public function __construct(Deployer $deployer) - { - parent::__construct('worker', null, $deployer); - $this->setHidden(true); - } - - protected function configure() - { - parent::configure(); - $this->addOption('task', null, Option::VALUE_REQUIRED); - $this->addOption('host', null, Option::VALUE_REQUIRED); - $this->addOption('port', null, Option::VALUE_REQUIRED); - $this->addOption('decorated', null, Option::VALUE_NONE); - } - - protected function execute(InputInterface $input, OutputInterface $output): int - { - $this->deployer->input = $input; - $this->deployer->output = $output; - $this->deployer['log'] = $input->getOption('log'); - $output->setDecorated($input->getOption('decorated')); - if (!$output->isDecorated() && !defined('NO_ANSI')) { - define('NO_ANSI', 'true'); - } - $this->deployer->config->set('master_url', 'http://localhost:' . $input->getOption('port')); - - $task = $this->deployer->tasks->get($input->getOption('task')); - $host = $this->deployer->hosts->get($input->getOption('host')); - $host->config()->load(); - - $worker = new Worker($this->deployer); - $exitCode = $worker->execute($task, $host); - - $host->config()->save(); - return $exitCode; - } -} diff --git a/src/Component/PharUpdate/Console/Command.php b/src/Component/PharUpdate/Console/Command.php deleted file mode 100644 index f63f4e6cd..000000000 --- a/src/Component/PharUpdate/Console/Command.php +++ /dev/null @@ -1,132 +0,0 @@ - - */ -class Command extends Base -{ - /** - * Disable the ability to upgrade? - * - * @var boolean - */ - private $disableUpgrade = false; - - /** - * The manifest file URI. - * - * @var string - */ - private $manifestUri; - - /** - * The running file (the Phar that will be updated). - * - * @var string - */ - private $runningFile; - - /** - * @param string $name The command name. - * @param boolean $disable Disable upgrading? - */ - public function __construct(string $name, bool $disable = false) - { - $this->disableUpgrade = $disable; - - parent::__construct($name); - } - - /** - * Sets the manifest URI. - * - * @param string $uri The URI. - */ - public function setManifestUri(string $uri) - { - $this->manifestUri = $uri; - } - - /** - * Sets the running file (the Phar that will be updated). - * - * @param string $file The file name or path. - */ - public function setRunningFile(string $file): void - { - $this->runningFile = $file; - } - - /** - * {@inheritdoc} - */ - protected function configure() - { - $this->setDescription('Updates the application.'); - $this->addOption( - 'pre', - 'p', - InputOption::VALUE_NONE, - 'Allow pre-release updates.' - ); - $this->addOption( - 'redo', - 'r', - InputOption::VALUE_NONE, - 'Redownload update if already using current version.' - ); - - if (false === $this->disableUpgrade) { - $this->addOption( - 'upgrade', - 'u', - InputOption::VALUE_NONE, - 'Upgrade to next major release, if available.' - ); - } - } - - /** - * {@inheritdoc} - */ - protected function execute(InputInterface $input, OutputInterface $output) - { - if (null === $this->manifestUri) { - throw new LogicException( - 'No manifest URI has been configured.' - ); - } - - $output->writeln('Looking for updates...'); - - /** @var Helper */ - $pharUpdate = $this->getHelper('phar-update'); - /** @var Manager $manager */ - $manager = $pharUpdate->getManager($this->manifestUri); - $manager->setRunningFile($this->runningFile); - - if ($manager->update( - $this->getApplication()->getVersion(), - $this->disableUpgrade ?: (false === $input->getOption('upgrade')), - $input->getOption('pre') - )) { - $output->writeln('Update successful!'); - } else { - $output->writeln('Already up-to-date.'); - } - - // Force exit to prevent warnings - die(0); - } -} diff --git a/src/Component/PharUpdate/Console/Helper.php b/src/Component/PharUpdate/Console/Helper.php deleted file mode 100644 index 3e66dc7fa..000000000 --- a/src/Component/PharUpdate/Console/Helper.php +++ /dev/null @@ -1,32 +0,0 @@ - - */ -class Helper extends Base -{ - /** - * Returns the update manager. - * - * @param string $uri The manifest file URI. - * - * @return Manager The update manager. - */ - public function getManager(string $uri): Manager - { - return new Manager(Manifest::loadFile($uri)); - } - - public function getName(): string - { - return 'phar-update'; - } -} diff --git a/src/Component/PharUpdate/Exception/Exception.php b/src/Component/PharUpdate/Exception/Exception.php deleted file mode 100644 index fce54bc20..000000000 --- a/src/Component/PharUpdate/Exception/Exception.php +++ /dev/null @@ -1,35 +0,0 @@ - - */ -class Exception extends \Exception implements ExceptionInterface -{ - /** - * Creates a new exception using a format and values. - * - * @param mixed $value,... The value(s). - */ - public static function create(string $format, $value = null): self - { - if (0 < func_num_args()) { - $format = vsprintf($format, array_slice(func_get_args(), 1)); - } - - return new static($format); - } - - /** - * Creates an exception for the last error message. - */ - public static function lastError(): self - { - $error = error_get_last(); - - return new static($error['message']); - } -} diff --git a/src/Component/PharUpdate/Exception/ExceptionInterface.php b/src/Component/PharUpdate/Exception/ExceptionInterface.php deleted file mode 100644 index 813798ac7..000000000 --- a/src/Component/PharUpdate/Exception/ExceptionInterface.php +++ /dev/null @@ -1,12 +0,0 @@ - - */ -interface ExceptionInterface -{ -} diff --git a/src/Component/PharUpdate/Exception/FileException.php b/src/Component/PharUpdate/Exception/FileException.php deleted file mode 100644 index 92585250c..000000000 --- a/src/Component/PharUpdate/Exception/FileException.php +++ /dev/null @@ -1,12 +0,0 @@ - - */ -class FileException extends Exception -{ -} diff --git a/src/Component/PharUpdate/Exception/InvalidArgumentException.php b/src/Component/PharUpdate/Exception/InvalidArgumentException.php deleted file mode 100644 index 7690c5687..000000000 --- a/src/Component/PharUpdate/Exception/InvalidArgumentException.php +++ /dev/null @@ -1,12 +0,0 @@ - - */ -class InvalidArgumentException extends Exception -{ -} diff --git a/src/Component/PharUpdate/Exception/LogicException.php b/src/Component/PharUpdate/Exception/LogicException.php deleted file mode 100644 index 1273dcf4a..000000000 --- a/src/Component/PharUpdate/Exception/LogicException.php +++ /dev/null @@ -1,12 +0,0 @@ - - */ -class LogicException extends Exception -{ -} diff --git a/src/Component/PharUpdate/Manager.php b/src/Component/PharUpdate/Manager.php deleted file mode 100644 index f7bd52cc9..000000000 --- a/src/Component/PharUpdate/Manager.php +++ /dev/null @@ -1,112 +0,0 @@ - - */ -class Manager -{ - /** - * The update manifest. - * - * @var Manifest - */ - private $manifest; - - /** - * The running file (the Phar that will be updated). - * - * @var string - */ - private $runningFile; - - /** - * Sets the update manifest. - * - * @param Manifest $manifest The manifest. - */ - public function __construct(Manifest $manifest) - { - $this->manifest = $manifest; - } - - /** - * Returns the manifest. - * - * @return Manifest The manifest. - */ - public function getManifest(): Manifest - { - return $this->manifest; - } - - /** - * Returns the running file (the Phar that will be updated). - * - * @return string The file. - */ - public function getRunningFile(): string - { - if (null === $this->runningFile) { - $this->runningFile = realpath($_SERVER['argv'][0]); - } - - return $this->runningFile; - } - - /** - * Sets the running file (the Phar that will be updated). - * - * @param string $file The file name or path. - * - * @throws Exception\Exception - * @throws InvalidArgumentException If the file path is invalid. - */ - public function setRunningFile(string $file): void - { - if (false === is_file($file)) { - throw InvalidArgumentException::create( - 'The file "%s" is not a file or it does not exist.', - $file - ); - } - - $this->runningFile = $file; - } - - /** - * Updates the running Phar if any is available. - * - * @param string|Version $version The current version. - * @param boolean $major Lock to current major version? - * @param boolean $pre Allow pre-releases? - * - * @return boolean TRUE if an update was performed, FALSE if none available. - */ - public function update($version, bool $major = false, bool $pre = false): bool - { - if (false === ($version instanceof Version)) { - $version = Parser::toVersion($version); - } - - if (null !== ($update = $this->manifest->findRecent( - $version, - $major, - $pre - ))) { - $update->getFile(); - $update->copyTo($this->getRunningFile()); - - return true; - } - - return false; - } -} diff --git a/src/Component/PharUpdate/Manifest.php b/src/Component/PharUpdate/Manifest.php deleted file mode 100644 index a9fa5f767..000000000 --- a/src/Component/PharUpdate/Manifest.php +++ /dev/null @@ -1,131 +0,0 @@ - - */ -class Manifest -{ - /** - * The list of updates in the manifest. - * - * @var Update[] - */ - private $updates; - - /** - * Sets the list of updates from the manifest. - * - * @param Update[] $updates The updates. - */ - public function __construct(array $updates = array()) - { - $this->updates = $updates; - } - - /** - * Finds the most recent update and returns it. - * - * @param Version $version The current version. - * @param boolean $major Lock to major version? - * @param boolean $pre Allow pre-releases? - */ - public function findRecent(Version $version, bool $major = false, bool $pre = false):? Update - { - /** @var Update|null */ - $current = null; - $major = $major ? $version->getMajor() : null; - - foreach ($this->updates as $update) { - if ($major && ($major !== $update->getVersion()->getMajor())) { - continue; - } - - if ((false === $pre) - && !$update->getVersion()->isStable()) { - continue; - } - - $test = $current ? $current->getVersion() : $version; - - if (false === $update->isNewer($test)) { - continue; - } - - $current = $update; - } - - return $current; - } - - /** - * Returns the list of updates in the manifest. - * - * @return Update[] The updates. - */ - public function getUpdates(): array - { - return $this->updates; - } - - /** - * Loads the manifest from a JSON encoded string. - * - * @param string $json The JSON encoded string. - */ - public static function load(string $json): self - { - return self::create(json_decode($json)); - } - - /** - * Loads the manifest from a JSON encoded file. - * - * @param string $file The JSON encoded file. - */ - public static function loadFile(string $file): self - { - return self::create(json_decode(file_get_contents($file))); - } - - /** - * Validates the data, processes it, and returns a new instance of Manifest. - * - * @param array $decoded The decoded JSON data. - * - * @return static The new instance. - */ - private static function create(array $decoded): self - { - $updates = array(); - - foreach ($decoded as $update) { - $updates[] = new Update( - $update->name, - $update->sha1, - $update->url, - Parser::toVersion($update->version), - isset($update->publicKey) ? $update->publicKey : null - ); - } - - usort( - $updates, - function (Update $a, Update $b) { - return Comparator::isGreaterThan( - $a->getVersion(), - $b->getVersion() - ) ? 1 : 0; - } - ); - - return new static($updates); - } -} diff --git a/src/Component/PharUpdate/Update.php b/src/Component/PharUpdate/Update.php deleted file mode 100644 index 7d897a30a..000000000 --- a/src/Component/PharUpdate/Update.php +++ /dev/null @@ -1,272 +0,0 @@ - - */ -class Update -{ - /** - * The temporary file path. - * - * @var string|null - */ - private $file; - - /** - * The name of the update file. - * - * @var string - */ - private $name; - - /** - * The URL where the public key can be downloaded from. - * - * @var string - */ - private $publicKey; - - /** - * The SHA1 file checksum. - * - * @var string - */ - private $sha1; - - /** - * The URL where the update can be downloaded from. - * - * @var string - */ - private $url; - - /** - * The version of the update. - * - * @var Version - */ - private $version; - - /** - * Sets the update information. - * - * @param string $name The name of the update file. - * @param string $sha1 The SHA1 file checksum. - * @param string $url The URL where the update can be downloaded from. - * @param Version $version The version of the update. - * @param string $key The URL where the public key can be downloaded - * from. - */ - public function __construct( - string $name, - string $sha1, - string $url, - Version $version, - string $key = null - ) { - $this->name = $name; - $this->publicKey = $key; - $this->sha1 = $sha1; - $this->url = $url; - $this->version = $version; - } - - /** - * Copies the update file to the destination. - * - * @param string $file The target file. - * - * @throws Exception\Exception - * @throws FileException If the file could not be replaced. - */ - public function copyTo(string $file): void - { - if (null === $this->file) { - throw LogicException::create( - 'The update file has not been downloaded.' - ); - } - - $mode = 0755; - - if (file_exists($file)) { - $mode = fileperms($file) & 511; - } - - if (false === @copy($this->file, $file)) { - throw FileException::lastError(); - } - - if (false === @chmod($file, $mode)) { - throw FileException::lastError(); - } - - $key = $file . '.pubkey'; - - if (file_exists($this->file . '.pubkey')) { - if (false === @copy($this->file . '.pubkey', $key)) { - throw FileException::lastError(); - } - } elseif (file_exists($key)) { - if (false === @unlink($key)) { - throw FileException::lastError(); - } - } - } - - /** - * Cleans up by deleting the temporary update file. - * - * @throws FileException If the file could not be deleted. - */ - public function deleteFile(): void - { - if ($this->file) { - if (file_exists($this->file)) { - if (false === @unlink($this->file)) { - throw FileException::lastError(); - } - } - - if (file_exists($this->file . '.pubkey')) { - if (false === @unlink($this->file . '.pubkey')) { - throw FileException::lastError(); - } - } - - $dir = dirname($this->file); - - if (file_exists($dir)) { - if (false === @rmdir($dir)) { - throw FileException::lastError(); - } - } - - $this->file = null; - } - } - - /** - * Downloads the update file to a temporary location. - * - * @return string The temporary file path. - * - * @throws Exception\Exception - * @throws FileException If the SHA1 checksum differs. - * @throws UnexpectedValueException If the Phar is corrupt. - */ - public function getFile():? string - { - if (null === $this->file) { - unlink($this->file = tempnam(sys_get_temp_dir(), 'upd')); - mkdir($this->file); - - $this->file .= DIRECTORY_SEPARATOR . $this->name; - - $in = new SplFileObject($this->url, 'rb', false); - $out = new SplFileObject($this->file, 'wb', false); - - while (false === $in->eof()) { - $out->fwrite($in->fgets()); - } - - unset($in, $out); - - if ($this->publicKey) { - $in = new SplFileObject($this->publicKey, 'r', false); - $out = new SplFileObject($this->file . '.pubkey', 'w', false); - - while (false === $in->eof()) { - $out->fwrite($in->fgets()); - } - - unset($in, $out); - } - - if ($this->sha1 !== ($sha1 = sha1_file($this->file))) { - $this->deleteFile(); - - throw FileException::create( - 'Mismatch of the SHA1 checksum (%s) of the downloaded file (%s).', - $this->sha1, - $sha1 - ); - } - - // double check - try { - new Phar($this->file); - } catch (UnexpectedValueException $exception) { - $this->deleteFile(); - - throw $exception; - } - } - - return $this->file; - } - - /** - * Returns name of the update file. - */ - public function getName(): string - { - return $this->name; - } - - /** - * Returns the URL where the public key can be downloaded from. - */ - public function getPublicKey(): string - { - return $this->publicKey; - } - - /** - * Returns the SHA1 file checksum. - */ - public function getSha1(): string - { - return $this->sha1; - } - - /** - * Returns the URL where the update can be downloaded from. - */ - public function getUrl(): string - { - return $this->url; - } - - /** - * Returns the version of the update. - */ - public function getVersion(): Version - { - return $this->version; - } - - /** - * Checks if this update is newer than the version given. - * - * @param Version $version The current version. - * - * @return boolean TRUE if the update is newer, FALSE if not. - */ - public function isNewer(Version $version): bool - { - return Comparator::isGreaterThan($this->version, $version); - } -} diff --git a/src/Component/PharUpdate/Version/Builder.php b/src/Component/PharUpdate/Version/Builder.php deleted file mode 100644 index 71451619e..000000000 --- a/src/Component/PharUpdate/Version/Builder.php +++ /dev/null @@ -1,278 +0,0 @@ - - */ -class Builder extends Version -{ - /** - * Removes the build metadata identifiers. - */ - public function clearBuild(): void - { - $this->build = array(); - } - - /** - * Removes the pre-release version identifiers. - */ - public function clearPreRelease(): void - { - $this->preRelease = array(); - } - - /** - * Creates a new Version builder. - * - * @return Builder The Version builder. - */ - public static function create(): Builder - { - return new Builder(); - } - - /** - * Returns a readonly Version instance. - * - * @return Version The readonly Version instance. - */ - public function getVersion(): Version - { - return new Version( - $this->major, - $this->minor, - $this->patch, - $this->preRelease, - $this->build - ); - } - - /** - * Imports the version components. - * - * @param array $components The components. - * - * @return Builder The Version builder. - */ - public function importComponents(array $components): self - { - if (isset($components[Parser::BUILD])) { - $this->build = $components[Parser::BUILD]; - } else { - $this->build = array(); - } - - if (isset($components[Parser::MAJOR])) { - $this->major = $components[Parser::MAJOR]; - } else { - $this->major = 0; - } - - if (isset($components[Parser::MINOR])) { - $this->minor = $components[Parser::MINOR]; - } else { - $this->minor = 0; - } - - if (isset($components[Parser::PATCH])) { - $this->patch = $components[Parser::PATCH]; - } else { - $this->patch = 0; - } - - if (isset($components[Parser::PRE_RELEASE])) { - $this->preRelease = $components[Parser::PRE_RELEASE]; - } else { - $this->preRelease = array(); - } - - return $this; - } - - /** - * Imports the version string representation. - * - * @param string $version The string representation. - * - * @return Builder The Version builder. - */ - public function importString(string $version): self - { - return $this->importComponents(Parser::toComponents($version)); - } - - /** - * Imports an existing Version instance. - * - * @param Version $version A Version instance. - * - * @return Builder The Version builder. - */ - public function importVersion(Version $version): self - { - return $this - ->setMajor($version->getMajor()) - ->setMinor($version->getMinor()) - ->setPatch($version->getPatch()) - ->setPreRelease($version->getPreRelease()) - ->setBuild($version->getBuild()); - } - - /** - * Increments the major version number and resets the minor and patch - * version numbers to zero. - * - * @param int $amount Increment by what amount? - * - * @return Builder The Version builder. - */ - public function incrementMajor(int $amount = 1): self - { - $this->major += $amount; - $this->minor = 0; - $this->patch = 0; - - return $this; - } - - /** - * Increments the minor version number and resets the patch version number - * to zero. - * - * @param int $amount Increment by what amount? - * - * @return Builder The Version builder. - */ - public function incrementMinor(int $amount = 1): self - { - $this->minor += $amount; - $this->patch = 0; - - return $this; - } - - /** - * Increments the patch version number. - * - * @param int $amount Increment by what amount? - * - * @return Builder The Version builder. - */ - public function incrementPatch(int $amount = 1): self - { - $this->patch += $amount; - - return $this; - } - - /** - * Sets the build metadata identifiers. - * - * @param array $identifiers The build metadata identifiers. - * - * @return Builder The Version builder. - * - * @throws InvalidIdentifierException If an identifier is invalid. - */ - public function setBuild(array $identifiers): self - { - foreach ($identifiers as $identifier) { - if (!Validator::isIdentifier($identifier)) { - throw new InvalidIdentifierException($identifier); - } - } - - $this->build = $identifiers; - - return $this; - } - - /** - * Sets the major version number. - * - * @param int $number The major version number. - * - * @return Builder The Version builder. - * - * @throws InvalidNumberException If the number is invalid. - */ - public function setMajor(int $number): self - { - if (!Validator::isNumber($number)) { - throw new InvalidNumberException($number); - } - - $this->major = intval($number); - - return $this; - } - - /** - * Sets the minor version number. - * - * @param int $number The minor version number. - * - * @return Builder The Version builder. - * - * @throws InvalidNumberException If the number is invalid. - */ - public function setMinor(int $number): self - { - if (!Validator::isNumber($number)) { - throw new InvalidNumberException($number); - } - - $this->minor = intval($number); - - return $this; - } - - /** - * Sets the patch version number. - * - * @param int $number The patch version number. - * - * @return Builder The Version builder. - * - * @throws InvalidNumberException If the number is invalid. - */ - public function setPatch(int $number): self - { - if (!Validator::isNumber($number)) { - throw new InvalidNumberException($number); - } - - $this->patch = intval($number); - - return $this; - } - - /** - * Sets the pre-release version identifiers. - * - * @param array $identifiers The pre-release version identifiers. - * - * @return Builder The Version builder. - * - * @throws InvalidIdentifierException If an identifier is invalid. - */ - public function setPreRelease(array $identifiers): self - { - foreach ($identifiers as $identifier) { - if (!Validator::isIdentifier($identifier)) { - throw new InvalidIdentifierException($identifier); - } - } - - $this->preRelease = $identifiers; - - return $this; - } -} diff --git a/src/Component/PharUpdate/Version/Comparator.php b/src/Component/PharUpdate/Version/Comparator.php deleted file mode 100644 index 0cbcd4237..000000000 --- a/src/Component/PharUpdate/Version/Comparator.php +++ /dev/null @@ -1,174 +0,0 @@ - - */ -class Comparator -{ - /** - * The version is equal to another. - */ - const EQUAL_TO = 0; - - /** - * The version is greater than another. - */ - const GREATER_THAN = 1; - - /** - * The version is less than another. - */ - const LESS_THAN = -1; - - /** - * Compares one version with another. - * - * @param Version $left The left version to compare. - * @param Version $right The right version to compare. - * - * @return integer Returns Comparator::EQUAL_TO if the two versions are - * equal. If the left version is less than the right - * version, Comparator::LESS_THAN is returned. If the left - * version is greater than the right version, - * Comparator::GREATER_THAN is returned. - */ - public static function compareTo(Version $left, Version $right) - { - switch (true) { - case ($left->getMajor() < $right->getMajor()): - return self::LESS_THAN; - case ($left->getMajor() > $right->getMajor()): - return self::GREATER_THAN; - case ($left->getMinor() > $right->getMinor()): - return self::GREATER_THAN; - case ($left->getMinor() < $right->getMinor()): - return self::LESS_THAN; - case ($left->getPatch() > $right->getPatch()): - return self::GREATER_THAN; - case ($left->getPatch() < $right->getPatch()): - return self::LESS_THAN; - // @codeCoverageIgnoreStart - } - // @codeCoverageIgnoreEnd - - return self::compareIdentifiers( - $left->getPreRelease(), - $right->getPreRelease() - ); - } - - /** - * Checks if the left version is equal to the right. - * - * @param Version $left The left version to compare. - * @param Version $right The right version to compare. - * - * @return boolean TRUE if the left version is equal to the right, FALSE - * if not. - */ - public static function isEqualTo(Version $left, Version $right) - { - return (self::EQUAL_TO === self::compareTo($left, $right)); - } - - /** - * Checks if the left version is greater than the right. - * - * @param Version $left The left version to compare. - * @param Version $right The right version to compare. - * - * @return boolean TRUE if the left version is greater than the right, - * FALSE if not. - */ - public static function isGreaterThan(Version $left, Version $right) - { - return (self::GREATER_THAN === self::compareTo($left, $right)); - } - - /** - * Checks if the left version is less than the right. - * - * @param Version $left The left version to compare. - * @param Version $right The right version to compare. - * - * @return boolean TRUE if the left version is less than the right, - * FALSE if not. - */ - public static function isLessThan(Version $left, Version $right) - { - return (self::LESS_THAN === self::compareTo($left, $right)); - } - - /** - * Compares the identifier components of the left and right versions. - * - * @param array $left The left identifiers. - * @param array $right The right identifiers. - * - * @return integer Returns Comparator::EQUAL_TO if the two identifiers are - * equal. If the left identifiers is less than the right - * identifiers, Comparator::LESS_THAN is returned. If the - * left identifiers is greater than the right identifiers, - * Comparator::GREATER_THAN is returned. - */ - public static function compareIdentifiers(array $left, array $right) - { - if ($left && empty($right)) { - return self::LESS_THAN; - } elseif (empty($left) && $right) { - return self::GREATER_THAN; - } - - $l = $left; - $r = $right; - $x = self::GREATER_THAN; - $y = self::LESS_THAN; - - if (count($l) < count($r)) { - $l = $right; - $r = $left; - $x = self::LESS_THAN; - $y = self::GREATER_THAN; - } - - foreach (array_keys($l) as $i) { - if (!isset($r[$i])) { - return $x; - } - - if ($l[$i] === $r[$i]) { - continue; - } - - if (true === ($li = (false != preg_match('/^\d+$/', $l[$i])))) { - $l[$i] = intval($l[$i]); - } - - if (true === ($ri = (false != preg_match('/^\d+$/', $r[$i])))) { - $r[$i] = intval($r[$i]); - } - - if ($li && $ri) { - return ($l[$i] > $r[$i]) ? $x : $y; - } elseif (!$li && $ri) { - return $x; - } elseif ($li && !$ri) { - return $y; - } - - $result = strcmp($l[$i], $r[$i]); - - if ($result > 0) { - return $x; - } elseif ($result < 0) { - return $y; - } - } - - return self::EQUAL_TO; - } -} diff --git a/src/Component/PharUpdate/Version/Dumper.php b/src/Component/PharUpdate/Version/Dumper.php deleted file mode 100644 index 4791328ec..000000000 --- a/src/Component/PharUpdate/Version/Dumper.php +++ /dev/null @@ -1,52 +0,0 @@ - - */ -class Dumper -{ - /** - * Returns the components of a Version instance. - * - * @param Version $version A version. - * - * @return array The components. - */ - public static function toComponents(Version $version) - { - return array( - Parser::MAJOR => $version->getMajor(), - Parser::MINOR => $version->getMinor(), - Parser::PATCH => $version->getPatch(), - Parser::PRE_RELEASE => $version->getPreRelease(), - Parser::BUILD => $version->getBuild() - ); - } - - /** - * Returns the string representation of a Version instance. - * - * @param Version $version A version. - * - * @return string The string representation. - */ - public static function toString(Version $version) - { - return sprintf( - '%d.%d.%d%s%s', - $version->getMajor(), - $version->getMinor(), - $version->getPatch(), - $version->getPreRelease() - ? '-' . join('.', $version->getPreRelease()) - : '', - $version->getBuild() - ? '+' . join('.', $version->getBuild()) - : '' - ); - } -} diff --git a/src/Component/PharUpdate/Version/Exception/InvalidIdentifierException.php b/src/Component/PharUpdate/Version/Exception/InvalidIdentifierException.php deleted file mode 100644 index 39b9f09c6..000000000 --- a/src/Component/PharUpdate/Version/Exception/InvalidIdentifierException.php +++ /dev/null @@ -1,45 +0,0 @@ - - */ -class InvalidIdentifierException extends VersionException -{ - /** - * The invalid identifier. - * - * @var string - */ - private $identifier; - - /** - * Sets the invalid identifier. - * - * @param string $identifier The invalid identifier. - */ - public function __construct(string $identifier) - { - parent::__construct( - sprintf( - 'The identifier "%s" is invalid.', - $identifier - ) - ); - - $this->identifier = $identifier; - } - - /** - * Returns the invalid identifier. - * - * @return string The invalid identifier. - */ - public function getIdentifier(): string - { - return $this->identifier; - } -} diff --git a/src/Component/PharUpdate/Version/Exception/InvalidNumberException.php b/src/Component/PharUpdate/Version/Exception/InvalidNumberException.php deleted file mode 100644 index afa7af07e..000000000 --- a/src/Component/PharUpdate/Version/Exception/InvalidNumberException.php +++ /dev/null @@ -1,45 +0,0 @@ - - */ -class InvalidNumberException extends VersionException -{ - /** - * The invalid version number. - * - * @var mixed - */ - private $number; - - /** - * Sets the invalid version number. - * - * @param mixed $number The invalid version number. - */ - public function __construct($number) - { - parent::__construct( - sprintf( - 'The version number "%s" is invalid.', - $number - ) - ); - - $this->number = $number; - } - - /** - * Returns the invalid version number. - * - * @return mixed The invalid version number. - */ - public function getNumber() - { - return $this->number; - } -} diff --git a/src/Component/PharUpdate/Version/Exception/InvalidStringRepresentationException.php b/src/Component/PharUpdate/Version/Exception/InvalidStringRepresentationException.php deleted file mode 100644 index 6839e187f..000000000 --- a/src/Component/PharUpdate/Version/Exception/InvalidStringRepresentationException.php +++ /dev/null @@ -1,45 +0,0 @@ - - */ -class InvalidStringRepresentationException extends VersionException -{ - /** - * The invalid string representation. - * - * @var string - */ - private $version; - - /** - * Sets the invalid string representation. - * - * @param string $version The string representation. - */ - public function __construct(string $version) - { - parent::__construct( - sprintf( - 'The version string representation "%s" is invalid.', - $version - ) - ); - - $this->version = $version; - } - - /** - * Returns the invalid string representation. - * - * @return string The invalid string representation. - */ - public function getVersion(): string - { - return $this->version; - } -} diff --git a/src/Component/PharUpdate/Version/Exception/VersionException.php b/src/Component/PharUpdate/Version/Exception/VersionException.php deleted file mode 100644 index 457023427..000000000 --- a/src/Component/PharUpdate/Version/Exception/VersionException.php +++ /dev/null @@ -1,14 +0,0 @@ - - */ -class VersionException extends Exception -{ -} diff --git a/src/Component/PharUpdate/Version/Parser.php b/src/Component/PharUpdate/Version/Parser.php deleted file mode 100644 index e33939597..000000000 --- a/src/Component/PharUpdate/Version/Parser.php +++ /dev/null @@ -1,115 +0,0 @@ - - */ -class Parser -{ - /** - * The build metadata component. - */ - const BUILD = 'build'; - - /** - * The major version number component. - */ - const MAJOR = 'major'; - - /** - * The minor version number component. - */ - const MINOR = 'minor'; - - /** - * The patch version number component. - */ - const PATCH = 'patch'; - - /** - * The pre-release version number component. - */ - const PRE_RELEASE = 'pre'; - - /** - * Returns a Version builder for the string representation. - * - * @param string $version The string representation. - * - * @return Builder A Version builder. - */ - public static function toBuilder(string $version): Builder - { - return Builder::create()->importComponents( - self::toComponents($version) - ); - } - - /** - * Returns the components of the string representation. - * - * @param string $version The string representation. - * - * @return array The components of the version. - * - * @throws InvalidStringRepresentationException If the string representation - * is invalid. - */ - public static function toComponents(string $version): array - { - if (!Validator::isVersion($version)) { - throw new InvalidStringRepresentationException($version); - } - - if (false !== strpos($version, '+')) { - list($version, $build) = explode('+', $version); - - $build = explode('.', $build); - } - - if (false !== strpos($version, '-')) { - list($version, $pre) = explode('-', $version); - - $pre = explode('.', $pre); - } - - list( - $major, - $minor, - $patch - ) = explode('.', $version); - - return array( - self::MAJOR => intval($major), - self::MINOR => intval($minor), - self::PATCH => intval($patch), - self::PRE_RELEASE => isset($pre) ? $pre : array(), - self::BUILD => isset($build) ? $build : array(), - ); - } - - /** - * Returns a Version instance for the string representation. - * - * @param string $version The string representation. - * - * @return Version A Version instance. - */ - public static function toVersion(string $version): Version - { - $components = self::toComponents($version); - - return new Version( - $components['major'], - $components['minor'], - $components['patch'], - $components['pre'], - $components['build'] - ); - } -} diff --git a/src/Component/PharUpdate/Version/Validator.php b/src/Component/PharUpdate/Version/Validator.php deleted file mode 100644 index 6fcf9965a..000000000 --- a/src/Component/PharUpdate/Version/Validator.php +++ /dev/null @@ -1,57 +0,0 @@ - - */ -class Validator -{ - /** - * The regular expression for a valid identifier. - */ - const IDENTIFIER_REGEX = '/^[0-9A-Za-z\-]+$/'; - - /** - * The regular expression for a valid semantic version number. - */ - const VERSION_REGEX = '/^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-([0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*))?(?:\+([0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*))?$/'; - - /** - * Checks if a identifier is valid. - * - * @param string $identifier A identifier. - * - * @return boolean TRUE if the identifier is valid, FALSE If not. - */ - public static function isIdentifier(string $identifier): bool - { - return (true == preg_match(self::IDENTIFIER_REGEX, $identifier)); - } - - /** - * Checks if a number is a valid version number. - * - * @param integer $number A number. - * - * @return boolean TRUE if the number is valid, FALSE If not. - */ - public static function isNumber(int $number): bool - { - return (true == preg_match('/^(0|[1-9]\d*)$/', (string)$number)); - } - - /** - * Checks if the string representation of a version number is valid. - * - * @param string $version The string representation. - * - * @return boolean TRUE if the string representation is valid, FALSE if not. - */ - public static function isVersion(string $version): bool - { - return (true == preg_match(self::VERSION_REGEX, $version)); - } -} diff --git a/src/Component/PharUpdate/Version/Version.php b/src/Component/PharUpdate/Version/Version.php deleted file mode 100644 index 737e7d533..000000000 --- a/src/Component/PharUpdate/Version/Version.php +++ /dev/null @@ -1,139 +0,0 @@ - - */ -class Version -{ - /** - * The build metadata identifiers. - * - * @var array - */ - protected $build; - - /** - * The major version number. - * - * @var integer - */ - protected $major; - - /** - * The minor version number. - * - * @var integer - */ - protected $minor; - - /** - * The patch version number. - * - * @var integer - */ - protected $patch; - - /** - * The pre-release version identifiers. - * - * @var array - */ - protected $preRelease; - - /** - * Sets the version information. - * - * @param int $major The major version number. - * @param int $minor The minor version number. - * @param int $patch The patch version number. - * @param array $pre The pre-release version identifiers. - * @param array $build The build metadata identifiers. - */ - public function __construct( - int $major = 0, - int $minor = 0, - int $patch = 0, - array $pre = array(), - array $build = array() - ) { - $this->build = $build; - $this->major = $major; - $this->minor = $minor; - $this->patch = $patch; - $this->preRelease = $pre; - } - - /** - * Returns the build metadata identifiers. - * - * @return array The build metadata identifiers. - */ - public function getBuild(): array - { - return $this->build; - } - - /** - * Returns the major version number. - * - * @return int The major version number. - */ - public function getMajor(): int - { - return $this->major; - } - - /** - * Returns the minor version number. - * - * @return int The minor version number. - */ - public function getMinor(): int - { - return $this->minor; - } - - /** - * Returns the patch version number. - * - * @return int The patch version number. - */ - public function getPatch(): int - { - return $this->patch; - } - - /** - * Returns the pre-release version identifiers. - * - * @return array The pre-release version identifiers. - */ - public function getPreRelease(): array - { - return $this->preRelease; - } - - /** - * Checks if the version number is stable. - * - * @return boolean TRUE if it is stable, FALSE if not. - */ - public function isStable(): bool - { - return empty($this->preRelease) && $this->major !== 0; - } - - /** - * Returns string representation. - * - * @return string The string representation. - */ - public function __toString(): string - { - return Dumper::toString($this); - } -} diff --git a/src/Component/Pimple/Container.php b/src/Component/Pimple/Container.php deleted file mode 100644 index b4daffde2..000000000 --- a/src/Component/Pimple/Container.php +++ /dev/null @@ -1,287 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Deployer\Component\Pimple; - -use Deployer\Component\Pimple\Exception\ExpectedInvokableException; -use Deployer\Component\Pimple\Exception\FrozenServiceException; -use Deployer\Component\Pimple\Exception\InvalidServiceIdentifierException; -use Deployer\Component\Pimple\Exception\UnknownIdentifierException; - -/** - * Container main class. - * - * @author Fabien Potencier - */ -class Container implements \ArrayAccess -{ - /** - * @var array - */ - private $values = []; - /** - * @var \SplObjectStorage - */ - private $factories; - /** - * @var \SplObjectStorage - */ - private $protected; - /** - * @var array - */ - private $frozen = []; - /** - * @var array - */ - private $raw = []; - /** - * @var array - */ - private $keys = []; - - /** - * Instantiates the container. - * - * Objects and parameters can be passed as argument to the constructor. - * - * @param array $values The parameters or objects - */ - public function __construct(array $values = []) - { - $this->factories = new \SplObjectStorage(); - $this->protected = new \SplObjectStorage(); - - foreach ($values as $key => $value) { - $this->offsetSet($key, $value); - } - } - - /** - * Sets a parameter or an object. - * - * Objects must be defined as Closures. - * - * Allowing any PHP callable leads to difficult to debug problems - * as function names (strings) are callable (creating a function with - * the same name as an existing parameter would break your container). - * - * @param string $id The unique identifier for the parameter or object - * @param mixed $value The value of the parameter or a closure to define an object - * - * @throws FrozenServiceException Prevent override of a frozen service - * @phpcsSuppress SlevomatCodingStandard.TypeHints.ParameterTypeHint.MissingNativeTypeHint - */ - #[\ReturnTypeWillChange] - public function offsetSet($id, $value) - { - if (isset($this->frozen[$id])) { - throw new FrozenServiceException($id); - } - - $this->values[$id] = $value; - $this->keys[$id] = true; - } - - /** - * Gets a parameter or an object. - * - * @param string $id The unique identifier for the parameter or object - * - * @return mixed The value of the parameter or an object - * - * @throws UnknownIdentifierException If the identifier is not defined - * @phpcsSuppress SlevomatCodingStandard.TypeHints.ParameterTypeHint.MissingNativeTypeHint - */ - #[\ReturnTypeWillChange] - public function offsetGet($id) - { - if (!isset($this->keys[$id])) { - throw new UnknownIdentifierException($id); - } - - if ( - isset($this->raw[$id]) - || !\is_object($this->values[$id]) - || isset($this->protected[$this->values[$id]]) - || !\method_exists($this->values[$id], '__invoke') - ) { - return $this->values[$id]; - } - - if (isset($this->factories[$this->values[$id]])) { - return $this->values[$id]($this); - } - - $raw = $this->values[$id]; - $val = $this->values[$id] = $raw($this); - $this->raw[$id] = $raw; - - $this->frozen[$id] = true; - - return $val; - } - - /** - * Checks if a parameter or an object is set. - * - * @param string $id The unique identifier for the parameter or object - * - * @return bool - * @phpcsSuppress SlevomatCodingStandard.TypeHints.ParameterTypeHint.MissingNativeTypeHint - */ - #[\ReturnTypeWillChange] - public function offsetExists($id) - { - return isset($this->keys[$id]); - } - - /** - * Unsets a parameter or an object. - * - * @param string $id The unique identifier for the parameter or object - * @phpcsSuppress SlevomatCodingStandard.TypeHints.ParameterTypeHint.MissingNativeTypeHint - */ - #[\ReturnTypeWillChange] - public function offsetUnset($id) - { - if (isset($this->keys[$id])) { - if (\is_object($this->values[$id])) { - unset($this->factories[$this->values[$id]], $this->protected[$this->values[$id]]); - } - - unset($this->values[$id], $this->frozen[$id], $this->raw[$id], $this->keys[$id]); - } - } - - /** - * Marks a callable as being a factory service. - * - * @param callable $callable A service definition to be used as a factory - * - * @return callable The passed callable - * - * @throws ExpectedInvokableException Service definition has to be a closure or an invokable object - */ - public function factory(callable $callable) - { - if (!\method_exists($callable, '__invoke')) { - throw new ExpectedInvokableException('Service definition is not a Closure or invokable object.'); - } - - $this->factories->attach($callable); - - return $callable; - } - - /** - * Protects a callable from being interpreted as a service. - * - * This is useful when you want to store a callable as a parameter. - * - * @param callable $callable A callable to protect from being evaluated - * - * @return callable The passed callable - * - * @throws ExpectedInvokableException Service definition has to be a closure or an invokable object - */ - public function protect(callable $callable) - { - if (!\method_exists($callable, '__invoke')) { - throw new ExpectedInvokableException('Callable is not a Closure or invokable object.'); - } - - $this->protected->attach($callable); - - return $callable; - } - - /** - * Gets a parameter or the closure defining an object. - * - * @param string $id The unique identifier for the parameter or object - * - * @return mixed The value of the parameter or the closure defining an object - * - * @throws UnknownIdentifierException If the identifier is not defined - */ - public function raw(string $id) - { - if (!isset($this->keys[$id])) { - throw new UnknownIdentifierException($id); - } - - if (isset($this->raw[$id])) { - return $this->raw[$id]; - } - - return $this->values[$id]; - } - - /** - * Extends an object definition. - * - * Useful when you want to extend an existing object definition, - * without necessarily loading that object. - * - * @param string $id The unique identifier for the object - * @param callable $callable A service definition to extend the original - * - * @return callable The wrapped callable - * - * @throws UnknownIdentifierException If the identifier is not defined - * @throws FrozenServiceException If the service is frozen - * @throws InvalidServiceIdentifierException If the identifier belongs to a parameter - * @throws ExpectedInvokableException If the extension callable is not a closure or an invokable object - */ - public function extend(string $id, callable $callable) - { - if (!isset($this->keys[$id])) { - throw new UnknownIdentifierException($id); - } - - if (isset($this->frozen[$id])) { - throw new FrozenServiceException($id); - } - - if (!\is_object($this->values[$id]) || !\method_exists($this->values[$id], '__invoke')) { - throw new InvalidServiceIdentifierException($id); - } - - if (isset($this->protected[$this->values[$id]])) { - @\trigger_error(\sprintf('How Pimple behaves when extending protected closures will be fixed in Pimple 4. Are you sure "%s" should be protected?', $id), E_USER_DEPRECATED); - } - - if (!\is_object($callable) || !\method_exists($callable, '__invoke')) { - throw new ExpectedInvokableException('Extension service definition is not a Closure or invokable object.'); - } - - $factory = $this->values[$id]; - - $extended = function ($c) use ($callable, $factory) { - return $callable($factory($c), $c); - }; - - if (isset($this->factories[$factory])) { - $this->factories->detach($factory); - $this->factories->attach($extended); - } - - return $this[$id] = $extended; - } - - /** - * Returns all defined value names. - * - * @return array An array of value names - */ - public function keys() - { - return \array_keys($this->values); - } -} diff --git a/src/Component/Pimple/Exception/ExpectedInvokableException.php b/src/Component/Pimple/Exception/ExpectedInvokableException.php deleted file mode 100644 index cd72204bb..000000000 --- a/src/Component/Pimple/Exception/ExpectedInvokableException.php +++ /dev/null @@ -1,20 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Deployer\Component\Pimple\Exception; - -use Psr\Container\ContainerExceptionInterface; - -/** - * A closure or invokable object was expected. - * - * @author Pascal Luna - */ -class ExpectedInvokableException extends \InvalidArgumentException implements ContainerExceptionInterface -{ -} diff --git a/src/Component/Pimple/Exception/FrozenServiceException.php b/src/Component/Pimple/Exception/FrozenServiceException.php deleted file mode 100644 index 8721fa1b1..000000000 --- a/src/Component/Pimple/Exception/FrozenServiceException.php +++ /dev/null @@ -1,27 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Deployer\Component\Pimple\Exception; - -use Psr\Container\ContainerExceptionInterface; - -/** - * An attempt to modify a frozen service was made. - * - * @author Pascal Luna - */ -class FrozenServiceException extends \RuntimeException implements ContainerExceptionInterface -{ - /** - * @param string $id Identifier of the frozen service - */ - public function __construct(string $id) - { - parent::__construct(\sprintf('Cannot override frozen service "%s".', $id)); - } -} diff --git a/src/Component/Pimple/Exception/InvalidServiceIdentifierException.php b/src/Component/Pimple/Exception/InvalidServiceIdentifierException.php deleted file mode 100644 index 481a8cb3e..000000000 --- a/src/Component/Pimple/Exception/InvalidServiceIdentifierException.php +++ /dev/null @@ -1,27 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Deployer\Component\Pimple\Exception; - -use Psr\Container\NotFoundExceptionInterface; - -/** - * An attempt to perform an operation that requires a service identifier was made. - * - * @author Pascal Luna - */ -class InvalidServiceIdentifierException extends \InvalidArgumentException implements NotFoundExceptionInterface -{ - /** - * @param string $id The invalid identifier - */ - public function __construct(string $id) - { - parent::__construct(\sprintf('Identifier "%s" does not contain an object definition.', $id)); - } -} diff --git a/src/Component/Pimple/Exception/UnknownIdentifierException.php b/src/Component/Pimple/Exception/UnknownIdentifierException.php deleted file mode 100644 index 1d9858c48..000000000 --- a/src/Component/Pimple/Exception/UnknownIdentifierException.php +++ /dev/null @@ -1,27 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Deployer\Component\Pimple\Exception; - -use Psr\Container\NotFoundExceptionInterface; - -/** - * The identifier of a valid service or parameter was expected. - * - * @author Pascal Luna - */ -class UnknownIdentifierException extends \InvalidArgumentException implements NotFoundExceptionInterface -{ - /** - * @param string $id The unknown identifier - */ - public function __construct(string $id) - { - parent::__construct(\sprintf('Identifier "%s" is not defined.', $id)); - } -} diff --git a/src/Component/ProcessRunner/Printer.php b/src/Component/ProcessRunner/Printer.php deleted file mode 100644 index a1f9422a1..000000000 --- a/src/Component/ProcessRunner/Printer.php +++ /dev/null @@ -1,74 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Deployer\Component\ProcessRunner; - -use Deployer\Host\Host; -use Symfony\Component\Console\Output\OutputInterface; - -class Printer -{ - /** - * @var OutputInterface - */ - private $output; - - public function __construct(OutputInterface $output) - { - $this->output = $output; - } - - public function command(Host $host, string $type, string $command): void - { - // -v for run command - if ($this->output->isVerbose()) { - $this->output->writeln("[$host] $type $command"); - } - } - - /** - * Returns a callable for use with the symfony Process->run($callable) method. - * - * @return callable A function expecting a int $type (e.g. Process::OUT or Process::ERR) and string $buffer parameters. - */ - public function callback(Host $host, bool $forceOutput): callable - { - return function ($type, $buffer) use ($forceOutput, $host) { - if ($this->output->isVerbose() || $forceOutput) { - $this->printBuffer($type, $host, $buffer); - } - }; - } - - /** - * @param string $type Process::OUT or Process::ERR - */ - public function printBuffer(string $type, Host $host, string $buffer): void - { - foreach (explode("\n", rtrim($buffer)) as $line) { - $this->writeln($type, $host, $line); - } - } - - public function writeln(string $type, Host $host, string $line): void - { - $line = self::filterOutput($line); - - // Omit empty lines - if (empty($line)) { - return; - } - - $this->output->writeln("[$host] $line"); - } - - public static function filterOutput(string $output): string - { - return preg_replace('/\[exit_code:(.*?)]/', '', $output); - } -} diff --git a/src/Component/ProcessRunner/ProcessRunner.php b/src/Component/ProcessRunner/ProcessRunner.php deleted file mode 100644 index cbd78cdb3..000000000 --- a/src/Component/ProcessRunner/ProcessRunner.php +++ /dev/null @@ -1,90 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Deployer\Component\ProcessRunner; - -use Deployer\Exception\RunException; -use Deployer\Exception\TimeoutException; -use Deployer\Host\Host; -use Deployer\Logger\Logger; -use Symfony\Component\Process\Exception\ProcessFailedException; -use Symfony\Component\Process\Exception\ProcessTimedOutException; -use Symfony\Component\Process\Process; - -class ProcessRunner -{ - /** - * @var Printer - */ - private $pop; - /** - * @var Logger - */ - private $logger; - - public function __construct(Printer $pop, Logger $logger) - { - $this->pop = $pop; - $this->logger = $logger; - } - - /** - * Runs a command, consider deployer global configs (timeout,...) - * - * @throws RunException - */ - public function run(Host $host, string $command, array $config = []): string - { - $defaults = [ - 'timeout' => $host->get('default_timeout', 300), - 'idle_timeout' => null, - 'cwd' => getenv('DEPLOYER_ROOT') !== false ? getenv('DEPLOYER_ROOT') : (defined('DEPLOYER_DEPLOY_FILE') ? dirname(DEPLOYER_DEPLOY_FILE) : null), - 'real_time_output' => false, - 'shell' => 'bash -s', - ]; - $config = array_merge($defaults, $config); - - $this->pop->command($host, 'run', $command); - - $terminalOutput = $this->pop->callback($host, $config['real_time_output']); - $callback = function ($type, $buffer) use ($host, $terminalOutput) { - $this->logger->printBuffer($host, $type, $buffer); - $terminalOutput($type, $buffer); - }; - - $command = str_replace('%secret%', $config['secret'] ?? '', $command); - $command = str_replace('%sudo_pass%', $config['sudo_pass'] ?? '', $command); - - $process = Process::fromShellCommandline($config['shell']) - ->setInput($command) - ->setTimeout($config['timeout']) - ->setIdleTimeout($config['idle_timeout']); - - if ($config['cwd'] !== null) { - $process->setWorkingDirectory($config['cwd']); - } - - try { - $process->mustRun($callback); - return $process->getOutput(); - } catch (ProcessFailedException $exception) { - throw new RunException( - $host, - $command, - $process->getExitCode(), - $process->getOutput(), - $process->getErrorOutput() - ); - } catch (ProcessTimedOutException $exception) { // @phpstan-ignore-line can be thrown but is absent from the phpdoc - throw new TimeoutException( - $command, - $exception->getExceededTimeout() - ); - } - } -} diff --git a/src/Component/Ssh/Client.php b/src/Component/Ssh/Client.php deleted file mode 100644 index 277c2ad5e..000000000 --- a/src/Component/Ssh/Client.php +++ /dev/null @@ -1,127 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Deployer\Component\Ssh; - -use Deployer\Component\ProcessRunner\Printer; -use Deployer\Exception\Exception; -use Deployer\Exception\RunException; -use Deployer\Exception\TimeoutException; -use Deployer\Host\Host; -use Deployer\Logger\Logger; -use Symfony\Component\Console\Output\OutputInterface; -use Symfony\Component\Process\Exception\ProcessTimedOutException; -use Symfony\Component\Process\Process; -use function Deployer\Support\parse_home_dir; - -class Client -{ - /** - * @var OutputInterface - */ - private $output; - - /** - * @var Printer - */ - private $pop; - - /** - * @var Logger - */ - private $logger; - - public function __construct(OutputInterface $output, Printer $pop, Logger $logger) - { - $this->output = $output; - $this->pop = $pop; - $this->logger = $logger; - } - - /** - * @throws RunException|TimeoutException|Exception - */ - public function run(Host $host, string $command, array $config = []): string - { - $defaults = [ - 'timeout' => $host->get('default_timeout', 300), - 'idle_timeout' => null, - 'real_time_output' => false, - 'no_throw' => false, - ]; - $config = array_merge($defaults, $config); - - $shellId = bin2hex(random_bytes(10)); - $shellCommand = $host->getShell(); - if ($host->has('become')) { - $shellCommand = "sudo -H -u {$host->get('become')} " . $shellCommand; - } - - $ssh = array_merge(['ssh'], $host->connectionOptionsArray(), [$host->connectionString(), ": $shellId; $shellCommand"]); - - // -vvv for ssh command - if ($this->output->isDebug()) { - $sshString = $ssh[0]; - for ($i = 1; $i < count($ssh); $i++) { - $sshString .= ' ' . escapeshellarg((string)$ssh[$i]); - } - $this->output->writeln("[$host] $sshString"); - } - - $this->pop->command($host, 'run', $command); - $this->logger->log("[{$host->getAlias()}] run $command"); - - $command = str_replace('%secret%', strval($config['secret'] ?? ''), $command); - $command = str_replace('%sudo_pass%', strval($config['sudo_pass'] ?? ''), $command); - - $process = new Process($ssh); - $process - ->setInput("( $command ); printf '[exit_code:%s]' $?;") - ->setTimeout($config['timeout']) - ->setIdleTimeout($config['idle_timeout']); - - $callback = function ($type, $buffer) use ($config, $host) { - $this->logger->printBuffer($host, $type, $buffer); - $this->pop->callback($host, boolval($config['real_time_output']))($type, $buffer); - }; - - try { - $process->run($callback); - } catch (ProcessTimedOutException $exception) { - // Let's try to kill all processes started by this command. - $pid = $this->run($host, "ps x | grep $shellId | grep -v grep | awk '{print \$1}'"); - // Minus before pid means all processes in this group. - $this->run($host, "kill -9 -$pid"); - throw new TimeoutException( - $command, - $exception->getExceededTimeout() - ); - } - - $output = $this->pop->filterOutput($process->getOutput()); - $exitCode = $this->parseExitStatus($process); - - if ($exitCode !== 0 && !$config['no_throw']) { - throw new RunException( - $host, - $command, - $exitCode, - $output, - $process->getErrorOutput() - ); - } - - return $output; - } - - private function parseExitStatus(Process $process): int - { - preg_match('/\[exit_code:(\d*)]/', $process->getOutput(), $match); - return (int)($match[1] ?? -1); - } -} diff --git a/src/Component/Ssh/IOArguments.php b/src/Component/Ssh/IOArguments.php deleted file mode 100644 index 90df28422..000000000 --- a/src/Component/Ssh/IOArguments.php +++ /dev/null @@ -1,73 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Deployer\Component\Ssh; - -use Deployer\Exception\Exception; -use Symfony\Component\Console\Input\InputInterface; -use Symfony\Component\Console\Output\OutputInterface; - -class IOArguments -{ - public static function collect(InputInterface $input, OutputInterface $output): array - { - $arguments = []; - foreach ($input->getOptions() as $name => $value) { - if (!$input->getOption($name)) { - continue; - } - if ($name === 'file') { - $arguments[] = "--file"; - $arguments[] = ltrim($value, '='); - continue; - } - if (in_array($name, ['verbose'], true)) { - continue; - } - if (!is_array($value)) { - $value = [$value]; - } - foreach ($value as $v) { - if (is_bool($v)) { - $arguments[] = "--$name"; - continue; - } - - $arguments[] = "--$name"; - $arguments[] = $v; - } - } - - if ($output->isDecorated()) { - $arguments[] = '--decorated'; - } - $verbosity = self::verbosity($output->getVerbosity()); - if (!empty($verbosity)) { - $arguments[] = $verbosity; - } - return $arguments; - } - - private static function verbosity(int $verbosity): string - { - switch ($verbosity) { - case OutputInterface::VERBOSITY_QUIET: - return '-q'; - case OutputInterface::VERBOSITY_NORMAL: - return ''; - case OutputInterface::VERBOSITY_VERBOSE: - return '-v'; - case OutputInterface::VERBOSITY_VERY_VERBOSE: - return '-vv'; - case OutputInterface::VERBOSITY_DEBUG: - return '-vvv'; - default: - throw new Exception('Unknown verbosity level: ' . $verbosity); - } - } -} diff --git a/src/Configuration/Configuration.php b/src/Configuration/Configuration.php deleted file mode 100644 index 0765d8069..000000000 --- a/src/Configuration/Configuration.php +++ /dev/null @@ -1,241 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Deployer\Configuration; - -use Deployer\Exception\ConfigurationException; -use Deployer\Utility\Httpie; -use function Deployer\Support\array_merge_alternate; -use function Deployer\Support\is_closure; -use function Deployer\Support\normalize_line_endings; - -class Configuration implements \ArrayAccess -{ - /** - * @var Configuration|null - */ - private $parent; - - /** - * @var array - */ - private $values = []; - - public function __construct(Configuration $parent = null) - { - $this->parent = $parent; - } - - public function update(array $values): void - { - $this->values = array_merge($this->values, $values); - } - - public function bind(Configuration $parent): void - { - $this->parent = $parent; - } - - /** - * @param mixed $value - */ - public function set(string $name, $value): void - { - $this->values[$name] = $value; - } - - public function has(string $name): bool - { - $ok = array_key_exists($name, $this->values); - if ($ok) { - return true; - } - if ($this->parent) { - return $this->parent->has($name); - } - return false; - } - - public function hasOwn(string $name): bool - { - return array_key_exists($name, $this->values); - } - - public function add(string $name, array $array): void - { - if ($this->has($name)) { - $config = $this->get($name); - if (!is_array($config)) { - throw new ConfigurationException("Config option \"$name\" isn't array."); - } - $this->set($name, array_merge_alternate($config, $array)); - } else { - $this->set($name, $array); - } - } - - /** - * @param mixed|null $default - * @return mixed|null - */ - public function get(string $name, $default = null) - { - if (array_key_exists($name, $this->values)) { - if (is_closure($this->values[$name])) { - return $this->values[$name] = $this->parse(call_user_func($this->values[$name])); - } else { - return $this->parse($this->values[$name]); - } - } - - if ($this->parent) { - $rawValue = $this->parent->fetch($name); - if ($rawValue !== null) { - if (is_closure($rawValue)) { - return $this->values[$name] = $this->parse(call_user_func($rawValue)); - } else { - return $this->values[$name]= $this->parse($rawValue); - } - } - } - - if (func_num_args() >= 2) { - return $this->parse($default); - } - - throw new ConfigurationException("Config option \"$name\" does not exist."); - } - - /** - * @return mixed|null - */ - public function fetch(string $name) - { - if (array_key_exists($name, $this->values)) { - return $this->values[$name]; - } - if ($this->parent) { - return $this->parent->fetch($name); - } - return null; - } - - /** - * @param string|mixed $value - * @return string|mixed - */ - public function parse($value) - { - if (is_string($value)) { - $normalizedValue = normalize_line_endings($value); - return preg_replace_callback('/\{\{\s*([\w\.\/-]+)\s*\}\}/', [$this, 'parseCallback'], $normalizedValue); - } - - return $value; - } - - public function ownValues(): array - { - return $this->values; - } - - public function keys(): array - { - return array_keys($this->values); - } - - /** - * @param array $matches - * @return mixed|null - */ - private function parseCallback(array $matches) - { - return isset($matches[1]) ? $this->get($matches[1]) : null; - } - - /** - * @param mixed $offset - * @return bool - */ - #[\ReturnTypeWillChange] - public function offsetExists($offset) - { - return $this->has($offset); - } - - /** - * @param string $offset - * @return mixed|null - * @phpcsSuppress SlevomatCodingStandard.TypeHints.ParameterTypeHint.MissingNativeTypeHint - */ - #[\ReturnTypeWillChange] - public function offsetGet($offset) - { - return $this->get($offset); - } - - /** - * @param string $offset - * @param mixed $value - * @phpcsSuppress SlevomatCodingStandard.TypeHints.ParameterTypeHint.MissingNativeTypeHint - */ - #[\ReturnTypeWillChange] - public function offsetSet($offset, $value): void - { - $this->set($offset, $value); - } - - /** - * @param mixed $offset - */ - #[\ReturnTypeWillChange] - public function offsetUnset($offset): void - { - unset($this->values[$offset]); - } - - public function load(): void - { - if (!$this->has('master_url')) { - return; - } - - $values = Httpie::get($this->get('master_url') . '/load') - ->jsonBody([ - 'host' => $this->get('alias'), - ]) - ->getJson(); - $this->update($values); - } - - public function save(): void - { - if (!$this->has('master_url')) { - return; - } - - Httpie::get($this->get('master_url') . '/save') - ->jsonBody([ - 'host' => $this->get('alias'), - 'config' => $this->persist(), - ]) - ->getJson(); - } - - public function persist(): array - { - $values = []; - foreach ($this->values as $key => $value) { - if (is_closure($value)) { - continue; - } - $values[$key] = $value; - } - return $values; - } -} diff --git a/src/Deployer.php b/src/Deployer.php deleted file mode 100755 index be8c9fc10..000000000 --- a/src/Deployer.php +++ /dev/null @@ -1,380 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Deployer; - -use Deployer\Collection\Collection; -use Deployer\Command\BlackjackCommand; -use Deployer\Command\ConfigCommand; -use Deployer\Command\InitCommand; -use Deployer\Command\MainCommand; -use Deployer\Command\RunCommand; -use Deployer\Command\SshCommand; -use Deployer\Command\TreeCommand; -use Deployer\Command\WorkerCommand; -use Deployer\Component\PharUpdate\Console\Command as PharUpdateCommand; -use Deployer\Component\PharUpdate\Console\Helper as PharUpdateHelper; -use Deployer\Component\Pimple\Container; -use Deployer\Component\ProcessRunner\Printer; -use Deployer\Component\ProcessRunner\ProcessRunner; -use Deployer\Component\Ssh\Client; -use Deployer\Configuration\Configuration; -use Deployer\Executor\Master; -use Deployer\Executor\Messenger; -use Deployer\Executor\Server; -use Deployer\Host\Host; -use Deployer\Host\HostCollection; -use Deployer\Host\Localhost; -use Deployer\Importer\Importer; -use Deployer\Logger\Handler\FileHandler; -use Deployer\Logger\Handler\NullHandler; -use Deployer\Logger\Logger; -use Deployer\Selector\Selector; -use Deployer\Task; -use Deployer\Task\ScriptManager; -use Deployer\Task\TaskCollection; -use Deployer\Utility\Httpie; -use Deployer\Utility\Rsync; -use Symfony\Component\Console; -use Symfony\Component\Console\Application; -use Symfony\Component\Console\Input\ArgvInput; -use Symfony\Component\Console\Input\InputDefinition; -use Symfony\Component\Console\Input\InputInterface; -use Symfony\Component\Console\Input\InputOption; -use Symfony\Component\Console\Output\ConsoleOutput; -use Symfony\Component\Console\Output\OutputInterface; -use Throwable; - -/** - * Deployer class represents DI container for configuring - * - * @property Application $console - * @property InputInterface $input - * @property OutputInterface $output - * @property Task\TaskCollection|Task\Task[] $tasks - * @property HostCollection|Host[] $hosts - * @property Configuration $config - * @property Rsync $rsync - * @property Client $sshClient - * @property ProcessRunner $processRunner - * @property Task\ScriptManager $scriptManager - * @property Selector $selector - * @property Server $server - * @property Master $master - * @property Messenger $messenger - * @property Messenger $logger - * @property Printer $pop - * @property Collection $fail - * @property InputDefinition $inputDefinition - * @property Importer $importer - */ -class Deployer extends Container -{ - /** - * Global instance of deployer. It's can be accessed only after constructor call. - * @var Deployer - */ - private static $instance; - - public function __construct(Application $console) - { - parent::__construct(); - - /****************************** - * Console * - ******************************/ - - $console->getDefinition()->addOption( - new InputOption('file', 'f', InputOption::VALUE_REQUIRED, 'Recipe file path') - ); - - $this['console'] = function () use ($console) { - return $console; - }; - $this['input'] = function () { - throw new \RuntimeException('Uninitialized "input" in Deployer container.'); - }; - $this['output'] = function () { - throw new \RuntimeException('Uninitialized "output" in Deployer container.'); - }; - $this['inputDefinition'] = function () { - return new InputDefinition(); - }; - $this['questionHelper'] = function () { - return $this->getHelper('question'); - }; - - /****************************** - * Config * - ******************************/ - - $this['config'] = function () { - return new Configuration(); - }; - // -l act as if it had been invoked as a login shell (i.e. source ~/.profile file) - // -s commands are read from the standard input (no arguments should remain after this option) - $this->config['shell'] = function () { - if (currentHost() instanceof Localhost) { - return 'bash -s'; // Non-login shell for localhost. - } - return 'bash -ls'; - }; - $this->config['forward_agent'] = true; - $this->config['ssh_multiplexing'] = true; - - /****************************** - * Core * - ******************************/ - - $this['pop'] = function ($c) { - return new Printer($c['output']); - }; - $this['sshClient'] = function ($c) { - return new Client($c['output'], $c['pop'], $c['logger']); - }; - $this['rsync'] = function ($c) { - return new Rsync($c['pop'], $c['output']); - }; - $this['processRunner'] = function ($c) { - return new ProcessRunner($c['pop'], $c['logger']); - }; - $this['tasks'] = function () { - return new TaskCollection(); - }; - $this['hosts'] = function () { - return new HostCollection(); - }; - $this['scriptManager'] = function ($c) { - return new ScriptManager($c['tasks']); - }; - $this['selector'] = function ($c) { - return new Selector($c['hosts']); - }; - $this['fail'] = function () { - return new Collection(); - }; - $this['messenger'] = function ($c) { - return new Messenger($c['input'], $c['output'], $c['logger']); - }; - $this['server'] = function ($c) { - return new Server( - $c['output'], - $this, - ); - }; - $this['master'] = function ($c) { - return new Master( - $c['input'], - $c['output'], - $c['server'], - $c['messenger'], - ); - }; - $this['importer'] = function () { - return new Importer(); - }; - - /****************************** - * Logger * - ******************************/ - - $this['log_handler'] = function () { - return !empty($this['log']) - ? new FileHandler($this['log']) - : new NullHandler(); - }; - $this['logger'] = function () { - return new Logger($this['log_handler']); - }; - - self::$instance = $this; - } - - public static function get(): self - { - return self::$instance; - } - - /** - * Init console application - */ - public function init() - { - $this->addTaskCommands(); - $this->getConsole()->add(new BlackjackCommand()); - $this->getConsole()->add(new ConfigCommand($this)); - $this->getConsole()->add(new WorkerCommand($this)); - $this->getConsole()->add(new InitCommand()); - $this->getConsole()->add(new TreeCommand($this)); - $this->getConsole()->add(new SshCommand($this)); - $this->getConsole()->add(new RunCommand($this)); - if (self::isPharArchive()) { - $selfUpdate = new PharUpdateCommand('self-update'); - $selfUpdate->setDescription('Updates deployer.phar to the latest version'); - $selfUpdate->setManifestUri('https://deployer.org/manifest.json'); - $selfUpdate->setRunningFile(DEPLOYER_BIN); - $this->getConsole()->add($selfUpdate); - $this->getConsole()->getHelperSet()->set(new PharUpdateHelper()); - } - } - - /** - * Transform tasks to console commands. - */ - public function addTaskCommands() - { - foreach ($this->tasks as $name => $task) { - $command = new MainCommand($name, $task->getDescription(), $this); - $command->setHidden($task->isHidden()); - - $this->getConsole()->add($command); - } - } - - /** - * @return mixed - * @throws \InvalidArgumentException - */ - public function __get(string $name) - { - if (isset($this[$name])) { - return $this[$name]; - } else { - throw new \InvalidArgumentException("Property \"$name\" does not exist."); - } - } - - /** - * @param mixed $value - */ - public function __set(string $name, $value) - { - $this[$name] = $value; - } - - public function getConsole(): Application - { - return $this['console']; - } - - public function getHelper(string $name): Console\Helper\HelperInterface - { - return $this->getConsole()->getHelperSet()->get($name); - } - - /** - * Run Deployer - */ - public static function run(string $version, ?string $deployFile) - { - if (str_contains($version, 'master')) { - // Get version from composer.lock - $lockFile = __DIR__ . '/../../../../composer.lock'; - if (file_exists($lockFile)) { - $content = file_get_contents($lockFile); - $json = json_decode($content); - foreach ($json->packages as $package) { - if ($package->name === 'deployer/deployer') { - $version = $package->version; - } - } - } - } - - // Version must be without "v" prefix. - // Incorrect: v7.0.0 - // Correct: 7.0.0 - // But deployphp/deployer uses tags with "v", and it gets passed to - // the composer.json file. Let's manually remove it from the version. - if (preg_match("/^v/", $version)) { - $version = substr($version, 1); - } - - if (!defined('DEPLOYER_VERSION')) { - define('DEPLOYER_VERSION', $version); - } - - $input = new ArgvInput(); - $output = new ConsoleOutput(); - - try { - // Init Deployer - $console = new Application('Deployer', $version); - $deployer = new self($console); - - // Import recipe file - if (is_readable($deployFile ?? '')) { - $deployer->importer->import($deployFile); - } - - // Run Deployer - $deployer->init(); - $console->run($input, $output); - - } catch (Throwable $exception) { - if (str_contains("$input", "-vvv")) { - $output->setVerbosity(OutputInterface::VERBOSITY_DEBUG); - } - self::printException($output, $exception); - - exit(1); - } - } - - public static function printException(OutputInterface $output, Throwable $exception) - { - $class = get_class($exception); - $file = basename($exception->getFile()); - $output->writeln([ - " {$class} in {$file} on line {$exception->getLine()}:", - "", - implode("\n", array_map(function ($line) { - return " " . $line; - }, explode("\n", $exception->getMessage()))), - "", - ]); - if ($output->isDebug()) { - $output->writeln($exception->getTraceAsString()); - } - - if ($exception->getPrevious()) { - self::printException($output, $exception->getPrevious()); - } - } - - public static function isWorker(): bool - { - return Deployer::get()->config->has('master_url'); - } - - /** - * @param mixed ...$arguments - * @return array|bool|string - * @throws \Exception - */ - public static function proxyCallToMaster(Host $host, string $func, ...$arguments) - { - // As request to master will stop master permanently, - // wait a little bit in order for periodic timer of - // master gather worker outputs and print it to user. - usleep(100000); // Sleep 100ms. - return Httpie::get(get('master_url') . '/proxy') - ->setopt(CURLOPT_TIMEOUT, 0) // no timeout - ->jsonBody([ - 'host' => $host->getAlias(), - 'func' => $func, - 'arguments' => $arguments, - ]) - ->getJson(); - } - - public static function isPharArchive(): bool - { - return 'phar:' === substr(__FILE__, 0, 5); - } -} diff --git a/src/Documentation/ApiGen.php b/src/Documentation/ApiGen.php deleted file mode 100644 index ff69d16e5..000000000 --- a/src/Documentation/ApiGen.php +++ /dev/null @@ -1,111 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Deployer\Documentation; - -class ApiGen -{ - /** - * @var array - */ - private $fns = []; - - public function parse(string $source): void - { - $comment = ''; - $params = ''; - - $source = str_replace("\r\n", "\n", $source); - - $state = 'root'; - foreach (explode("\n", $source) as $lineNumber => $line) { - switch ($state) { - case 'root': - if (str_starts_with($line, '/**')) { - $state = 'comment'; - break; - } - if (str_starts_with($line, 'function')) { - $signature = preg_replace('/^function\s+/', '', $line); - $funcName = preg_replace('/\(.+$/', '', $signature); - $this->fns[] = [ - 'comment' => $comment, - 'params' => $params, - 'funcName' => $funcName, - 'signature' => $signature, - ]; - $comment = ''; - $params = ''; - break; - } - break; - - case 'comment': - if (str_ends_with($line, '*/')) { - $state = 'root'; - break; - } - if (preg_match('/^\s\*\s@param\s(?.+?)\$(?.+?)\s(?.+)$/', $line, $matches)) { - if (empty($params)) { - $params = "| Argument | Type | Comment |\n|---|---|---|\n"; - } - $type = implode(' or ', array_map(function ($t) { - $t = trim($t, ' '); - return "`$t`"; - }, explode('|', $matches['type']))); - $params .= "| `\${$matches['name']}` | $type | {$matches['comment']} |\n"; - break; - } - if (str_starts_with($line, ' * @')) { - break; - } - $comment .= preg_replace('/^\s\*\s?/', '', $line) . "\n"; - break; - } - } - } - - public function markdown(): string - { - $output = << - - - -# API Reference - - -MD; - - foreach ($this->fns as $fn) { - [ - 'comment' => $comment, - 'params' => $params, - 'funcName' => $funcName, - 'signature' => $signature, - ] = $fn; - - if (!empty($params)) { - $params = "\n$params"; - } - - $output .= << - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Deployer\Documentation; - - -class DocConfig -{ - /** - * @var string - */ - public $name; - /** - * @var string - */ - public $defaultValue; - /** - * @var string - */ - public $comment; - /** - * @var string - */ - public $recipePath; - /** - * @var int - */ - public $lineNumber; -} diff --git a/src/Documentation/DocGen.php b/src/Documentation/DocGen.php deleted file mode 100644 index 00ad078fc..000000000 --- a/src/Documentation/DocGen.php +++ /dev/null @@ -1,259 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Deployer\Documentation; - -use RecursiveDirectoryIterator; -use RecursiveIteratorIterator; -use RecursiveRegexIterator; -use RegexIterator; - -class DocGen -{ - /** - * @var string - */ - public $root; - /** - * @var DocRecipe[] - */ - public $recipes = []; - - public function __construct(string $root) - { - $this->root = str_replace(DIRECTORY_SEPARATOR, '/', realpath($root)); - } - - public function parse(string $source): void - { - $directory = new RecursiveDirectoryIterator($source); - $iterator = new RegexIterator(new RecursiveIteratorIterator($directory), '/^.+\.php$/i', RecursiveRegexIterator::GET_MATCH); - foreach ($iterator as [$path]) { - $realPath = str_replace(DIRECTORY_SEPARATOR, '/', realpath($path)); - $recipePath = str_replace($this->root . '/', '', $realPath); - $recipeName = preg_replace('/\.php$/i', '', basename($recipePath)); - $recipe = new DocRecipe($recipeName, $recipePath); - $recipe->parse(file_get_contents($path)); - $this->recipes[$recipePath] = $recipe; - } - } - - public function gen(string $destination): ?string - { - foreach ($this->recipes as $recipe) { - // $find will try to return DocConfig for a given config $name. - $findConfig = function (string $name) use ($recipe): ?DocConfig { - if (array_key_exists($name, $recipe->config)) { - return $recipe->config[$name]; - } - foreach ($recipe->require as $r) { - if (array_key_exists($r, $this->recipes)) { - if (array_key_exists($name, $this->recipes[$r]->config)) { - return $this->recipes[$r]->config[$name]; - } - } - } - foreach ($this->recipes as $r) { - if (array_key_exists($name, $r->config)) { - return $r->config[$name]; - } - } - return null; - }; - $findConfigOverride = function (DocRecipe $recipe, string $name) use (&$findConfigOverride): ?DocConfig { - foreach ($recipe->require as $r) { - if (array_key_exists($r, $this->recipes)) { - if (array_key_exists($name, $this->recipes[$r]->config)) { - return $this->recipes[$r]->config[$name]; - } - } - } - foreach ($recipe->require as $r) { - if (array_key_exists($r, $this->recipes)) { - return $findConfigOverride($this->recipes[$r], $name); - } - } - return null; - }; - // Replace all {{name}} with link to correct config declaration. - $replaceLinks = function (string $comment) use ($findConfig): string { - $output = ''; - $code = false; - foreach (explode("\n", $comment) as $i => $line) { - if (str_starts_with($line, '```') || str_starts_with($line, '~~~')) { - $code = !$code; - } - if ($code) { - $output .= $line; - $output .= "\n"; - continue; - } - $output .= preg_replace_callback('#(\{\{(?[\w_:\-/]+)\}\})#', function ($m) use ($findConfig) { - $name = $m['name']; - $config = $findConfig($name); - if ($config !== null) { - $md = php_to_md($config->recipePath); - $anchor = anchor($name); - return "[$name](/docs/$md#$anchor)"; - } - return "{{" . $name . "}}"; - }, $line); - $output .= "\n"; - } - return $output; - }; - $findTask = function (string $name) use ($recipe): ?DocTask { - if (array_key_exists($name, $recipe->tasks)) { - return $recipe->tasks[$name]; - } - foreach ($recipe->require as $r) { - if (array_key_exists($r, $this->recipes)) { - if (array_key_exists($name, $this->recipes[$r]->tasks)) { - return $this->recipes[$r]->tasks[$name]; - } - } - } - foreach ($this->recipes as $r) { - if (array_key_exists($name, $r->tasks)) { - return $r->tasks[$name]; - } - } - return null; - }; - - - $filePath = "$destination/" . php_to_md($recipe->recipePath); - - $intro = ''; - $config = ''; - $tasks = ''; - if (count($recipe->require) > 0) { - $intro .= "* Requires\n"; - foreach ($recipe->require as $r) { - $md = php_to_md($r); - $basename = basename($r, '.php'); - $intro .= " * [{$basename}](/docs/{$md})\n"; - } - } - if (!empty($recipe->comment)) { - $intro .= "\n$recipe->comment\n"; - } - if (count($recipe->config) > 0) { - $config .= "## Configuration\n"; - foreach ($recipe->config as $c) { - $anchor = anchor($c->name); - $config .= "### {$c->name}\n"; - $config .= "[Source](https://github.com/deployphp/deployer/blob/master/{$c->recipePath}#L{$c->lineNumber})\n\n"; - $o = $findConfigOverride($recipe, $c->name); - if ($o !== null) { - $md = php_to_md($o->recipePath); - $anchor = anchor($c->name); - $config .= "Overrides [{$c->name}](/docs/$md#$anchor) from `$o->recipePath`.\n\n"; - } - $config .= $replaceLinks($c->comment); - $config .= "\n"; - if ( - !empty($c->defaultValue) - && $c->defaultValue !== "''" - && $c->defaultValue !== '[]' - ) { - $config .= "```php title=\"Default value\"\n"; - $config .= $c->defaultValue; - $config .= "\n"; - $config .= "```\n"; - } - $config .= "\n\n"; - } - } - if (count($recipe->tasks) > 0) { - $tasks .= "## Tasks\n\n"; - foreach ($recipe->tasks as $t) { - $anchor = anchor($t->name); - $tasks .= "### {$t->name}\n"; - $tasks .= "[Source](https://github.com/deployphp/deployer/blob/master/{$t->recipePath}#L{$t->lineNumber})\n\n"; - $tasks .= add_tailing_dot($t->desc) . "\n\n"; - $tasks .= $replaceLinks($t->comment); - if (is_array($t->group)) { - $tasks .= "\n\n"; - $tasks .= "This task is group task which contains next tasks:\n"; - foreach ($t->group as $taskName) { - $t = $findTask($taskName); - if ($t !== null) { - $md = php_to_md($t->recipePath); - $anchor = anchor($t->name); - $tasks .= "* [$taskName](/docs/$md#$anchor)\n"; - } else { - $tasks .= "* `$taskName`\n"; - } - } - } - $tasks .= "\n\n"; - } - } - - $output = << - - - -# $recipe->recipeName - -[Source](/$recipe->recipePath) - -$intro -$config -$tasks -MD; - - if (!file_exists(dirname($filePath))) { - mkdir(dirname($filePath), 0755, true); - } - $output = remove_text_emoji($output); - file_put_contents($filePath, $output); - } - return null; - } -} - -function trim_comment(string $line): string -{ - return preg_replace('#^(/\*\*?\s?|\s\*\s?|//\s?)#', '', $line); -} - -function indent(string $text): string -{ - return implode("\n", array_map(function ($line) { - return " " . $line; - }, explode("\n", $text))); -} - -function php_to_md(string $file): string -{ - return preg_replace('#\.php$#', '.md', $file); -} - -function anchor(string $s): string -{ - return strtolower(str_replace(':', '', $s)); -} - -function remove_text_emoji(string $text): string -{ - return preg_replace('/:(bowtie|smile|laughing|blush|smiley|relaxed|smirk|heart_eyes|kissing_heart|kissing_closed_eyes|flushed|relieved|satisfied|grin|wink|stuck_out_tongue_winking_eye|stuck_out_tongue_closed_eyes|grinning|kissing|kissing_smiling_eyes|stuck_out_tongue|sleeping|worried|frowning|anguished|open_mouth|grimacing|confused|hushed|expressionless|unamused|sweat_smile|sweat|disappointed_relieved|weary|pensive|disappointed|confounded|fearful|cold_sweat|persevere|cry|sob|joy|astonished|scream|neckbeard|tired_face|angry|rage|triumph|sleepy|yum|mask|sunglasses|dizzy_face|imp|smiling_imp|neutral_face|no_mouth|innocent|alien|yellow_heart|blue_heart|purple_heart|heart|green_heart|broken_heart|heartbeat|heartpulse|two_hearts|revolving_hearts|cupid|sparkling_heart|sparkles|star|star2|dizzy|boom|collision|anger|exclamation|question|grey_exclamation|grey_question|zzz|dash|sweat_drops|notes|musical_note|fire|hankey|poop|shit|\+1|thumbsup|\-1|thumbsdown|ok_hand|punch|facepunch|fist|v|wave|hand|raised_hand|open_hands|point_up|point_down|point_left|point_right|raised_hands|pray|point_up_2|clap|muscle|metal|fu|walking|runner|running|couple|family|two_men_holding_hands|two_women_holding_hands|dancer|dancers|ok_woman|no_good|information_desk_person|raising_hand|bride_with_veil|person_with_pouting_face|person_frowning|bow|couplekiss|couple_with_heart|massage|haircut|nail_care|boy|girl|woman|man|baby|older_woman|older_man|person_with_blond_hair|man_with_gua_pi_mao|man_with_turban|construction_worker|cop|angel|princess|smiley_cat|smile_cat|heart_eyes_cat|kissing_cat|smirk_cat|scream_cat|crying_cat_face|joy_cat|pouting_cat|japanese_ogre|japanese_goblin|see_no_evil|hear_no_evil|speak_no_evil|guardsman|skull|feet|lips|kiss|droplet|ear|eyes|nose|tongue|love_letter|bust_in_silhouette|busts_in_silhouette|speech_balloon|thought_balloon|feelsgood|finnadie|goberserk|godmode|hurtrealbad|rage1|rage2|rage3|rage4|suspect|trollface|sunny|umbrella|cloud|snowflake|snowman|zap|cyclone|foggy|ocean|cat|dog|mouse|hamster|rabbit|wolf|frog|tiger|koala|bear|pig|pig_nose|cow|boar|monkey_face|monkey|horse|racehorse|camel|sheep|elephant|panda_face|snake|bird|baby_chick|hatched_chick|hatching_chick|chicken|penguin|turtle|bug|honeybee|ant|beetle|snail|octopus|tropical_fish|fish|whale|whale2|dolphin|cow2|ram|rat|water_buffalo|tiger2|rabbit2|dragon|goat|rooster|dog2|pig2|mouse2|ox|dragon_face|blowfish|crocodile|dromedary_camel|leopard|cat2|poodle|paw_prints|bouquet|cherry_blossom|tulip|four_leaf_clover|rose|sunflower|hibiscus|maple_leaf|leaves|fallen_leaf|herb|mushroom|cactus|palm_tree|evergreen_tree|deciduous_tree|chestnut|seedling|blossom|ear_of_rice|shell|globe_with_meridians|sun_with_face|full_moon_with_face|new_moon_with_face|new_moon|waxing_crescent_moon|first_quarter_moon|waxing_gibbous_moon|full_moon|waning_gibbous_moon|last_quarter_moon|waning_crescent_moon|last_quarter_moon_with_face|first_quarter_moon_with_face|moon|earth_africa|earth_americas|earth_asia|volcano|milky_way|partly_sunny|octocat|squirrel|bamboo|gift_heart|dolls|school_satchel|mortar_board|flags|fireworks|sparkler|wind_chime|rice_scene|jack_o_lantern|ghost|santa|christmas_tree|gift|bell|no_bell|tanabata_tree|tada|confetti_ball|balloon|crystal_ball|cd|dvd|floppy_disk|camera|video_camera|movie_camera|computer|tv|iphone|phone|telephone|telephone_receiver|pager|fax|minidisc|vhs|sound|speaker|mute|loudspeaker|mega|hourglass|hourglass_flowing_sand|alarm_clock|watch|radio|satellite|loop|mag|mag_right|unlock|lock|lock_with_ink_pen|closed_lock_with_key|key|bulb|flashlight|high_brightness|low_brightness|electric_plug|battery|calling|email|mailbox|postbox|bath|bathtub|shower|toilet|wrench|nut_and_bolt|hammer|seat|moneybag|yen|dollar|pound|euro|credit_card|money_with_wings|e-mail|inbox_tray|outbox_tray|envelope|incoming_envelope|postal_horn|mailbox_closed|mailbox_with_mail|mailbox_with_no_mail|door|smoking|bomb|gun|hocho|pill|syringe|page_facing_up|page_with_curl|bookmark_tabs|bar_chart|chart_with_upwards_trend|chart_with_downwards_trend|scroll|clipboard|calendar|date|card_index|file_folder|open_file_folder|scissors|pushpin|paperclip|black_nib|pencil2|straight_ruler|triangular_ruler|closed_book|green_book|blue_book|orange_book|notebook|notebook_with_decorative_cover|ledger|books|bookmark|name_badge|microscope|telescope|newspaper|football|basketball|soccer|baseball|tennis|8ball|rugby_football|bowling|golf|mountain_bicyclist|bicyclist|horse_racing|snowboarder|swimmer|surfer|ski|spades|hearts|clubs|diamonds|gem|ring|trophy|musical_score|musical_keyboard|violin|space_invader|video_game|black_joker|flower_playing_cards|game_die|dart|mahjong|clapper|memo|pencil|book|art|microphone|headphones|trumpet|saxophone|guitar|shoe|sandal|high_heel|lipstick|boot|shirt|tshirt|necktie|womans_clothes|dress|running_shirt_with_sash|jeans|kimono|bikini|ribbon|tophat|crown|womans_hat|mans_shoe|closed_umbrella|briefcase|handbag|pouch|purse|eyeglasses|fishing_pole_and_fish|coffee|tea|sake|baby_bottle|beer|beers|cocktail|tropical_drink|wine_glass|fork_and_knife|pizza|hamburger|fries|poultry_leg|meat_on_bone|spaghetti|curry|fried_shrimp|bento|sushi|fish_cake|rice_ball|rice_cracker|rice|ramen|stew|oden|dango|egg|bread|doughnut|custard|icecream|ice_cream|shaved_ice|birthday|cake|cookie|chocolate_bar|candy|lollipop|honey_pot|apple|green_apple|tangerine|lemon|cherries|grapes|watermelon|strawberry|peach|melon|banana|pear|pineapple|sweet_potato|eggplant|tomato|corn|house|house_with_garden|school|office|post_office|hospital|bank|convenience_store|love_hotel|hotel|wedding|church|department_store|european_post_office|city_sunrise|city_sunset|japanese_castle|european_castle|tent|factory|tokyo_tower|japan|mount_fuji|sunrise_over_mountains|sunrise|stars|statue_of_liberty|bridge_at_night|carousel_horse|rainbow|ferris_wheel|fountain|roller_coaster|ship|speedboat|boat|sailboat|rowboat|anchor|rocket|airplane|helicopter|steam_locomotive|tram|mountain_railway|bike|aerial_tramway|suspension_railway|mountain_cableway|tractor|blue_car|oncoming_automobile|car|red_car|taxi|oncoming_taxi|articulated_lorry|bus|oncoming_bus|rotating_light|police_car|oncoming_police_car|fire_engine|ambulance|minibus|truck|train|station|train2|bullettrain_front|bullettrain_side|light_rail|monorail|railway_car|trolleybus|ticket|fuelpump|vertical_traffic_light|traffic_light|warning|construction|beginner|atm|slot_machine|busstop|barber|hotsprings|checkered_flag|crossed_flags|izakaya_lantern|moyai|circus_tent|performing_arts|round_pushpin|triangular_flag_on_post|jp|kr|cn|us|fr|es|it|ru|gb|uk|de|one|two|three|four|five|six|seven|eight|nine|keycap_ten|1234|zero|hash|symbols|arrow_backward|arrow_down|arrow_forward|arrow_left|capital_abcd|abcd|abc|arrow_lower_left|arrow_lower_right|arrow_right|arrow_up|arrow_upper_left|arrow_upper_right|arrow_double_down|arrow_double_up|arrow_down_small|arrow_heading_down|arrow_heading_up|leftwards_arrow_with_hook|arrow_right_hook|left_right_arrow|arrow_up_down|arrow_up_small|arrows_clockwise|arrows_counterclockwise|rewind|fast_forward|information_source|ok|twisted_rightwards_arrows|repeat|repeat_one|new|top|up|cool|free|ng|cinema|koko|signal_strength|u5272|u5408|u55b6|u6307|u6708|u6709|u6e80|u7121|u7533|u7a7a|u7981|sa|restroom|mens|womens|baby_symbol|no_smoking|parking|wheelchair|metro|baggage_claim|accept|wc|potable_water|put_litter_in_its_place|secret|congratulations|m|passport_control|left_luggage|customs|ideograph_advantage|cl|sos|id|no_entry_sign|underage|no_mobile_phones|do_not_litter|non-potable_water|no_bicycles|no_pedestrians|children_crossing|no_entry|eight_spoked_asterisk|eight_pointed_black_star|heart_decoration|vs|vibration_mode|mobile_phone_off|chart|currency_exchange|aries|taurus|gemini|cancer|leo|virgo|libra|scorpius|sagittarius|capricorn|aquarius|pisces|ophiuchus|six_pointed_star|negative_squared_cross_mark|a|b|ab|o2|diamond_shape_with_a_dot_inside|recycle|end|on|soon|clock1|clock130|clock10|clock1030|clock11|clock1130|clock12|clock1230|clock2|clock230|clock3|clock330|clock4|clock430|clock5|clock530|clock6|clock630|clock7|clock730|clock8|clock830|clock9|clock930|heavy_dollar_sign|copyright|registered|tm|x|heavy_exclamation_mark|bangbang|interrobang|o|heavy_multiplication_x|heavy_plus_sign|heavy_minus_sign|heavy_division_sign|white_flower|100|heavy_check_mark|ballot_box_with_check|radio_button|link|curly_loop|wavy_dash|part_alternation_mark|trident|black_square|white_square|white_check_mark|black_square_button|white_square_button|black_circle|white_circle|red_circle|large_blue_circle|large_blue_diamond|large_orange_diamond|small_blue_diamond|small_orange_diamond|small_red_triangle|small_red_triangle_down|shipit):/i', ':​\1:', $text); -} - -function add_tailing_dot(string $sentence): string -{ - if (empty($sentence)) { - return $sentence; - } - if (str_ends_with($sentence, '.')) { - return $sentence; - } - return $sentence . '.'; -} diff --git a/src/Documentation/DocRecipe.php b/src/Documentation/DocRecipe.php deleted file mode 100644 index 7a0022bf3..000000000 --- a/src/Documentation/DocRecipe.php +++ /dev/null @@ -1,162 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Deployer\Documentation; - -class DocRecipe -{ - /** - * @var string - */ - public $recipeName; - /** - * @var string - */ - public $recipePath; - /** - * @var string - */ - public $comment; - /** - * @var string[] - */ - public $require = []; - /** - * @var DocConfig[] - */ - public $config = []; - /** - * @var DocTask[] - */ - public $tasks = []; - - public function __construct(string $recipeName, string $recipePath) - { - $this->recipeName = $recipeName; - $this->recipePath = $recipePath; - } - - /** - * @return bool|int - */ - public function parse(string $content) - { - $comment = ''; - $desc = ''; - $currentTask = null; - - $content = str_replace("\r\n", "\n", $content); - - $state = 'root'; - $lines = explode("\n", $content); - - for ($i = 0; $i < count($lines); $i++) { - $line = $lines[$i]; - $m = []; - $match = function ($regexp) use ($line, &$m) { - return preg_match("#$regexp#", $line, $m); - }; - switch ($state) { - case 'root': - if ($match('^/\*\*?')) { - $state = 'comment'; - $comment .= trim_comment($line) . "\n"; - break; - } - if ($match('^//')) { - $comment .= trim_comment($line) . "\n"; - break; - } - if ($match('^require.+?[\'"](?.+?)[\'"]')) { - $this->require[] = dirname($this->recipePath) . $m['recipe']; - break; - } - if ($match('^set\([\'"](?[\w_:\-/]+?)[\'"]')) { - $set = new DocConfig(); - $set->name = $m['config_name']; - $set->comment = trim($comment); - $comment = ''; - $set->recipePath = $this->recipePath; - $set->lineNumber = $i + 1; - if (preg_match('#^set\(.+?,\s(?.+?)\);$#', $line, $m)) { - $set->defaultValue = $m['value']; - } - if (preg_match('#^set\(.+?,\s\[$#', $line, $m)) { - $multiLineArray = "[\n"; - $line = $lines[++$i]; - while (!preg_match('/^]/', $line)) { - $multiLineArray .= $line . "\n"; - $line = $lines[++$i]; - } - $multiLineArray .= "]"; - $set->defaultValue = $multiLineArray; - } - $this->config[$set->name] = $set; - break; - } - if ($match('^desc\([\'"](?.+?)[\'"]\);$')) { - $desc = $m['desc']; - break; - } - if ($match('^task\([\'"](?[\w_:-]+?)[\'"],\s\[$')) { - $task = new DocTask(); - $task->name = $m['task_name']; - $task->desc = $desc; - $task->comment = trim($comment); - $comment = ''; - $task->group = []; - $task->recipePath = $this->recipePath; - $task->lineNumber = $i + 1; - $this->tasks[$task->name] = $task; - $state = 'group_task'; - $currentTask = $task; - break; - } - if ($match('^task\([\'"](?[\w_:-]+?)[\'"]')) { - $task = new DocTask(); - $task->name = $m['task_name']; - $task->desc = $desc; - $task->comment = trim($comment); - $comment = ''; - $task->recipePath = $this->recipePath; - $task->lineNumber = $i + 1; - $this->tasks[$task->name] = $task; - break; - } - if ($match('^<\?php')) { - break; - } - if ($match('^namespace Deployer;$')) { - $this->comment = $comment; - break; - } - - $desc = ''; - $comment = ''; - break; - - case 'comment': - if ($match('\*/\s*$')) { - $state = 'root'; - break; - } - $comment .= trim_comment($line) . "\n"; - break; - - case 'group_task': - if ($match('^\s+\'(?[\w_:-]+?)\',$')) { - $currentTask->group[] = $m['task_name']; - break; - } - $state = 'root'; - break; - } - } - return false; - } -} diff --git a/src/Documentation/DocTask.php b/src/Documentation/DocTask.php deleted file mode 100644 index 94ed034c2..000000000 --- a/src/Documentation/DocTask.php +++ /dev/null @@ -1,37 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Deployer\Documentation; - -class DocTask -{ - /** - * @var string - */ - public $name; - /** - * @var string - */ - public $desc; - /** - * @var string - */ - public $comment; - /** - * @var array - */ - public $group; - /** - * @var string - */ - public $recipePath; - /** - * @var int - */ - public $lineNumber; -} diff --git a/src/Exception/ConfigurationException.php b/src/Exception/ConfigurationException.php deleted file mode 100644 index 46eb86188..000000000 --- a/src/Exception/ConfigurationException.php +++ /dev/null @@ -1,13 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Deployer\Exception; - -class ConfigurationException extends \RuntimeException -{ -} diff --git a/src/Exception/Exception.php b/src/Exception/Exception.php deleted file mode 100644 index 1da52a902..000000000 --- a/src/Exception/Exception.php +++ /dev/null @@ -1,68 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Deployer\Exception; - -use Throwable; - -class Exception extends \Exception -{ - /** - * @var string - */ - private static $taskSourceLocation = ''; - /** - * @var string - */ - private $taskFilename = ''; - /** - * @var int|mixed - */ - private $taskLineNumber = 0; - - public function __construct(string $message = "", int $code = 0, Throwable $previous = null) - { - if (function_exists('debug_backtrace')) { - $trace = debug_backtrace(); - foreach ($trace as $t) { - if (!empty($t['file']) && $t['file'] === self::$taskSourceLocation) { - $this->taskFilename = basename($t['file']); - $this->taskLineNumber = $t['line']; - break; - } - } - } - parent::__construct($message, $code, $previous); - } - - public static function setTaskSourceLocation(string $filepath): void - { - self::$taskSourceLocation = $filepath; - } - - public function getTaskFilename(): string - { - return $this->taskFilename; - } - - public function getTaskLineNumber(): int - { - return $this->taskLineNumber; - } - - public function setTaskFilename(string $taskFilename): void - { - $this->taskFilename = $taskFilename; - } - - public function setTaskLineNumber(int $taskLineNumber): void - { - $this->taskLineNumber = $taskLineNumber; - } -} - diff --git a/src/Exception/GracefulShutdownException.php b/src/Exception/GracefulShutdownException.php deleted file mode 100644 index 6b25735db..000000000 --- a/src/Exception/GracefulShutdownException.php +++ /dev/null @@ -1,25 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Deployer\Exception; - -/** - * Then this exception thrown, it will not trigger "fail" callback. - * - * fail('deploy', 'deploy:failed'); - * - * task('deploy', function () { - * throw new GracefulShutdownException(...); - * }); - * - * In example above task `deploy:failed` will not be called. - */ -class GracefulShutdownException extends Exception -{ - const EXIT_CODE = 42; -} diff --git a/src/Exception/HttpieException.php b/src/Exception/HttpieException.php deleted file mode 100644 index 793a7ae76..000000000 --- a/src/Exception/HttpieException.php +++ /dev/null @@ -1,13 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Deployer\Exception; - -class HttpieException extends \RuntimeException -{ -} diff --git a/src/Exception/RunException.php b/src/Exception/RunException.php deleted file mode 100644 index 1d5d835ec..000000000 --- a/src/Exception/RunException.php +++ /dev/null @@ -1,83 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Deployer\Exception; - -use Deployer\Host\Host; -use Symfony\Component\Process\Process; - -class RunException extends Exception -{ - /** - * @var Host - */ - private $host; - /** - * @var string - */ - private $command; - /** - * @var int - */ - private $exitCode; - /** - * @var string - */ - private $output; - /** - * @var string - */ - private $errorOutput; - - public function __construct( - Host $host, - string $command, - int $exitCode, - string $output, - string $errorOutput - ) { - $this->host = $host; - $this->command = $command; - $this->exitCode = $exitCode; - $this->output = $output; - $this->errorOutput = $errorOutput; - - $message = sprintf('The command "%s" failed.', $command); - parent::__construct($message, $exitCode); - } - - public function getHost(): Host - { - return $this->host; - } - - public function getCommand(): string - { - return $this->command; - } - - public function getExitCode(): int - { - return $this->exitCode; - } - - public function getExitCodeText(): string - { - return Process::$exitCodes[$this->exitCode] ?? 'Unknown error'; - } - - public function getOutput(): string - { - return $this->output; - } - - public function getErrorOutput(): string - { - return $this->errorOutput; - } -} diff --git a/src/Exception/TimeoutException.php b/src/Exception/TimeoutException.php deleted file mode 100644 index 38592b581..000000000 --- a/src/Exception/TimeoutException.php +++ /dev/null @@ -1,20 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Deployer\Exception; - -class TimeoutException extends Exception -{ - public function __construct( - string $command, - ?float $timeout - ) { - $message = sprintf('The command "%s" exceeded the timeout of %s seconds.', $command, $timeout); - parent::__construct($message, 1); - } -} diff --git a/src/Exception/WillAskUser.php b/src/Exception/WillAskUser.php deleted file mode 100644 index 241c55da4..000000000 --- a/src/Exception/WillAskUser.php +++ /dev/null @@ -1,16 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Deployer\Exception; - -class WillAskUser extends Exception -{ - public function __construct(string $message) { - parent::__construct($message); - } -} diff --git a/src/Executor/Master.php b/src/Executor/Master.php deleted file mode 100644 index c4967f824..000000000 --- a/src/Executor/Master.php +++ /dev/null @@ -1,285 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Deployer\Executor; - -use Deployer\Component\Ssh\Client; -use Deployer\Component\Ssh\IOArguments; -use Deployer\Deployer; -use Deployer\Host\Host; -use Deployer\Host\Localhost; -use Deployer\Selector\Selector; -use Deployer\Task\Task; -use Symfony\Component\Console\Input\InputInterface; -use Symfony\Component\Console\Output\OutputInterface; -use Symfony\Component\Process\PhpExecutableFinder; -use Symfony\Component\Process\Process; - -const FRAMES = ['⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '⠇', '⠏']; - -function spinner(string $message = ''): string -{ - $frame = FRAMES[(int) ((new \DateTime)->format('u') / 1e5) % count(FRAMES)]; - return " $frame $message\r"; -} - -class Master -{ - /** - * @var InputInterface - */ - private $input; - - /** - * @var OutputInterface - */ - private $output; - - /** - * @var Server - */ - private $server; - - /** - * @var Messenger - */ - private $messenger; - - /** - * @var false|string - */ - private $phpBin; - - public function __construct( - InputInterface $input, - OutputInterface $output, - Server $server, - Messenger $messenger - ) - { - $this->input = $input; - $this->output = $output; - $this->server = $server; - $this->messenger = $messenger; - $this->phpBin = (new PhpExecutableFinder())->find(); - } - - /** - * @param Task[] $tasks - * @param Host[] $hosts - */ - public function run(array $tasks, array $hosts, ?Planner $plan = null): int - { - $globalLimit = (int)$this->input->getOption('limit') ?: count($hosts); - - foreach ($tasks as $task) { - if (!$plan) { - $this->messenger->startTask($task); - } - - $plannedHosts = $hosts; - - $limit = min($globalLimit, $task->getLimit() ?? $globalLimit); - - if ($task->isOnce()) { - $plannedHosts = []; - foreach ($hosts as $currentHost) { - if (Selector::apply($task->getSelector(), $currentHost)) { - $plannedHosts[] = $currentHost; - break; - } - } - } else if ($task->isOncePerNode()) { - $plannedHosts = []; - foreach ($hosts as $currentHost) { - if (Selector::apply($task->getSelector(), $currentHost)) { - $nodeLabel = $currentHost->getHostname(); - $labels = $currentHost->config()->get('labels', []); - if (is_array($labels) && array_key_exists('node', $labels)) { - $nodeLabel = $labels['node']; - } - if (array_key_exists($nodeLabel, $plannedHosts)) { - continue; - } - $plannedHosts[$nodeLabel] = $currentHost; - } - } - } - - if ($limit === 1 || count($plannedHosts) === 1) { - foreach ($plannedHosts as $currentHost) { - if (!Selector::apply($task->getSelector(), $currentHost)) { - if ($plan) { - $plan->commit([], $task); - } - continue; - } - - if ($plan) { - $plan->commit([$currentHost], $task); - continue; - } - - $exitCode = $this->runTask($task, [$currentHost]); - if ($exitCode !== 0) { - return $exitCode; - } - } - } else { - foreach (array_chunk($plannedHosts, $limit) as $chunk) { - $selectedHosts = []; - foreach ($chunk as $currentHost) { - if (Selector::apply($task->getSelector(), $currentHost)) { - $selectedHosts[] = $currentHost; - } - } - - if ($plan) { - $plan->commit($selectedHosts, $task); - continue; - } - - $exitCode = $this->runTask($task, $selectedHosts); - if ($exitCode !== 0) { - return $exitCode; - } - } - } - - if (!$plan) { - $this->messenger->endTask($task); - } - } - - return 0; - } - - /** - * @param Host[] $hosts - */ - private function runTask(Task $task, array $hosts): int - { - if (getenv('DEPLOYER_LOCAL_WORKER') === 'true') { - // This allows to code coverage all recipe, - // as well as speedup tests by not spawning - // lots of processes. Also there is a few tests - // what runs with workers for tests subprocess - // communications. - foreach ($hosts as $host) { - $worker = new Worker(Deployer::get()); - $exitCode = $worker->execute($task, $host); - if ($exitCode !== 0) { - return $exitCode; - } - } - return 0; - } - - $callback = function (string $output) { - $output = preg_replace('/\n$/', '', $output); - if (strlen($output) !== 0) { - $this->output->writeln($output); - } - }; - - /** @var Process[] $processes */ - $processes = []; - - $this->server->loop->futureTick(function () use (&$processes, $hosts, $task) { - foreach ($hosts as $host) { - $processes[] = $this->createProcess($host, $task); - } - - foreach ($processes as $process) { - $process->start(); - } - }); - - $this->server->loop->addPeriodicTimer(0.03, function ($timer) use (&$processes, $callback) { - $this->gatherOutput($processes, $callback); - if ($this->output->isDecorated() && !getenv('CI')) { - $this->output->write(spinner()); - } - if ($this->allFinished($processes)) { - $this->server->loop->stop(); - $this->server->loop->cancelTimer($timer); - } - }); - - $this->server->loop->run(); - - if ($this->output->isDecorated() && !getenv('CI')) { - $this->output->write(" \r"); // clear spinner - } - $this->gatherOutput($processes, $callback); - - return $this->cumulativeExitCode($processes); - } - - protected function createProcess(Host $host, Task $task): Process - { - $command = [ - $this->phpBin, DEPLOYER_BIN, - 'worker', '--port', $this->server->getPort(), - '--task', $task, - '--host', $host->getAlias(), - ]; - $command = array_merge($command, IOArguments::collect($this->input, $this->output)); - if ($task->isVerbose() && $this->output->getVerbosity() === OutputInterface::VERBOSITY_NORMAL) { - $command[] = '-v'; - } - if ($this->output->isDebug()) { - $this->output->writeln("[$host] " . join(' ', $command)); - } - return new Process($command); - } - - /** - * @param Process[] $processes - */ - protected function allFinished(array $processes): bool - { - foreach ($processes as $process) { - if (!$process->isTerminated()) { - return false; - } - } - return true; - } - - /** - * @param Process[] $processes - */ - protected function gatherOutput(array $processes, callable $callback): void - { - foreach ($processes as $process) { - $output = $process->getIncrementalOutput(); - if (strlen($output) !== 0) { - $callback($output); - } - - $errorOutput = $process->getIncrementalErrorOutput(); - if (strlen($errorOutput) !== 0) { - $callback($errorOutput); - } - } - } - - /** - * @param Process[] $processes - */ - protected function cumulativeExitCode(array $processes): int - { - foreach ($processes as $process) { - if ($process->getExitCode() > 0) { - return $process->getExitCode(); - } - } - return 0; - } -} diff --git a/src/Executor/Messenger.php b/src/Executor/Messenger.php deleted file mode 100644 index c6751da90..000000000 --- a/src/Executor/Messenger.php +++ /dev/null @@ -1,158 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Deployer\Executor; - -use Deployer\Exception\Exception; -use Deployer\Exception\RunException; -use Deployer\Host\Host; -use Deployer\Logger\Logger; -use Deployer\Task\Task; -use Symfony\Component\Console\Input\Input; -use Symfony\Component\Console\Output\Output; -use Throwable; - -class Messenger -{ - /** - * @var Input - */ - private $input; - - /** - * @var Output - */ - private $output; - - /** - * @var Logger - */ - private $logger; - - /** - * @var int|double - */ - private $startTime; - - public function __construct(Input $input, Output $output, Logger $logger) - { - $this->input = $input; - $this->output = $output; - $this->logger = $logger; - } - - public function startTask(Task $task): void - { - $this->startTime = round(microtime(true) * 1000); - if (getenv('GITHUB_WORKFLOW')) { - $this->output->writeln("::group::task {$task->getName()}"); - } else if (getenv('GITLAB_CI')) { - $this->output->writeln("\e[0Ksection_start:{$this->startTime}:{$this->startTime}[collapsed=true]\r\e[0K{$task->getName()}"); - } else { - $this->output->writeln("task {$task->getName()}"); - } - $this->logger->log("task {$task->getName()}"); - } - - /* - * Print task was ok. - */ - public function endTask(Task $task): void - { - if (empty($this->startTime)) { - $this->startTime = round(microtime(true) * 1000); - } - - $endTime = round(microtime(true) * 1000); - $millis = $endTime - $this->startTime; - $seconds = floor($millis / 1000); - $millis = $millis - $seconds * 1000; - $taskTime = ($seconds > 0 ? "{$seconds}s " : "") . "{$millis}ms"; - - if (getenv('GITHUB_WORKFLOW')) { - $this->output->writeln("::endgroup::"); - } else if (getenv('GITLAB_CI')) { - $this->output->writeln("\e[0Ksection_end:{$taskTime}:{$this->startTime}\r\e[0K"); - } else if ($this->output->isVeryVerbose()) { - $this->output->writeln("done {$task->getName()} $taskTime"); - } - $this->logger->log("done {$task->getName()} $taskTime"); - - if (!empty($this->input->getOption('profile'))) { - $line = sprintf("%s\t%s\n", $task->getName(), $taskTime); - file_put_contents($this->input->getOption('profile'), $line, FILE_APPEND); - } - } - - public function endOnHost(Host $host): void - { - if ($this->output->isVeryVerbose()) { - $this->output->writeln("done on $host"); - } - } - - public function renderException(Throwable $exception, Host $host): void - { - if ($exception instanceof RunException) { - - $message = ""; - $message .= "[$host] error in {$exception->getTaskFilename()} on line {$exception->getTaskLineNumber()}:\n"; - if ($this->output->getVerbosity() === Output::VERBOSITY_NORMAL) { - $message .= "[$host] run {$exception->getCommand()}\n"; - foreach (explode("\n", $exception->getErrorOutput()) as $line) { - $line = trim($line); - if ($line !== "") { - $message .= "[$host] err $line\n"; - } - } - foreach (explode("\n", $exception->getOutput()) as $line) { - $line = trim($line); - if ($line !== "") { - $message .= "[$host] $line\n"; - } - } - } - $message .= "[$host] exit code {$exception->getExitCode()} ({$exception->getExitCodeText()})\n"; - $this->output->write($message); - - } else { - $message = ""; - $class = get_class($exception); - $file = basename($exception->getFile()); - $line = $exception->getLine(); - if ($exception instanceof Exception) { - $file = $exception->getTaskFilename(); - $line = $exception->getTaskLineNumber(); - } - $message .= "[$host] $class in $file on line $line:\n"; - $message .= "[$host]\n"; - foreach (explode("\n", $exception->getMessage()) as $line) { - $line = trim($line); - if ($line !== "") { - $message .= "[$host] $line\n"; - } - } - $message .= "[$host]\n"; - if ($this->output->isDebug()) { - foreach (explode("\n", $exception->getTraceAsString()) as $line) { - $line = trim($line); - if ($line !== "") { - $message .= "[$host] $line\n"; - } - } - } - $this->output->write($message); - } - - $this->logger->log($exception->__toString()); - - if ($exception->getPrevious()) { - $this->renderException($exception->getPrevious(), $host); - } - } -} diff --git a/src/Executor/Planner.php b/src/Executor/Planner.php deleted file mode 100644 index 15b1bfb0f..000000000 --- a/src/Executor/Planner.php +++ /dev/null @@ -1,68 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Deployer\Executor; - -use Deployer\Host\Host; -use Deployer\Task\Task; -use Symfony\Component\Console\Helper\Table; -use Symfony\Component\Console\Output\OutputInterface; - -class Planner -{ - /** - * @var Table - */ - private $table; - /** - * @var array - */ - private $template; - - /** - * Planner constructor. - * - * @param Host[] $hosts - */ - public function __construct(OutputInterface $output, array $hosts) - { - $headers = []; - $this->template = []; - foreach ($hosts as $host) { - $headers[] = $host->getTag(); - $this->template[] = $host->getAlias(); - } - $this->table = new Table($output); - $this->table->setHeaders($headers); - $this->table->setStyle('box'); - } - - /** - * @param Host[] $hosts - */ - public function commit(array $hosts, Task $task): void - { - $row = []; - foreach ($this->template as $alias) { - $on = "-"; - foreach ($hosts as $host) { - if ($alias === $host->getAlias()) { - $on = $task->getName(); - break; - } - } - $row[] = $on; - } - $this->table->addRow($row); - } - - public function render() - { - $this->table->render(); - } -} diff --git a/src/Executor/Server.php b/src/Executor/Server.php deleted file mode 100644 index 81d022bc8..000000000 --- a/src/Executor/Server.php +++ /dev/null @@ -1,114 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Deployer\Executor; - -use Deployer\Deployer; -use Deployer\Exception\Exception; -use Deployer\Task\Context; -use Psr\Http\Message\ServerRequestInterface; -use React; -use React\EventLoop\Loop; -use React\Http\HttpServer; -use React\Http\Message\Response; -use Symfony\Component\Console\Input\InputInterface; -use Symfony\Component\Console\Output\OutputInterface; -use Throwable; - -class Server -{ - /** - * @var OutputInterface - */ - private $output; - - /** - * @var Deployer - */ - private $deployer; - - /** - * @var React\EventLoop\LoopInterface - */ - public $loop; - - /** - * @var int - */ - private $port; - - public function __construct( - OutputInterface $output, - Deployer $deployer - ) - { - $this->output = $output; - $this->deployer = $deployer; - } - - public function start() - { - $this->loop = Loop::get(); - $server = new HttpServer( - $this->loop, - new React\Http\Middleware\StreamingRequestMiddleware(), - new React\Http\Middleware\RequestBodyBufferMiddleware(16 * 1024 * 1024), // 16 MiB - function (ServerRequestInterface $request) { - try { - return $this->router($request); - } catch (Throwable $exception) { - Deployer::printException($this->output, $exception); - return new React\Http\Message\Response(500, ['Content-Type' => 'text/plain'], 'Master error: ' . $exception->getMessage()); - } - } - ); - $socket = new React\Socket\Server(0, $this->loop); - $server->listen($socket); - $address = $socket->getAddress(); - $this->port = parse_url($address, PHP_URL_PORT); - } - - private function router(ServerRequestInterface $request): Response - { - $path = $request->getUri()->getPath(); - switch ($path) { - case '/load': - ['host' => $host] = json_decode((string)$request->getBody(), true); - - $host = $this->deployer->hosts->get($host); - $config = json_encode($host->config()->persist()); - - return new Response(200, ['Content-Type' => 'application/json'], $config); - - case '/save': - ['host' => $host, 'config' => $config] = json_decode((string)$request->getBody(), true); - - $host = $this->deployer->hosts->get($host); - $host->config()->update($config); - - return new Response(200, ['Content-Type' => 'application/json'], 'true'); - - case '/proxy': - ['host' => $host, 'func' => $func, 'arguments' => $arguments] = json_decode((string)$request->getBody(), true); - - Context::push(new Context($this->deployer->hosts->get($host))); - $answer = call_user_func($func, ...$arguments); - Context::pop(); - - return new Response(200, ['Content-Type' => 'application/json'], json_encode($answer)); - - default: - throw new Exception('Server path not found: ' . $request->getUri()->getPath()); - } - } - - public function getPort(): int - { - return $this->port; - } -} diff --git a/src/Executor/Worker.php b/src/Executor/Worker.php deleted file mode 100644 index 2aea644ff..000000000 --- a/src/Executor/Worker.php +++ /dev/null @@ -1,55 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Deployer\Executor; - -use Deployer\Deployer; -use Deployer\Exception\Exception; -use Deployer\Exception\GracefulShutdownException; -use Deployer\Exception\RunException; -use Deployer\Host\Host; -use Deployer\Task\Context; -use Deployer\Task\Task; -use Throwable; - -class Worker -{ - /** - * @var Deployer - */ - private $deployer; - - public function __construct(Deployer $deployer) - { - $this->deployer = $deployer; - } - - public function execute(Task $task, Host $host): int - { - try { - Exception::setTaskSourceLocation($task->getSourceLocation()); - - $context = new Context($host); - $task->run($context); - - if ($task->getName() !== 'connect') { - $this->deployer->messenger->endOnHost($host); - } - return 0; - } catch (Throwable $e) { - $this->deployer->messenger->renderException($e, $host); - if ($e instanceof GracefulShutdownException) { - return GracefulShutdownException::EXIT_CODE; - } - if ($e instanceof RunException) { - return $e->getExitCode(); - } - return 255; - } - } -} diff --git a/src/Host/Host.php b/src/Host/Host.php deleted file mode 100644 index 125c3adcb..000000000 --- a/src/Host/Host.php +++ /dev/null @@ -1,305 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Deployer\Host; - -use Deployer\Configuration\Configuration; -use Deployer\Deployer; -use Deployer\Exception\ConfigurationException; -use Deployer\Exception\Exception; -use Deployer\Task\Context; -use function Deployer\Support\colorize_host; -use function Deployer\Support\parse_home_dir; - -class Host -{ - /** - * @var Configuration $config - */ - private $config; - - public function __construct(string $hostname) - { - $parent = null; - if (Deployer::get()) { - $parent = Deployer::get()->config; - } - $this->config = new Configuration($parent); - $this->set('#alias', $hostname); - $this->set('hostname', preg_replace('/\/.+$/', '', $hostname)); - } - - public function __toString(): string - { - return $this->getTag(); - } - - public function config(): Configuration - { - return $this->config; - } - - /** - * @param mixed $value - */ - public function set(string $name, $value): self - { - if ($name === 'alias') { - throw new ConfigurationException("Can not update alias of the host.\nThis will change only host own alias,\nbut not the key it is stored in HostCollection."); - } - if ($name === '#alias') { - $name = 'alias'; - } - $this->config->set($name, $value); - return $this; - } - - public function add(string $name, array $value): self - { - $this->config->add($name, $value); - return $this; - } - - public function has(string $name): bool - { - return $this->config->has($name); - } - - public function hasOwn(string $name): bool - { - return $this->config->hasOwn($name); - } - - /** - * @param mixed|null $default - * @return mixed|null - */ - public function get(string $name, $default = null) - { - return $this->config->get($name, $default); - } - - public function getAlias(): ?string - { - return $this->config->get('alias', null); - } - - public function setTag(string $tag): self - { - $this->config->set('tag', $tag); - return $this; - } - - public function getTag(): ?string - { - return $this->config->get('tag', colorize_host($this->getAlias())); - } - - public function setHostname(string $hostname): self - { - $this->config->set('hostname', $hostname); - return $this; - } - - public function getHostname(): ?string - { - return $this->config->get('hostname', null); - } - - public function setRemoteUser(string $user): self - { - $this->config->set('remote_user', $user); - return $this; - } - - public function getRemoteUser(): ?string - { - return $this->config->get('remote_user', null); - } - - /** - * @param string|int|null $port - * @return $this - */ - public function setPort($port): self - { - $this->config->set('port', $port); - return $this; - } - - /** - * @return string|int|null - */ - public function getPort() - { - return $this->config->get('port', null); - } - - public function setConfigFile(string $file): self - { - $this->config->set('config_file', $file); - return $this; - } - - public function getConfigFile(): ?string - { - return $this->config->get('config_file', null); - } - - public function setIdentityFile(string $file): self - { - $this->config->set('identity_file', $file); - return $this; - } - - public function getIdentityFile(): ?string - { - return $this->config->get('identity_file', null); - } - - public function setForwardAgent(bool $on): self - { - $this->config->set('forward_agent', $on); - return $this; - } - - public function getForwardAgent(): ?bool - { - return $this->config->get('forward_agent', null); - } - - public function setSshMultiplexing(bool $on): self - { - $this->config->set('ssh_multiplexing', $on); - return $this; - } - - public function getSshMultiplexing(): ?bool - { - return $this->config->get('ssh_multiplexing', null); - } - - public function setShell(string $command): self - { - $this->config->set('shell', $command); - return $this; - } - - public function getShell(): ?string - { - return $this->config->get('shell', null); - } - - public function setDeployPath(string $path): self - { - $this->config->set('deploy_path', $path); - return $this; - } - - public function getDeployPath(): ?string - { - return $this->config->get('deploy_path', null); - } - - public function setLabels(array $labels): self - { - $this->config->set('labels', $labels); - return $this; - } - - public function getLabels(): ?array - { - return $this->config->get('labels', null); - } - - public function setSshArguments(array $args): self - { - $this->config->set('ssh_arguments', $args); - return $this; - } - - public function getSshArguments(): ?array - { - return $this->config->get('ssh_arguments', null); - } - - public function setSshControlPath(string $path): self - { - $this->config->set('ssh_control_path', $path); - return $this; - } - - public function getSshControlPath(): string - { - return $this->config->get('ssh_control_path', $this->generateControlPath()); - } - - private function generateControlPath(): string - { - $C = $this->getHostname(); - if ($this->has('remote_user')) { - $C = $this->getRemoteUser() . '@' . $C; - } - if ($this->has('port')) { - $C .= ':' . $this->getPort(); - } - - // In case of CI environment, lets use shared memory. - if (getenv('CI') && is_writable('/dev/shm')) { - return "/dev/shm/$C"; - } - - return "~/.ssh/$C"; - } - - public function connectionString(): string - { - if ($this->get('remote_user', '') !== '') { - return $this->get('remote_user') . '@' . $this->get('hostname'); - } - return $this->get('hostname'); - } - - public function connectionOptionsString(): string - { - return implode(' ', array_map('escapeshellarg', $this->connectionOptionsArray())); - } - - /** - * @return string[] - */ - public function connectionOptionsArray(): array - { - $options = []; - if ($this->has('ssh_arguments')) { - foreach ($this->getSshArguments() as $arg) { - $options = array_merge($options, explode(' ', $arg)); - } - } - if ($this->has('port')) { - $options = array_merge($options, ['-p', $this->getPort()]); - } - if ($this->has('config_file')) { - $options = array_merge($options, ['-F', parse_home_dir($this->getConfigFile())]); - } - if ($this->has('identity_file')) { - $options = array_merge($options, ['-i', parse_home_dir($this->getIdentityFile())]); - } - if ($this->has('forward_agent') && $this->getForwardAgent()) { - $options = array_merge($options, ['-A']); - } - if ($this->has('ssh_multiplexing') && $this->getSshMultiplexing()) { - $options = array_merge($options, [ - '-o', 'ControlMaster=auto', - '-o', 'ControlPersist=60', - '-o', 'ControlPath=' . $this->getSshControlPath(), - ]); - } - return $options; - } -} diff --git a/src/Host/HostCollection.php b/src/Host/HostCollection.php deleted file mode 100644 index 26c512c08..000000000 --- a/src/Host/HostCollection.php +++ /dev/null @@ -1,23 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Deployer\Host; - -use Deployer\Collection\Collection; - -/** - * @method Host get($name) - * @method Host[] getIterator() - */ -class HostCollection extends Collection -{ - protected function throwNotFound(string $name): void - { - throw new \InvalidArgumentException("Host \"$name\" not found."); - } -} diff --git a/src/Host/Localhost.php b/src/Host/Localhost.php deleted file mode 100644 index 2da827cc3..000000000 --- a/src/Host/Localhost.php +++ /dev/null @@ -1,17 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Deployer\Host; - -class Localhost extends Host -{ - public function __construct(string $hostname = 'localhost') - { - parent::__construct($hostname); - } -} diff --git a/src/Host/Range.php b/src/Host/Range.php deleted file mode 100644 index a51c931b6..000000000 --- a/src/Host/Range.php +++ /dev/null @@ -1,42 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Deployer\Host; - -class Range -{ - const PATTERN = '/\[(.+?)\]/'; - - public static function expand(array $hostnames): array - { - $expanded = []; - foreach ($hostnames as $hostname) { - if (preg_match(self::PATTERN, $hostname, $matches)) { - [$start, $end] = explode(':', $matches[1]); - $zeroBased = (bool) preg_match('/^0[1-9]/', $start); - - foreach (range($start, $end) as $i) { - $expanded[] = preg_replace(self::PATTERN, self::format((string) $i, $zeroBased), $hostname); - } - } else { - $expanded[] = $hostname; - } - } - - return $expanded; - } - - private static function format(string $i, bool $zeroBased): string - { - if ($zeroBased) { - return strlen($i) === 1 ? "0$i" : $i; - } else { - return $i; - } - } -} diff --git a/src/Importer/Importer.php b/src/Importer/Importer.php deleted file mode 100644 index 47c72b0c7..000000000 --- a/src/Importer/Importer.php +++ /dev/null @@ -1,264 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Deployer\Importer; - -use Deployer\Deployer; -use Deployer\Exception\ConfigurationException; -use Deployer\Exception\Exception; -use JsonSchema\Constraints\Constraint; -use JsonSchema\Constraints\Factory; -use JsonSchema\SchemaStorage; -use JsonSchema\Validator; -use Symfony\Component\Yaml\Yaml; -use function array_filter; -use function array_keys; -use function Deployer\after; -use function Deployer\before; -use function Deployer\cd; -use function Deployer\download; -use function Deployer\host; -use function Deployer\localhost; -use function Deployer\run; -use function Deployer\runLocally; -use function Deployer\set; -use function Deployer\Support\find_line_number; -use function Deployer\task; -use function Deployer\upload; -use function substr; -use const ARRAY_FILTER_USE_KEY; - -class Importer -{ - /** - * @var string - */ - private static $recipeFilename; - /** - * @var string - */ - private static $recipeSource; - - /** - * @param string|string[] $paths - */ - public static function import($paths) - { - if (!is_array($paths)) { - $paths = [$paths]; - } - foreach ($paths as $path) { - if (preg_match('/\.php$/i', $path)) { - // Prevent variable leak into deploy.php file - call_user_func(function () use ($path) { - // Reorder autoload stack - $originStack = spl_autoload_functions(); - - require $path; - - $newStack = spl_autoload_functions(); - if ($originStack[0] !== $newStack[0]) { - foreach (array_reverse($originStack) as $loader) { - spl_autoload_unregister($loader); - spl_autoload_register($loader, true, true); - } - } - }); - } else if (preg_match('/\.ya?ml$/i', $path)) { - self::$recipeFilename = basename($path); - self::$recipeSource = file_get_contents($path); - $root = array_filter(Yaml::parse(self::$recipeSource), static function (string $key) { - return substr($key, 0, 1) !== '.'; - }, ARRAY_FILTER_USE_KEY); - - $schema = 'file://' . __DIR__ . '/../schema.json'; - if (Deployer::isPharArchive()) { - $schema = __DIR__ . '/../schema.json'; - } - $yamlSchema = json_decode(file_get_contents($schema)); - $schemaStorage = new SchemaStorage(); - $schemaStorage->addSchema('file://schema', $yamlSchema); - $validator = new Validator(new Factory($schemaStorage)); - $validator->validate($root, $yamlSchema, Constraint::CHECK_MODE_TYPE_CAST); - if (!$validator->isValid()) { - $msg = "YAML " . self::$recipeFilename . " does not validate. Violations:\n"; - foreach ($validator->getErrors() as $error) { - $msg .= "[{$error['property']}] {$error['message']}\n"; - } - throw new ConfigurationException($msg); - } - - foreach (array_keys($root) as $key) { - static::$key($root[$key]); - } - } else { - throw new Exception("Unknown file format: $path\nOnly .php and .yaml supported."); - } - } - } - - protected static function hosts(array $hosts) - { - foreach ($hosts as $alias => $config) { - if ($config['local'] ?? false) { - $host = localhost($alias); - } else { - $host = host($alias); - } - if (is_array($config)) { - foreach ($config as $key => $value) { - $host->set($key, $value); - } - } - } - } - - protected static function config(array $config) - { - foreach ($config as $key => $value) { - set($key, $value); - } - } - - protected static function tasks(array $tasks) - { - $buildTask = function ($name, $steps) { - $body = function () { - }; - $task = task($name, $body); - - foreach ($steps as $step) { - $buildStep = function ($step) use (&$body, $task) { - extract($step); - - if (isset($cd)) { - $prev = $body; - $body = function () use ($cd, $prev) { - $prev(); - cd($cd); - }; - } - - if (isset($run)) { - $has = 'run'; - $prev = $body; - $body = function () use ($run, $prev) { - $prev(); - try { - run($run); - } catch (Exception $e) { - $e->setTaskFilename(self::$recipeFilename); - $e->setTaskLineNumber(find_line_number(self::$recipeSource, $run)); - throw $e; - } - }; - } - - if (isset($run_locally)) { - if (isset($has)) { - throw new ConfigurationException("Task step can not have both $has and run_locally."); - } - $has = 'run_locally'; - $prev = $body; - $body = function () use ($run_locally, $prev) { - $prev(); - try { - runLocally($run_locally); - } catch (Exception $e) { - $e->setTaskFilename(self::$recipeFilename); - $e->setTaskLineNumber(find_line_number(self::$recipeSource, $run_locally)); - throw $e; - } - }; - } - - if (isset($upload)) { - if (isset($has)) { - throw new ConfigurationException("Task step can not have both $has and upload."); - } - $has = 'upload'; - $prev = $body; - $body = function () use ($upload, $prev) { - $prev(); - upload($upload['src'], $upload['dest']); - }; - } - - if (isset($download)) { - if (isset($has)) { - throw new ConfigurationException("Task step can not have both $has and downlaod."); - } - $has = 'downlaod'; - $prev = $body; - $body = function () use ($download, $prev) { - $prev(); - download($download['src'], $download['dest']); - }; - } - - $methods = [ - 'desc', - 'once', - 'hidden', - 'limit', - 'select', - ]; - foreach ($methods as $method) { - if (isset($$method)) { - $task->$method($$method); - } - } - }; - - $buildStep($step); - $task->setCallback($body); - } - }; - - foreach ($tasks as $name => $config) { - foreach ($config as $key => $value) { - if (!is_int($key) || !is_string($value)) { - goto not_a_group_task; - } - } - - // Create a group task. - task($name, $config); - continue; - - not_a_group_task: - $buildTask($name, $config); - } - } - - protected static function after(array $after) - { - foreach ($after as $key => $value) { - if (is_array($value)) { - foreach (array_reverse($value) as $v) { - after($key, $v); - } - } else { - after($key, $value); - } - } - } - - protected static function before(array $before) - { - foreach ($before as $key => $value) { - if (is_array($value)) { - foreach (array_reverse($value) as $v) { - before($key, $v); - } - } else { - before($key, $value); - } - } - } -} diff --git a/src/Logger/Handler/FileHandler.php b/src/Logger/Handler/FileHandler.php deleted file mode 100644 index ca8c0b031..000000000 --- a/src/Logger/Handler/FileHandler.php +++ /dev/null @@ -1,27 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Deployer\Logger\Handler; - -class FileHandler implements HandlerInterface -{ - /** - * @var string - */ - private $filePath; - - public function __construct(string $filePath) - { - $this->filePath = $filePath; - } - - public function log(string $message): void - { - file_put_contents($this->filePath, $message, FILE_APPEND); - } -} diff --git a/src/Logger/Handler/HandlerInterface.php b/src/Logger/Handler/HandlerInterface.php deleted file mode 100644 index f0ab20271..000000000 --- a/src/Logger/Handler/HandlerInterface.php +++ /dev/null @@ -1,14 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Deployer\Logger\Handler; - -interface HandlerInterface -{ - public function log(string $message): void; -} diff --git a/src/Logger/Handler/NullHandler.php b/src/Logger/Handler/NullHandler.php deleted file mode 100644 index 3a1df24de..000000000 --- a/src/Logger/Handler/NullHandler.php +++ /dev/null @@ -1,16 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Deployer\Logger\Handler; - -class NullHandler implements HandlerInterface -{ - public function log(string $message): void - { - } -} diff --git a/src/Logger/Logger.php b/src/Logger/Logger.php deleted file mode 100644 index f2eb3b00a..000000000 --- a/src/Logger/Logger.php +++ /dev/null @@ -1,57 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Deployer\Logger; - -use Deployer\Component\ProcessRunner\Printer; -use Deployer\Host\Host; -use Deployer\Logger\Handler\HandlerInterface; - -class Logger -{ - /** - * @var HandlerInterface - */ - private $handler; - - public function __construct(HandlerInterface $handler) - { - $this->handler = $handler; - } - - public function log(string $message): void - { - $this->handler->log("$message\n"); - } - - public function callback(Host $host): \Closure - { - return function ($type, $buffer) use ($host) { - $this->printBuffer($host, $type, $buffer); - }; - } - - public function printBuffer(Host $host, string $type, string $buffer): void - { - foreach (explode("\n", rtrim($buffer)) as $line) { - $this->writeln($host, $type, $line); - } - } - - public function writeln(Host $host, string $type, string $line): void - { - $line = Printer::filterOutput($line); - - // Omit empty lines - if (empty($line)) { - return; - } - - $this->log("[{$host->getAlias()}] $line"); - } -} diff --git a/src/Selector/Selector.php b/src/Selector/Selector.php deleted file mode 100644 index c9be60472..000000000 --- a/src/Selector/Selector.php +++ /dev/null @@ -1,114 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Deployer\Selector; - -use Deployer\Host\Host; -use Deployer\Host\HostCollection; -use function Deployer\Support\array_all; - -class Selector -{ - /** - * @var HostCollection - */ - private $hosts; - - public function __construct(HostCollection $hosts) - { - $this->hosts = $hosts; - } - - /** - * @return Host[] - */ - public function select(string $selectExpression) - { - $conditions = self::parse($selectExpression); - - $hosts = []; - foreach ($this->hosts as $host) { - if (self::apply($conditions, $host)) { - $hosts[] = $host; - } - } - - return $hosts; - } - - public static function apply(?array $conditions, Host $host): bool - { - if (empty($conditions)) { - return true; - } - - $labels = $host->get('labels', []); - $labels['alias'] = $host->getAlias(); - $labels['true'] = 'true'; - $isTrue = function ($value) { - return $value; - }; - - foreach ($conditions as $hmm) { - $ok = []; - foreach ($hmm as list($op, $var, $value)) { - $ok[] = self::compare($op, $labels[$var] ?? null, $value); - } - if (count($ok) > 0 && array_all($ok, $isTrue)) { - return true; - } - } - return false; - } - - /** - * @param string|string[] $a - */ - private static function compare(string $op, $a, ?string $b): bool - { - $matchFunction = function($a, ?string $b) { - foreach ((array)$a as $item) { - if ($item === $b) { - return true; - } - } - - return false; - }; - - if ($op === '=') { - return $matchFunction($a, $b); - } - if ($op === '!=') { - return !$matchFunction($a, $b); - } - return false; - } - - public static function parse(string $expression): array - { - $all = []; - foreach (explode(',', $expression) as $sub) { - $conditions = []; - foreach (explode('&', $sub) as $part) { - $part = trim($part); - if ($part === 'all') { - $conditions[] = ['=', 'true', 'true']; - continue; - } - if (preg_match('/(?.+?)(?!?=)(?.+)/', $part, $match)) { - $conditions[] = [$match['op'], trim($match['var']), trim($match['value'])]; - } else { - $conditions[] = ['=', 'alias', trim($part)]; - } - } - $all[] = $conditions; - } - return $all; - } -} diff --git a/src/Support/ObjectProxy.php b/src/Support/ObjectProxy.php deleted file mode 100644 index 3c8f348e7..000000000 --- a/src/Support/ObjectProxy.php +++ /dev/null @@ -1,30 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Deployer\Support; - -class ObjectProxy -{ - /** - * @var array - */ - private $objects; - - public function __construct(array $objects) - { - $this->objects = $objects; - } - - public function __call(string $name, array $arguments): self - { - foreach ($this->objects as $object) { - $object->$name(...$arguments); - } - return $this; - } -} diff --git a/src/Support/Reporter.php b/src/Support/Reporter.php deleted file mode 100644 index 05e4bfa9b..000000000 --- a/src/Support/Reporter.php +++ /dev/null @@ -1,45 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Deployer\Support; - -use Deployer\Utility\Httpie; -use Symfony\Component\Process\PhpProcess; - -/** - * @codeCoverageIgnore - */ -class Reporter -{ - public static function report(array $stats): void - { - $version = DEPLOYER_VERSION; - $body = json_encode($stats); - $length = strlen($body); - $php = new PhpProcess(<<start(); - } -} diff --git a/src/Support/helpers.php b/src/Support/helpers.php deleted file mode 100644 index cea17111c..000000000 --- a/src/Support/helpers.php +++ /dev/null @@ -1,254 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Deployer\Support; - -/** - * Flatten array - * - * @param array $array - * @return array - */ -function array_flatten(array $array) -{ - $flatten = []; - array_walk_recursive($array, function ($value) use (&$flatten) { - $flatten[] = $value; - }); - return $flatten; -} - -/** - * Recursively merge two config arrays with a specific behavior: - * - * 1. scalar values are overridden - * 2. array values are extended uniquely if all keys are numeric - * 3. all other array values are merged - * - * @param array $original - * @param array $override - * @return array - * @see http://stackoverflow.com/a/36366886/6812729 - */ -function array_merge_alternate(array $original, array $override) -{ - foreach ($override as $key => $value) { - if (isset($original[$key])) { - if (!is_array($original[$key])) { - if (is_numeric($key)) { - // Append scalar value - $original[] = $value; - } else { - // Override scalar value - $original[$key] = $value; - } - } elseif (array_keys($original[$key]) === range(0, count($original[$key]) - 1)) { - // Uniquely append to array with numeric keys - $original[$key] = array_unique(array_merge($original[$key], $value)); - } else { - // Merge all other arrays - $original[$key] = array_merge_alternate($original[$key], $value); - } - } else { - // Simply add new key/value - $original[$key] = $value; - } - } - - return $original; -} - -/** - * Determines if the given string contains the given value. - */ -function str_contains(string $haystack, string $needle): bool -{ - return strpos($haystack, $needle) !== false; -} - -/** - * Checks if string stars with given prefix. - */ -function starts_with(string $string, string $startString): bool -{ - $len = strlen($startString); - return (substr($string, 0, $len) === $startString); -} - -/** - * This function used for create environment string. - */ -function env_stringify(array $array): string -{ - return implode(' ', array_map( - function ($key, $value) { - return sprintf("%s=%s", $key, escapeshellarg((string)$value)); - }, - array_keys($array), - $array - )); -} - -/** - * Check if var is closure. - * @param mixed $var - */ -function is_closure($var): bool -{ - return is_object($var) && ($var instanceof \Closure); -} - -/** - * Check if all elements satisfy predicate. - */ -function array_all(array $array, callable $predicate): bool -{ - foreach ($array as $key => $value) { - if (!$predicate($value, $key)) { - return false; - } - } - return true; -} - -/** - * Cleanup CRLF new line endings. - */ -function normalize_line_endings(string $string): string -{ - return str_replace(["\r\n", "\r"], "\n", $string); -} - -/** - * Expand leading tilde (~) symbol in given path. - */ -function parse_home_dir(string $path): string -{ - if ('~' === $path || 0 === strpos($path, '~/')) { - if (isset($_SERVER['HOME'])) { - $home = $_SERVER['HOME']; - } elseif (isset($_SERVER['HOMEDRIVE'], $_SERVER['HOMEPATH'])) { - $home = $_SERVER['HOMEDRIVE'] . $_SERVER['HOMEPATH']; - } else { - return $path; - } - - return $home . substr($path, 1); - } - - return $path; -} - -function find_line_number(string $source, string $string): int -{ - $string = explode(PHP_EOL, $string)[0]; - $before = strstr($source, $string, true); - if (false !== $before) { - return count(explode(PHP_EOL, $before)); - } - return 1; -} - -function find_config_line(string $source, string $name): \Generator -{ - foreach (explode(PHP_EOL, $source) as $n => $line) { - if (preg_match("/\(['\"]{$name}['\"]/", $line)) { - yield [$n + 1, $line]; - } - if (preg_match("/\s{$name}:/", $line)) { - yield [$n + 1, $line]; - } - } -} - -function colorize_host(string $alias): string -{ - if (defined('NO_ANSI')) { - return $alias; - } - - if (in_array($alias, ['localhost', 'local'], true)) { - return $alias; - } - - if (getenv('COLORTERM') === 'truecolor') { - $hsv = function ($h, $s, $v) { - $r = $g = $b = $i = $f = $p = $q = $t = 0; - $i = floor($h * 6); - $f = $h * 6 - $i; - $p = $v * (1 - $s); - $q = $v * (1 - $f * $s); - $t = $v * (1 - (1 - $f) * $s); - switch ($i % 6) { - case 0: - $r = $v; - $g = $t; - $b = $p; - break; - case 1: - $r = $q; - $g = $v; - $b = $p; - break; - case 2: - $r = $p; - $g = $v; - $b = $t; - break; - case 3: - $r = $p; - $g = $q; - $b = $v; - break; - case 4: - $r = $t; - $g = $p; - $b = $v; - break; - case 5: - $r = $v; - $g = $p; - $b = $q; - break; - } - $r = round($r * 255); - $g = round($g * 255); - $b = round($b * 255); - return "\x1b[38;2;{$r};{$g};{$b}m"; - }; - $total = 100; - $colors = []; - for ($i = 0; $i < $total; $i++) { - $colors[] = $hsv($i / $total, .5, .9); - } - if ($alias === 'prod' || $alias === 'production') { - return "$colors[99]$alias\x1b[0m"; - } - if ($alias === 'beta') { - return "$colors[14]$alias\x1b[0m"; - } - $tag = $colors[abs(crc32($alias)) % count($colors)]; - return "$tag$alias\x1b[0m"; - } - - $colors = [ - 'fg=cyan;options=bold', - 'fg=green;options=bold', - 'fg=yellow;options=bold', - 'fg=cyan', - 'fg=blue', - 'fg=yellow', - 'fg=magenta', - 'fg=blue;options=bold', - 'fg=green', - 'fg=magenta;options=bold', - 'fg=red;options=bold', - ]; - $tag = $colors[abs(crc32($alias)) % count($colors)]; - return "<$tag>$alias"; -} diff --git a/src/Support/update_manifest.php b/src/Support/update_manifest.php deleted file mode 100644 index 43035979c..000000000 --- a/src/Support/update_manifest.php +++ /dev/null @@ -1,41 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Deployer; - -task('update_manifest', function () { - $version = get('version'); - $manifestPath = '~/deployer.org/artifacts/manifest.json'; - $manifest = json_decode(run("cat $manifestPath"), true); - - $newPharManifest = [ - 'name' => 'deployer.phar', - 'sha1' => get('sha1'), - 'url' => "https://github.com/deployphp/deployer/releases/download/v$version/deployer.phar", - 'version' => $version, - ]; - - // Check if this version already in manifest.json. - $alreadyExistVersion = null; - foreach ($manifest as $i => $m) { - if ($m['version'] === $version) { - $alreadyExistVersion = $i; - } - } - - // Save or update. - if (empty($alreadyExistVersion)) { - $manifest[] = $newPharManifest; - } else { - $manifest[$alreadyExistVersion] = $newPharManifest; - } - - // Write manifest to manifest.json. - $content = json_encode($manifest, JSON_PRETTY_PRINT); - run("echo '$content' > $manifestPath"); -}); diff --git a/src/Task/Context.php b/src/Task/Context.php deleted file mode 100644 index c0f0f8d88..000000000 --- a/src/Task/Context.php +++ /dev/null @@ -1,85 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Deployer\Task; - -use Deployer\Configuration\Configuration; -use Deployer\Exception\Exception; -use Deployer\Host\Host; -use Symfony\Component\Console\Input\InputInterface; -use Symfony\Component\Console\Output\OutputInterface; - -class Context -{ - /** - * @var Host - */ - private $host; - - /** - * @var Context[] - */ - private static $contexts = []; - - public function __construct(Host $host) - { - $this->host = $host; - } - - public static function push(Context $context): void - { - self::$contexts[] = $context; - } - - public static function has(): bool - { - return !empty(self::$contexts); - } - - /** - * @return Context|false - * @throws Exception - */ - public static function get() - { - if (empty(self::$contexts)) { - throw new Exception("Context was requested but was not available."); - } - return end(self::$contexts); - } - - public static function pop(): ?Context - { - return array_pop(self::$contexts); - } - - /** - * Throws a Exception when not called within a task-context and therefore no Context is available. - * - * This method provides a useful error to the end-user to make him/her aware - * to use a function in the required task-context. - * - * @throws Exception - */ - public static function required(string $callerName): void - { - if (empty(self::$contexts)) { - throw new Exception("'$callerName' can only be used within a task."); - } - } - - public function getConfig(): Configuration - { - return $this->host->config(); - } - - public function getHost(): Host - { - return $this->host; - } -} diff --git a/src/Task/GroupTask.php b/src/Task/GroupTask.php deleted file mode 100644 index a43a77eb2..000000000 --- a/src/Task/GroupTask.php +++ /dev/null @@ -1,52 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Deployer\Task; - -use function Deployer\invoke; - -class GroupTask extends Task -{ - /** - * List of tasks. - * - * @var string[] - */ - private $group; - - /** - * @param string[] $group - */ - public function __construct(string $name, array $group) - { - parent::__construct($name); - $this->group = $group; - } - - public function run(Context $context): void - { - foreach ($this->group as $item) { - invoke($item); - } - } - - /** - * List of dependent tasks names - * - * @return string[] - */ - public function getGroup(): array - { - return $this->group; - } - - public function setGroup(array $group): void - { - $this->group = $group; - } -} diff --git a/src/Task/ScriptManager.php b/src/Task/ScriptManager.php deleted file mode 100644 index 7757624ea..000000000 --- a/src/Task/ScriptManager.php +++ /dev/null @@ -1,123 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Deployer\Task; - -use Deployer\Exception\Exception; -use function Deployer\Support\array_flatten; - -class ScriptManager -{ - /** - * @var TaskCollection - */ - private $tasks; - /** - * @var bool - */ - private $hooksEnabled = true; - /** - * @var array - */ - private $visitedTasks = []; - - public function __construct(TaskCollection $tasks) - { - $this->tasks = $tasks; - } - - /** - * Return tasks to run. - * - * @return Task[] - */ - public function getTasks(string $name, ?string $startFrom = null, array &$skipped = []): array - { - $tasks = []; - $this->visitedTasks = []; - $allTasks = $this->doGetTasks($name); - - if ($startFrom === null) { - $tasks = $allTasks; - } else { - $skip = true; - foreach ($allTasks as $task) { - if ($skip) { - if ($task->getName() === $startFrom) { - $skip = false; - } else { - $skipped[] = $task->getName(); - continue; - } - } - $tasks[] = $task; - } - if (count($tasks) === 0) { - throw new Exception('All tasks skipped via --start-from option. Nothing to run.'); - } - } - - $enabledTasks = []; - foreach ($tasks as $task) { - if ($task->isEnabled()) { - $enabledTasks[] = $task; - } - } - - return $enabledTasks; - } - - /** - * @return Task[] - */ - public function doGetTasks(string $name): array - { - if (array_key_exists($name, $this->visitedTasks)) { - if ($this->visitedTasks[$name] >= 100) { - throw new Exception("Looks like a circular dependency with \"$name\" task."); - } - $this->visitedTasks[$name]++; - } else { - $this->visitedTasks[$name] = 1; - } - - $tasks = []; - $task = $this->tasks->get($name); - if ($this->hooksEnabled) { - $tasks = array_merge(array_map([$this, 'doGetTasks'], $task->getBefore()), $tasks); - } - if ($task instanceof GroupTask) { - foreach ($task->getGroup() as $taskName) { - $subTasks = $this->doGetTasks($taskName); - foreach ($subTasks as $subTask) { - $subTask->addSelector($task->getSelector()); - if ($task->isOnce()) { - $subTask->once(); - } - $tasks[] = $subTask; - } - } - } else { - $tasks[] = $task; - } - if ($this->hooksEnabled) { - $tasks = array_merge($tasks, array_map([$this, 'doGetTasks'], $task->getAfter())); - } - return array_flatten($tasks); - } - - public function getHooksEnabled(): bool - { - return $this->hooksEnabled; - } - - public function setHooksEnabled(bool $hooksEnabled): void - { - $this->hooksEnabled = $hooksEnabled; - } -} diff --git a/src/Task/Task.php b/src/Task/Task.php deleted file mode 100644 index 0dab358ee..000000000 --- a/src/Task/Task.php +++ /dev/null @@ -1,273 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Deployer\Task; - -use Deployer\Selector\Selector; - -class Task -{ - /** - * @var string - */ - private $name; - /** - * @var callable|null - */ - private $callback; - /** - * @var string - */ - private $description; - /** - * @var string - */ - private $sourceLocation = ''; - /** - * @var array - */ - private $before = []; - /** - * @var array - */ - private $after = []; - /** - * @var bool - */ - private $hidden = false; - /** - * @var bool - */ - private $once = false; - /** - * @var bool - */ - private $oncePerNode = false; - /** - * @var int|null - */ - private $limit = null; - /** - * @var array|null - */ - private $selector = null; - /** - * @var bool - */ - private $verbose = false; - /** - * @var bool - */ - private $enabled = true; - - /** - * @param callable():void $callback - */ - public function __construct(string $name, callable $callback = null) - { - $this->name = $name; - $this->callback = $callback; - } - - /** - * @param callable():void $callback - */ - public function setCallback(callable $callback): void - { - $this->callback = $callback; - } - - public function run(Context $context): void - { - Context::push($context); - - try { - call_user_func($this->callback); // call task - } finally { - if ($context->getConfig() !== null) { - $context->getConfig()->set('working_path', null); - } - - Context::pop(); - } - } - - public function getName(): string - { - return $this->name; - } - - public function __toString(): string - { - return $this->getName(); - } - - public function getDescription(): ?string - { - return $this->description; - } - - public function desc(string $description): self - { - $this->description = $description; - return $this; - } - - public function getSourceLocation(): string - { - return $this->sourceLocation; - } - - public function setSourceLocation(string $path): void - { - $this->sourceLocation = $path; - } - - public function saveSourceLocation(): void - { - if (function_exists('debug_backtrace')) { - $trace = debug_backtrace(); - $this->sourceLocation = $trace[1]['file']; - } - } - - /** - * Mark this task to run only once on one of hosts. - */ - public function once(bool $once = true): self - { - $this->once = $once; - return $this; - } - - public function isOnce(): bool - { - return $this->once; - } - - /** - * Mark task to only run once per node. - * Node is a group of hosts with same hostname or with same node label. - */ - public function oncePerNode(bool $once = true): self - { - $this->oncePerNode = $once; - return $this; - } - - public function isOncePerNode(): bool - { - return $this->oncePerNode; - } - - /** - * Mark task as hidden and not accessible from CLI. - */ - public function hidden(bool $hidden = true): self - { - $this->hidden = $hidden; - return $this; - } - - public function isHidden(): bool - { - return $this->hidden; - } - - /** - * Make $task being run before this task. - */ - public function addBefore(string $task): self - { - array_unshift($this->before, $task); - return $this; - } - - /** - * Make $task being run after this task - */ - public function addAfter(string $task): self - { - array_push($this->after, $task); - return $this; - } - - public function getBefore(): array - { - return $this->before; - } - - public function getAfter(): array - { - return $this->after; - } - - public function getLimit(): ?int - { - return $this->limit; - } - - public function limit(?int $limit): self - { - $this->limit = $limit; - return $this; - } - - public function select(string $selector): self - { - $this->selector = Selector::parse($selector); - return $this; - } - - /** - * @return array - */ - public function getSelector(): ?array - { - return $this->selector; - } - - public function addSelector(?array $newSelector): void - { - if ($newSelector !== null) { - if ($this->selector === null) { - $this->selector = $newSelector; - } else { - $this->selector = array_merge($this->selector, $newSelector); - } - } - } - - public function isVerbose(): bool - { - return $this->verbose; - } - - public function verbose(bool $verbose = true): self - { - $this->verbose = $verbose; - return $this; - } - - public function isEnabled(): bool - { - return $this->enabled; - } - - public function disable(): self - { - $this->enabled = false; - return $this; - } - - public function enable(): self - { - $this->enabled = true; - return $this; - } -} diff --git a/src/Task/TaskCollection.php b/src/Task/TaskCollection.php deleted file mode 100644 index eb3c3e0b0..000000000 --- a/src/Task/TaskCollection.php +++ /dev/null @@ -1,28 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Deployer\Task; - -use Deployer\Collection\Collection; - -/** - * @method Task get($name) - * @method Task[] getIterator() - */ -class TaskCollection extends Collection -{ - protected function throwNotFound(string $name): void - { - throw new \InvalidArgumentException("Task `$name` not found."); - } - - public function add(Task $task): void - { - $this->set($task->getName(), $task); - } -} diff --git a/src/Utility/Httpie.php b/src/Utility/Httpie.php deleted file mode 100644 index 3549e5558..000000000 --- a/src/Utility/Httpie.php +++ /dev/null @@ -1,185 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Deployer\Utility; - -use Deployer\Exception\HttpieException; - -class Httpie -{ - /** - * @var string - */ - private $method = 'GET'; - /** - * @var string - */ - private $url = ''; - /** - * @var array - */ - private $headers = []; - /** - * @var string - */ - private $body = ''; - /** - * @var array - */ - private $curlopts = []; - /** - * @var bool - */ - private $nothrow = false; - - public function __construct() - { - if (!extension_loaded('curl')) { - throw new \Exception( - "Please, install curl extension.\n" . - "https://goo.gl/yTAeZh" - ); - } - } - - public static function get(string $url): Httpie - { - $http = new self; - $http->method = 'GET'; - $http->url = $url; - return $http; - } - - public static function post(string $url): Httpie - { - $http = new self; - $http->method = 'POST'; - $http->url = $url; - return $http; - } - - public static function patch(string $url): Httpie - { - $http = new self; - $http->method = 'PATCH'; - $http->url = $url; - return $http; - } - - public function query(array $params): Httpie - { - $http = clone $this; - $http->url .= '?' . http_build_query($params); - return $http; - } - - public function header(string $header, string $value): Httpie - { - $http = clone $this; - $http->headers[$header] = $value; - return $http; - } - - public function body(string $body): Httpie - { - $http = clone $this; - $http->body = $body; - $http->headers = array_merge($http->headers, [ - 'Content-Type' => 'application/json', - 'Content-Length' => strlen($http->body), - ]); - return $http; - } - - public function jsonBody(array $data): Httpie - { - $http = clone $this; - $http->body = json_encode($data, JSON_PRETTY_PRINT); - $http->headers = array_merge($http->headers, [ - 'Content-Type' => 'application/json', - 'Content-Length' => strlen($http->body), - ]); - return $http; - } - - public function formBody(array $data): Httpie - { - $http = clone $this; - $http->body = http_build_query($data); - $http->headers = array_merge($this->headers, [ - 'Content-type' => 'application/x-www-form-urlencoded', - 'Content-Length' => strlen($http->body), - ]); - return $http; - } - - /** - * @param mixed $value - */ - public function setopt(int $key, $value): Httpie - { - $http = clone $this; - $http->curlopts[$key] = $value; - return $http; - } - - public function nothrow(bool $on = true): Httpie - { - $http = clone $this; - $http->nothrow = $on; - return $http; - } - - public function send(?array &$info = null): string - { - $ch = curl_init($this->url); - curl_setopt($ch, CURLOPT_USERAGENT, 'Deployer ' . DEPLOYER_VERSION); - curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $this->method); - $headers = []; - foreach ($this->headers as $key => $value) { - $headers[] = "$key: $value"; - } - curl_setopt($ch, CURLOPT_HTTPHEADER, $headers); - curl_setopt($ch, CURLOPT_POSTFIELDS, $this->body); - curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); - curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); - curl_setopt($ch, CURLOPT_MAXREDIRS, 10); - curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 5); - curl_setopt($ch, CURLOPT_TIMEOUT, 5); - foreach ($this->curlopts as $key => $value) { - curl_setopt($ch, $key, $value); - } - $result = curl_exec($ch); - $info = curl_getinfo($ch); - if ($result === false) { - if ($this->nothrow) { - $result = ''; - } else { - $error = curl_error($ch); - $errno = curl_errno($ch); - curl_close($ch); - throw new HttpieException($error, $errno); - } - } - curl_close($ch); - return $result; - } - - /** - * @return mixed - */ - public function getJson() - { - $result = $this->send(); - $response = json_decode($result, true); - if (json_last_error() !== JSON_ERROR_NONE) { - throw new HttpieException('JSON Error: ' . json_last_error_msg()); - } - return $response; - } -} diff --git a/src/Utility/Rsync.php b/src/Utility/Rsync.php deleted file mode 100644 index 0e17dda5b..000000000 --- a/src/Utility/Rsync.php +++ /dev/null @@ -1,152 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Deployer\Utility; - -use Deployer\Component\ProcessRunner\Printer; -use Deployer\Component\Ssh\Client; -use Deployer\Exception\RunException; -use Deployer\Host\Host; -use Symfony\Component\Console\Helper\ProgressBar; -use Symfony\Component\Console\Output\OutputInterface; -use Symfony\Component\Process\Exception\ProcessFailedException; -use Symfony\Component\Process\Process; -use function Deployer\writeln; - -class Rsync -{ - /** - * @var Printer - */ - private $pop; - /** - * @var OutputInterface - */ - private $output; - - public function __construct(Printer $pop, OutputInterface $output) - { - $this->pop = $pop; - $this->output = $output; - } - - /** - * Start rsync process. - * - * @param string|string[] $source - * @phpstan-param array{flags?: string, options?: array, timeout?: int|null, progress_bar?: bool, display_stats?: bool} $config - * @throws RunException - */ - public function call(Host $host, $source, string $destination, array $config = []): void - { - $defaults = [ - 'timeout' => null, - 'options' => [], - 'flags' => '-azP', - 'progress_bar' => true, - 'display_stats' => false - ]; - $config = array_merge($defaults, $config); - - $options = $config['options'] ?? []; - $flags = $config['flags']; - $displayStats = $config['display_stats'] || in_array('--stats', $options, true); - - if ($displayStats && !in_array('--stats', $options, true)) { - $options[] = '--stats'; - } - - $connectionOptions = $host->connectionOptionsString(); - if ($connectionOptions !== '') { - $options = array_merge($options, ['-e', "ssh $connectionOptions"]); - } - if ($host->has("become")) { - $options = array_merge($options, ['--rsync-path', "sudo -H -u {$host->get('become')} rsync"]); - } - if (!is_array($source)) { - $source = [$source]; - } - $command = array_merge(['rsync', $flags], $options, $source, [$destination]); - - $commandString = $command[0]; - for ($i = 1; $i < count($command); $i++) { - $commandString .= ' ' . escapeshellarg($command[$i]); - } - if ($this->output->isVerbose()) { - $this->output->writeln("[$host] $commandString"); - } - - $progressBar = null; - if ($this->output->getVerbosity() === OutputInterface::VERBOSITY_NORMAL && $config['progress_bar']) { - $progressBar = new ProgressBar($this->output); - $progressBar->setBarCharacter(''); - $progressBar->setProgressCharacter('>'); - $progressBar->setEmptyBarCharacter('-'); - } - - $fullOutput = ''; - - $callback = function ($type, $buffer) use ($host, $progressBar, &$fullOutput) { - $fullOutput .= $buffer; - if ($progressBar) { - foreach (explode("\n", $buffer) as $line) { - if (preg_match('/(to-chk|to-check)=(\d+?)\/(\d+)/', $line, $match)) { - $max = intval($match[3]); - $step = $max - intval($match[2]); - $progressBar->setMaxSteps($max); - $progressBar->setFormat("[$host] %current%/%max% [%bar%] %percent:3s%% %elapsed:6s%/%estimated:-6s%"); - $progressBar->setProgress($step); - } - } - return; - } - if ($this->output->isVerbose()) { - $this->pop->printBuffer($type, $host, $buffer); - } - }; - - $process = new Process($command); - $process->setTimeout($config['timeout']); - try { - $process->mustRun($callback); - - if ($displayStats) { - $stats = []; - - $statsStarted = false; - foreach (explode("\n", $fullOutput) as $line) { - if (strpos($line, 'Number of files') === 0) { - $statsStarted = true; - } - - if ($statsStarted) { - if (empty($line)) { - break; - } - $stats[] = $line; - } - } - - writeln("Rsync operation stats\n" . '' . implode("\n", $stats) . ''); - } - - } catch (ProcessFailedException $exception) { - throw new RunException( - $host, - $commandString, - $process->getExitCode(), - $process->getOutput(), - $process->getErrorOutput() - ); - } finally { - if ($progressBar) { - $progressBar->clear(); - } - } - } -} diff --git a/src/functions.php b/src/functions.php deleted file mode 100644 index 03fd7794a..000000000 --- a/src/functions.php +++ /dev/null @@ -1,951 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Deployer; - -use Deployer\Exception\Exception; -use Deployer\Exception\GracefulShutdownException; -use Deployer\Exception\RunException; -use Deployer\Exception\TimeoutException; -use Deployer\Exception\WillAskUser; -use Deployer\Host\Host; -use Deployer\Host\Localhost; -use Deployer\Host\Range; -use Deployer\Importer\Importer; -use Deployer\Support\ObjectProxy; -use Deployer\Task\Context; -use Deployer\Task\GroupTask; -use Deployer\Task\Task; -use Deployer\Utility\Httpie; -use Symfony\Component\Console\Helper\QuestionHelper; -use Symfony\Component\Console\Input\InputInterface; -use Symfony\Component\Console\Input\InputOption; -use Symfony\Component\Console\Output\OutputInterface; -use Symfony\Component\Console\Question\ChoiceQuestion; -use Symfony\Component\Console\Question\ConfirmationQuestion; -use Symfony\Component\Console\Question\Question; -use function Deployer\Support\array_merge_alternate; -use function Deployer\Support\env_stringify; -use function Deployer\Support\is_closure; -use function Deployer\Support\str_contains; - -/** - * Defines a host or hosts. - * ```php - * host('example.org'); - * host('prod.example.org', 'staging.example.org'); - * ``` - * - * Inside task can be used to get `Host` instance of an alias. - * ```php - * task('test', function () { - * $port = host('example.org')->get('port'); - * }); - * ``` - * - * @return Host|ObjectProxy - */ -function host(string ...$hostname) -{ - $deployer = Deployer::get(); - if (count($hostname) === 1 && $deployer->hosts->has($hostname[0])) { - return $deployer->hosts->get($hostname[0]); - } - $aliases = Range::expand($hostname); - - foreach ($aliases as $alias) { - if ($deployer->hosts->has($alias)) { - $host = $deployer->hosts->get($alias); - throw new \InvalidArgumentException("Host \"$host\" already exists."); - } - } - - if (count($aliases) === 1) { - $host = new Host($aliases[0]); - $deployer->hosts->set($aliases[0], $host); - return $host; - } else { - $hosts = array_map(function ($hostname) use ($deployer): Host { - $host = new Host($hostname); - $deployer->hosts->set($hostname, $host); - return $host; - }, $aliases); - return new ObjectProxy($hosts); - } -} - -/** - * @return Localhost|ObjectProxy - */ -function localhost(string ...$hostnames) -{ - $deployer = Deployer::get(); - $hostnames = Range::expand($hostnames); - - if (count($hostnames) <= 1) { - $host = count($hostnames) === 1 ? new Localhost($hostnames[0]) : new Localhost(); - $deployer->hosts->set($host->getAlias(), $host); - return $host; - } else { - $hosts = array_map(function ($hostname) use ($deployer): Localhost { - $host = new Localhost($hostname); - $deployer->hosts->set($host->getAlias(), $host); - return $host; - }, $hostnames); - return new ObjectProxy($hosts); - } -} - -/** - * Returns current host. - */ -function currentHost(): Host -{ - return Context::get()->getHost(); -} - -/** - * Returns hosts based on provided selector. - * - * ```php - * on(select('stage=prod, role=db'), function (Host $host) { - * ... - * }); - * ``` - * - * @return Host[] - */ -function select(string $selector): array -{ - return Deployer::get()->selector->select($selector); -} - -/** - * Returns array of hosts selected by user via CLI. - * - * @return Host[] - */ -function selectedHosts(): array -{ - $hosts = []; - foreach (get('selected_hosts', []) as $alias) { - $hosts[] = Deployer::get()->hosts->get($alias); - } - return $hosts; -} - -/** - * Import other php or yaml recipes. - * - * ```php - * import('recipe/common.php'); - * ``` - * - * ```php - * import(__DIR__ . '/config/hosts.yaml'); - * ``` - * - * @throws Exception - */ -function import(string $file): void -{ - Importer::import($file); -} - -/** - * Set task description. - */ -function desc(?string $title = null): ?string -{ - static $store = null; - - if ($title === null) { - return $store; - } else { - return $store = $title; - } -} - -/** - * Define a new task and save to tasks list. - * - * Alternatively get a defined task. - * - * @param string $name Name of current task. - * @param callable():void|array|null $body Callable task, array of other tasks names or nothing to get a defined tasks - */ -function task(string $name, $body = null): Task -{ - $deployer = Deployer::get(); - - if (empty($body)) { - return $deployer->tasks->get($name); - } - - if (is_callable($body)) { - $task = new Task($name, $body); - } elseif (is_array($body)) { - $task = new GroupTask($name, $body); - } else { - throw new \InvalidArgumentException('Task body should be a function or an array.'); - } - - if ($deployer->tasks->has($name)) { - // If task already exists, try to replace. - $existingTask = $deployer->tasks->get($name); - if (get_class($existingTask) !== get_class($task)) { - // There is no "up" or "down"casting in PHP. - throw new \Exception('Tried to replace Task \'' . $name . '\' with a GroupTask or vice-versa. This is not supported. If you are sure you want to do that, remove the old task `Deployer::get()->tasks->remove()` and then re-add the task.'); - } - if ($existingTask instanceof GroupTask) { - $existingTask->setGroup($body); - } elseif ($existingTask instanceof Task) { - $existingTask->setCallback($body); - } - $task = $existingTask; - } else { - // If task does not exist, add it to the Collection. - $deployer->tasks->set($name, $task); - } - - $task->saveSourceLocation(); - - if (!empty(desc())) { - $task->desc(desc()); - desc(''); // Clear title. - } - - return $task; -} - -/** - * Call that task before specified task runs. - * - * @param string $task The task before $that should be run. - * @param string|callable():void $do The task to be run. - * - * @return Task|null - */ -function before(string $task, $do) -{ - if (is_closure($do)) { - $newTask = task("before:$task", $do); - before($task, "before:$task"); - return $newTask; - } - task($task)->addBefore($do); - - return null; -} - -/** - * Call that task after specified task runs. - * - * @param string $task The task after $that should be run. - * @param string|callable():void $do The task to be run. - * - * @return Task|null - */ -function after(string $task, $do) -{ - if (is_closure($do)) { - $newTask = task("after:$task", $do); - after($task, "after:$task"); - return $newTask; - } - task($task)->addAfter($do); - - return null; -} - -/** - * Setup which task run on failure of $task. - * When called multiple times for a task, previous fail() definitions will be overridden. - * - * @param string $task The task which need to fail so $that should be run. - * @param string|callable():void $do The task to be run. - * - * @return Task|null - */ -function fail(string $task, $do) -{ - if (is_callable($do)) { - $newTask = task("fail:$task", $do); - fail($task, "fail:$task"); - return $newTask; - } - $deployer = Deployer::get(); - $deployer->fail->set($task, $do); - - return null; -} - -/** - * Add users options. - * - * @param string $name The option name - * @param string|array|null $shortcut The shortcuts, can be null, a string of shortcuts delimited by | or an array of shortcuts - * @param int|null $mode The option mode: One of the VALUE_* constants - * @param string $description A description text - * @param string|string[]|int|bool|null $default The default value (must be null for self::VALUE_NONE) - */ -function option(string $name, $shortcut = null, ?int $mode = null, string $description = '', $default = null): void -{ - Deployer::get()->inputDefinition->addOption( - new InputOption($name, $shortcut, $mode, $description, $default) - ); -} - -/** - * Change the current working directory. - */ -function cd(string $path): void -{ - set('working_path', parse($path)); -} - -/** - * Execute a callback within a specific directory and revert back to the initial working directory. - * - * @return mixed|null Return value of the $callback function or null if callback doesn't return anything - */ -function within(string $path, callable $callback) -{ - $lastWorkingPath = get('working_path', ''); - try { - set('working_path', parse($path)); - return $callback(); - } finally { - set('working_path', $lastWorkingPath); - } - - return null; -} - -/** - * Executes given command on remote host. - * - * Examples: - * - * ```php - * run('echo hello world'); - * run('cd {{deploy_path}} && git status'); - * run('password %secret%', secret: getenv('CI_SECRET')); - * run('curl medv.io', timeout: 5); - * ``` - * - * ```php - * $path = run('readlink {{deploy_path}}/current'); - * run("echo $path"); - * ``` - * - * @param string $command Command to run on remote host. - * @param array|null $options Array of options will override passed named arguments. - * @param int|null $timeout Sets the process timeout (max. runtime). The timeout in seconds (default: 300 sec; see {{default_timeout}}, `null` to disable). - * @param int|null $idle_timeout Sets the process idle timeout (max. time since last output) in seconds. - * @param string|null $secret Placeholder `%secret%` can be used in command. Placeholder will be replaced with this value and will not appear in any logs. - * @param array|null $env Array of environment variables: `run('echo $KEY', env: ['key' => 'value']);` - * @param bool|null $real_time_output Print command output in real-time. - * @param bool|null $no_throw Don't throw an exception of non-zero exit code. - * - * @throws Exception|RunException|TimeoutException - */ -function run(string $command, ?array $options = [], ?int $timeout = null, ?int $idle_timeout = null, ?string $secret = null, ?array $env = null, ?bool $real_time_output = false, ?bool $no_throw = false): string -{ - $namedArguments = []; - foreach (['timeout', 'idle_timeout', 'secret', 'env', 'real_time_output', 'no_throw'] as $arg) { - if ($$arg !== null) { - $namedArguments[$arg] = $$arg; - } - } - $options = array_merge($namedArguments, $options); - $run = function ($command, $options = []): string { - $host = currentHost(); - - $command = parse($command); - $workingPath = get('working_path', ''); - - if (!empty($workingPath)) { - $command = "cd $workingPath && ($command)"; - } - - $env = array_merge_alternate(get('env', []), $options['env'] ?? []); - if (!empty($env)) { - $env = env_stringify($env); - $command = "export $env; $command"; - } - - $dotenv = get('dotenv', false); - if (!empty($dotenv)) { - $command = ". $dotenv; $command"; - } - - if ($host instanceof Localhost) { - $process = Deployer::get()->processRunner; - $output = $process->run($host, $command, $options); - } else { - $client = Deployer::get()->sshClient; - $output = $client->run($host, $command, $options); - } - - return rtrim($output); - }; - - if (preg_match('/^sudo\b/', $command)) { - try { - return $run($command, $options); - } catch (RunException $exception) { - $askpass = get('sudo_askpass', '/tmp/dep_sudo_pass'); - $password = get('sudo_pass', false); - if ($password === false) { - writeln("run $command"); - $password = askHiddenResponse(" [sudo] password for {{remote_user}}: "); - } - $run("echo -e '#!/bin/sh\necho \"\$PASSWORD\"' > $askpass"); - $run("chmod a+x $askpass"); - $command = preg_replace('/^sudo\b/', 'sudo -A', $command); - $output = $run(" SUDO_ASKPASS=$askpass PASSWORD=%sudo_pass% $command", array_merge($options, ['sudo_pass' => escapeshellarg($password)])); - $run("rm $askpass"); - return $output; - } - } else { - return $run($command, $options); - } -} - - -/** - * Execute commands on a local machine. - * - * Examples: - * - * ```php - * $user = runLocally('git config user.name'); - * runLocally("echo $user"); - * ``` - * - * @param string $command Command to run on localhost. - * @param array|null $options Array of options will override passed named arguments. - * @param int|null $timeout Sets the process timeout (max. runtime). The timeout in seconds (default: 300 sec, `null` to disable). - * @param int|null $idle_timeout Sets the process idle timeout (max. time since last output) in seconds. - * @param string|null $secret Placeholder `%secret%` can be used in command. Placeholder will be replaced with this value and will not appear in any logs. - * @param array|null $env Array of environment variables: `runLocally('echo $KEY', env: ['key' => 'value']);` - * @param string|null $shell Shell to run in. Default is `bash -s`. - * - * @throws RunException - */ -function runLocally(string $command, ?array $options = [], ?int $timeout = null, ?int $idle_timeout = null, ?string $secret = null, ?array $env = null, ?string $shell = null): string -{ - $namedArguments = []; - foreach (['timeout', 'idle_timeout', 'secret', 'env', 'shell'] as $arg) { - if ($$arg !== null) { - $namedArguments[$arg] = $$arg; - } - } - $options = array_merge($namedArguments, $options); - - $process = Deployer::get()->processRunner; - $command = parse($command); - - $env = array_merge_alternate(get('env', []), $options['env'] ?? []); - if (!empty($env)) { - $env = env_stringify($env); - $command = "export $env; $command"; - } - - $output = $process->run(new Localhost(), $command, $options); - - return rtrim($output); -} - -/** - * Run test command. - * Example: - * - * ```php - * if (test('[ -d {{release_path}} ]')) { - * ... - * } - * ``` - * - */ -function test(string $command): bool -{ - $true = '+' . array_rand(array_flip(['accurate', 'appropriate', 'correct', 'legitimate', 'precise', 'right', 'true', 'yes', 'indeed'])); - return run("if $command; then echo $true; fi") === $true; -} - -/** - * Run test command locally. - * Example: - * - * testLocally('[ -d {{local_release_path}} ]') - * - */ -function testLocally(string $command): bool -{ - return runLocally("if $command; then echo +true; fi") === '+true'; -} - -/** - * Iterate other hosts, allowing to call run a func in callback. - * - * ```php - * on(select('stage=prod, role=db'), function ($host) { - * ... - * }); - * ``` - * - * ```php - * on(host('example.org'), function ($host) { - * ... - * }); - * ``` - * - * ```php - * on(Deployer::get()->hosts, function ($host) { - * ... - * }); - * ``` - * - * @param Host|Host[] $hosts - */ -function on($hosts, callable $callback): void -{ - if (!is_array($hosts) && !($hosts instanceof \Traversable)) { - $hosts = [$hosts]; - } - - foreach ($hosts as $host) { - if ($host instanceof Host) { - $host->config()->load(); - Context::push(new Context($host)); - try { - $callback($host); - $host->config()->save(); - } catch (GracefulShutdownException $e) { - Deployer::get()->messenger->renderException($e, $host); - } finally { - Context::pop(); - } - } else { - throw new \InvalidArgumentException("Function on can iterate only on Host instances."); - } - } -} - -/** - * Runs a task. - * ```php - * invoke('deploy:symlink'); - * ``` - * - * @throws Exception - */ -function invoke(string $taskName): void -{ - $task = Deployer::get()->tasks->get($taskName); - Deployer::get()->messenger->startTask($task); - $task->run(Context::get()); - Deployer::get()->messenger->endTask($task); -} - -/** - * Upload file or directory to host. - * - * > You may have noticed that there is a trailing slash (/) at the end of the first argument in the above command, this is necessary to mean “the contents of build“. - * > - * > The alternative, without the trailing slash, would place build, including the directory, within public. This would create a hierarchy that looks like: {{release_path}}/public/build - * - * The `$config` array supports the following keys: - * - * - `flags` for overriding the default `-azP` passed to the `rsync` command - * - `options` with additional flags passed directly to the `rsync` command - * - `timeout` for `Process::fromShellCommandline()` (`null` by default) - * - `progress_bar` to display upload/download progress - * - `display_stats' to display rsync set of statistics - * - * @param string|string[] $source - * @param array $config - * @phpstan-param array{flags?: string, options?: array, timeout?: int|null, progress_bar?: bool, display_stats?: bool} $config - * - * @throws RunException - */ -function upload($source, string $destination, array $config = []): void -{ - $rsync = Deployer::get()->rsync; - $host = currentHost(); - $source = is_array($source) ? array_map('Deployer\parse', $source) : parse($source); - $destination = parse($destination); - - if ($host instanceof Localhost) { - $rsync->call($host, $source, $destination, $config); - } else { - $rsync->call($host, $source, "{$host->connectionString()}:$destination", $config); - } -} - -/** - * Download file or directory from host - * - * @param array $config - * - * @throws RunException - */ -function download(string $source, string $destination, array $config = []): void -{ - $rsync = Deployer::get()->rsync; - $host = currentHost(); - $source = parse($source); - $destination = parse($destination); - - if ($host instanceof Localhost) { - $rsync->call($host, $source, $destination, $config); - } else { - $rsync->call($host, "{$host->connectionString()}:$source", $destination, $config); - } -} - -/** - * Writes an info message. - */ -function info(string $message): void -{ - writeln("info " . parse($message)); -} - -/** - * Writes an warning message. - */ -function warning(string $message): void -{ - $message = "warning $message"; - - if (Context::has()) { - writeln($message); - } else { - Deployer::get()->output->writeln($message); - } -} - -/** - * Writes a message to the output and adds a newline at the end. - */ -function writeln(string $message, int $options = 0): void -{ - $host = currentHost(); - output()->writeln("[$host] " . parse($message), $options); -} - -/** - * Parse set values. - */ -function parse(string $value): string -{ - return Context::get()->getConfig()->parse($value); -} - -/** - * Setup configuration option. - * @param mixed $value - * @throws Exception - */ -function set(string $name, $value): void -{ - if (!Context::has()) { - Deployer::get()->config->set($name, $value); - } else { - Context::get()->getConfig()->set($name, $value); - } -} - -/** - * Merge new config params to existing config array. - * - * @param array $array - */ -function add(string $name, array $array): void -{ - if (!Context::has()) { - Deployer::get()->config->add($name, $array); - } else { - Context::get()->getConfig()->add($name, $array); - } -} - -/** - * Get configuration value. - * - * @param mixed|null $default - * - * @return mixed - */ -function get(string $name, $default = null) -{ - if (!Context::has()) { - return Deployer::get()->config->get($name, $default); - } else { - return Context::get()->getConfig()->get($name, $default); - } -} - -/** - * Check if there is such configuration option. - */ -function has(string $name): bool -{ - if (!Context::has()) { - return Deployer::get()->config->has($name); - } else { - return Context::get()->getConfig()->has($name); - } -} - -function ask(string $message, ?string $default = null, ?array $autocomplete = null): ?string -{ - if (defined('DEPLOYER_NO_ASK')) { - throw new WillAskUser($message); - } - Context::required(__FUNCTION__); - - if (output()->isQuiet()) { - return $default; - } - - if (Deployer::isWorker()) { - return Deployer::proxyCallToMaster(currentHost(), __FUNCTION__, ...func_get_args()); - } - - /** @var QuestionHelper */ - $helper = Deployer::get()->getHelper('question'); - - $tag = currentHost()->getTag(); - $message = parse($message); - $message = "[$tag] $message " . (($default === null) ? "" : "(default: $default) "); - - $question = new Question($message, $default); - if (!empty($autocomplete)) { - $question->setAutocompleterValues($autocomplete); - } - - return $helper->ask(input(), output(), $question); -} - -/** - * @param mixed $default - * @return mixed - * @throws Exception - */ -function askChoice(string $message, array $availableChoices, $default = null, bool $multiselect = false) -{ - if (defined('DEPLOYER_NO_ASK')) { - throw new WillAskUser($message); - } - Context::required(__FUNCTION__); - - if (empty($availableChoices)) { - throw new \InvalidArgumentException('Available choices should not be empty'); - } - - if ($default !== null && !array_key_exists($default, $availableChoices)) { - throw new \InvalidArgumentException('Default choice is not available'); - } - - if (output()->isQuiet()) { - if ($default === null) { - $default = key($availableChoices); - } - return [$default => $availableChoices[$default]]; - } - - if (Deployer::isWorker()) { - return Deployer::proxyCallToMaster(currentHost(), __FUNCTION__, ...func_get_args()); - } - - /** @var QuestionHelper */ - $helper = Deployer::get()->getHelper('question'); - - $tag = currentHost()->getTag(); - $message = parse($message); - $message = "[$tag] $message " . (($default === null) ? "" : "(default: $default) "); - - $question = new ChoiceQuestion($message, $availableChoices, $default); - $question->setMultiselect($multiselect); - - return $helper->ask(input(), output(), $question); -} - -function askConfirmation(string $message, bool $default = false): bool -{ - if (defined('DEPLOYER_NO_ASK')) { - throw new WillAskUser($message); - } - Context::required(__FUNCTION__); - - if (output()->isQuiet()) { - return $default; - } - - if (Deployer::isWorker()) { - return Deployer::proxyCallToMaster(currentHost(), __FUNCTION__, ...func_get_args()); - } - - /** @var QuestionHelper */ - $helper = Deployer::get()->getHelper('question'); - - $yesOrNo = $default ? 'Y/n' : 'y/N'; - $tag = currentHost()->getTag(); - $message = parse($message); - $message = "[$tag] $message [$yesOrNo] "; - - $question = new ConfirmationQuestion($message, $default); - - return $helper->ask(input(), output(), $question); -} - -function askHiddenResponse(string $message): string -{ - if (defined('DEPLOYER_NO_ASK')) { - throw new WillAskUser($message); - } - Context::required(__FUNCTION__); - - if (output()->isQuiet()) { - return ''; - } - - if (Deployer::isWorker()) { - return (string)Deployer::proxyCallToMaster(currentHost(), __FUNCTION__, ...func_get_args()); - } - - /** @var QuestionHelper */ - $helper = Deployer::get()->getHelper('question'); - - $tag = currentHost()->getTag(); - $message = parse($message); - $message = "[$tag] $message "; - - $question = new Question($message); - $question->setHidden(true); - $question->setHiddenFallback(false); - - return (string)$helper->ask(input(), output(), $question); -} - -function input(): InputInterface -{ - return Deployer::get()->input; -} - -function output(): OutputInterface -{ - return Deployer::get()->output; -} - -/** - * Check if command exists - * - * @throws RunException - */ -function commandExist(string $command): bool -{ - return test("hash $command 2>/dev/null"); -} - -/** - * @throws RunException - */ -function commandSupportsOption(string $command, string $option): bool -{ - $man = run("(man $command 2>&1 || $command -h 2>&1 || $command --help 2>&1) | grep -- $option || true"); - if (empty($man)) { - return false; - } - return str_contains($man, $option); -} - -/** - * @throws RunException - */ -function which(string $name): string -{ - $nameEscaped = escapeshellarg($name); - - // Try `command`, should cover all Bourne-like shells - // Try `which`, should cover most other cases - // Fallback to `type` command, if the rest fails - $path = run("command -v $nameEscaped || which $nameEscaped || type -p $nameEscaped"); - if (empty($path)) { - throw new \RuntimeException("Can't locate [$nameEscaped] - neither of [command|which|type] commands are available"); - } - - // Deal with issue when `type -p` outputs something like `type -ap` in some implementations - return trim(str_replace("$name is", "", $path)); - -} - -/** - * Returns remote environments variables as an array. - * ```php - * $remotePath = remoteEnv()['PATH']; - * run('echo $PATH', env: ['PATH' => "/home/user/bin:$remotePath"]); - * ``` - */ -function remoteEnv(): array -{ - $vars = []; - $data = run('env'); - foreach (explode("\n", $data) as $line) { - list($name, $value) = explode('=', $line, 2); - $vars[$name] = $value; - } - return $vars; -} - -/** - * Creates a new exception. - */ -function error(string $message): Exception -{ - return new Exception(parse($message)); -} - -/** - * Returns current timestamp in UTC timezone in ISO8601 format. - */ -function timestamp(): string -{ - return (new \DateTime('now', new \DateTimeZone('UTC')))->format(\DateTime::ISO8601); -} - -/** - * Example usage: - * ```php - * $result = fetch('{{domain}}', info: $info); - * var_dump($info['http_code'], $result); - * ``` - */ -function fetch(string $url, string $method = 'get', array $headers = [], ?string $body = null, ?array &$info = null, bool $nothrow = false): string -{ - $url = parse($url); - if (strtolower($method) === 'get') { - $http = Httpie::get($url); - } elseif (strtolower($method) === 'post') { - $http = Httpie::post($url); - } else { - throw new \InvalidArgumentException("Unknown method \"$method\"."); - } - $http = $http->nothrow($nothrow); - foreach ($headers as $key => $value) { - $http = $http->header($key, $value); - } - if ($body !== null) { - $http = $http->body($body); - } - return $http->send($info); -} diff --git a/src/schema.json b/src/schema.json deleted file mode 100644 index 6e2ba78f6..000000000 --- a/src/schema.json +++ /dev/null @@ -1,130 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "$id": "http://deployer.org/schema.json#", - "type": "object", - "additionalProperties": false, - "properties": { - "version": { - "type": "string" - }, - "import": { - "oneOf": [ - { - "type": "string" - }, - { - "type": "array", - "items": { - "type": "string" - } - } - ] - }, - "config": { - "type": "object" - }, - "hosts": { - "type": "object", - "patternProperties": { - "^": { - "oneOf": [ - { - "type": "object", - "properties": { - "local": { - "type": "boolean" - } - } - }, - { - "type": "null" - } - ] - } - } - }, - "tasks": { - "type": "object", - "patternProperties": { - "^": { - "oneOf": [ - { - "type": "array", - "items": { - "type": "object", - "properties": { - "cd": { - "type": "string" - }, - "run": { - "type": "string" - }, - "run_locally": { - "type": "string" - }, - "upload": { - "type": "object", - "required": [ - "src", - "dest" - ], - "properties": { - "src": { - "type": "string" - }, - "dest": { - "type": "string" - } - } - }, - "download": { - "type": "object", - "required": [ - "src", - "dest" - ], - "properties": { - "src": { - "type": "string" - }, - "dest": { - "type": "string" - } - } - }, - "desc": { - "type": "string" - }, - "once": { - "type": "boolean" - }, - "hidden": { - "type": "boolean" - }, - "limit": { - "type": "number" - }, - "select": { - "type": "string" - } - } - } - }, - { - "type": "array", - "items": { - "type": "string" - } - } - ] - } - } - }, - "before": { - "type": "object" - }, - "after": { - "type": "object" - } - } -}