diff --git a/composer.json b/composer.json index 28a5eca0..b618ce56 100644 --- a/composer.json +++ b/composer.json @@ -31,7 +31,7 @@ "react/promise": "^2.9", "symfony/dotenv": "^6.0", "php-etl/packaging": "*", - "php-etl/configurator-contracts": "0.7.*", + "php-etl/configurator-contracts": "0.8.*", "php-etl/satellite-toolbox": "*", "php-etl/pipeline-console-runtime": "*", "php-etl/gyroscops-api-client": "*", @@ -87,7 +87,7 @@ "bin": ["bin/satellite", "bin/cloud"], "extra": { "branch-alias": { - "dev-main": "0.5.x-dev" + "dev-main": "0.6.x-dev" }, "gyroscops": { "adapters": [ diff --git a/composer.lock b/composer.lock index 5ae28416..730dce84 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "4d37b77d3c0ac3f6c064a6fc6704b9d7", + "content-hash": "d14cc2c15f243096e28439ab402f8de2", "packages": [ { "name": "clue/stream-filter", @@ -1184,23 +1184,23 @@ }, { "name": "nyholm/psr7", - "version": "1.6.1", + "version": "1.7.0", "source": { "type": "git", "url": "https://github.com/Nyholm/psr7.git", - "reference": "e874c8c4286a1e010fb4f385f3a55ac56a05cc93" + "reference": "ed7cf98f6562831dbc3c962406b5e49dc8179c8c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Nyholm/psr7/zipball/e874c8c4286a1e010fb4f385f3a55ac56a05cc93", - "reference": "e874c8c4286a1e010fb4f385f3a55ac56a05cc93", + "url": "https://api.github.com/repos/Nyholm/psr7/zipball/ed7cf98f6562831dbc3c962406b5e49dc8179c8c", + "reference": "ed7cf98f6562831dbc3c962406b5e49dc8179c8c", "shasum": "" }, "require": { - "php": ">=7.1", + "php": ">=7.2", "php-http/message-factory": "^1.0", "psr/http-factory": "^1.0", - "psr/http-message": "^1.0" + "psr/http-message": "^1.1 || ^2.0" }, "provide": { "php-http/message-factory-implementation": "1.0", @@ -1209,14 +1209,14 @@ }, "require-dev": { "http-interop/http-factory-tests": "^0.9", - "php-http/psr7-integration-tests": "^1.0", + "php-http/psr7-integration-tests": "^1.0@dev", "phpunit/phpunit": "^7.5 || 8.5 || 9.4", "symfony/error-handler": "^4.4" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.6-dev" + "dev-master": "1.7-dev" } }, "autoload": { @@ -1246,7 +1246,7 @@ ], "support": { "issues": "https://github.com/Nyholm/psr7/issues", - "source": "https://github.com/Nyholm/psr7/tree/1.6.1" + "source": "https://github.com/Nyholm/psr7/tree/1.7.0" }, "funding": [ { @@ -1258,7 +1258,7 @@ "type": "github" } ], - "time": "2023-04-17T16:03:48+00:00" + "time": "2023-04-20T08:38:48+00:00" }, { "name": "phar-io/manifest", @@ -1371,6 +1371,170 @@ }, "time": "2022-02-21T01:04:05+00:00" }, + { + "name": "php-etl/action", + "version": "v0.1.0", + "source": { + "type": "git", + "url": "https://github.com/php-etl/action.git", + "reference": "e3a3baa20a4c09dea59879def5cd523f37d5d1dc" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-etl/action/zipball/e3a3baa20a4c09dea59879def5cd523f37d5d1dc", + "reference": "e3a3baa20a4c09dea59879def5cd523f37d5d1dc", + "shasum": "" + }, + "require": { + "php": "^8.2", + "php-etl/action-contracts": "0.1.*", + "php-etl/satellite-contracts": "0.1.*", + "psr/log": "^3.0" + }, + "require-dev": { + "rector/rector": "^0.15.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "0.1.x-dev" + } + }, + "autoload": { + "psr-4": { + "Kiboko\\Component\\Action\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Kiboko SAS", + "homepage": "http://kiboko.fr" + }, + { + "name": "Grégory Planchat", + "email": "gregory@kiboko.fr" + } + ], + "description": "This library implements the Extract-Transform-Load pattern asynchronously in PHP with the help of iterators and generators", + "support": { + "issues": "https://github.com/php-etl/action/issues", + "source": "https://github.com/php-etl/action/tree/v0.1.0" + }, + "time": "2023-04-19T09:11:30+00:00" + }, + { + "name": "php-etl/action-console-runtime", + "version": "v0.1.0", + "source": { + "type": "git", + "url": "https://github.com/php-etl/action-console-runtime.git", + "reference": "5864a9af352690ea72438a2d7ec205ad8906aa7f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-etl/action-console-runtime/zipball/5864a9af352690ea72438a2d7ec205ad8906aa7f", + "reference": "5864a9af352690ea72438a2d7ec205ad8906aa7f", + "shasum": "" + }, + "require": { + "php": "^8.2", + "php-etl/action-contracts": "0.1.*", + "php-etl/console-state": "*", + "php-etl/satellite-contracts": "0.1.*", + "symfony/console": "^6.0" + }, + "require-dev": { + "rector/rector": "^0.15.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "0.1.x-dev" + } + }, + "autoload": { + "psr-4": { + "Kiboko\\Component\\Runtime\\Action\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Kiboko SAS", + "homepage": "http://kiboko.fr" + }, + { + "name": "Grégory Planchat", + "email": "gregory@kiboko.fr" + } + ], + "description": "This library allows you to use the action console runtime", + "support": { + "issues": "https://github.com/php-etl/action-console-runtime/issues", + "source": "https://github.com/php-etl/action-console-runtime/tree/v0.1.0" + }, + "time": "2023-04-19T09:16:30+00:00" + }, + { + "name": "php-etl/action-contracts", + "version": "v0.1.0", + "source": { + "type": "git", + "url": "https://github.com/php-etl/action-contracts.git", + "reference": "42b3f800ab4898e06249b73afad852160d225884" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-etl/action-contracts/zipball/42b3f800ab4898e06249b73afad852160d225884", + "reference": "42b3f800ab4898e06249b73afad852160d225884", + "shasum": "" + }, + "require": { + "php": "^8.2", + "php-etl/bucket-contracts": "0.2.*" + }, + "require-dev": { + "rector/rector": "^0.15.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "0.1.x-dev" + } + }, + "autoload": { + "psr-4": { + "Kiboko\\Contract\\Action\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Kiboko SAS", + "homepage": "http://kiboko.fr" + }, + { + "name": "Grégory Planchat", + "email": "gregory@kiboko.fr" + } + ], + "description": "This library describes contracts for the Action pattern.", + "support": { + "issues": "https://github.com/php-etl/action-contracts/issues", + "source": "https://github.com/php-etl/action-contracts/tree/v0.1.0" + }, + "time": "2023-04-18T15:03:09+00:00" + }, { "name": "php-etl/bucket", "version": "v0.3.0", @@ -1483,16 +1647,16 @@ }, { "name": "php-etl/configurator-contracts", - "version": "v0.7.0", + "version": "v0.8.0", "source": { "type": "git", "url": "https://github.com/php-etl/configurator-contracts.git", - "reference": "f17ac6f867132853ec10564801c7ad393134fdef" + "reference": "9c576e4ed31ac1f025526282a79b4ba3c69988e7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-etl/configurator-contracts/zipball/f17ac6f867132853ec10564801c7ad393134fdef", - "reference": "f17ac6f867132853ec10564801c7ad393134fdef", + "url": "https://api.github.com/repos/php-etl/configurator-contracts/zipball/9c576e4ed31ac1f025526282a79b4ba3c69988e7", + "reference": "9c576e4ed31ac1f025526282a79b4ba3c69988e7", "shasum": "" }, "require": { @@ -1511,7 +1675,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "0.7.x-dev" + "dev-main": "0.8.x-dev" } }, "autoload": { @@ -1536,22 +1700,22 @@ "description": "This library describes contracts for defining configuration formats and building optimized code from it", "support": { "issues": "https://github.com/php-etl/configurator-contracts/issues", - "source": "https://github.com/php-etl/configurator-contracts/tree/v0.7.0" + "source": "https://github.com/php-etl/configurator-contracts/tree/v0.8.0" }, - "time": "2023-04-12T13:47:02+00:00" + "time": "2023-04-19T11:47:36+00:00" }, { "name": "php-etl/console-state", - "version": "v0.2.0", + "version": "v0.2.1", "source": { "type": "git", "url": "https://github.com/php-etl/console-state.git", - "reference": "830d3f55506b1a743c6b8a12c62def7025188650" + "reference": "2f6de75fe9bef2e453f63d4e26706eb4f39a22e9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-etl/console-state/zipball/830d3f55506b1a743c6b8a12c62def7025188650", - "reference": "830d3f55506b1a743c6b8a12c62def7025188650", + "url": "https://api.github.com/repos/php-etl/console-state/zipball/2f6de75fe9bef2e453f63d4e26706eb4f39a22e9", + "reference": "2f6de75fe9bef2e453f63d4e26706eb4f39a22e9", "shasum": "" }, "require": { @@ -1594,9 +1758,9 @@ "description": "This library allows you to use states", "support": { "issues": "https://github.com/php-etl/console-state/issues", - "source": "https://github.com/php-etl/console-state/tree/v0.2.0" + "source": "https://github.com/php-etl/console-state/tree/v0.2.1" }, - "time": "2023-04-12T12:55:42+00:00" + "time": "2023-04-19T08:43:31+00:00" }, { "name": "php-etl/dockerfile", @@ -1941,21 +2105,22 @@ }, { "name": "php-etl/pipeline-contracts", - "version": "v0.4.0", + "version": "v0.4.1", "source": { "type": "git", "url": "https://github.com/php-etl/pipeline-contracts.git", - "reference": "499da7f0d7340cf90dd47f76426e952eb23bf6c2" + "reference": "b5c45090ed92f93530f3f69782bb016b52627b1a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-etl/pipeline-contracts/zipball/499da7f0d7340cf90dd47f76426e952eb23bf6c2", - "reference": "499da7f0d7340cf90dd47f76426e952eb23bf6c2", + "url": "https://api.github.com/repos/php-etl/pipeline-contracts/zipball/b5c45090ed92f93530f3f69782bb016b52627b1a", + "reference": "b5c45090ed92f93530f3f69782bb016b52627b1a", "shasum": "" }, "require": { "php": "^8.2", - "php-etl/bucket-contracts": "0.2.*" + "php-etl/bucket-contracts": "0.2.*", + "php-etl/satellite-contracts": "0.1.*" }, "require-dev": { "friendsofphp/php-cs-fixer": "^3.0", @@ -1990,28 +2155,80 @@ "description": "This library describes contracts for the Extract-Transform-Load pattern.", "support": { "issues": "https://github.com/php-etl/pipeline-contracts/issues", - "source": "https://github.com/php-etl/pipeline-contracts/tree/v0.4.0" + "source": "https://github.com/php-etl/pipeline-contracts/tree/v0.4.1" }, - "time": "2023-04-17T13:08:18+00:00" + "time": "2023-04-18T14:32:57+00:00" + }, + { + "name": "php-etl/satellite-contracts", + "version": "v0.1.0", + "source": { + "type": "git", + "url": "https://github.com/php-etl/satellite-contracts.git", + "reference": "1d2bc6822bfdb3efc6a1f490e706db995c99ef41" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-etl/satellite-contracts/zipball/1d2bc6822bfdb3efc6a1f490e706db995c99ef41", + "reference": "1d2bc6822bfdb3efc6a1f490e706db995c99ef41", + "shasum": "" + }, + "require": { + "php": "^8.2" + }, + "require-dev": { + "rector/rector": "^0.15.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "0.1.x-dev" + } + }, + "autoload": { + "psr-4": { + "Kiboko\\Contract\\Satellite\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Kiboko SAS", + "homepage": "http://kiboko.fr" + }, + { + "name": "Grégory Planchat", + "email": "gregory@kiboko.fr" + } + ], + "description": "This library describes contracts for defining satellite formats", + "support": { + "issues": "https://github.com/php-etl/satellite-contracts/issues", + "source": "https://github.com/php-etl/satellite-contracts/tree/v0.1.0" + }, + "time": "2023-04-18T13:53:22+00:00" }, { "name": "php-etl/satellite-toolbox", - "version": "v0.5.0", + "version": "v0.5.1", "source": { "type": "git", "url": "https://github.com/php-etl/satellite-toolbox.git", - "reference": "acfdf758359d3025fa01848e4a8316a41b6193be" + "reference": "94552565ade7d29a632672aaed05ec98b623700d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-etl/satellite-toolbox/zipball/acfdf758359d3025fa01848e4a8316a41b6193be", - "reference": "acfdf758359d3025fa01848e4a8316a41b6193be", + "url": "https://api.github.com/repos/php-etl/satellite-toolbox/zipball/94552565ade7d29a632672aaed05ec98b623700d", + "reference": "94552565ade7d29a632672aaed05ec98b623700d", "shasum": "" }, "require": { "nikic/php-parser": "^4.10", "php": "^8.2", - "php-etl/configurator-contracts": "0.7.*", + "php-etl/configurator-contracts": "0.8.*", "symfony/expression-language": "^6.0" }, "require-dev": { @@ -2056,30 +2273,33 @@ "description": "This library aims at building and running lambda PHP functions", "support": { "issues": "https://github.com/php-etl/satellite-toolbox/issues", - "source": "https://github.com/php-etl/satellite-toolbox/tree/v0.5.0" + "source": "https://github.com/php-etl/satellite-toolbox/tree/v0.5.1" }, - "time": "2023-04-12T13:48:45+00:00" + "time": "2023-04-20T08:03:07+00:00" }, { "name": "php-etl/workflow-console-runtime", - "version": "v0.2.0", + "version": "v0.3.0", "source": { "type": "git", "url": "https://github.com/php-etl/workflow-console-runtime.git", - "reference": "d07a947b20ef5a44e949c0aa1008da854944b13c" + "reference": "d0654936e8e267bf42dc7f8fd88f6cf81a290917" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-etl/workflow-console-runtime/zipball/d07a947b20ef5a44e949c0aa1008da854944b13c", - "reference": "d07a947b20ef5a44e949c0aa1008da854944b13c", + "url": "https://api.github.com/repos/php-etl/workflow-console-runtime/zipball/d0654936e8e267bf42dc7f8fd88f6cf81a290917", + "reference": "d0654936e8e267bf42dc7f8fd88f6cf81a290917", "shasum": "" }, "require": { "php": "^8.2", + "php-etl/action": "*", + "php-etl/action-console-runtime": "*", "php-etl/console-state": "*", "php-etl/pipeline": "*", "php-etl/pipeline-console-runtime": "*", "php-etl/pipeline-contracts": "0.4.*", + "php-etl/satellite-contracts": "0.1.*", "symfony/console": "^6.0" }, "require-dev": { @@ -2090,7 +2310,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "0.2.x-dev" + "dev-main": "0.3.x-dev" } }, "autoload": { @@ -2115,9 +2335,9 @@ "description": "This library allows you to use the workflow console runtime", "support": { "issues": "https://github.com/php-etl/workflow-console-runtime/issues", - "source": "https://github.com/php-etl/workflow-console-runtime/tree/v0.2.0" + "source": "https://github.com/php-etl/workflow-console-runtime/tree/v0.3.0" }, - "time": "2023-04-12T13:59:36+00:00" + "time": "2023-04-19T11:48:30+00:00" }, { "name": "php-http/client-common", @@ -7722,23 +7942,23 @@ }, { "name": "php-etl/akeneo-plugin", - "version": "v0.6.0", + "version": "v0.6.1", "source": { "type": "git", "url": "https://github.com/php-etl/akeneo-plugin.git", - "reference": "7d13dfacd25609084206146a1ff009321f923d89" + "reference": "e752707ab02e4cdd0d8e617b7238de8f271cab06" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-etl/akeneo-plugin/zipball/7d13dfacd25609084206146a1ff009321f923d89", - "reference": "7d13dfacd25609084206146a1ff009321f923d89", + "url": "https://api.github.com/repos/php-etl/akeneo-plugin/zipball/e752707ab02e4cdd0d8e617b7238de8f271cab06", + "reference": "e752707ab02e4cdd0d8e617b7238de8f271cab06", "shasum": "" }, "require": { "ext-json": "*", "nikic/php-parser": "^4.13.2", "php": "^8.2", - "php-etl/configurator-contracts": "0.7.*", + "php-etl/configurator-contracts": "0.8.*", "php-etl/fast-map-plugin": "*", "php-etl/packaging-contracts": "0.3.*", "php-etl/satellite-toolbox": "*", @@ -7795,9 +8015,9 @@ "description": "Adapters for the Akeneo API client", "support": { "issues": "https://github.com/php-etl/akeneo-plugin/issues", - "source": "https://github.com/php-etl/akeneo-plugin/tree/v0.6.0" + "source": "https://github.com/php-etl/akeneo-plugin/tree/v0.6.1" }, - "time": "2023-04-12T14:32:20+00:00" + "time": "2023-04-20T09:13:42+00:00" }, { "name": "php-etl/array-expression-language", @@ -7855,23 +8075,23 @@ }, { "name": "php-etl/csv-plugin", - "version": "v0.6.1", + "version": "v0.6.2", "source": { "type": "git", "url": "https://github.com/php-etl/csv-plugin.git", - "reference": "c7446d176d0f44c0645f960adef7b704b03d30a4" + "reference": "4636a131213ad94ad726763a7c439eecf999e1bd" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-etl/csv-plugin/zipball/c7446d176d0f44c0645f960adef7b704b03d30a4", - "reference": "c7446d176d0f44c0645f960adef7b704b03d30a4", + "url": "https://api.github.com/repos/php-etl/csv-plugin/zipball/4636a131213ad94ad726763a7c439eecf999e1bd", + "reference": "4636a131213ad94ad726763a7c439eecf999e1bd", "shasum": "" }, "require": { "ext-json": "*", "nikic/php-parser": "^4.10", "php": "^8.2", - "php-etl/configurator-contracts": "0.7.*", + "php-etl/configurator-contracts": "0.8.*", "php-etl/packaging-contracts": "0.3.*", "php-etl/satellite-toolbox": "*", "symfony/config": "^6.0", @@ -7916,22 +8136,22 @@ "description": "Plugins for CSV Extractor and Loader", "support": { "issues": "https://github.com/php-etl/csv-plugin/issues", - "source": "https://github.com/php-etl/csv-plugin/tree/v0.6.1" + "source": "https://github.com/php-etl/csv-plugin/tree/v0.6.2" }, - "time": "2023-04-18T13:06:47+00:00" + "time": "2023-04-20T09:14:41+00:00" }, { "name": "php-etl/fast-map", - "version": "v0.5.0", + "version": "v0.5.1", "source": { "type": "git", "url": "https://github.com/php-etl/fast-map.git", - "reference": "45ffe13c21febd777378d888eb659175ea5bcec8" + "reference": "00ec4b7b76e80a02a90499e5af8d8ade39e3fdf6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-etl/fast-map/zipball/45ffe13c21febd777378d888eb659175ea5bcec8", - "reference": "45ffe13c21febd777378d888eb659175ea5bcec8", + "url": "https://api.github.com/repos/php-etl/fast-map/zipball/00ec4b7b76e80a02a90499e5af8d8ade39e3fdf6", + "reference": "00ec4b7b76e80a02a90499e5af8d8ade39e3fdf6", "shasum": "" }, "require": { @@ -7983,22 +8203,22 @@ "description": "This library implements a compiled data mapping library", "support": { "issues": "https://github.com/php-etl/fast-map/issues", - "source": "https://github.com/php-etl/fast-map/tree/v0.5.0" + "source": "https://github.com/php-etl/fast-map/tree/v0.5.1" }, - "time": "2023-04-12T13:50:21+00:00" + "time": "2023-04-20T08:07:25+00:00" }, { "name": "php-etl/fast-map-config", - "version": "v0.5.0", + "version": "v0.5.1", "source": { "type": "git", "url": "https://github.com/php-etl/fast-map-config.git", - "reference": "a9588f92e4e88a9db22947ca809e052b2521116f" + "reference": "0bae2d768d16fdd423500967a55b75f19013b729" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-etl/fast-map-config/zipball/a9588f92e4e88a9db22947ca809e052b2521116f", - "reference": "a9588f92e4e88a9db22947ca809e052b2521116f", + "url": "https://api.github.com/repos/php-etl/fast-map-config/zipball/0bae2d768d16fdd423500967a55b75f19013b729", + "reference": "0bae2d768d16fdd423500967a55b75f19013b729", "shasum": "" }, "require": { @@ -8044,29 +8264,29 @@ "description": "This library implements the Extract-Transform-Load pattern asynchronously in PHP with the help of iterators and generators", "support": { "issues": "https://github.com/php-etl/fast-map-config/issues", - "source": "https://github.com/php-etl/fast-map-config/tree/v0.5.0" + "source": "https://github.com/php-etl/fast-map-config/tree/v0.5.1" }, - "time": "2023-04-12T13:51:34+00:00" + "time": "2023-04-20T08:09:52+00:00" }, { "name": "php-etl/fast-map-plugin", - "version": "v0.8.1", + "version": "v0.8.2", "source": { "type": "git", "url": "https://github.com/php-etl/fast-map-plugin.git", - "reference": "14b47eab951fb586bf04df3c8db6781aaa6b5e40" + "reference": "e95562c5aa4f2517072414a02e665a1b35a3896f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-etl/fast-map-plugin/zipball/14b47eab951fb586bf04df3c8db6781aaa6b5e40", - "reference": "14b47eab951fb586bf04df3c8db6781aaa6b5e40", + "url": "https://api.github.com/repos/php-etl/fast-map-plugin/zipball/e95562c5aa4f2517072414a02e665a1b35a3896f", + "reference": "e95562c5aa4f2517072414a02e665a1b35a3896f", "shasum": "" }, "require": { "ext-json": "*", "nikic/php-parser": "^4.10", "php": "^8.2", - "php-etl/configurator-contracts": "0.7.*", + "php-etl/configurator-contracts": "0.8.0", "php-etl/fast-map-config": "*", "php-etl/packaging-contracts": "0.3.*", "php-etl/satellite-toolbox": "*", @@ -8111,9 +8331,9 @@ "description": "Adapters for the Fast Map mapping library", "support": { "issues": "https://github.com/php-etl/fast-map-plugin/issues", - "source": "https://github.com/php-etl/fast-map-plugin/tree/v0.8.1" + "source": "https://github.com/php-etl/fast-map-plugin/tree/v0.8.2" }, - "time": "2023-04-18T12:52:48+00:00" + "time": "2023-04-20T08:15:46+00:00" }, { "name": "php-etl/mapping-contracts", @@ -8345,22 +8565,22 @@ }, { "name": "php-etl/spreadsheet-plugin", - "version": "v0.5.1", + "version": "v0.5.2", "source": { "type": "git", "url": "https://github.com/php-etl/spreadsheet-plugin.git", - "reference": "f0a36823a34ca1b7c715abd8a87c437f3b65905a" + "reference": "08b7801d0442a316f70a2988c678a8a56d6a644c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-etl/spreadsheet-plugin/zipball/f0a36823a34ca1b7c715abd8a87c437f3b65905a", - "reference": "f0a36823a34ca1b7c715abd8a87c437f3b65905a", + "url": "https://api.github.com/repos/php-etl/spreadsheet-plugin/zipball/08b7801d0442a316f70a2988c678a8a56d6a644c", + "reference": "08b7801d0442a316f70a2988c678a8a56d6a644c", "shasum": "" }, "require": { "nikic/php-parser": "^4.10", "php": "^8.2", - "php-etl/configurator-contracts": "0.7.*", + "php-etl/configurator-contracts": "0.8.*", "php-etl/packaging-contracts": "0.3.*", "php-etl/satellite-toolbox": "*", "symfony/config": "^6.0" @@ -8406,28 +8626,28 @@ "description": "Plugin for XLS Extractor and Loader", "support": { "issues": "https://github.com/php-etl/spreadsheet-plugin/issues", - "source": "https://github.com/php-etl/spreadsheet-plugin/tree/v0.5.1" + "source": "https://github.com/php-etl/spreadsheet-plugin/tree/v0.5.2" }, - "time": "2023-04-18T13:05:59+00:00" + "time": "2023-04-20T09:21:42+00:00" }, { "name": "php-etl/sql-plugin", - "version": "v0.4.1", + "version": "v0.4.2", "source": { "type": "git", "url": "https://github.com/php-etl/sql-plugin.git", - "reference": "8ee817ead548a55941032af6be534402575666fa" + "reference": "420003c99207ffa4ac30c376a17c0eb1c72698a4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-etl/sql-plugin/zipball/8ee817ead548a55941032af6be534402575666fa", - "reference": "8ee817ead548a55941032af6be534402575666fa", + "url": "https://api.github.com/repos/php-etl/sql-plugin/zipball/420003c99207ffa4ac30c376a17c0eb1c72698a4", + "reference": "420003c99207ffa4ac30c376a17c0eb1c72698a4", "shasum": "" }, "require": { "nikic/php-parser": "^4.10", "php": "^8.2", - "php-etl/configurator-contracts": "0.7.*", + "php-etl/configurator-contracts": "0.8.*", "php-etl/fast-map-plugin": "*", "php-etl/packaging": "*", "php-etl/satellite-toolbox": "*", @@ -8474,9 +8694,9 @@ "description": "This plugin allows you to perform SQL queries in the ETL pipelines", "support": { "issues": "https://github.com/php-etl/sql-plugin/issues", - "source": "https://github.com/php-etl/sql-plugin/tree/v0.4.1" + "source": "https://github.com/php-etl/sql-plugin/tree/v0.4.2" }, - "time": "2023-04-18T13:04:50+00:00" + "time": "2023-04-20T09:24:09+00:00" }, { "name": "php-etl/string-expression-language", @@ -8532,23 +8752,23 @@ }, { "name": "php-etl/sylius-plugin", - "version": "v0.7.0", + "version": "v0.7.1", "source": { "type": "git", "url": "https://github.com/php-etl/sylius-plugin.git", - "reference": "aa850c4f0aae13037975678d7e17ec8d709e7373" + "reference": "a0360efc2ba92e5b8a9b9bbdfd7f3d5f66398462" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-etl/sylius-plugin/zipball/aa850c4f0aae13037975678d7e17ec8d709e7373", - "reference": "aa850c4f0aae13037975678d7e17ec8d709e7373", + "url": "https://api.github.com/repos/php-etl/sylius-plugin/zipball/a0360efc2ba92e5b8a9b9bbdfd7f3d5f66398462", + "reference": "a0360efc2ba92e5b8a9b9bbdfd7f3d5f66398462", "shasum": "" }, "require": { "ext-json": "*", "nikic/php-parser": "^4.10", "php": "^8.2", - "php-etl/configurator-contracts": "0.7.*", + "php-etl/configurator-contracts": "0.8.*", "php-etl/fast-map-plugin": "*", "php-etl/packaging-contracts": "0.3.*", "php-etl/satellite-toolbox": "*", @@ -8598,9 +8818,9 @@ "description": "Adapters for the Sylius API client", "support": { "issues": "https://github.com/php-etl/sylius-plugin/issues", - "source": "https://github.com/php-etl/sylius-plugin/tree/v0.7.0" + "source": "https://github.com/php-etl/sylius-plugin/tree/v0.7.1" }, - "time": "2023-04-12T15:11:23+00:00" + "time": "2023-04-20T09:17:25+00:00" }, { "name": "php-http/mock-client", @@ -9138,16 +9358,16 @@ }, { "name": "phpstan/phpstan", - "version": "1.10.13", + "version": "1.10.14", "source": { "type": "git", "url": "https://github.com/phpstan/phpstan.git", - "reference": "f07bf8c6980b81bf9e49d44bd0caf2e737614a70" + "reference": "d232901b09e67538e5c86a724be841bea5768a7c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpstan/zipball/f07bf8c6980b81bf9e49d44bd0caf2e737614a70", - "reference": "f07bf8c6980b81bf9e49d44bd0caf2e737614a70", + "url": "https://api.github.com/repos/phpstan/phpstan/zipball/d232901b09e67538e5c86a724be841bea5768a7c", + "reference": "d232901b09e67538e5c86a724be841bea5768a7c", "shasum": "" }, "require": { @@ -9196,7 +9416,7 @@ "type": "tidelift" } ], - "time": "2023-04-12T19:29:52+00:00" + "time": "2023-04-19T13:47:27+00:00" }, { "name": "psr/event-dispatcher", diff --git a/src/Action/Action.php b/src/Action/Action.php new file mode 100644 index 00000000..4e40eb23 --- /dev/null +++ b/src/Action/Action.php @@ -0,0 +1,62 @@ +plugin, $config)) { + return; + } + + if (\array_key_exists('logger', $config)) { + $service = new Logger\Service($this->interpreter); + + $compiled = $service->compile($config['logger']); + $repository->merge($compiled); + $logger = $compiled->getBuilder()->getNode(); + } else { + $logger = new Node\Expr\New_( + new Node\Name\FullyQualified(\Psr\Log\NullLogger::class), + ); + } + + if (\array_key_exists('state', $config)) { + $service = new State\Service($this->interpreter); + + $compiled = $service->compile($config['state']); + $repository->merge($compiled); + $state = $compiled->getBuilder()->getNode(); + } else { + $state = new Node\Expr\New_( + new Node\Name\FullyQualified(\Kiboko\Contract\Action\NullState::class), + ); + } + + /** @var ActionBuilderInterface $builder */ + $builder = $repository->getBuilder(); + + $action->addAction( + $builder + ->withLogger($logger) + ->withState($state), + $state, + ); + } +} diff --git a/src/Action/ConfigurationApplier.php b/src/Action/ConfigurationApplier.php new file mode 100644 index 00000000..1dcc4011 --- /dev/null +++ b/src/Action/ConfigurationApplier.php @@ -0,0 +1,47 @@ +action = new Action($this->plugin, clone $this->interpreter); + + return $this; + } + + public function withPackages(string ...$packages): self + { + array_push($this->packages, ...$packages); + + return $this; + } + + public function appendTo(array $config, Satellite\Builder\Repository\Action $action): void + { + $repository = $this->service->compile($config[$this->plugin]); + + ($this->action)($config, $action->getBuilder(), $repository); + + $action->addPackages(...$this->packages); + + $action->merge($repository); + } +} diff --git a/src/Action/SFTP/Builder/Action.php b/src/Action/SFTP/Builder/Action.php new file mode 100644 index 00000000..c950ce26 --- /dev/null +++ b/src/Action/SFTP/Builder/Action.php @@ -0,0 +1,64 @@ +logger = $logger; + + return $this; + } + + public function withState(Node\Expr $state): self + { + $this->state = $state; + + return $this; + } + + public function getNode(): Node + { + return new Node\Expr\New_( + class: new Node\Name\FullyQualified('Kiboko\Component\Action\Flow\SFTP\Action'), + args: [ + new Node\Arg( + value: $this->host, + ), + new Node\Arg( + value: $this->port, + ), + new Node\Arg( + value: $this->username, + ), + new Node\Arg( + value: $this->password, + ), + new Node\Arg( + value: $this->localFilePath, + ), + new Node\Arg( + value: $this->serverFilePath, + ), + ] + ); + } +} diff --git a/src/Action/SFTP/Builder/ActionBuilderInterface.php b/src/Action/SFTP/Builder/ActionBuilderInterface.php new file mode 100644 index 00000000..4841e377 --- /dev/null +++ b/src/Action/SFTP/Builder/ActionBuilderInterface.php @@ -0,0 +1,15 @@ +getRootNode() + ->children() + ->arrayNode('expression_language') + ->scalarPrototype()->end() + ->end() + ->scalarNode('file')->isRequired()->end() + ->arrayNode('server') + ->isRequired() + ->children() + ->scalarNode('host') + ->isRequired() + ->cannotBeEmpty() + ->validate() + ->ifTrue(isExpression()) + ->then(asExpression()) + ->end() + ->end() + ->integerNode('port') + ->min(1) + ->max(65535) + ->defaultValue(22) + ->validate() + ->ifTrue(isExpression()) + ->then(asExpression()) + ->end() + ->end() + ->scalarNode('username') + ->isRequired() + ->cannotBeEmpty() + ->validate() + ->ifTrue(isExpression()) + ->then(asExpression()) + ->end() + ->end() + ->scalarNode('password') + ->isRequired() + ->cannotBeEmpty() + ->validate() + ->ifTrue(isExpression()) + ->then(asExpression()) + ->end() + ->end() + ->end() + ->end() + ->arrayNode('destination') + ->isRequired() + ->children() + ->scalarNode('path') + ->isRequired() + ->cannotBeEmpty() + ->validate() + ->ifTrue(isExpression()) + ->then(asExpression()) + ->end() + ->end() + ->end() + ->end() + ->end() + ; + + return $builder; + } +} diff --git a/src/Action/SFTP/Factory/Action.php b/src/Action/SFTP/Factory/Action.php new file mode 100644 index 00000000..03a51221 --- /dev/null +++ b/src/Action/SFTP/Factory/Action.php @@ -0,0 +1,75 @@ +processor = new Processor(); + $this->configuration = new SFTP\Configuration(); + } + + public function configuration(): ConfigurationInterface + { + return $this->configuration; + } + + /** + * @throws Configurator\ConfigurationExceptionInterface + */ + public function normalize(array $config): array + { + try { + return $this->processor->processConfiguration($this->configuration, $config); + } catch (Symfony\InvalidTypeException|Symfony\InvalidConfigurationException $exception) { + throw new Configurator\InvalidConfigurationException($exception->getMessage(), 0, $exception); + } + } + + public function validate(array $config): bool + { + try { + $this->normalize($config); + + return true; + } catch (Symfony\InvalidTypeException|Symfony\InvalidConfigurationException) { + return false; + } + } + + public function compile(array $config): Repository + { + $builder = new SFTP\Builder\Action( + compileValueWhenExpression($this->interpreter, $config['server']['host']), + compileValueWhenExpression($this->interpreter, $config['server']['port']), + compileValueWhenExpression($this->interpreter, $config['server']['username']), + compileValueWhenExpression($this->interpreter, $config['server']['password']), + compileValueWhenExpression($this->interpreter, $config['file']), + compileValueWhenExpression($this->interpreter, $config['destination']['path']), + ); + + try { + return new Repository($builder); + } catch (Symfony\InvalidTypeException|Symfony\InvalidConfigurationException $exception) { + throw new Configurator\InvalidConfigurationException(message: $exception->getMessage(), previous: $exception); + } + } +} diff --git a/src/Action/SFTP/Factory/Repository/Repository.php b/src/Action/SFTP/Factory/Repository/Repository.php new file mode 100644 index 00000000..f9f87a4a --- /dev/null +++ b/src/Action/SFTP/Factory/Repository/Repository.php @@ -0,0 +1,46 @@ +builder; + } + + public function merge(Configurator\RepositoryInterface $friend): self + { + return $this; + } +} diff --git a/src/Action/SFTP/Service.php b/src/Action/SFTP/Service.php new file mode 100644 index 00000000..9255277d --- /dev/null +++ b/src/Action/SFTP/Service.php @@ -0,0 +1,87 @@ +processor = new Processor(); + $this->configuration = new Configuration(); + } + + public function interpreter(): ExpressionLanguage + { + return $this->interpreter; + } + + public function configuration(): Configurator\ActionConfigurationInterface + { + return $this->configuration; + } + + /** + * @throws Configurator\ConfigurationExceptionInterface + */ + public function normalize(array $config): array + { + try { + return $this->processor->processConfiguration($this->configuration, $config); + } catch (Symfony\InvalidTypeException|Symfony\InvalidConfigurationException $exception) { + throw new Configurator\InvalidConfigurationException($exception->getMessage(), 0, $exception); + } + } + + public function validate(array $config): bool + { + try { + $this->processor->processConfiguration($this->configuration, $config); + + return true; + } catch (Symfony\InvalidTypeException|Symfony\InvalidConfigurationException) { + return false; + } + } + + /** + * @throws Configurator\ConfigurationExceptionInterface + */ + public function compile(array $config): Configurator\RepositoryInterface + { + $interpreter = clone $this->interpreter; + + if (\array_key_exists('expression_language', $config) + && \is_array($config['expression_language']) + && \count($config['expression_language']) + ) { + foreach ($config['expression_language'] as $provider) { + $interpreter->registerProvider(new $provider()); + } + } + + $actionFactory = new Action($this->interpreter); + + $action = $actionFactory->compile($config); + $actionBuilder = $action->getBuilder(); + + return new Repository($actionBuilder); + } +} diff --git a/src/Builder/Action.php b/src/Builder/Action.php new file mode 100644 index 00000000..fefd9944 --- /dev/null +++ b/src/Builder/Action.php @@ -0,0 +1,39 @@ +action = new Node\Expr\MethodCall( + var: $this->runtime, + name: new Node\Identifier('execute'), + args: [ + new Node\Arg($loader instanceof Builder ? $loader->getNode() : $loader), + new Node\Arg($state instanceof Builder ? $state->getNode() : $state), + ] + ); + + return $this; + } + + public function getNode(): Node\Expr + { + return $this->action ?? $this->runtime; + } +} diff --git a/src/Builder/Repository/Action.php b/src/Builder/Repository/Action.php new file mode 100644 index 00000000..7014d598 --- /dev/null +++ b/src/Builder/Repository/Action.php @@ -0,0 +1,60 @@ +files, ...$files); + + return $this; + } + + /** @return iterable */ + public function getFiles(): iterable + { + return $this->files; + } + + public function addPackages(string ...$packages): Configurator\RepositoryInterface + { + array_push($this->packages, ...$packages); + + return $this; + } + + /** @return iterable */ + public function getPackages(): iterable + { + return $this->packages; + } + + public function getBuilder(): Satellite\Builder\Action + { + return $this->builder; + } + + public function merge(Configurator\RepositoryInterface $friend): Configurator\RepositoryInterface + { + array_push($this->files, ...$friend->getFiles()); + array_push($this->packages, ...$friend->getPackages()); + + return $this; + } +} diff --git a/src/Builder/Workflow.php b/src/Builder/Workflow.php index 518f4ea4..da085ffe 100644 --- a/src/Builder/Workflow.php +++ b/src/Builder/Workflow.php @@ -9,7 +9,7 @@ final class Workflow implements Builder { - private array $pipelines = []; + private array $jobs = []; public function __construct( private readonly Node\Expr $runtime @@ -19,7 +19,7 @@ public function __construct( public function addPipeline( string $pipelineFilename, ): self { - array_push($this->pipelines, fn (Node\Expr $runtime) => new Node\Expr\MethodCall( + $this->jobs[] = fn (Node\Expr $runtime) => new Node\Expr\MethodCall( var: $runtime, name: new Node\Identifier('job'), args: [ @@ -43,7 +43,38 @@ public function addPipeline( ), ), ], - )); + ); + + return $this; + } + + public function addAction(string $pipelineFilename): self + { + $this->jobs[] = fn (Node\Expr $runtime) => new Node\Expr\MethodCall( + var: $runtime, + name: new Node\Identifier('job'), + args: [ + new Node\Arg( + new Node\Expr\MethodCall( + var: new Node\Expr\Variable('runtime'), + name: 'loadAction', + args: [ + new Node\Arg( + value: new Node\Expr\BinaryOp\Concat( + left: new Node\Scalar\MagicConst\Dir(), + right: new Node\Scalar\Encapsed( + parts: [ + new Node\Scalar\EncapsedStringPart('/'), + new Node\Scalar\EncapsedStringPart($pipelineFilename), + ], + ), + ), + ), + ], + ), + ), + ], + ); return $this; } @@ -52,8 +83,8 @@ public function getNode(): Node { $workflow = $this->runtime; - foreach ($this->pipelines as $pipeline) { - $workflow = $pipeline($workflow); + foreach ($this->jobs as $job) { + $workflow = $job($workflow); } return $workflow; diff --git a/src/Builder/Workflow/ActionBuilder.php b/src/Builder/Workflow/ActionBuilder.php new file mode 100644 index 00000000..e9e162b4 --- /dev/null +++ b/src/Builder/Workflow/ActionBuilder.php @@ -0,0 +1,38 @@ + true, + 'params' => [ + new Node\Param( + var: new Node\Expr\Variable('runtime'), + type: new Node\Name\FullyQualified(\Kiboko\Component\Runtime\Action\ActionRuntimeInterface::class), + ), + ], + 'stmts' => [ + new Node\Stmt\Expression( + $this->builder->getNode() + ), + new Node\Stmt\Return_( + expr: new Node\Expr\Variable('runtime') + ), + ], + ] + ); + } +} diff --git a/src/Composer/Accumulator.php b/src/Composer/Accumulator.php index a8025dad..5e4488d8 100644 --- a/src/Composer/Accumulator.php +++ b/src/Composer/Accumulator.php @@ -117,6 +117,43 @@ public function formatRuntimeInstance(): \Generator } } + public function formatActionInstance(): \Generator + { + /** @var Package $package */ + foreach ($this as $package) { + $configuration = $package->getExtra(); + if (\array_key_exists('satellite', $configuration)) { + // Enter fallback mode. + if (!\array_key_exists('class', $configuration['satellite'])) { + continue; + } + + yield <<interpreter()) + PHP; + continue; + } + if (!\array_key_exists('gyroscops', $configuration)) { + continue; + } + if (!\array_key_exists('actions', $configuration['gyroscops'])) { + continue; + } + + if (\is_string($configuration['gyroscops']['actions'])) { + yield <<interpreter()) + PHP; + } elseif (\is_array($configuration['gyroscops']['actions'])) { + foreach ($configuration['gyroscops']['actions'] as $plugin) { + yield <<interpreter()) + PHP; + } + } + } + } + public function __toString() { return sprintf( @@ -132,11 +169,15 @@ public function __toString() ) ->registerRuntimes( %s + ) + ->registerActions( + %s ); PHP, implode(",\n".str_pad('', 8), iterator_to_array($this->formatPluginInstance())), implode(",\n".str_pad('', 8), iterator_to_array($this->formatAdapterInstance())), implode(",\n".str_pad('', 8), iterator_to_array($this->formatRuntimeInstance())), + implode(",\n".str_pad('', 8), iterator_to_array($this->formatActionInstance())), ); } } diff --git a/src/ComposerScripts.php b/src/ComposerScripts.php index 6f33840f..0037485b 100644 --- a/src/ComposerScripts.php +++ b/src/ComposerScripts.php @@ -64,6 +64,7 @@ private static function updatePlugins( && !isset($package->getExtra()['gyroscops']['plugins']) && !isset($package->getExtra()['gyroscops']['adapters']) && !isset($package->getExtra()['gyroscops']['runtimes']) + && !isset($package->getExtra()['gyroscops']['actions']) ) { $io->error(strtr( 'There is no service class defined for the package %package%, please set the extra.gyroscops.plugins,' diff --git a/src/Configuration.php b/src/Configuration.php index f9c891d0..c17e60d6 100644 --- a/src/Configuration.php +++ b/src/Configuration.php @@ -11,6 +11,9 @@ use Symfony\Component\Config\Definition\Builder\TreeBuilder; use Symfony\Component\Config\Definition\ConfigurationInterface; +use function Kiboko\Component\SatelliteToolbox\Configuration\mutuallyDependentFields; +use function Kiboko\Component\SatelliteToolbox\Configuration\mutuallyExclusiveFields; + final class Configuration implements ConfigurationInterface { /** @var array */ @@ -21,6 +24,8 @@ final class Configuration implements ConfigurationInterface private array $plugins = []; /** @var array */ private array $features = []; + /** @var array */ + private array $actions = []; private readonly BackwardCompatibilityConfiguration $backwardCompatibilityConfiguration; public function __construct() @@ -47,6 +52,9 @@ public function addRuntime(string $name, Configurator\RuntimeConfigurationInterf foreach ($this->plugins as $name => $plugin) { $runtime->addPlugin($name, $plugin); } + foreach ($this->actions as $name => $action) { + $runtime->addAction($name, $action); + } return $this; } @@ -75,6 +83,18 @@ public function addFeature(string $name, Configurator\FeatureConfigurationInterf return $this; } + public function addAction(string $name, Configurator\ActionConfigurationInterface $action): self + { + $this->actions[$name] = $action; + $this->backwardCompatibilityConfiguration->addAction($name, $action); + + foreach ($this->runtimes as $runtime) { + $runtime->addAction($name, $action); + } + + return $this; + } + public function getConfigTreeBuilder(): TreeBuilder { $builder = new TreeBuilder('etl'); @@ -84,10 +104,10 @@ public function getConfigTreeBuilder(): TreeBuilder ->append((new VersionConfiguration())->getConfigTreeBuilder()->getRootNode()) ->append($this->backwardCompatibilityConfiguration->getConfigTreeBuilder()->getRootNode()) ->beforeNormalization() - ->always($this->mutuallyDependentFields('satellites', 'version')) + ->always(mutuallyDependentFields('satellites', 'version')) ->end() ->beforeNormalization() - ->always($this->mutuallyExclusiveFields('satellite', 'version')) + ->always(mutuallyExclusiveFields('satellite', 'version')) ->end() ->validate() ->ifTrue(fn ($data) => \array_key_exists('satellites', $data) && \is_array($data['satellites']) && \count($data['satellites']) <= 0) @@ -132,10 +152,10 @@ private function buildSatelliteTree(ArrayNodeDefinition $node): void /* @phpstan-ignore-next-line */ $node ->beforeNormalization() - ->always($this->mutuallyExclusiveFields(...array_keys($this->adapters))) + ->always(mutuallyExclusiveFields(...array_keys($this->adapters))) ->end() ->beforeNormalization() - ->always($this->mutuallyExclusiveFields(...array_keys($this->runtimes))) + ->always(mutuallyExclusiveFields(...array_keys($this->runtimes))) ->end() ->children() ->scalarNode('label') @@ -153,41 +173,4 @@ private function buildSatelliteTree(ArrayNodeDefinition $node): void $node->append($config->getConfigTreeBuilder()->getRootNode()); } } - - private function mutuallyExclusiveFields(string ...$exclusions): \Closure - { - return function (array $value) use ($exclusions) { - $fields = []; - foreach ($exclusions as $exclusion) { - if (\array_key_exists($exclusion, $value)) { - $fields[] = $exclusion; - } - - if (\count($fields) < 2) { - continue; - } - - throw new \InvalidArgumentException(sprintf('Your configuration should either contain the "%s" or the "%s" field, not both.', ...$fields)); - } - - return $value; - }; - } - - private function mutuallyDependentFields(string $field, string ...$dependencies): \Closure - { - return function (array $value) use ($field, $dependencies) { - if (!\array_key_exists($field, $value)) { - return $value; - } - - foreach ($dependencies as $dependency) { - if (!\array_key_exists($dependency, $value)) { - throw new \InvalidArgumentException(sprintf('Your configuration should contain the "%s" field if the "%s" field is present.', $dependency, $field)); - } - } - - return $value; - }; - } } diff --git a/src/Configuration/BackwardCompatibilityConfiguration.php b/src/Configuration/BackwardCompatibilityConfiguration.php index 6d271c30..c20afee8 100644 --- a/src/Configuration/BackwardCompatibilityConfiguration.php +++ b/src/Configuration/BackwardCompatibilityConfiguration.php @@ -10,6 +10,8 @@ use Symfony\Component\Config\Definition\Builder\TreeBuilder; use Symfony\Component\Config\Definition\ConfigurationInterface; +use function Kiboko\Component\SatelliteToolbox\Configuration\mutuallyExclusiveFields; + final class BackwardCompatibilityConfiguration implements ConfigurationInterface { /** @var array */ @@ -20,6 +22,8 @@ final class BackwardCompatibilityConfiguration implements ConfigurationInterface private array $plugins = []; /** @var array */ private array $features = []; + /** @var array */ + private array $actions = []; public function addAdapter(string $name, Configurator\AdapterConfigurationInterface $adapter): self { @@ -49,6 +53,13 @@ public function addFeature(string $name, Configurator\FeatureConfigurationInterf return $this; } + public function addAction(string $name, Configurator\ActionConfigurationInterface $action): self + { + $this->actions[$name] = $action; + + return $this; + } + public function getConfigTreeBuilder(): TreeBuilder { $builder = new TreeBuilder('satellite'); @@ -56,10 +67,10 @@ public function getConfigTreeBuilder(): TreeBuilder /* @phpstan-ignore-next-line */ $builder->getRootNode() ->beforeNormalization() - ->always($this->mutuallyExclusiveFields(...array_keys($this->adapters))) + ->always(mutuallyExclusiveFields(...array_keys($this->adapters))) ->end() ->beforeNormalization() - ->always($this->mutuallyExclusiveFields(...array_keys($this->runtimes))) + ->always(mutuallyExclusiveFields(...array_keys($this->runtimes))) ->end() ->children() ->append((new Satellite\Feature\Composer\Configuration())->getConfigTreeBuilder()->getRootNode()) @@ -83,41 +94,4 @@ public function getConfigTreeBuilder(): TreeBuilder return $builder; } - - private function mutuallyExclusiveFields(string ...$exclusions): \Closure - { - return function (array $value) use ($exclusions) { - $fields = []; - foreach ($exclusions as $exclusion) { - if (\array_key_exists($exclusion, $value)) { - $fields[] = $exclusion; - } - - if (\count($fields) < 2) { - continue; - } - - throw new \InvalidArgumentException(sprintf('Your configuration should either contain the "%s" or the "%s" field, not both.', ...$fields)); - } - - return $value; - }; - } - - private function mutuallyDependentFields(string $field, string ...$dependencies): \Closure - { - return function (array $value) use ($field, $dependencies) { - if (!\array_key_exists($field, $value)) { - return $value; - } - - foreach ($dependencies as $dependency) { - if (!\array_key_exists($dependency, $value)) { - throw new \InvalidArgumentException(sprintf('Your configuration should contain the "%s" field if the "%s" field is present.', $dependency, $field)); - } - } - - return $value; - }; - } } diff --git a/src/Runtime/Api/Configuration.php b/src/Runtime/Api/Configuration.php index 84163f09..ab7de13c 100644 --- a/src/Runtime/Api/Configuration.php +++ b/src/Runtime/Api/Configuration.php @@ -14,6 +14,8 @@ final class Configuration implements Configurator\RuntimeConfigurationInterface private iterable $plugins = []; /** @var array */ private iterable $features = []; + /** @var array */ + private iterable $actions = []; public function addPlugin(string $name, Configurator\PluginConfigurationInterface $plugin): self { @@ -29,6 +31,13 @@ public function addFeature(string $name, Configurator\FeatureConfigurationInterf return $this; } + public function addAction(string $name, Configurator\ActionConfigurationInterface $action): self + { + $this->actions[$name] = $action; + + return $this; + } + public function getStepsTreeBuilder(): TreeBuilder { $builder = new TreeBuilder('steps'); diff --git a/src/Runtime/HttpHook/Configuration.php b/src/Runtime/HttpHook/Configuration.php index ec6099a5..5c28d2ba 100644 --- a/src/Runtime/HttpHook/Configuration.php +++ b/src/Runtime/HttpHook/Configuration.php @@ -14,6 +14,8 @@ final class Configuration implements Configurator\RuntimeConfigurationInterface private iterable $plugins = []; /** @var array */ private iterable $features = []; + /** @var array */ + private iterable $actions = []; public function addPlugin(string $name, Configurator\PluginConfigurationInterface $plugin): self { @@ -29,6 +31,13 @@ public function addFeature(string $name, Configurator\FeatureConfigurationInterf return $this; } + public function addAction(string $name, Configurator\ActionConfigurationInterface $action): self + { + $this->actions[$name] = $action; + + return $this; + } + public function getStepsTreeBuilder(): TreeBuilder { $builder = new TreeBuilder('steps'); diff --git a/src/Runtime/Pipeline/Configuration.php b/src/Runtime/Pipeline/Configuration.php index 9d6f1710..a3086eeb 100644 --- a/src/Runtime/Pipeline/Configuration.php +++ b/src/Runtime/Pipeline/Configuration.php @@ -14,6 +14,8 @@ final class Configuration implements Configurator\RuntimeConfigurationInterface private iterable $plugins = []; /** @var array */ private iterable $features = []; + /** @var array */ + private iterable $actions = []; public function addPlugin(string $name, Configurator\PluginConfigurationInterface $plugin): self { @@ -29,6 +31,13 @@ public function addFeature(string $name, Configurator\FeatureConfigurationInterf return $this; } + public function addAction(string $name, Configurator\ActionConfigurationInterface $action): self + { + $this->actions[$name] = $action; + + return $this; + } + public function getStepsTreeBuilder(): TreeBuilder { $builder = new TreeBuilder('steps'); @@ -67,12 +76,12 @@ public function getConfigTreeBuilder(): TreeBuilder /* @phpstan-ignore-next-line */ $builder->getRootNode() ->children() - ->arrayNode('expression_language') - ->scalarPrototype()->end() - ->end() - ->scalarNode('name')->end() - ->scalarNode('code')->end() - ->append($this->getStepsTreeBuilder()->getRootNode()) + ->arrayNode('expression_language') + ->scalarPrototype()->end() + ->end() + ->scalarNode('name')->end() + ->scalarNode('code')->end() + ->append($this->getStepsTreeBuilder()->getRootNode()) ->end() ; @@ -85,8 +94,8 @@ private function applyPlugins(ArrayNodeDefinition $node): self /* @phpstan-ignore-next-line */ $node ->children() - ->scalarNode('name')->end() - ->scalarNode('code')->end() + ->scalarNode('name')->end() + ->scalarNode('code')->end() ->end() ->append($plugin->getConfigTreeBuilder()->getRootNode()) ; @@ -100,8 +109,8 @@ private function applyFeatures(ArrayNodeDefinition $node): self foreach ($this->features as $feature) { /* @phpstan-ignore-next-line */ $node->children() - ->scalarNode('name')->end() - ->scalarNode('code')->end() + ->scalarNode('name')->end() + ->scalarNode('code')->end() ->end() ->append($feature->getConfigTreeBuilder()->getRootNode()) ; diff --git a/src/Runtime/Workflow/Action/Configuration.php b/src/Runtime/Workflow/Action/Configuration.php new file mode 100644 index 00000000..0b11a899 --- /dev/null +++ b/src/Runtime/Workflow/Action/Configuration.php @@ -0,0 +1,37 @@ + */ + private iterable $actions = []; + + public function addAction(string $name, Configurator\ActionConfigurationInterface $action): self + { + $this->actions[$name] = $action; + + return $this; + } + + public function getConfigTreeBuilder(): TreeBuilder + { + $builder = new TreeBuilder('action'); + + /** @var ArrayNodeDefinition $node */ + $node = $builder->getRootNode(); + + foreach ($this->actions as $action) { + $node->append($action->getConfigTreeBuilder()->getRootNode()); + } + + return $builder; + } +} diff --git a/src/Runtime/Workflow/Configuration.php b/src/Runtime/Workflow/Configuration.php index 297d3864..fec70034 100644 --- a/src/Runtime/Workflow/Configuration.php +++ b/src/Runtime/Workflow/Configuration.php @@ -8,18 +8,15 @@ use Kiboko\Contract\Configurator; use Symfony\Component\Config\Definition\Builder\TreeBuilder; -final class Configuration implements Configurator\RuntimeConfigurationInterface +final readonly class Configuration implements Configurator\RuntimeConfigurationInterface { - /** @var array */ - private iterable $plugins = []; - /** @var array */ - private iterable $features = []; - - private readonly Satellite\Runtime\Pipeline\Configuration $pipelineConfiguration; + private Satellite\Runtime\Pipeline\Configuration $pipelineConfiguration; + private Satellite\Runtime\Workflow\Action\Configuration $actionConfiguration; public function __construct() { $this->pipelineConfiguration = new Satellite\Runtime\Pipeline\Configuration(); + $this->actionConfiguration = new Satellite\Runtime\Workflow\Action\Configuration(); } public function addPlugin(string $name, Configurator\PluginConfigurationInterface $plugin): self @@ -42,6 +39,16 @@ public function addFeature(string $name, Configurator\FeatureConfigurationInterf return $this; } + public function addAction(string $name, Configurator\ActionConfigurationInterface $action): self + { + $this->actionConfiguration->addAction( + $name, + $action + ); + + return $this; + } + public function getConfigTreeBuilder(): TreeBuilder { $builder = new TreeBuilder('workflow'); @@ -49,19 +56,20 @@ public function getConfigTreeBuilder(): TreeBuilder /* @phpstan-ignore-next-line */ $builder->getRootNode() ->children() - ->append((new Satellite\DependencyInjection\Configuration\ServicesConfiguration())->getConfigTreeBuilder()->getRootNode()) - ->arrayNode('expression_language') - ->scalarPrototype()->end() - ->end() - ->scalarNode('name')->end() - ->arrayNode('jobs') - ->arrayPrototype() - ->children() - ->scalarNode('name')->end() - ->append($this->pipelineConfiguration->getConfigTreeBuilder()->getRootNode()) - ->end() - ->end() - ->end() + ->append((new Satellite\DependencyInjection\Configuration\ServicesConfiguration())->getConfigTreeBuilder()->getRootNode()) + ->arrayNode('expression_language') + ->scalarPrototype()->end() + ->end() + ->scalarNode('name')->end() + ->arrayNode('jobs') + ->arrayPrototype() + ->children() + ->scalarNode('name')->end() + ->append($this->pipelineConfiguration->getConfigTreeBuilder()->getRootNode()) + ->append($this->actionConfiguration->getConfigTreeBuilder()->getRootNode()) + ->end() + ->end() + ->end() ->end() ; diff --git a/src/Runtime/Workflow/Factory.php b/src/Runtime/Workflow/Factory.php index 4bef4790..bbd67101 100644 --- a/src/Runtime/Workflow/Factory.php +++ b/src/Runtime/Workflow/Factory.php @@ -37,6 +37,16 @@ public function addPlugin(string $name, Configurator\FactoryInterface $plugin): return $this; } + public function addAction(string $name, Configurator\FactoryInterface $action): self + { + $configuration = $action->configuration(); + \assert($configuration instanceof Configurator\ActionConfigurationInterface); + + $this->configuration->addAction($name, $configuration); + + return $this; + } + public function configuration(): Configurator\RuntimeConfigurationInterface { return $this->configuration; diff --git a/src/Runtime/Workflow/Runtime.php b/src/Runtime/Workflow/Runtime.php index 8b57ddc7..4f06458e 100644 --- a/src/Runtime/Workflow/Runtime.php +++ b/src/Runtime/Workflow/Runtime.php @@ -54,17 +54,11 @@ public function build(Builder $builder): array ), ], 'stmts' => [ - new Node\Stmt\Expression($builder->getNode()), + new Node\Stmt\Return_(expr: $builder->getNode()), ], ] ), ), - // new Node\Stmt\Expression( - // new Node\Expr\MethodCall( - // var: $builder->getNode(), - // name: 'run' - // ), - // ) ]; } } diff --git a/src/Service.php b/src/Service.php index dde524bf..2b6593ca 100644 --- a/src/Service.php +++ b/src/Service.php @@ -7,7 +7,6 @@ use Kiboko\Component\Packaging; use Kiboko\Component\Satellite; use Kiboko\Contract\Configurator; -use Kiboko\Contract\Configurator\Adapter\FactoryInterface; use PhpParser\Node; use Symfony\Component\Config\Definition\ConfigurationInterface; use Symfony\Component\Config\Definition\Exception as Symfony; @@ -19,7 +18,7 @@ final class Service implements Configurator\FactoryInterface private readonly Processor $processor; private readonly Satellite\Configuration $configuration; private readonly ExpressionLanguage $interpreter; - /** @var array */ + /** @var array */ private array $adapters = []; /** @var array */ private array $runtimes = []; @@ -29,6 +28,10 @@ final class Service implements Configurator\FactoryInterface private array $pipelines = []; /** @var array */ private array $plugins = []; + /** @var array */ + private array $actions = []; + /** @var array */ + private array $actionPlugins = []; public function __construct(?ExpressionLanguage $expressionLanguage = null) { @@ -100,6 +103,21 @@ private function addPipelinePlugin( return $this; } + private function addAction( + Configurator\Action $attribute, + Configurator\ActionInterface $action, + ): self { + $this->configuration->addAction($attribute->name, $action->configuration()); + $this->actions[$attribute->name] = $action; + + $this->actionPlugins[$attribute->name] = $applier = new Satellite\Action\ConfigurationApplier($attribute->name, $action, $action->interpreter()); + $applier->withPackages(...$attribute->dependencies); + + $applier->withAction(); + + return $this; + } + public function registerAdapters(Configurator\Adapter\FactoryInterface ...$adapters): self { foreach ($adapters as $adapter) { @@ -144,6 +162,18 @@ public function registerPlugins(Configurator\PipelinePluginInterface|Configurato return $this; } + public function registerActions(Configurator\ActionInterface ...$actions): self + { + foreach ($actions as $action) { + /** @var Configurator\Action $attribute */ + foreach (extractAttributes($action, Configurator\Action::class) as $attribute) { + $this->addAction($attribute, $action); + } + } + + return $this; + } + public function configuration(): ConfigurationInterface { return $this->configuration; @@ -259,6 +289,22 @@ private function compileWorkflow(array $config): Satellite\Builder\Repository\Wo ); $workflow->addPipeline($pipelineFilename); + } elseif (\array_key_exists('action', $job)) { + $action = $this->compileActionJob($job); + $actionFilename = sprintf('%s.php', uniqid('action')); + + $repository->addFiles( + new Packaging\File( + $actionFilename, + new Packaging\Asset\AST( + new Node\Stmt\Return_( + (new Satellite\Builder\Workflow\ActionBuilder($action->getBuilder()))->getNode() + ) + ) + ) + ); + + $workflow->addAction($actionFilename); } else { throw new \LogicException('Not implemented'); } @@ -306,6 +352,22 @@ private function compilePipelineJob(array $config): Satellite\Builder\Repository return $repository; } + private function compileActionJob(array $config): Satellite\Builder\Repository\Action + { + $action = new Satellite\Builder\Action( + new Node\Expr\Variable('runtime'), + ); + + $repository = new Satellite\Builder\Repository\Action($action); + + $actions = array_intersect_key($this->actionPlugins, $config['action']); + foreach ($actions as $action) { + $action->appendTo($config['action'], $repository); + } + + return $repository; + } + private function compilePipeline(array $config): Satellite\Builder\Repository\Pipeline { $repository = $this->compilePipelineJob($config);