diff --git a/CHANGELOG.md b/CHANGELOG.md index ba4733e..5b82df2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,7 @@ Latest ------ ### Changes +* [#51](https://github.com/cleverage/flysystem-process-bundle/issues/51) Give a code to the tasks ([cleverage/process-bundle#91](https://github.com/cleverage/process-bundle/issues/91)): `flysystem_file_fetch`, `flysystem_list_content` and `flysystem_remove_file` (`task: flysystem_file_fetch`, with `cleverage/process-bundle` 5.4 or later, referencing them by `service` being deprecated there). The tasks have their class name as service id; fetching them directly from the service container is deprecated (`container.private`), they will be private in 4.0. The former ids `cleverage_flysystem_process.task.file_fetch` / `cleverage_flysystem_process.task.list_content` / `cleverage_flysystem_process.task.remove_file` are deprecated aliases, removed in 4.0. Update documentation, add tests. * [#49](https://github.com/cleverage/flysystem-process-bundle/issues/49) CI: test the lowest versions allowed by `composer.json` (`--prefer-lowest`, PHP 8.2). Require `psr/log` `^2|^3`: `cleverage/process-bundle` 5.x uses the typed `LoggerInterface` signatures (fatal error with `psr/log` 1). * [#47](https://github.com/cleverage/flysystem-process-bundle/issues/47) Add a `.gitattributes`: the development files (`.docker/`, `.github/`, `tests/`, quality tools and PHPUnit configurations, `Makefile`) are no longer part of the archive installed by Composer (`dist`). * [#45](https://github.com/cleverage/flysystem-process-bundle/issues/45) Require `league/flysystem` and `psr/log`, used directly by the tasks but only installed through `league/flysystem-bundle` and `cleverage/process-bundle`; add `league/flysystem-local` (used by the tests) to the dev requirements. diff --git a/config/services/task.yaml b/config/services/task.yaml index b74eb90..83fad06 100644 --- a/config/services/task.yaml +++ b/config/services/task.yaml @@ -1,31 +1,48 @@ services: _defaults: - public: false + # Public for the direct access from the service container, deprecated since 3.3: private in 4.0 + public: true tags: - { name: monolog.logger, channel: cleverage_process_task } + - { name: container.private, package: cleverage/flysystem-process-bundle, version: '3.3' } - cleverage_flysystem_process.task.file_fetch: - class: CleverAge\FlysystemProcessBundle\Task\FileFetchTask + CleverAge\FlysystemProcessBundle\Task\FileFetchTask: shared: false arguments: [!tagged_locator { tag: 'flysystem.storage', index_by: 'storage' }] - CleverAge\FlysystemProcessBundle\Task\FileFetchTask: - alias: cleverage_flysystem_process.task.file_fetch - public: true + tags: + - { name: cleverage.task, code: flysystem_file_fetch } + cleverage_flysystem_process.task.file_fetch: + alias: CleverAge\FlysystemProcessBundle\Task\FileFetchTask + public: false + deprecated: + package: cleverage/flysystem-process-bundle + version: '3.3' + message: 'The "%alias_id%" service alias is deprecated, use the "flysystem_file_fetch" task code or the class name of the task instead. It will be removed in 4.0.' - cleverage_flysystem_process.task.list_content: - class: CleverAge\FlysystemProcessBundle\Task\ListContentTask + CleverAge\FlysystemProcessBundle\Task\ListContentTask: shared: false arguments: [!tagged_locator { tag: 'flysystem.storage', index_by: 'storage' }] - CleverAge\FlysystemProcessBundle\Task\ListContentTask: - alias: cleverage_flysystem_process.task.list_content - public: true + tags: + - { name: cleverage.task, code: flysystem_list_content } + cleverage_flysystem_process.task.list_content: + alias: CleverAge\FlysystemProcessBundle\Task\ListContentTask + public: false + deprecated: + package: cleverage/flysystem-process-bundle + version: '3.3' + message: 'The "%alias_id%" service alias is deprecated, use the "flysystem_list_content" task code or the class name of the task instead. It will be removed in 4.0.' - cleverage_flysystem_process.task.remove_file: - class: CleverAge\FlysystemProcessBundle\Task\RemoveFileTask + CleverAge\FlysystemProcessBundle\Task\RemoveFileTask: shared: false arguments: - '@logger' - !tagged_locator { tag: 'flysystem.storage', index_by: 'storage' } - CleverAge\FlysystemProcessBundle\Task\RemoveFileTask: - alias: cleverage_flysystem_process.task.remove_file - public: true + tags: + - { name: cleverage.task, code: flysystem_remove_file } + cleverage_flysystem_process.task.remove_file: + alias: CleverAge\FlysystemProcessBundle\Task\RemoveFileTask + public: false + deprecated: + package: cleverage/flysystem-process-bundle + version: '3.3' + message: 'The "%alias_id%" service alias is deprecated, use the "flysystem_remove_file" task code or the class name of the task instead. It will be removed in 4.0.' diff --git a/docs/cookbooks/remote_cleanup.md b/docs/cookbooks/remote_cleanup.md index 3d79682..73702a3 100644 --- a/docs/cookbooks/remote_cleanup.md +++ b/docs/cookbooks/remote_cleanup.md @@ -12,27 +12,27 @@ clever_age_process: help: "bin/console cleverage:process:execute app.remote_cleanup -c year:2025" tasks: list: - service: '@CleverAge\FlysystemProcessBundle\Task\ListContentTask' + task: flysystem_list_content options: filesystem: 'remote.storage.archive' file_pattern: '/^catalog_{{ year }}.*\.csv$/' outputs: [only_files] only_files: - service: '@CleverAge\ProcessBundle\Task\FilterTask' + task: filter options: match: type: 'file' outputs: [get_path] get_path: - service: '@CleverAge\ProcessBundle\Task\PropertyGetterTask' + task: property_getter options: property: 'path' outputs: [remove] remove: - service: '@CleverAge\FlysystemProcessBundle\Task\RemoveFileTask' + task: flysystem_remove_file options: filesystem: 'remote.storage.archive' ``` @@ -59,7 +59,7 @@ clever_age_process: app.remote_cleanup_pattern: tasks: remove: - service: '@CleverAge\FlysystemProcessBundle\Task\RemoveFileTask' + task: flysystem_remove_file options: filesystem: 'remote.storage.archive' file_pattern: '/^catalog_{{ year }}.*\.csv$/' diff --git a/docs/cookbooks/sftp_export.md b/docs/cookbooks/sftp_export.md index 17a03d0..13dc18f 100644 --- a/docs/cookbooks/sftp_export.md +++ b/docs/cookbooks/sftp_export.md @@ -14,7 +14,7 @@ clever_age_process: description: 'Export the catalog to the SFTP server' tasks: data: - service: '@CleverAge\ProcessBundle\Task\ConstantIterableOutputTask' # Replace with your own reader + task: constant_iterable_output # Replace with your own reader options: output: - { sku: 'SKU-001', name: 'Product 1', price: '12.50' } @@ -22,14 +22,14 @@ clever_age_process: outputs: [write] write: - service: '@CleverAge\ProcessBundle\Task\File\Csv\CsvWriterTask' + task: csv_writer options: file_path: '%local.storage.dir%/catalog_{date_time}.csv' headers: [sku, name, price] outputs: [relative_path] relative_path: - service: '@CleverAge\ProcessBundle\Task\TransformerTask' + task: transformer options: transformers: callback: @@ -37,7 +37,7 @@ clever_age_process: outputs: [upload] upload: - service: '@CleverAge\FlysystemProcessBundle\Task\FileFetchTask' + task: flysystem_file_fetch options: source_filesystem: 'local.storage' destination_filesystem: 'remote.storage.outgoing' @@ -45,7 +45,7 @@ clever_age_process: outputs: [log_upload] log_upload: - service: '@CleverAge\ProcessBundle\Task\Reporting\LoggerTask' + task: logger options: level: info message: 'File uploaded' diff --git a/docs/cookbooks/sftp_import.md b/docs/cookbooks/sftp_import.md index 8c508a5..daabc4e 100644 --- a/docs/cookbooks/sftp_import.md +++ b/docs/cookbooks/sftp_import.md @@ -43,7 +43,7 @@ clever_age_process: description: 'Import the CSV files dropped on the SFTP server' tasks: fetch: - service: '@CleverAge\FlysystemProcessBundle\Task\FileFetchTask' + task: flysystem_file_fetch options: source_filesystem: 'remote.storage.incoming' destination_filesystem: 'local.storage' @@ -51,20 +51,20 @@ clever_age_process: outputs: [read, archive] # "archive" is executed once "read" has read the whole file read: - service: '@CleverAge\ProcessBundle\Task\File\Csv\InputCsvReaderTask' + task: input_csv_reader options: base_path: '%local.storage.dir%' delimiter: ';' outputs: [import_line] import_line: - service: '@CleverAge\ProcessBundle\Task\Reporting\LoggerTask' # Replace with your own transformation and writer tasks + task: logger # Replace with your own transformation and writer tasks options: level: info message: 'Imported line' archive: - service: '@CleverAge\FlysystemProcessBundle\Task\FileFetchTask' + task: flysystem_file_fetch options: source_filesystem: 'remote.storage.incoming' destination_filesystem: 'remote.storage.archive' @@ -72,7 +72,7 @@ clever_age_process: outputs: [cleanup_local] cleanup_local: - service: '@CleverAge\FlysystemProcessBundle\Task\RemoveFileTask' + task: flysystem_remove_file options: filesystem: 'local.storage' ``` diff --git a/docs/index.md b/docs/index.md index 180eb8b..a4691eb 100644 --- a/docs/index.md +++ b/docs/index.md @@ -25,6 +25,17 @@ require their own package, e.g. `composer require league/flysystem-sftp-v3` for ## Configuration +The tasks of this bundle are registered as services (non-shared) and are used in your processes by their code, +`flysystem_file_fetch`, `flysystem_list_content` and `flysystem_remove_file` (e.g. `task: flysystem_file_fetch`, requires +`cleverage/process-bundle` 5.4 or later, see its [task definition](https://github.com/cleverage/process-bundle/blob/main/docs/reference/02-task_definition.md)). +Referencing them by their class name (`service: '@CleverAge\FlysystemProcessBundle\Task\FileFetchTask'`) is +deprecated since `cleverage/process-bundle` 5.4. + +Their service id is their class name. Fetching them directly from the service container is deprecated since 3.3 (they +will be private in 4.0); their former ids, `cleverage_flysystem_process.task.file_fetch`, +`cleverage_flysystem_process.task.list_content` and `cleverage_flysystem_process.task.remove_file`, are deprecated +aliases since 3.3, removed in 4.0. + The tasks of this bundle work with the Flysystem **storages** configured in `config/packages/flysystem.yaml`: their `filesystem`, `source_filesystem` and `destination_filesystem` options take the name of a storage (the key under `flysystem.storages`). Configure at least one storage: diff --git a/docs/reference/tasks/_template.md b/docs/reference/tasks/_template.md index 919390a..d4545a0 100644 --- a/docs/reference/tasks/_template.md +++ b/docs/reference/tasks/_template.md @@ -7,6 +7,7 @@ Task reference -------------- * **Service**: `Fully\Qualified\ClassName` +* **Code**: `flysystem_task_code` (`task: flysystem_task_code`) * **Iterable task** _(only if it implements `IterableTaskInterface`)_ * **Blocking task** _(only if it implements `BlockingTaskInterface`)_ * **Flushable task** _(only if it implements `FlushableTaskInterface`)_ @@ -39,7 +40,7 @@ Examples ```yaml # Task configuration level code: - service: '@Fully\Qualified\ClassName' + task: flysystem_task_code options: a: 1 b: 2 diff --git a/docs/reference/tasks/file_fetch_task.md b/docs/reference/tasks/file_fetch_task.md index ca05c04..e3f2340 100644 --- a/docs/reference/tasks/file_fetch_task.md +++ b/docs/reference/tasks/file_fetch_task.md @@ -11,6 +11,7 @@ Task reference -------------- * **Service**: `CleverAge\FlysystemProcessBundle\Task\FileFetchTask` +* **Code**: `flysystem_file_fetch` (`task: flysystem_file_fetch`) * **Iterable task** Accepted inputs @@ -55,7 +56,7 @@ Examples ```yaml # Task configuration level fetch: - service: '@CleverAge\FlysystemProcessBundle\Task\FileFetchTask' + task: flysystem_file_fetch options: source_filesystem: 'remote.storage' destination_filesystem: 'local.storage' @@ -74,7 +75,7 @@ my_process: entry_point: copy_from_input tasks: copy_from_input: - service: '@CleverAge\FlysystemProcessBundle\Task\FileFetchTask' + task: flysystem_file_fetch options: source_filesystem: '{{ source }}' destination_filesystem: '{{ destination }}' @@ -86,7 +87,7 @@ my_process: ```yaml # Task configuration level archive: - service: '@CleverAge\FlysystemProcessBundle\Task\FileFetchTask' + task: flysystem_file_fetch options: source_filesystem: 'remote.storage.incoming' destination_filesystem: 'remote.storage.archive' diff --git a/docs/reference/tasks/list_content_task.md b/docs/reference/tasks/list_content_task.md index 1db9737..0499325 100644 --- a/docs/reference/tasks/list_content_task.md +++ b/docs/reference/tasks/list_content_task.md @@ -8,6 +8,7 @@ Task reference -------------- * **Service**: `CleverAge\FlysystemProcessBundle\Task\ListContentTask` +* **Code**: `flysystem_list_content` (`task: flysystem_list_content`) * **Iterable task** Accepted inputs @@ -45,13 +46,13 @@ Examples ```yaml # Task configuration level list: - service: '@CleverAge\FlysystemProcessBundle\Task\ListContentTask' + task: flysystem_list_content options: filesystem: 'remote.storage' file_pattern: '/\.csv$/' outputs: [get_path] get_path: - service: '@CleverAge\ProcessBundle\Task\PropertyGetterTask' + task: property_getter options: property: 'path' outputs: [log] @@ -63,12 +64,12 @@ get_path: ```yaml # Task configuration level list: - service: '@CleverAge\FlysystemProcessBundle\Task\ListContentTask' + task: flysystem_list_content options: filesystem: 'remote.storage' outputs: [only_files] only_files: - service: '@CleverAge\ProcessBundle\Task\FilterTask' + task: filter options: match: type: 'file' diff --git a/docs/reference/tasks/remove_file_task.md b/docs/reference/tasks/remove_file_task.md index be9af89..6f7a667 100644 --- a/docs/reference/tasks/remove_file_task.md +++ b/docs/reference/tasks/remove_file_task.md @@ -7,6 +7,7 @@ Task reference -------------- * **Service**: `CleverAge\FlysystemProcessBundle\Task\RemoveFileTask` +* **Code**: `flysystem_remove_file` (`task: flysystem_remove_file`) Accepted inputs --------------- @@ -42,7 +43,7 @@ my_process: entry_point: remove_from_input tasks: remove_from_input: - service: '@CleverAge\FlysystemProcessBundle\Task\RemoveFileTask' + task: flysystem_remove_file options: filesystem: 'remote.storage' ``` @@ -52,7 +53,7 @@ my_process: ```yaml # Task configuration level purge: - service: '@CleverAge\FlysystemProcessBundle\Task\RemoveFileTask' + task: flysystem_remove_file options: filesystem: 'remote.storage' file_pattern: '/\.csv$/' diff --git a/tests/DependencyInjection/CleverAgeFlysystemProcessExtensionTest.php b/tests/DependencyInjection/CleverAgeFlysystemProcessExtensionTest.php index 08691d2..cea6766 100644 --- a/tests/DependencyInjection/CleverAgeFlysystemProcessExtensionTest.php +++ b/tests/DependencyInjection/CleverAgeFlysystemProcessExtensionTest.php @@ -28,28 +28,33 @@ class CleverAgeFlysystemProcessExtensionTest extends TestCase { /** - * @return iterable + * @return iterable */ public static function provideTasks(): iterable { - yield 'file_fetch' => ['cleverage_flysystem_process.task.file_fetch', FileFetchTask::class]; - yield 'list_content' => ['cleverage_flysystem_process.task.list_content', ListContentTask::class]; - yield 'remove_file' => ['cleverage_flysystem_process.task.remove_file', RemoveFileTask::class]; + yield 'file_fetch' => [FileFetchTask::class, 'flysystem_file_fetch', 'cleverage_flysystem_process.task.file_fetch']; + yield 'list_content' => [ListContentTask::class, 'flysystem_list_content', 'cleverage_flysystem_process.task.list_content']; + yield 'remove_file' => [RemoveFileTask::class, 'flysystem_remove_file', 'cleverage_flysystem_process.task.remove_file']; } /** * @param class-string $class */ #[DataProvider('provideTasks')] - public function testTaskIsRegistered(string $id, string $class): void + public function testTaskIsRegistered(string $class, string $code, string $deprecatedId): void { $container = new ContainerBuilder(); (new CleverAgeFlysystemProcessExtension())->load([], $container); - $definition = $container->getDefinition($id); - self::assertSame($class, $definition->getClass()); + // The class name is the service id + $definition = $container->getDefinition($class); // Tasks are stateful: each process execution must get its own instance self::assertFalse($definition->isShared()); + // Referenced by its code in the process configurations (task: ) + self::assertSame([['code' => $code]], $definition->getTag('cleverage.task')); + // Public for the direct access from the service container, deprecated + self::assertTrue($definition->isPublic()); + self::assertSame([['package' => 'cleverage/flysystem-process-bundle', 'version' => '3.3']], $definition->getTag('container.private')); // The Flysystem storages, indexed by name $storages = array_values(array_filter( @@ -62,10 +67,15 @@ public function testTaskIsRegistered(string $id, string $class): void self::assertSame('flysystem.storage', $taggedIterator->getTag()); self::assertSame('storage', $taggedIterator->getIndexAttribute()); - // Referenced as '@' in process configurations - $alias = $container->getAlias($class); - self::assertSame($id, (string) $alias); - self::assertTrue($alias->isPublic()); + // Former id, deprecated + $alias = $container->getAlias($deprecatedId); + self::assertSame($class, (string) $alias); + self::assertFalse($alias->isPublic()); + self::assertTrue($alias->isDeprecated()); + self::assertSame( + ['package' => 'cleverage/flysystem-process-bundle', 'version' => '3.3', 'message' => 'The "'.$deprecatedId.'" service alias is deprecated, use the "'.$code.'" task code or the class name of the task instead. It will be removed in 4.0.'], + $alias->getDeprecation($deprecatedId) + ); } public function testEveryTaskIsTested(): void @@ -75,7 +85,7 @@ public function testEveryTaskIsTested(): void $ids = array_filter( array_keys($container->getDefinitions()), - static fn (string $id): bool => str_starts_with($id, 'cleverage_flysystem_process.task.') + static fn (string $id): bool => str_starts_with($id, 'CleverAge\\FlysystemProcessBundle\\Task\\') ); self::assertEqualsCanonicalizing(array_column(iterator_to_array(self::provideTasks()), 0), array_values($ids)); }