From 76699687265378d93991ad9f20f71332277b40e8 Mon Sep 17 00:00:00 2001 From: Ryan Weaver Date: Fri, 17 Dec 2021 12:01:37 -0500 Subject: [PATCH] Adding a command to generate the complete archived recipe history for a repository --- composer.json | 11 +- composer.lock | 402 ++++++++++++++++++------- run | 2 + src/GenerateArchivedRecipesCommand.php | 107 +++++++ 4 files changed, 417 insertions(+), 105 deletions(-) create mode 100644 src/GenerateArchivedRecipesCommand.php diff --git a/composer.json b/composer.json index 32111cd..bbdc15e 100644 --- a/composer.json +++ b/composer.json @@ -17,10 +17,13 @@ "ext-ctype": "*", "ext-intl": "*", "ext-mbstring": "*", - "symfony/console": "^5.3", - "symfony/http-client": "^5.3", - "symfony/runtime": "^5.3", - "symfony/yaml": "^5.3" + "symfony/console": "^5.4", + "symfony/filesystem": "^5.4", + "symfony/finder": "^5.4", + "symfony/http-client": "^5.4", + "symfony/process": "^5.4", + "symfony/runtime": "^5.4", + "symfony/yaml": "^5.4" }, "require-dev": { "symfony/var-dumper": "^5.3" diff --git a/composer.lock b/composer.lock index 89a0d8f..3dc6fa1 100644 --- a/composer.lock +++ b/composer.lock @@ -4,26 +4,31 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "659fa332629741ae0654163129d3a547", + "content-hash": "b25ce32c7d6e71b918aac859e08fcd3d", "packages": [ { "name": "psr/container", - "version": "1.1.1", + "version": "2.0.2", "source": { "type": "git", "url": "https://github.com/php-fig/container.git", - "reference": "8622567409010282b7aeebe4bb841fe98b58dcaf" + "reference": "c71ecc56dfe541dbd90c5360474fbc405f8d5963" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-fig/container/zipball/8622567409010282b7aeebe4bb841fe98b58dcaf", - "reference": "8622567409010282b7aeebe4bb841fe98b58dcaf", + "url": "https://api.github.com/repos/php-fig/container/zipball/c71ecc56dfe541dbd90c5360474fbc405f8d5963", + "reference": "c71ecc56dfe541dbd90c5360474fbc405f8d5963", "shasum": "" }, "require": { - "php": ">=7.2.0" + "php": ">=7.4.0" }, "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, "autoload": { "psr-4": { "Psr\\Container\\": "src/" @@ -50,9 +55,9 @@ ], "support": { "issues": "https://github.com/php-fig/container/issues", - "source": "https://github.com/php-fig/container/tree/1.1.1" + "source": "https://github.com/php-fig/container/tree/2.0.2" }, - "time": "2021-03-05T17:36:06+00:00" + "time": "2021-11-05T16:47:00+00:00" }, { "name": "psr/log", @@ -106,26 +111,26 @@ }, { "name": "symfony/console", - "version": "v5.3.7", + "version": "v5.4.1", "source": { "type": "git", "url": "https://github.com/symfony/console.git", - "reference": "8b1008344647462ae6ec57559da166c2bfa5e16a" + "reference": "9130e1a0fc93cb0faadca4ee917171bd2ca9e5f4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/8b1008344647462ae6ec57559da166c2bfa5e16a", - "reference": "8b1008344647462ae6ec57559da166c2bfa5e16a", + "url": "https://api.github.com/repos/symfony/console/zipball/9130e1a0fc93cb0faadca4ee917171bd2ca9e5f4", + "reference": "9130e1a0fc93cb0faadca4ee917171bd2ca9e5f4", "shasum": "" }, "require": { "php": ">=7.2.5", - "symfony/deprecation-contracts": "^2.1", + "symfony/deprecation-contracts": "^2.1|^3", "symfony/polyfill-mbstring": "~1.0", - "symfony/polyfill-php73": "^1.8", + "symfony/polyfill-php73": "^1.9", "symfony/polyfill-php80": "^1.16", - "symfony/service-contracts": "^1.1|^2", - "symfony/string": "^5.1" + "symfony/service-contracts": "^1.1|^2|^3", + "symfony/string": "^5.1|^6.0" }, "conflict": { "psr/log": ">=3", @@ -140,12 +145,12 @@ }, "require-dev": { "psr/log": "^1|^2", - "symfony/config": "^4.4|^5.0", - "symfony/dependency-injection": "^4.4|^5.0", - "symfony/event-dispatcher": "^4.4|^5.0", - "symfony/lock": "^4.4|^5.0", - "symfony/process": "^4.4|^5.0", - "symfony/var-dumper": "^4.4|^5.0" + "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", @@ -185,7 +190,7 @@ "terminal" ], "support": { - "source": "https://github.com/symfony/console/tree/v5.3.7" + "source": "https://github.com/symfony/console/tree/v5.4.1" }, "funding": [ { @@ -201,29 +206,29 @@ "type": "tidelift" } ], - "time": "2021-08-25T20:02:16+00:00" + "time": "2021-12-09T11:22:43+00:00" }, { "name": "symfony/deprecation-contracts", - "version": "v2.4.0", + "version": "v3.0.0", "source": { "type": "git", "url": "https://github.com/symfony/deprecation-contracts.git", - "reference": "5f38c8804a9e97d23e0c8d63341088cd8a22d627" + "reference": "c726b64c1ccfe2896cb7df2e1331c357ad1c8ced" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/5f38c8804a9e97d23e0c8d63341088cd8a22d627", - "reference": "5f38c8804a9e97d23e0c8d63341088cd8a22d627", + "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/c726b64c1ccfe2896cb7df2e1331c357ad1c8ced", + "reference": "c726b64c1ccfe2896cb7df2e1331c357ad1c8ced", "shasum": "" }, "require": { - "php": ">=7.1" + "php": ">=8.0.2" }, "type": "library", "extra": { "branch-alias": { - "dev-main": "2.4-dev" + "dev-main": "3.0-dev" }, "thanks": { "name": "symfony/contracts", @@ -252,7 +257,134 @@ "description": "A generic function and convention to trigger deprecation notices", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/deprecation-contracts/tree/v2.4.0" + "source": "https://github.com/symfony/deprecation-contracts/tree/v3.0.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-01T23:48:49+00:00" + }, + { + "name": "symfony/filesystem", + "version": "v5.4.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/filesystem.git", + "reference": "731f917dc31edcffec2c6a777f3698c33bea8f01" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/filesystem/zipball/731f917dc31edcffec2c6a777f3698c33bea8f01", + "reference": "731f917dc31edcffec2c6a777f3698c33bea8f01", + "shasum": "" + }, + "require": { + "php": ">=7.2.5", + "symfony/polyfill-ctype": "~1.8", + "symfony/polyfill-mbstring": "~1.8", + "symfony/polyfill-php80": "^1.16" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Filesystem\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides basic utilities for the filesystem", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/filesystem/tree/v5.4.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-28T13:39:27+00:00" + }, + { + "name": "symfony/finder", + "version": "v5.4.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/finder.git", + "reference": "d2f29dac98e96a98be467627bd49c2efb1bc2590" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/finder/zipball/d2f29dac98e96a98be467627bd49c2efb1bc2590", + "reference": "d2f29dac98e96a98be467627bd49c2efb1bc2590", + "shasum": "" + }, + "require": { + "php": ">=7.2.5", + "symfony/deprecation-contracts": "^2.1|^3", + "symfony/polyfill-php80": "^1.16" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Finder\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Finds files and directories via an intuitive fluent interface", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/finder/tree/v5.4.0" }, "funding": [ { @@ -268,30 +400,30 @@ "type": "tidelift" } ], - "time": "2021-03-23T23:28:01+00:00" + "time": "2021-11-28T15:25:38+00:00" }, { "name": "symfony/http-client", - "version": "v5.3.7", + "version": "v5.4.1", "source": { "type": "git", "url": "https://github.com/symfony/http-client.git", - "reference": "da8638ffecefc4e8ba2bc848d7b61a408119b333" + "reference": "78b69fc4532253f3025db7f2429d8765e506cbf2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-client/zipball/da8638ffecefc4e8ba2bc848d7b61a408119b333", - "reference": "da8638ffecefc4e8ba2bc848d7b61a408119b333", + "url": "https://api.github.com/repos/symfony/http-client/zipball/78b69fc4532253f3025db7f2429d8765e506cbf2", + "reference": "78b69fc4532253f3025db7f2429d8765e506cbf2", "shasum": "" }, "require": { "php": ">=7.2.5", "psr/log": "^1|^2|^3", - "symfony/deprecation-contracts": "^2.1", + "symfony/deprecation-contracts": "^2.1|^3", "symfony/http-client-contracts": "^2.4", "symfony/polyfill-php73": "^1.11", "symfony/polyfill-php80": "^1.16", - "symfony/service-contracts": "^1.0|^2" + "symfony/service-contracts": "^1.0|^2|^3" }, "provide": { "php-http/async-client-implementation": "*", @@ -308,10 +440,10 @@ "nyholm/psr7": "^1.0", "php-http/httplug": "^1.0|^2.0", "psr/http-client": "^1.0", - "symfony/dependency-injection": "^4.4|^5.0", - "symfony/http-kernel": "^4.4.13|^5.1.5", - "symfony/process": "^4.4|^5.0", - "symfony/stopwatch": "^4.4|^5.0" + "symfony/dependency-injection": "^4.4|^5.0|^6.0", + "symfony/http-kernel": "^4.4.13|^5.1.5|^6.0", + "symfony/process": "^4.4|^5.0|^6.0", + "symfony/stopwatch": "^4.4|^5.0|^6.0" }, "type": "library", "autoload": { @@ -339,7 +471,7 @@ "description": "Provides powerful methods to fetch HTTP resources synchronously or asynchronously", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/http-client/tree/v5.3.7" + "source": "https://github.com/symfony/http-client/tree/v5.4.1" }, "funding": [ { @@ -355,20 +487,20 @@ "type": "tidelift" } ], - "time": "2021-08-28T16:24:37+00:00" + "time": "2021-12-01T15:04:08+00:00" }, { "name": "symfony/http-client-contracts", - "version": "v2.4.0", + "version": "v2.5.0", "source": { "type": "git", "url": "https://github.com/symfony/http-client-contracts.git", - "reference": "7e82f6084d7cae521a75ef2cb5c9457bbda785f4" + "reference": "ec82e57b5b714dbb69300d348bd840b345e24166" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-client-contracts/zipball/7e82f6084d7cae521a75ef2cb5c9457bbda785f4", - "reference": "7e82f6084d7cae521a75ef2cb5c9457bbda785f4", + "url": "https://api.github.com/repos/symfony/http-client-contracts/zipball/ec82e57b5b714dbb69300d348bd840b345e24166", + "reference": "ec82e57b5b714dbb69300d348bd840b345e24166", "shasum": "" }, "require": { @@ -380,7 +512,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "2.4-dev" + "dev-main": "2.5-dev" }, "thanks": { "name": "symfony/contracts", @@ -417,7 +549,7 @@ "standards" ], "support": { - "source": "https://github.com/symfony/http-client-contracts/tree/v2.4.0" + "source": "https://github.com/symfony/http-client-contracts/tree/v2.5.0" }, "funding": [ { @@ -433,20 +565,82 @@ "type": "tidelift" } ], - "time": "2021-04-11T23:07:08+00:00" + "time": "2021-11-03T09:24:47+00:00" + }, + { + "name": "symfony/process", + "version": "v5.4.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/process.git", + "reference": "5be20b3830f726e019162b26223110c8f47cf274" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/process/zipball/5be20b3830f726e019162b26223110c8f47cf274", + "reference": "5be20b3830f726e019162b26223110c8f47cf274", + "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.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-28T15:25:38+00:00" }, { "name": "symfony/runtime", - "version": "v5.3.4", + "version": "v5.4.1", "source": { "type": "git", "url": "https://github.com/symfony/runtime.git", - "reference": "685a4a5491e25c7f2dd251d8fcca583b427ff290" + "reference": "f7a8403ae0e6847e56881c3c106e4ea2ec4ef8c9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/runtime/zipball/685a4a5491e25c7f2dd251d8fcca583b427ff290", - "reference": "685a4a5491e25c7f2dd251d8fcca583b427ff290", + "url": "https://api.github.com/repos/symfony/runtime/zipball/f7a8403ae0e6847e56881c3c106e4ea2ec4ef8c9", + "reference": "f7a8403ae0e6847e56881c3c106e4ea2ec4ef8c9", "shasum": "" }, "require": { @@ -459,10 +653,10 @@ }, "require-dev": { "composer/composer": "^1.0.2|^2.0", - "symfony/console": "^4.4|^5", - "symfony/dotenv": "^5.1", - "symfony/http-foundation": "^4.4|^5", - "symfony/http-kernel": "^4.4|^5" + "symfony/console": "^4.4.30|^5.3.7|^6.0", + "symfony/dotenv": "^5.1|^6.0", + "symfony/http-foundation": "^4.4.30|^5.3.7|^6.0", + "symfony/http-kernel": "^4.4.30|^5.3.7|^6.0" }, "type": "composer-plugin", "extra": { @@ -494,7 +688,7 @@ "description": "Enables decoupling PHP applications from global state", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/runtime/tree/v5.3.4" + "source": "https://github.com/symfony/runtime/tree/v5.4.1" }, "funding": [ { @@ -510,25 +704,28 @@ "type": "tidelift" } ], - "time": "2021-06-30T13:49:12+00:00" + "time": "2021-12-01T15:47:38+00:00" }, { "name": "symfony/service-contracts", - "version": "v2.4.0", + "version": "v3.0.0", "source": { "type": "git", "url": "https://github.com/symfony/service-contracts.git", - "reference": "f040a30e04b57fbcc9c6cbcf4dbaa96bd318b9bb" + "reference": "36715ebf9fb9db73db0cb24263c79077c6fe8603" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/service-contracts/zipball/f040a30e04b57fbcc9c6cbcf4dbaa96bd318b9bb", - "reference": "f040a30e04b57fbcc9c6cbcf4dbaa96bd318b9bb", + "url": "https://api.github.com/repos/symfony/service-contracts/zipball/36715ebf9fb9db73db0cb24263c79077c6fe8603", + "reference": "36715ebf9fb9db73db0cb24263c79077c6fe8603", "shasum": "" }, "require": { - "php": ">=7.2.5", - "psr/container": "^1.1" + "php": ">=8.0.2", + "psr/container": "^2.0" + }, + "conflict": { + "ext-psr": "<1.1|>=2" }, "suggest": { "symfony/service-implementation": "" @@ -536,7 +733,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "2.4-dev" + "dev-main": "3.0-dev" }, "thanks": { "name": "symfony/contracts", @@ -573,7 +770,7 @@ "standards" ], "support": { - "source": "https://github.com/symfony/service-contracts/tree/v2.4.0" + "source": "https://github.com/symfony/service-contracts/tree/v3.0.0" }, "funding": [ { @@ -589,35 +786,37 @@ "type": "tidelift" } ], - "time": "2021-04-01T10:43:52+00:00" + "time": "2021-11-04T17:53:12+00:00" }, { "name": "symfony/string", - "version": "v5.3.7", + "version": "v6.0.1", "source": { "type": "git", "url": "https://github.com/symfony/string.git", - "reference": "8d224396e28d30f81969f083a58763b8b9ceb0a5" + "reference": "0cfed595758ec6e0a25591bdc8ca733c1896af32" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/string/zipball/8d224396e28d30f81969f083a58763b8b9ceb0a5", - "reference": "8d224396e28d30f81969f083a58763b8b9ceb0a5", + "url": "https://api.github.com/repos/symfony/string/zipball/0cfed595758ec6e0a25591bdc8ca733c1896af32", + "reference": "0cfed595758ec6e0a25591bdc8ca733c1896af32", "shasum": "" }, "require": { - "php": ">=7.2.5", + "php": ">=8.0.2", "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" + "symfony/polyfill-mbstring": "~1.0" + }, + "conflict": { + "symfony/translation-contracts": "<2.0" }, "require-dev": { - "symfony/error-handler": "^4.4|^5.0", - "symfony/http-client": "^4.4|^5.0", - "symfony/translation-contracts": "^1.1|^2", - "symfony/var-exporter": "^4.4|^5.0" + "symfony/error-handler": "^5.4|^6.0", + "symfony/http-client": "^5.4|^6.0", + "symfony/translation-contracts": "^2.0|^3.0", + "symfony/var-exporter": "^5.4|^6.0" }, "type": "library", "autoload": { @@ -656,7 +855,7 @@ "utf8" ], "support": { - "source": "https://github.com/symfony/string/tree/v5.3.7" + "source": "https://github.com/symfony/string/tree/v6.0.1" }, "funding": [ { @@ -672,32 +871,32 @@ "type": "tidelift" } ], - "time": "2021-08-26T08:00:08+00:00" + "time": "2021-12-08T15:13:44+00:00" }, { "name": "symfony/yaml", - "version": "v5.3.6", + "version": "v5.4.0", "source": { "type": "git", "url": "https://github.com/symfony/yaml.git", - "reference": "4500fe63dc9c6ffc32d3b1cb0448c329f9c814b7" + "reference": "034ccc0994f1ae3f7499fa5b1f2e75d5e7a94efc" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/yaml/zipball/4500fe63dc9c6ffc32d3b1cb0448c329f9c814b7", - "reference": "4500fe63dc9c6ffc32d3b1cb0448c329f9c814b7", + "url": "https://api.github.com/repos/symfony/yaml/zipball/034ccc0994f1ae3f7499fa5b1f2e75d5e7a94efc", + "reference": "034ccc0994f1ae3f7499fa5b1f2e75d5e7a94efc", "shasum": "" }, "require": { "php": ">=7.2.5", - "symfony/deprecation-contracts": "^2.1", - "symfony/polyfill-ctype": "~1.8" + "symfony/deprecation-contracts": "^2.1|^3", + "symfony/polyfill-ctype": "^1.8" }, "conflict": { - "symfony/console": "<4.4" + "symfony/console": "<5.3" }, "require-dev": { - "symfony/console": "^4.4|^5.0" + "symfony/console": "^5.3|^6.0" }, "suggest": { "symfony/console": "For validating YAML files using the lint command" @@ -731,7 +930,7 @@ "description": "Loads and dumps YAML files", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/yaml/tree/v5.3.6" + "source": "https://github.com/symfony/yaml/tree/v5.4.0" }, "funding": [ { @@ -747,22 +946,22 @@ "type": "tidelift" } ], - "time": "2021-07-29T06:20:01+00:00" + "time": "2021-11-28T15:25:38+00:00" } ], "packages-dev": [ { "name": "symfony/var-dumper", - "version": "v5.3.7", + "version": "v5.4.1", "source": { "type": "git", "url": "https://github.com/symfony/var-dumper.git", - "reference": "3ad5af4aed07d0a0201bbcfc42658fe6c5b2fb8f" + "reference": "2366ac8d8abe0c077844613c1a4f0c0a9f522dcc" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/var-dumper/zipball/3ad5af4aed07d0a0201bbcfc42658fe6c5b2fb8f", - "reference": "3ad5af4aed07d0a0201bbcfc42658fe6c5b2fb8f", + "url": "https://api.github.com/repos/symfony/var-dumper/zipball/2366ac8d8abe0c077844613c1a4f0c0a9f522dcc", + "reference": "2366ac8d8abe0c077844613c1a4f0c0a9f522dcc", "shasum": "" }, "require": { @@ -776,8 +975,9 @@ }, "require-dev": { "ext-iconv": "*", - "symfony/console": "^4.4|^5.0", - "symfony/process": "^4.4|^5.0", + "symfony/console": "^4.4|^5.0|^6.0", + "symfony/process": "^4.4|^5.0|^6.0", + "symfony/uid": "^5.1|^6.0", "twig/twig": "^2.13|^3.0.4" }, "suggest": { @@ -821,7 +1021,7 @@ "dump" ], "support": { - "source": "https://github.com/symfony/var-dumper/tree/v5.3.7" + "source": "https://github.com/symfony/var-dumper/tree/v5.4.1" }, "funding": [ { @@ -837,7 +1037,7 @@ "type": "tidelift" } ], - "time": "2021-08-04T23:19:25+00:00" + "time": "2021-12-01T15:04:08+00:00" } ], "aliases": [], diff --git a/run b/run index 83306d2..710ee1f 100755 --- a/run +++ b/run @@ -4,6 +4,7 @@ require __DIR__.'/vendor/autoload_runtime.php'; use App\DiffRecipeVersionsCommand; +use App\GenerateArchivedRecipesCommand; use App\GenerateFlexEndpointCommand; use App\LintManifestsCommand; use App\LintPackagesCommand; @@ -17,6 +18,7 @@ return function() { $app->add(new DiffRecipeVersionsCommand()); $app->add(new GenerateFlexEndpointCommand()); + $app->add(new GenerateArchivedRecipesCommand()); $app->add(new LintManifestsCommand()); $app->add(new LintPackagesCommand()); $app->add(new LintPullRequestCommand()); diff --git a/src/GenerateArchivedRecipesCommand.php b/src/GenerateArchivedRecipesCommand.php new file mode 100644 index 0000000..625da3a --- /dev/null +++ b/src/GenerateArchivedRecipesCommand.php @@ -0,0 +1,107 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace App; + +use Symfony\Component\Console\Attribute\AsCommand; +use Symfony\Component\Console\Command\Command; +use Symfony\Component\Console\Helper\ProgressBar; +use Symfony\Component\Console\Input\InputArgument; +use Symfony\Component\Console\Input\InputInterface; +use Symfony\Component\Console\Output\OutputInterface; +use Symfony\Component\Filesystem\Filesystem; +use Symfony\Component\Finder\Finder; +use Symfony\Component\Process\Process; + +#[AsCommand(name: 'generate:archived-recipes', description: 'Generates an "archived" directory containing the history of every recipe.')] +class GenerateArchivedRecipesCommand extends Command +{ + protected function configure(): void + { + $this + ->addArgument('directory', InputArgument::REQUIRED, 'Path to the local recipes repository') + ->addArgument('branch', InputArgument::REQUIRED, 'Branch on the recipes repository to use') + ->addArgument('output_directory', InputArgument::REQUIRED, 'The directory where generated files should be stored') + ; + } + + protected function execute(InputInterface $input, OutputInterface $output): int + { + $recipesDirectory = $input->getArgument('directory'); + $branch = $input->getArgument('branch'); + $outputDir = $input->getArgument('output_directory'); + $filesystem = new Filesystem(); + + if (!file_exists($recipesDirectory)) { + throw new \InvalidArgumentException(sprintf('Cannot find directory "%s"', $recipesDirectory)); + } + + if (!file_exists($outputDir)) { + $filesystem->mkdir($outputDir); + } + + $process = new Process(['git', 'checkout', $branch], $recipesDirectory); + $process->mustRun(); + + $tmpDir = sys_get_temp_dir().'/_flex_archive/'; + $filesystem->mkdir($tmpDir); + + $process = (new Process(['git', 'rev-list', '--count', $branch, '--no-merges'], $recipesDirectory))->mustRun(); + // an imperfect estimate of the total commits + $totalCommits = (int) trim($process->getOutput()); + $progress = new ProgressBar($output, $totalCommits); + while (true) { + // most arguments to the command do not matter for us and so are hardcoded + $process = Process::fromShellCommandline( + sprintf('git ls-tree HEAD */*/* | php %s/run generate:flex-endpoint symfony/recipes master flex/main $OUTPUT_DIR', realpath(__DIR__.'/../')), + $recipesDirectory + ); + // this WILL occasionally fail: some legacy recipes were invalid and pointed to non-existent files + $process->run(null, ['OUTPUT_DIR' => $tmpDir]); + + $finder = new Finder(); + $finder->in($tmpDir.'/archived') + ->name('*.json') + ->notName('index.json'); + + foreach ($finder as $file) { + $data = json_decode($file->getContents(), true); + $manifests = array_values($data['manifests']); + $treeRef = $manifests[0]['ref']; + + $parts = explode('.', $file->getRelativePathname()); + $dottedPackageName = implode('.', [$parts[0], $parts[1]]); + + $targetPath = sprintf('%s/%s/%s.json', $outputDir, $dottedPackageName, $treeRef); + if (!file_exists(\dirname($targetPath))) { + $filesystem->mkdir(\dirname($targetPath)); + } + if (!file_exists($targetPath)) { + file_put_contents($targetPath, $file->getContents()); + } + } + + $process = new Process(['git', 'checkout', 'HEAD^1'], $recipesDirectory); + $process->mustRun(); + + $process = (new Process(['git', 'rev-list', '--count', 'HEAD', '--no-merges'], $recipesDirectory))->mustRun(); + $newCount = (int) trim($process->getOutput()); + // when we've come to the final commit, this will be 1 + if (1 === $newCount) { + break; + } + $progress->setProgress($totalCommits - $newCount); + } + + $progress->finish(); + $filesystem->remove($tmpDir); + + return 0; + } +}