diff --git a/CHANGELOG.md b/CHANGELOG.md index c46d4e2d..d98af95b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,8 +2,9 @@ Latest ------ ## Changes +* [#91](https://github.com/cleverage/process-bundle/issues/91) Reference a task by a code in the process configurations: new `task` key (`task: transformer`), next to its `options`. The code of a task service is declared with the new `code` attribute of the `cleverage.task` tag or the new `#[AsTask(code: '...')]` attribute (autoconfiguration); every task of the bundle has a code, given on its reference page (snake case of its class name without `Task`, e.g. `transformer`, `constant_output`, `csv_reader`). The codes are resolved when the container is compiled (`TaskLocatorCompilerPass`): an unknown or duplicate code fails the compilation. Referencing a task by its `service` (e.g. `service: '@CleverAge\ProcessBundle\Task\TransformerTask'`) is deprecated (configuration deprecation), it will be removed in v6.0: use `task: `. The documentation examples use the codes. Update documentation, add tests. * [#276](https://github.com/cleverage/process-bundle/issues/276) TransformerRegistry: the transformers are loaded lazily from a service locator indexed by code (new internal `TransformerLocatorCompilerPass`, new optional `TransformerRegistry` constructor argument): a transformer is only instantiated when a process uses it. The code is given by the new `code` attribute of the `cleverage.transformer` tag, or by the new `#[AsTransformer(code: '...')]` attribute (autoconfiguration); it must be the one returned by `getCode()`. All the bundle transformers and the generic transformers have their code. Duplicate codes fail the container compilation. A transformer tagged without `code` is still registered eagerly, with `TransformerRegistry::addTransformer()`, which is deprecated (the `code` will be required in v6.0, #280). `RegistryCompilerPass` is no longer used and deprecated. `TransformerInterface::getCode()` is deprecated (`@deprecated` PHPDoc: no runtime notice is possible for an interface method), it will be removed from the interface in v6.0 (#280): keep implementing it, returning the code of the tag until then. Update documentation, add tests. -* [#149](https://github.com/cleverage/process-bundle/issues/149) Apply Symfony best practices to the tasks and transformers services: they are defined explicitly (no more autowiring, autoconfiguration nor bindings in the bundle), with `cleverage_process.task.*` / `cleverage_process.transformer.*` ids (private) and a public alias named after their class, so the `service: '@CleverAge\ProcessBundle\Task\...'` references, the autowiring of the transformers by class and `$container->get()` keep working. Same arguments, tags and `shared` settings as before (generated from the previously autowired definitions). Update documentation. +* [#149](https://github.com/cleverage/process-bundle/issues/149) Apply Symfony best practices to the tasks and transformers services: they are defined explicitly (no more autowiring, autoconfiguration nor bindings in the bundle), keeping their class name as service id. Same arguments, tags and `shared` settings as before (generated from the previously autowired definitions). They stay public, but fetching them directly from the service container (`$container->get()`) is deprecated (`container.private` tag): they will be private in v6.0, use dependency injection (autowiring by class and decoration keep working). Update documentation. * [#275](https://github.com/cleverage/process-bundle/issues/275) The tasks are fetched from a service locator built at compile time from the services referenced by the process configurations (new `TaskRegistry`, `cleverage_process.registry.task`, and internal `TaskLocatorCompilerPass`) instead of the whole service container: a task service can be private. `ProcessManager` and `ProcessHelpCommand` get the registry as a new optional last constructor argument; not passing it is deprecated (the tasks are then fetched from the container), and fetching a task service not referenced by the process configurations known at compile time falls back on the container with a deprecation. Both fallbacks will be removed in v6.0 (#114). Update documentation, add tests. * [#278](https://github.com/cleverage/process-bundle/issues/278) The container no longer fails to compile when the Symfony serializer or validator is not enabled: the tasks and transformers depending on them (`NormalizerTask`, `DenormalizerTask`, `SerializerTask`, `DeserializerTask`, `normalize` and `denormalize` transformers, `ValidatorTask`) are replaced by services failing with an explicit message when they are used (new internal `UnavailableServicesCompilerPass`). `CheckSerializerCompilerPass` is no longer used and deprecated. Update documentation, add tests. * [#272](https://github.com/cleverage/process-bundle/issues/272) DependencyInjection: autoconfiguration of the services implementing `TaskInterface` (`public`, not shared, `monolog.logger` tag on `cleverage_process_task`) and `TransformerInterface` (`cleverage.transformer` tag, `monolog.logger` tag on `cleverage_process_transformer`): the `_instanceof` rules or explicit tags are no longer needed with `autoconfigure: true`; a setting explicitly defined on a service wins. Add FQCN aliases to autowire `ProcessManager`, `ProcessConfigurationRegistry`, `TransformerRegistry` and `ContextualOptionResolver`. Update documentation, add tests. diff --git a/config/services/task.yaml b/config/services/task.yaml index 38b3ce38..d6df2447 100644 --- a/config/services/task.yaml +++ b/config/services/task.yaml @@ -1,478 +1,365 @@ services: _defaults: - public: false + # Public for the deprecated direct access from the service container (fallback of TaskRegistry, service: of the + # task configurations), private in v6.0 + public: true tags: - { name: monolog.logger, channel: cleverage_process_task } + - { name: container.private, package: cleverage/process-bundle, version: '5.4' } - cleverage_process.task.aggregate_iterable: - class: CleverAge\ProcessBundle\Task\AggregateIterableTask - shared: false CleverAge\ProcessBundle\Task\AggregateIterableTask: - alias: cleverage_process.task.aggregate_iterable - public: true - - cleverage_process.task.array_merge: - class: CleverAge\ProcessBundle\Task\ArrayMergeTask + tags: + - { name: cleverage.task, code: aggregate_iterable } shared: false + CleverAge\ProcessBundle\Task\ArrayMergeTask: - alias: cleverage_process.task.array_merge - public: true + tags: + - { name: cleverage.task, code: array_merge } + shared: false - cleverage_process.task.column_aggregator: - class: CleverAge\ProcessBundle\Task\ColumnAggregatorTask + CleverAge\ProcessBundle\Task\ColumnAggregatorTask: + tags: + - { name: cleverage.task, code: column_aggregator } shared: false arguments: - '@property_accessor' - '@logger' - CleverAge\ProcessBundle\Task\ColumnAggregatorTask: - alias: cleverage_process.task.column_aggregator - public: true - cleverage_process.task.constant_iterable_output: - class: CleverAge\ProcessBundle\Task\ConstantIterableOutputTask - shared: false CleverAge\ProcessBundle\Task\ConstantIterableOutputTask: - alias: cleverage_process.task.constant_iterable_output - public: true - - cleverage_process.task.constant_output: - class: CleverAge\ProcessBundle\Task\ConstantOutputTask + tags: + - { name: cleverage.task, code: constant_iterable_output } shared: false - CleverAge\ProcessBundle\Task\ConstantOutputTask: - alias: cleverage_process.task.constant_output - public: true - cleverage_process.task.counter: - class: CleverAge\ProcessBundle\Task\CounterTask + CleverAge\ProcessBundle\Task\ConstantOutputTask: + tags: + - { name: cleverage.task, code: constant_output } shared: false - CleverAge\ProcessBundle\Task\CounterTask: - alias: cleverage_process.task.counter - public: true - cleverage_process.task.debug: - class: CleverAge\ProcessBundle\Task\Debug\DebugTask + CleverAge\ProcessBundle\Task\CounterTask: + tags: + - { name: cleverage.task, code: counter } shared: false - CleverAge\ProcessBundle\Task\Debug\DebugTask: - alias: cleverage_process.task.debug - public: true - cleverage_process.task.die: - class: CleverAge\ProcessBundle\Task\Debug\DieTask + CleverAge\ProcessBundle\Task\Debug\DebugTask: + tags: + - { name: cleverage.task, code: debug } shared: false - CleverAge\ProcessBundle\Task\Debug\DieTask: - alias: cleverage_process.task.die - public: true - cleverage_process.task.error_forwarder: - class: CleverAge\ProcessBundle\Task\Debug\ErrorForwarderTask + CleverAge\ProcessBundle\Task\Debug\DieTask: + tags: + - { name: cleverage.task, code: die } shared: false + CleverAge\ProcessBundle\Task\Debug\ErrorForwarderTask: - alias: cleverage_process.task.error_forwarder - public: true + tags: + - { name: cleverage.task, code: error_forwarder } + shared: false - cleverage_process.task.stopwatch: - class: CleverAge\ProcessBundle\Task\Debug\StopwatchTask + CleverAge\ProcessBundle\Task\Debug\StopwatchTask: + tags: + - { name: cleverage.task, code: stopwatch } shared: false arguments: - '@logger' - '@debug.stopwatch' - CleverAge\ProcessBundle\Task\Debug\StopwatchTask: - alias: cleverage_process.task.stopwatch - public: true - cleverage_process.task.dummy: - class: CleverAge\ProcessBundle\Task\DummyTask - shared: false CleverAge\ProcessBundle\Task\DummyTask: - alias: cleverage_process.task.dummy - public: true + tags: + - { name: cleverage.task, code: dummy } + shared: false - cleverage_process.task.event_dispatcher: - class: CleverAge\ProcessBundle\Task\Event\EventDispatcherTask + CleverAge\ProcessBundle\Task\Event\EventDispatcherTask: + tags: + - { name: cleverage.task, code: event_dispatcher } shared: false arguments: - '@event_dispatcher' - CleverAge\ProcessBundle\Task\Event\EventDispatcherTask: - alias: cleverage_process.task.event_dispatcher - public: true - cleverage_process.task.csv_reader: - class: CleverAge\ProcessBundle\Task\File\Csv\CsvReaderTask + CleverAge\ProcessBundle\Task\File\Csv\CsvReaderTask: + tags: + - { name: cleverage.task, code: csv_reader } shared: false arguments: - '@logger' - CleverAge\ProcessBundle\Task\File\Csv\CsvReaderTask: - alias: cleverage_process.task.csv_reader - public: true - cleverage_process.task.csv_splitter: - class: CleverAge\ProcessBundle\Task\File\Csv\CsvSplitterTask + CleverAge\ProcessBundle\Task\File\Csv\CsvSplitterTask: + tags: + - { name: cleverage.task, code: csv_splitter } shared: false arguments: - '@logger' - CleverAge\ProcessBundle\Task\File\Csv\CsvSplitterTask: - alias: cleverage_process.task.csv_splitter - public: true - cleverage_process.task.csv_writer: - class: CleverAge\ProcessBundle\Task\File\Csv\CsvWriterTask - shared: false CleverAge\ProcessBundle\Task\File\Csv\CsvWriterTask: - alias: cleverage_process.task.csv_writer - public: true + tags: + - { name: cleverage.task, code: csv_writer } + shared: false - cleverage_process.task.input_csv_reader: - class: CleverAge\ProcessBundle\Task\File\Csv\InputCsvReaderTask + CleverAge\ProcessBundle\Task\File\Csv\InputCsvReaderTask: + tags: + - { name: cleverage.task, code: input_csv_reader } shared: false arguments: - '@logger' - CleverAge\ProcessBundle\Task\File\Csv\InputCsvReaderTask: - alias: cleverage_process.task.input_csv_reader - public: true - cleverage_process.task.file_mover: - class: CleverAge\ProcessBundle\Task\File\FileMoverTask - shared: false CleverAge\ProcessBundle\Task\File\FileMoverTask: - alias: cleverage_process.task.file_mover - public: true - - cleverage_process.task.file_reader: - class: CleverAge\ProcessBundle\Task\File\FileReaderTask + tags: + - { name: cleverage.task, code: file_mover } shared: false - CleverAge\ProcessBundle\Task\File\FileReaderTask: - alias: cleverage_process.task.file_reader - public: true - cleverage_process.task.file_remover: - class: CleverAge\ProcessBundle\Task\File\FileRemoverTask + CleverAge\ProcessBundle\Task\File\FileReaderTask: + tags: + - { name: cleverage.task, code: file_reader } shared: false - CleverAge\ProcessBundle\Task\File\FileRemoverTask: - alias: cleverage_process.task.file_remover - public: true - cleverage_process.task.file_splitter: - class: CleverAge\ProcessBundle\Task\File\FileSplitterTask + CleverAge\ProcessBundle\Task\File\FileRemoverTask: + tags: + - { name: cleverage.task, code: file_remover } shared: false - CleverAge\ProcessBundle\Task\File\FileSplitterTask: - alias: cleverage_process.task.file_splitter - public: true - cleverage_process.task.file_writer: - class: CleverAge\ProcessBundle\Task\File\FileWriterTask + CleverAge\ProcessBundle\Task\File\FileSplitterTask: + tags: + - { name: cleverage.task, code: file_splitter } shared: false + CleverAge\ProcessBundle\Task\File\FileWriterTask: - alias: cleverage_process.task.file_writer - public: true + tags: + - { name: cleverage.task, code: file_writer } + shared: false - cleverage_process.task.folder_browser: - class: CleverAge\ProcessBundle\Task\File\FolderBrowserTask + CleverAge\ProcessBundle\Task\File\FolderBrowserTask: + tags: + - { name: cleverage.task, code: folder_browser } shared: false arguments: - '@logger' - CleverAge\ProcessBundle\Task\File\FolderBrowserTask: - alias: cleverage_process.task.folder_browser - public: true - cleverage_process.task.input_file_reader: - class: CleverAge\ProcessBundle\Task\File\InputFileReaderTask - shared: false CleverAge\ProcessBundle\Task\File\InputFileReaderTask: - alias: cleverage_process.task.input_file_reader - public: true + tags: + - { name: cleverage.task, code: input_file_reader } + shared: false - cleverage_process.task.input_folder_browser: - class: CleverAge\ProcessBundle\Task\File\InputFolderBrowserTask + CleverAge\ProcessBundle\Task\File\InputFolderBrowserTask: + tags: + - { name: cleverage.task, code: input_folder_browser } shared: false arguments: - '@logger' - CleverAge\ProcessBundle\Task\File\InputFolderBrowserTask: - alias: cleverage_process.task.input_folder_browser - public: true - cleverage_process.task.input_line_reader: - class: CleverAge\ProcessBundle\Task\File\InputLineReaderTask - shared: false CleverAge\ProcessBundle\Task\File\InputLineReaderTask: - alias: cleverage_process.task.input_line_reader - public: true - - cleverage_process.task.json_stream_reader: - class: CleverAge\ProcessBundle\Task\File\JsonStream\JsonStreamReaderTask + tags: + - { name: cleverage.task, code: input_line_reader } shared: false - CleverAge\ProcessBundle\Task\File\JsonStream\JsonStreamReaderTask: - alias: cleverage_process.task.json_stream_reader - public: true - cleverage_process.task.json_stream_writer: - class: CleverAge\ProcessBundle\Task\File\JsonStream\JsonStreamWriterTask + CleverAge\ProcessBundle\Task\File\JsonStream\JsonStreamReaderTask: + tags: + - { name: cleverage.task, code: json_stream_reader } shared: false - CleverAge\ProcessBundle\Task\File\JsonStream\JsonStreamWriterTask: - alias: cleverage_process.task.json_stream_writer - public: true - cleverage_process.task.line_reader: - class: CleverAge\ProcessBundle\Task\File\LineReaderTask + CleverAge\ProcessBundle\Task\File\JsonStream\JsonStreamWriterTask: + tags: + - { name: cleverage.task, code: json_stream_writer } shared: false + CleverAge\ProcessBundle\Task\File\LineReaderTask: - alias: cleverage_process.task.line_reader - public: true + tags: + - { name: cleverage.task, code: line_reader } + shared: false - cleverage_process.task.xml_reader: - class: CleverAge\ProcessBundle\Task\File\Xml\XmlReaderTask + CleverAge\ProcessBundle\Task\File\Xml\XmlReaderTask: + tags: + - { name: cleverage.task, code: xml_reader } shared: false arguments: - '@logger' - CleverAge\ProcessBundle\Task\File\Xml\XmlReaderTask: - alias: cleverage_process.task.xml_reader - public: true - cleverage_process.task.xml_stream_reader: - class: CleverAge\ProcessBundle\Task\File\Xml\XmlStreamReaderTask - shared: false CleverAge\ProcessBundle\Task\File\Xml\XmlStreamReaderTask: - alias: cleverage_process.task.xml_stream_reader - public: true + tags: + - { name: cleverage.task, code: xml_stream_reader } + shared: false - cleverage_process.task.xml_writer: - class: CleverAge\ProcessBundle\Task\File\Xml\XmlWriterTask + CleverAge\ProcessBundle\Task\File\Xml\XmlWriterTask: + tags: + - { name: cleverage.task, code: xml_writer } shared: false arguments: - '@logger' - CleverAge\ProcessBundle\Task\File\Xml\XmlWriterTask: - alias: cleverage_process.task.xml_writer - public: true - cleverage_process.task.yaml_reader: - class: CleverAge\ProcessBundle\Task\File\Yaml\YamlReaderTask - shared: false CleverAge\ProcessBundle\Task\File\Yaml\YamlReaderTask: - alias: cleverage_process.task.yaml_reader - public: true - - cleverage_process.task.yaml_writer: - class: CleverAge\ProcessBundle\Task\File\Yaml\YamlWriterTask + tags: + - { name: cleverage.task, code: yaml_reader } shared: false - CleverAge\ProcessBundle\Task\File\Yaml\YamlWriterTask: - alias: cleverage_process.task.yaml_writer - public: true - cleverage_process.task.filter: - class: CleverAge\ProcessBundle\Task\FilterTask + CleverAge\ProcessBundle\Task\File\Yaml\YamlWriterTask: + tags: + - { name: cleverage.task, code: yaml_writer } shared: false + CleverAge\ProcessBundle\Task\FilterTask: - alias: cleverage_process.task.filter - public: true + tags: + - { name: cleverage.task, code: filter } + shared: false - cleverage_process.task.group_by_aggregate_iterable: - class: CleverAge\ProcessBundle\Task\GroupByAggregateIterableTask + CleverAge\ProcessBundle\Task\GroupByAggregateIterableTask: + tags: + - { name: cleverage.task, code: group_by_aggregate_iterable } shared: false arguments: - '@property_accessor' - CleverAge\ProcessBundle\Task\GroupByAggregateIterableTask: - alias: cleverage_process.task.group_by_aggregate_iterable - public: true - cleverage_process.task.input_aggregator: - class: CleverAge\ProcessBundle\Task\InputAggregatorTask - shared: false CleverAge\ProcessBundle\Task\InputAggregatorTask: - alias: cleverage_process.task.input_aggregator - public: true - - cleverage_process.task.input_iterator: - class: CleverAge\ProcessBundle\Task\InputIteratorTask + tags: + - { name: cleverage.task, code: input_aggregator } shared: false + CleverAge\ProcessBundle\Task\InputIteratorTask: - alias: cleverage_process.task.input_iterator - public: true + tags: + - { name: cleverage.task, code: input_iterator } + shared: false - cleverage_process.task.iterable_batch: - class: CleverAge\ProcessBundle\Task\IterableBatchTask + CleverAge\ProcessBundle\Task\IterableBatchTask: + tags: + - { name: cleverage.task, code: iterable_batch } shared: false arguments: - '@logger' - CleverAge\ProcessBundle\Task\IterableBatchTask: - alias: cleverage_process.task.iterable_batch - public: true - cleverage_process.task.object_updater: - class: CleverAge\ProcessBundle\Task\ObjectUpdaterTask + CleverAge\ProcessBundle\Task\ObjectUpdaterTask: + tags: + - { name: cleverage.task, code: object_updater } shared: false arguments: - '@property_accessor' - CleverAge\ProcessBundle\Task\ObjectUpdaterTask: - alias: cleverage_process.task.object_updater - public: true - cleverage_process.task.command_runner: - class: CleverAge\ProcessBundle\Task\Process\CommandRunnerTask + CleverAge\ProcessBundle\Task\Process\CommandRunnerTask: + tags: + - { name: cleverage.task, code: command_runner } shared: false arguments: - '@kernel' - CleverAge\ProcessBundle\Task\Process\CommandRunnerTask: - alias: cleverage_process.task.command_runner - public: true - cleverage_process.task.process_executor: - class: CleverAge\ProcessBundle\Task\Process\ProcessExecutorTask + CleverAge\ProcessBundle\Task\Process\ProcessExecutorTask: + tags: + - { name: cleverage.task, code: process_executor } shared: false arguments: - '@cleverage_process.manager.process' - '@cleverage_process.registry.process_configuration' - '@logger' - CleverAge\ProcessBundle\Task\Process\ProcessExecutorTask: - alias: cleverage_process.task.process_executor - public: true - cleverage_process.task.process_launcher: - class: CleverAge\ProcessBundle\Task\Process\ProcessLauncherTask + CleverAge\ProcessBundle\Task\Process\ProcessLauncherTask: + tags: + - { name: cleverage.task, code: process_launcher } shared: false arguments: - '@logger' - '@cleverage_process.registry.process_configuration' - '@kernel' - CleverAge\ProcessBundle\Task\Process\ProcessLauncherTask: - alias: cleverage_process.task.process_launcher - public: true - cleverage_process.task.property_getter: - class: CleverAge\ProcessBundle\Task\PropertyGetterTask + CleverAge\ProcessBundle\Task\PropertyGetterTask: + tags: + - { name: cleverage.task, code: property_getter } shared: false arguments: - '@logger' - '@property_accessor' - CleverAge\ProcessBundle\Task\PropertyGetterTask: - alias: cleverage_process.task.property_getter - public: true - cleverage_process.task.property_setter: - class: CleverAge\ProcessBundle\Task\PropertySetterTask + CleverAge\ProcessBundle\Task\PropertySetterTask: + tags: + - { name: cleverage.task, code: property_setter } shared: false arguments: - '@logger' - '@property_accessor' - CleverAge\ProcessBundle\Task\PropertySetterTask: - alias: cleverage_process.task.property_setter - public: true - cleverage_process.task.advanced_stat_counter: - class: CleverAge\ProcessBundle\Task\Reporting\AdvancedStatCounterTask + CleverAge\ProcessBundle\Task\Reporting\AdvancedStatCounterTask: + tags: + - { name: cleverage.task, code: advanced_stat_counter } shared: false arguments: - '@logger' - CleverAge\ProcessBundle\Task\Reporting\AdvancedStatCounterTask: - alias: cleverage_process.task.advanced_stat_counter - public: true - cleverage_process.task.logger: - class: CleverAge\ProcessBundle\Task\Reporting\LoggerTask + CleverAge\ProcessBundle\Task\Reporting\LoggerTask: + tags: + - { name: cleverage.task, code: logger } shared: false arguments: - '@logger' - '@property_accessor' - CleverAge\ProcessBundle\Task\Reporting\LoggerTask: - alias: cleverage_process.task.logger - public: true - cleverage_process.task.stat_counter: - class: CleverAge\ProcessBundle\Task\Reporting\StatCounterTask + CleverAge\ProcessBundle\Task\Reporting\StatCounterTask: + tags: + - { name: cleverage.task, code: stat_counter } shared: false arguments: - '@logger' - CleverAge\ProcessBundle\Task\Reporting\StatCounterTask: - alias: cleverage_process.task.stat_counter - public: true - cleverage_process.task.row_aggregator: - class: CleverAge\ProcessBundle\Task\RowAggregatorTask + CleverAge\ProcessBundle\Task\RowAggregatorTask: + tags: + - { name: cleverage.task, code: row_aggregator } shared: false arguments: - '@logger' - CleverAge\ProcessBundle\Task\RowAggregatorTask: - alias: cleverage_process.task.row_aggregator - public: true - cleverage_process.task.denormalizer: - class: CleverAge\ProcessBundle\Task\Serialization\DenormalizerTask + CleverAge\ProcessBundle\Task\Serialization\DenormalizerTask: + tags: + - { name: cleverage.task, code: denormalizer } shared: false arguments: - '@serializer' - CleverAge\ProcessBundle\Task\Serialization\DenormalizerTask: - alias: cleverage_process.task.denormalizer - public: true - cleverage_process.task.deserializer: - class: CleverAge\ProcessBundle\Task\Serialization\DeserializerTask + CleverAge\ProcessBundle\Task\Serialization\DeserializerTask: + tags: + - { name: cleverage.task, code: deserializer } shared: false arguments: - '@serializer' - CleverAge\ProcessBundle\Task\Serialization\DeserializerTask: - alias: cleverage_process.task.deserializer - public: true - cleverage_process.task.normalizer: - class: CleverAge\ProcessBundle\Task\Serialization\NormalizerTask + CleverAge\ProcessBundle\Task\Serialization\NormalizerTask: + tags: + - { name: cleverage.task, code: normalizer } shared: false arguments: - '@serializer' - CleverAge\ProcessBundle\Task\Serialization\NormalizerTask: - alias: cleverage_process.task.normalizer - public: true - cleverage_process.task.serializer: - class: CleverAge\ProcessBundle\Task\Serialization\SerializerTask + CleverAge\ProcessBundle\Task\Serialization\SerializerTask: + tags: + - { name: cleverage.task, code: serializer } shared: false arguments: - '@serializer' - CleverAge\ProcessBundle\Task\Serialization\SerializerTask: - alias: cleverage_process.task.serializer - public: true - cleverage_process.task.simple_batch: - class: CleverAge\ProcessBundle\Task\SimpleBatchTask - shared: false CleverAge\ProcessBundle\Task\SimpleBatchTask: - alias: cleverage_process.task.simple_batch - public: true - - cleverage_process.task.skip_empty: - class: CleverAge\ProcessBundle\Task\SkipEmptyTask + tags: + - { name: cleverage.task, code: simple_batch } shared: false - CleverAge\ProcessBundle\Task\SkipEmptyTask: - alias: cleverage_process.task.skip_empty - public: true - cleverage_process.task.split_join_line: - class: CleverAge\ProcessBundle\Task\SplitJoinLineTask + CleverAge\ProcessBundle\Task\SkipEmptyTask: + tags: + - { name: cleverage.task, code: skip_empty } shared: false - CleverAge\ProcessBundle\Task\SplitJoinLineTask: - alias: cleverage_process.task.split_join_line - public: true - cleverage_process.task.stop: - class: CleverAge\ProcessBundle\Task\StopTask + CleverAge\ProcessBundle\Task\SplitJoinLineTask: + tags: + - { name: cleverage.task, code: split_join_line } shared: false + CleverAge\ProcessBundle\Task\StopTask: - alias: cleverage_process.task.stop - public: true + tags: + - { name: cleverage.task, code: stop } + shared: false - cleverage_process.task.transformer: - class: CleverAge\ProcessBundle\Task\TransformerTask + CleverAge\ProcessBundle\Task\TransformerTask: + tags: + - { name: cleverage.task, code: transformer } shared: false arguments: - '@logger' - '@cleverage_process.registry.transformer' - CleverAge\ProcessBundle\Task\TransformerTask: - alias: cleverage_process.task.transformer - public: true - cleverage_process.task.validator: - class: CleverAge\ProcessBundle\Task\Validation\ValidatorTask + CleverAge\ProcessBundle\Task\Validation\ValidatorTask: + tags: + - { name: cleverage.task, code: validator } shared: false arguments: - '@logger' - '@validator' - CleverAge\ProcessBundle\Task\Validation\ValidatorTask: - alias: cleverage_process.task.validator - public: true diff --git a/config/services/transformer.yaml b/config/services/transformer.yaml index f94e7148..e30e22b4 100644 --- a/config/services/transformer.yaml +++ b/config/services/transformer.yaml @@ -1,328 +1,182 @@ services: _defaults: - public: false + # Public for the direct access from the service container (deprecated), private in v6.0 + public: true tags: - { name: monolog.logger, channel: cleverage_process_transformer } + - { name: container.private, package: cleverage/process-bundle, version: '5.4' } - cleverage_process.transformer.array_element: - class: CleverAge\ProcessBundle\Transformer\Array\ArrayElementTransformer + CleverAge\ProcessBundle\Transformer\Array\ArrayElementTransformer: tags: - { name: cleverage.transformer, code: array_element } - CleverAge\ProcessBundle\Transformer\Array\ArrayElementTransformer: - alias: cleverage_process.transformer.array_element - public: true - cleverage_process.transformer.array_filter: - class: CleverAge\ProcessBundle\Transformer\Array\ArrayFilterTransformer + CleverAge\ProcessBundle\Transformer\Array\ArrayFilterTransformer: tags: - { name: cleverage.transformer, code: array_filter } arguments: - '@property_accessor' - CleverAge\ProcessBundle\Transformer\Array\ArrayFilterTransformer: - alias: cleverage_process.transformer.array_filter - public: true - cleverage_process.transformer.array_first: - class: CleverAge\ProcessBundle\Transformer\Array\ArrayFirstTransformer + CleverAge\ProcessBundle\Transformer\Array\ArrayFirstTransformer: tags: - { name: cleverage.transformer, code: array_first } - CleverAge\ProcessBundle\Transformer\Array\ArrayFirstTransformer: - alias: cleverage_process.transformer.array_first - public: true - cleverage_process.transformer.array_last: - class: CleverAge\ProcessBundle\Transformer\Array\ArrayLastTransformer + CleverAge\ProcessBundle\Transformer\Array\ArrayLastTransformer: tags: - { name: cleverage.transformer, code: array_last } - CleverAge\ProcessBundle\Transformer\Array\ArrayLastTransformer: - alias: cleverage_process.transformer.array_last - public: true - cleverage_process.transformer.array_map: - class: CleverAge\ProcessBundle\Transformer\Array\ArrayMapTransformer + CleverAge\ProcessBundle\Transformer\Array\ArrayMapTransformer: tags: - { name: cleverage.transformer, code: array_map } arguments: - '@cleverage_process.registry.transformer' - CleverAge\ProcessBundle\Transformer\Array\ArrayMapTransformer: - alias: cleverage_process.transformer.array_map - public: true - cleverage_process.transformer.array_unset: - class: CleverAge\ProcessBundle\Transformer\Array\ArrayUnsetTransformer + CleverAge\ProcessBundle\Transformer\Array\ArrayUnsetTransformer: tags: - { name: cleverage.transformer, code: array_unset } - CleverAge\ProcessBundle\Transformer\Array\ArrayUnsetTransformer: - alias: cleverage_process.transformer.array_unset - public: true - cleverage_process.transformer.cached: - class: CleverAge\ProcessBundle\Transformer\CachedTransformer + CleverAge\ProcessBundle\Transformer\CachedTransformer: tags: - { name: cleverage.transformer, code: cached } arguments: - '@cleverage_process.registry.transformer' - '@cache.app' - '@logger' - CleverAge\ProcessBundle\Transformer\CachedTransformer: - alias: cleverage_process.transformer.cached - public: true - cleverage_process.transformer.callback: - class: CleverAge\ProcessBundle\Transformer\CallbackTransformer + CleverAge\ProcessBundle\Transformer\CallbackTransformer: tags: - { name: cleverage.transformer, code: callback } - CleverAge\ProcessBundle\Transformer\CallbackTransformer: - alias: cleverage_process.transformer.callback - public: true - cleverage_process.transformer.cast: - class: CleverAge\ProcessBundle\Transformer\CastTransformer + CleverAge\ProcessBundle\Transformer\CastTransformer: tags: - { name: cleverage.transformer, code: cast } - CleverAge\ProcessBundle\Transformer\CastTransformer: - alias: cleverage_process.transformer.cast - public: true - cleverage_process.transformer.constant: - class: CleverAge\ProcessBundle\Transformer\ConstantTransformer + CleverAge\ProcessBundle\Transformer\ConstantTransformer: tags: - { name: cleverage.transformer, code: constant } - CleverAge\ProcessBundle\Transformer\ConstantTransformer: - alias: cleverage_process.transformer.constant - public: true - cleverage_process.transformer.convert_value: - class: CleverAge\ProcessBundle\Transformer\ConvertValueTransformer + CleverAge\ProcessBundle\Transformer\ConvertValueTransformer: tags: - { name: cleverage.transformer, code: convert_value } - CleverAge\ProcessBundle\Transformer\ConvertValueTransformer: - alias: cleverage_process.transformer.convert_value - public: true - cleverage_process.transformer.date_format: - class: CleverAge\ProcessBundle\Transformer\Date\DateFormatTransformer + CleverAge\ProcessBundle\Transformer\Date\DateFormatTransformer: tags: - { name: cleverage.transformer, code: date_format } - CleverAge\ProcessBundle\Transformer\Date\DateFormatTransformer: - alias: cleverage_process.transformer.date_format - public: true - cleverage_process.transformer.date_parser: - class: CleverAge\ProcessBundle\Transformer\Date\DateParserTransformer + CleverAge\ProcessBundle\Transformer\Date\DateParserTransformer: tags: - { name: cleverage.transformer, code: date_parser } - CleverAge\ProcessBundle\Transformer\Date\DateParserTransformer: - alias: cleverage_process.transformer.date_parser - public: true - cleverage_process.transformer.debug: - class: CleverAge\ProcessBundle\Transformer\DebugTransformer + CleverAge\ProcessBundle\Transformer\DebugTransformer: tags: - { name: cleverage.transformer, code: dump } - CleverAge\ProcessBundle\Transformer\DebugTransformer: - alias: cleverage_process.transformer.debug - public: true - cleverage_process.transformer.default: - class: CleverAge\ProcessBundle\Transformer\DefaultTransformer + CleverAge\ProcessBundle\Transformer\DefaultTransformer: tags: - { name: cleverage.transformer, code: default } - CleverAge\ProcessBundle\Transformer\DefaultTransformer: - alias: cleverage_process.transformer.default - public: true - cleverage_process.transformer.evaluator: - class: CleverAge\ProcessBundle\Transformer\EvaluatorTransformer + CleverAge\ProcessBundle\Transformer\EvaluatorTransformer: tags: - { name: cleverage.transformer, code: evaluator } - CleverAge\ProcessBundle\Transformer\EvaluatorTransformer: - alias: cleverage_process.transformer.evaluator - public: true - cleverage_process.transformer.expression_language_map: - class: CleverAge\ProcessBundle\Transformer\ExpressionLanguageMapTransformer + CleverAge\ProcessBundle\Transformer\ExpressionLanguageMapTransformer: tags: - { name: cleverage.transformer, code: expression_language_map } arguments: - '@cleverage_process.expression_language' - CleverAge\ProcessBundle\Transformer\ExpressionLanguageMapTransformer: - alias: cleverage_process.transformer.expression_language_map - public: true - cleverage_process.transformer.mapping: - class: CleverAge\ProcessBundle\Transformer\MappingTransformer + CleverAge\ProcessBundle\Transformer\MappingTransformer: tags: - { name: cleverage.transformer, code: mapping } arguments: - '@cleverage_process.registry.transformer' - '@logger' - '@property_accessor' - CleverAge\ProcessBundle\Transformer\MappingTransformer: - alias: cleverage_process.transformer.mapping - public: true - cleverage_process.transformer.multi_replace: - class: CleverAge\ProcessBundle\Transformer\MultiReplaceTransformer + CleverAge\ProcessBundle\Transformer\MultiReplaceTransformer: tags: - { name: cleverage.transformer, code: multi_replace } - CleverAge\ProcessBundle\Transformer\MultiReplaceTransformer: - alias: cleverage_process.transformer.multi_replace - public: true - cleverage_process.transformer.instantiate: - class: CleverAge\ProcessBundle\Transformer\Object\InstantiateTransformer + CleverAge\ProcessBundle\Transformer\Object\InstantiateTransformer: tags: - { name: cleverage.transformer, code: instantiate } - CleverAge\ProcessBundle\Transformer\Object\InstantiateTransformer: - alias: cleverage_process.transformer.instantiate - public: true - cleverage_process.transformer.property_accessor: - class: CleverAge\ProcessBundle\Transformer\Object\PropertyAccessorTransformer + CleverAge\ProcessBundle\Transformer\Object\PropertyAccessorTransformer: tags: - { name: cleverage.transformer, code: property_accessor } arguments: - '@property_accessor' - CleverAge\ProcessBundle\Transformer\Object\PropertyAccessorTransformer: - alias: cleverage_process.transformer.property_accessor - public: true - cleverage_process.transformer.recursive_property_setter: - class: CleverAge\ProcessBundle\Transformer\Object\RecursivePropertySetterTransformer + CleverAge\ProcessBundle\Transformer\Object\RecursivePropertySetterTransformer: tags: - { name: cleverage.transformer, code: recursive_property_setter } arguments: - '@property_accessor' - CleverAge\ProcessBundle\Transformer\Object\RecursivePropertySetterTransformer: - alias: cleverage_process.transformer.recursive_property_setter - public: true - cleverage_process.transformer.preg_filter: - class: CleverAge\ProcessBundle\Transformer\PregFilterTransformer + CleverAge\ProcessBundle\Transformer\PregFilterTransformer: tags: - { name: cleverage.transformer, code: preg_filter } - CleverAge\ProcessBundle\Transformer\PregFilterTransformer: - alias: cleverage_process.transformer.preg_filter - public: true - cleverage_process.transformer.rules: - class: CleverAge\ProcessBundle\Transformer\RulesTransformer + CleverAge\ProcessBundle\Transformer\RulesTransformer: tags: - { name: cleverage.transformer, code: rules } arguments: - '@cleverage_process.registry.transformer' - '@cleverage_process.expression_language' - CleverAge\ProcessBundle\Transformer\RulesTransformer: - alias: cleverage_process.transformer.rules - public: true - cleverage_process.transformer.denormalize: - class: CleverAge\ProcessBundle\Transformer\Serialization\DenormalizeTransformer + CleverAge\ProcessBundle\Transformer\Serialization\DenormalizeTransformer: tags: - { name: cleverage.transformer, code: denormalize } arguments: - '@serializer' - CleverAge\ProcessBundle\Transformer\Serialization\DenormalizeTransformer: - alias: cleverage_process.transformer.denormalize - public: true - cleverage_process.transformer.normalize: - class: CleverAge\ProcessBundle\Transformer\Serialization\NormalizeTransformer + CleverAge\ProcessBundle\Transformer\Serialization\NormalizeTransformer: tags: - { name: cleverage.transformer, code: normalize } arguments: - '@serializer' - CleverAge\ProcessBundle\Transformer\Serialization\NormalizeTransformer: - alias: cleverage_process.transformer.normalize - public: true - cleverage_process.transformer.explode: - class: CleverAge\ProcessBundle\Transformer\String\ExplodeTransformer + CleverAge\ProcessBundle\Transformer\String\ExplodeTransformer: tags: - { name: cleverage.transformer, code: explode } - CleverAge\ProcessBundle\Transformer\String\ExplodeTransformer: - alias: cleverage_process.transformer.explode - public: true - cleverage_process.transformer.hash: - class: CleverAge\ProcessBundle\Transformer\String\HashTransformer + CleverAge\ProcessBundle\Transformer\String\HashTransformer: tags: - { name: cleverage.transformer, code: hash } - CleverAge\ProcessBundle\Transformer\String\HashTransformer: - alias: cleverage_process.transformer.hash - public: true - cleverage_process.transformer.implode: - class: CleverAge\ProcessBundle\Transformer\String\ImplodeTransformer + CleverAge\ProcessBundle\Transformer\String\ImplodeTransformer: tags: - { name: cleverage.transformer, code: implode } - CleverAge\ProcessBundle\Transformer\String\ImplodeTransformer: - alias: cleverage_process.transformer.implode - public: true - cleverage_process.transformer.preg_match: - class: CleverAge\ProcessBundle\Transformer\String\PregMatchTransformer + CleverAge\ProcessBundle\Transformer\String\PregMatchTransformer: tags: - { name: cleverage.transformer, code: preg_match } - CleverAge\ProcessBundle\Transformer\String\PregMatchTransformer: - alias: cleverage_process.transformer.preg_match - public: true - cleverage_process.transformer.slugify: - class: CleverAge\ProcessBundle\Transformer\String\SlugifyTransformer + CleverAge\ProcessBundle\Transformer\String\SlugifyTransformer: tags: - { name: cleverage.transformer, code: slugify } - CleverAge\ProcessBundle\Transformer\String\SlugifyTransformer: - alias: cleverage_process.transformer.slugify - public: true - cleverage_process.transformer.sprintf: - class: CleverAge\ProcessBundle\Transformer\String\SprintfTransformer + CleverAge\ProcessBundle\Transformer\String\SprintfTransformer: tags: - { name: cleverage.transformer, code: sprintf } - CleverAge\ProcessBundle\Transformer\String\SprintfTransformer: - alias: cleverage_process.transformer.sprintf - public: true - cleverage_process.transformer.trim: - class: CleverAge\ProcessBundle\Transformer\String\TrimTransformer + CleverAge\ProcessBundle\Transformer\String\TrimTransformer: tags: - { name: cleverage.transformer, code: trim } - CleverAge\ProcessBundle\Transformer\String\TrimTransformer: - alias: cleverage_process.transformer.trim - public: true - cleverage_process.transformer.type_setter: - class: CleverAge\ProcessBundle\Transformer\TypeSetterTransformer + CleverAge\ProcessBundle\Transformer\TypeSetterTransformer: tags: - { name: cleverage.transformer, code: type_setter } - CleverAge\ProcessBundle\Transformer\TypeSetterTransformer: - alias: cleverage_process.transformer.type_setter - public: true - cleverage_process.transformer.unset: - class: CleverAge\ProcessBundle\Transformer\UnsetTransformer + CleverAge\ProcessBundle\Transformer\UnsetTransformer: tags: - { name: cleverage.transformer, code: unset } arguments: - '@property_accessor' - CleverAge\ProcessBundle\Transformer\UnsetTransformer: - alias: cleverage_process.transformer.unset - public: true - cleverage_process.transformer.wrapper: - class: CleverAge\ProcessBundle\Transformer\WrapperTransformer + CleverAge\ProcessBundle\Transformer\WrapperTransformer: tags: - { name: cleverage.transformer, code: wrapper } - CleverAge\ProcessBundle\Transformer\WrapperTransformer: - alias: cleverage_process.transformer.wrapper - public: true - cleverage_process.transformer.xpath_evaluator: - class: CleverAge\ProcessBundle\Transformer\Xml\XpathEvaluatorTransformer + CleverAge\ProcessBundle\Transformer\Xml\XpathEvaluatorTransformer: tags: - { name: cleverage.transformer, code: xpath_evaluator } - CleverAge\ProcessBundle\Transformer\Xml\XpathEvaluatorTransformer: - alias: cleverage_process.transformer.xpath_evaluator - public: true diff --git a/docs/01-quick_start.md b/docs/01-quick_start.md index ed0ad362..f83b0a96 100644 --- a/docs/01-quick_start.md +++ b/docs/01-quick_start.md @@ -121,11 +121,11 @@ clever_age_process: tasks: [] ``` -Then you can add tasks in this array. They consist of a `service`, optionally configured by `options`, and eventually +Then you can add tasks in this array. They consist of a `task` code, optionally configured by `options`, and eventually chained with others through their `outputs`. Minimal syntax is: ```yaml : - service: + task: # e.g. transformer, see the reference page of each task options: : : @@ -154,7 +154,7 @@ clever_age_process: project_prefix.process_name: tasks: extract: - service: '@CleverAge\ProcessBundle\Task\ConstantOutputTask' + task: constant_output options: output: id: 123 @@ -163,7 +163,7 @@ clever_age_process: outputs: [transform] transform: - service: '@CleverAge\ProcessBundle\Task\TransformerTask' + task: transformer options: transformers: mapping: @@ -181,7 +181,7 @@ clever_age_process: outputs: [load] load: - service: '@CleverAge\ProcessBundle\Task\Debug\DebugTask' + task: debug ``` There is more to know about process configuration. See [the full process configuration reference](reference/01-process_definition.md) @@ -257,7 +257,7 @@ task of the process: ```yaml read: - service: '@CleverAge\ProcessBundle\Task\File\Csv\CsvReaderTask' + task: csv_reader options: file_path: '%kernel.project_dir%/var/import/{{ file_name }}' ``` diff --git a/docs/03-custom_tasks.md b/docs/03-custom_tasks.md index 6fbb962d..f019c486 100644 --- a/docs/03-custom_tasks.md +++ b/docs/03-custom_tasks.md @@ -9,12 +9,12 @@ create your own. As stated before, tasks are simple services implementing `CleverAge\ProcessBundle\Model\TaskInterface`, so you can design them like any other service, with only small specificities: -- the service does **not need to be public**: the process manager fetches it, using the `service` reference of the - task configuration (a service id or alias, with or without the leading `@`, see - [task definition](reference/02-task_definition.md#task-attributes)), from a service locator built from the process - configurations when the container is compiled. Only a service that is not referenced by these configurations (e.g. a - configuration added at runtime) is fetched from the service container, which requires a public service and is - deprecated +- the service should have a **code**, to reference it in the process configurations (`task: `, see + [task code](#task-code)) +- the service does **not need to be public**: the process manager fetches it from a service locator built from the + process configurations when the container is compiled. Only a service that is not referenced by these configurations + (e.g. a configuration added at runtime) is fetched from the service container, which requires a public service and + is deprecated - the service should **not be shared** ([`shared: false`](https://symfony.com/doc/current/service_container/shared.html)) Most of the time you don't want a task declared in a process to share some data with another declaration using the @@ -52,6 +52,42 @@ services: If your `services.yaml` also has the default `App\:` resource (which includes `src/Task/`), declare `App\Task\:` after it: the last definition of a service wins. +### Task code + +A task is referenced in the process configurations by its code (`task: app_my_task`, see +[task definition](reference/02-task_definition.md#task-attributes); referencing it by its service, +`service: '@App\Task\MyTask'`, is deprecated since 5.4). Give your task a code: with autoconfiguration, add the +`CleverAge\ProcessBundle\Attribute\AsTask` attribute to the class; without, add a `cleverage.task` tag with a `code` +attribute to the service. Use an internal prefix in your codes to avoid conflicts +with the tasks of the bundles. Two services cannot share the same code (the container compilation fails). + +```php +namespace App\Task; + +use CleverAge\ProcessBundle\Attribute\AsTask; +use CleverAge\ProcessBundle\Model\ProcessState; +use CleverAge\ProcessBundle\Model\TaskInterface; + +#[AsTask(code: 'app_my_task')] +class MyTask implements TaskInterface +{ + public function execute(ProcessState $state): void + { + // ... + } +} +``` + +```yaml +# Without autoconfiguration +services: + App\Task\MyTask: + autowire: true + shared: false + tags: + - { name: cleverage.task, code: app_my_task } +``` + ## Using the state object With the `TaskInterface::execute` method comes a small container object: the state @@ -140,7 +176,7 @@ class PrefixTask extends AbstractConfigurableTask ```yaml prefix: - service: '@App\Task\PrefixTask' + task: app_prefix # with #[AsTask(code: 'app_prefix')] on the class, see "task code" above options: prefix: 'SKU-' ``` @@ -269,7 +305,7 @@ standard additions. ```yaml transform: - service: '@CleverAge\ProcessBundle\Task\TransformerTask' + task: transformer options: transformers: app_vat: diff --git a/docs/04-advanced_workflow.md b/docs/04-advanced_workflow.md index a30ff54e..0dac8136 100644 --- a/docs/04-advanced_workflow.md +++ b/docs/04-advanced_workflow.md @@ -29,18 +29,15 @@ the process code, the task code and the original message. The original exception ### Executing a process from PHP -The process manager service id is `cleverage_process.manager.process`. It is private and has no class alias, so it -cannot be autowired by type: inject it explicitly (or declare the alias yourself). +The process manager service (`cleverage_process.manager.process`, private) can be autowired by its class, +`CleverAge\ProcessBundle\Manager\ProcessManager`, or injected explicitly: ```yaml # config/services.yaml services: App\Service\ProductImporter: arguments: - $processManager: '@cleverage_process.manager.process' - - # Or, to enable autowiring of the ProcessManager type everywhere: - CleverAge\ProcessBundle\Manager\ProcessManager: '@cleverage_process.manager.process' + $processManager: '@cleverage_process.manager.process' # not needed with autowiring ``` ```php @@ -72,12 +69,12 @@ clever_age_process: app.csv_copy: tasks: read: - service: '@CleverAge\ProcessBundle\Task\File\Csv\CsvReaderTask' + task: csv_reader options: file_path: '%kernel.project_dir%/var/data/input.csv' outputs: [transform] transform: - service: '@CleverAge\ProcessBundle\Task\TransformerTask' + task: transformer options: transformers: mapping: @@ -86,12 +83,12 @@ clever_age_process: name: { code: '[name]' } outputs: [write] write: - service: '@CleverAge\ProcessBundle\Task\File\Csv\CsvWriterTask' + task: csv_writer options: file_path: '%kernel.project_dir%/var/data/output.csv' outputs: [log] log: - service: '@CleverAge\ProcessBundle\Task\Debug\DebugTask' + task: debug ``` ### Orphan tasks @@ -123,7 +120,7 @@ stops. ```yaml transform: - service: '@CleverAge\ProcessBundle\Task\TransformerTask' + task: transformer error_strategy: skip # Continue with the next item on error log_level: warning # Log errors as warning instead of critical options: @@ -134,7 +131,7 @@ transform: outputs: [write] error_outputs: [write_errors] # Receives the input that failed write_errors: - service: '@CleverAge\ProcessBundle\Task\File\JsonStream\JsonStreamWriterTask' + task: json_stream_writer options: file_path: '%kernel.project_dir%/var/data/errors_{date_time}.json-stream' ``` @@ -165,13 +162,13 @@ clever_age_process: app.import_all: tasks: list_files: - service: '@CleverAge\ProcessBundle\Task\File\FolderBrowserTask' + task: folder_browser options: folder_path: '%kernel.project_dir%/var/import' name_pattern: '*.csv' outputs: [import_file] import_file: - service: '@CleverAge\ProcessBundle\Task\Process\ProcessExecutorTask' + task: process_executor options: process: app.import_file context: @@ -182,10 +179,10 @@ clever_age_process: entry_point: read tasks: read: - service: '@CleverAge\ProcessBundle\Task\File\Csv\InputCsvReaderTask' + task: input_csv_reader outputs: [save] save: - service: '@App\Task\SaveProductTask' + task: app_save_product # code of an application task, see #[AsTask] ``` If the parent process is executed without a `dry_run` context value, the placeholder is not replaced and the @@ -313,7 +310,7 @@ PHP executes a process in a single thread. To use several CPU cores, the ```yaml parallel_import: - service: '@CleverAge\ProcessBundle\Task\Process\ProcessLauncherTask' + task: process_launcher options: process: app.import_file max_processes: 4 diff --git a/docs/06-testing.md b/docs/06-testing.md index ff8786e3..d0b61350 100644 --- a/docs/06-testing.md +++ b/docs/06-testing.md @@ -116,7 +116,7 @@ clever_age_process: end_point: transform tasks: transform: - service: '@CleverAge\ProcessBundle\Task\TransformerTask' + task: transformer options: transformers: app_vat: diff --git a/docs/cookbooks/01-common_setup.md b/docs/cookbooks/01-common_setup.md index 746cc3fe..afa29816 100644 --- a/docs/cookbooks/01-common_setup.md +++ b/docs/cookbooks/01-common_setup.md @@ -115,14 +115,14 @@ clever_age_process: help: 'bin/console cleverage:process:execute app.file_import -c "file:''products.csv''"' tasks: read_csv: - service: '@CleverAge\ProcessBundle\Task\File\Csv\CsvReaderTask' + task: csv_reader options: file_path: '%kernel.project_dir%/var/data/{{ file }}' delimiter: ';' outputs: [transform] transform: - service: '@CleverAge\ProcessBundle\Task\TransformerTask' + task: transformer error_strategy: skip options: transformers: @@ -142,7 +142,7 @@ clever_age_process: outputs: [write_csv] write_csv: - service: '@CleverAge\ProcessBundle\Task\File\Csv\CsvWriterTask' + task: csv_writer options: file_path: '%kernel.project_dir%/var/output/products_prepared_{date_time}.csv' headers: [id, slug] diff --git a/docs/cookbooks/etl_aggregate_reports.md b/docs/cookbooks/etl_aggregate_reports.md index 26941dc4..0e3c9309 100644 --- a/docs/cookbooks/etl_aggregate_reports.md +++ b/docs/cookbooks/etl_aggregate_reports.md @@ -17,18 +17,18 @@ clever_age_process: description: 'Aggregate API logs per service' tasks: list_sources: - service: '@CleverAge\ProcessBundle\Task\File\FolderBrowserTask' + task: folder_browser options: folder_path: '%kernel.project_dir%/var/logs/api' name_pattern: '*.json-stream' outputs: [read_log] read_log: - service: '@CleverAge\ProcessBundle\Task\File\JsonStream\JsonStreamReaderTask' # Reads the file path given as input + task: json_stream_reader # Reads the file path given as input outputs: [map_log] map_log: - service: '@CleverAge\ProcessBundle\Task\TransformerTask' + task: transformer options: transformers: mapping: @@ -39,7 +39,7 @@ clever_age_process: outputs: [group_by_service] group_by_service: - service: '@CleverAge\ProcessBundle\Task\RowAggregatorTask' + task: row_aggregator options: aggregate_by: service aggregate_columns: [duration, status] @@ -47,11 +47,11 @@ clever_age_process: outputs: [iterate_services] iterate_services: - service: '@CleverAge\ProcessBundle\Task\InputIteratorTask' + task: input_iterator outputs: [compute_stats] compute_stats: - service: '@CleverAge\ProcessBundle\Task\TransformerTask' + task: transformer options: transformers: mapping: @@ -74,7 +74,7 @@ clever_age_process: outputs: [write_summary] write_summary: - service: '@CleverAge\ProcessBundle\Task\File\Csv\CsvWriterTask' + task: csv_writer options: file_path: '%kernel.project_dir%/var/exports/report_summary_{date}.csv' headers: [service, calls, total_duration] diff --git a/docs/cookbooks/etl_file_sync.md b/docs/cookbooks/etl_file_sync.md index 30d36154..fb4518ef 100644 --- a/docs/cookbooks/etl_file_sync.md +++ b/docs/cookbooks/etl_file_sync.md @@ -11,14 +11,14 @@ clever_age_process: description: 'Normalize the catalog CSV file' tasks: read_source: - service: '@CleverAge\ProcessBundle\Task\File\Csv\CsvReaderTask' + task: csv_reader options: file_path: '%kernel.project_dir%/var/data/catalog.csv' delimiter: ';' outputs: [filter_valid] filter_valid: - service: '@CleverAge\ProcessBundle\Task\FilterTask' + task: filter options: not_empty: '[sku]': ~ @@ -26,13 +26,13 @@ clever_age_process: error_outputs: [log_rejected] # Lines without sku log_rejected: - service: '@CleverAge\ProcessBundle\Task\Reporting\LoggerTask' + task: logger options: level: warning message: 'Line without sku' normalize: - service: '@CleverAge\ProcessBundle\Task\TransformerTask' + task: transformer error_strategy: skip # A line with an invalid date is logged and skipped options: transformers: @@ -55,20 +55,20 @@ clever_age_process: outputs: [deduplicate, count_rows] count_rows: - service: '@CleverAge\ProcessBundle\Task\Reporting\StatCounterTask' + task: stat_counter deduplicate: - service: '@CleverAge\ProcessBundle\Task\GroupByAggregateIterableTask' + task: group_by_aggregate_iterable options: group_by_accessors: ['[sku]'] # The last line of each sku is kept outputs: [iterate] iterate: - service: '@CleverAge\ProcessBundle\Task\InputIteratorTask' + task: input_iterator outputs: [write_target] write_target: - service: '@CleverAge\ProcessBundle\Task\File\Csv\CsvWriterTask' + task: csv_writer options: file_path: '%kernel.project_dir%/var/exports/catalog_normalized_{date}.csv' headers: [sku, price, updated_at] diff --git a/docs/cookbooks/memory_usage_graph.md b/docs/cookbooks/memory_usage_graph.md index 2976f127..2c509dfe 100644 --- a/docs/cookbooks/memory_usage_graph.md +++ b/docs/cookbooks/memory_usage_graph.md @@ -7,7 +7,7 @@ desktop environment. Add these tasks to your process: ```yaml memory: - service: '@CleverAge\ProcessBundle\Task\TransformerTask' + task: transformer options: transformers: mapping: @@ -20,7 +20,7 @@ memory: outputs: [write_memory] write_memory: - service: '@CleverAge\ProcessBundle\Task\File\Csv\CsvWriterTask' + task: csv_writer options: file_path: '%kernel.project_dir%/memory.dat' headers: [memory_usage] @@ -47,7 +47,7 @@ identify each of them. All measure tasks send their output to the same `write_me ```yaml memory_after_read: - service: '@CleverAge\ProcessBundle\Task\TransformerTask' + task: transformer options: transformers: mapping: @@ -62,7 +62,7 @@ memory_after_read: outputs: [write_memory] memory_after_transform: - service: '@CleverAge\ProcessBundle\Task\TransformerTask' + task: transformer options: transformers: mapping: @@ -77,7 +77,7 @@ memory_after_transform: outputs: [write_memory] write_memory: - service: '@CleverAge\ProcessBundle\Task\File\Csv\CsvWriterTask' + task: csv_writer options: file_path: '%kernel.project_dir%/memory_phase.csv' headers: [phase, memory_usage] diff --git a/docs/reference/02-task_definition.md b/docs/reference/02-task_definition.md index bcec492f..adeb9bd7 100644 --- a/docs/reference/02-task_definition.md +++ b/docs/reference/02-task_definition.md @@ -5,8 +5,8 @@ YAML Configuration ------------------ ```yaml -: - service: +: # name of the task in the process, used in the outputs + task: # service: is deprecated description: help: options: @@ -20,27 +20,26 @@ YAML Configuration Task attributes --------------- -**service**: required, reference to the service used for the task: a service **id** or a service **alias**, with or -without a leading `@` (quote the value when it starts with `@`, as YAML requires). The service must implement -`CleverAge\ProcessBundle\Model\TaskInterface`. For instance, the `UnzipTask` of the archive bridge is registered as -`cleverage_archive_process.task.unzip`, with an alias named after its class: these four references are equivalent. +**task**: required, code of the task, e.g. `task: transformer`. The code of each task of this bundle is given on its +[reference page](tasks/) (e.g. `transformer` for the [TransformerTask](tasks/transformer_task.md)); the code of a task +service is declared with a `cleverage.task` tag with a `code` attribute, or with the +`#[CleverAge\ProcessBundle\Attribute\AsTask(code: '...')]` attribute (see +[custom tasks](../03-custom_tasks.md#task-code)). A code is **unique**: it identifies a single task service in the +application (the tasks of this bundle have unprefixed codes, use a prefix for the ones of your own tasks), two services +with the same code fail the container compilation. +The codes are resolved when the container is compiled: an unknown code fails the compilation, with the list of the +known codes. The services of the tasks referenced by the process +configurations are collected when the container is compiled, so they can be private. -```yaml -service: '@cleverage_archive_process.task.unzip' # id, with @ -service: cleverage_archive_process.task.unzip # id, without @ -service: '@CleverAge\ArchiveProcessBundle\Task\UnzipTask' # alias, with @ -service: CleverAge\ArchiveProcessBundle\Task\UnzipTask # alias, without @ -``` - -The tasks of this bundle and of the bridge bundles are registered with a `cleverage_process.task.*` / -`cleverage_*_process.task.*` id and an alias named after their class (e.g. `cleverage_process.task.transformer` and -`'@CleverAge\ProcessBundle\Task\TransformerTask'`, the class name being the reference used in this documentation), and -your own task services with any id or alias you choose. With an unknown service, a reference with `@` throws the -`ServiceNotFoundException` of the service container, a reference without `@` an `\UnexpectedValueException` -(`Unable to resolve service reference for Task ''`). +**service**: **deprecated since 5.4, removed in v6.0**, use `task`. Reference to the service used for the task, instead +of its code: its service id, with or without a leading `@` (quote the value when it starts with `@`, as YAML requires), +e.g. `service: '@CleverAge\ProcessBundle\Task\TransformerTask'` (the tasks of this bundle have their class name as +service id). The service must implement `CleverAge\ProcessBundle\Model\TaskInterface`. With an unknown service, a +reference with `@` throws the `ServiceNotFoundException` of the service container, a reference without `@` an +`\UnexpectedValueException` (`Unable to resolve service reference for Task ''`). A task defines either `task` +or `service`, not both. -The services referenced by the process configurations are collected when the container is compiled, so they can be -private (as well as the aliases). Only a service that is not referenced by these configurations (e.g. a configuration +Only a service that is not referenced by the configurations known when the container is compiled (e.g. a configuration added at runtime) is fetched from the service container, which requires a public service and is deprecated since 5.4. **description**: optional string to describe a task, displayed in process help (should not exceed one line). diff --git a/docs/reference/03-generic_transformers_definition.md b/docs/reference/03-generic_transformers_definition.md index 90a24f35..606fb990 100644 --- a/docs/reference/03-generic_transformers_definition.md +++ b/docs/reference/03-generic_transformers_definition.md @@ -62,7 +62,7 @@ clever_age_process: app.demo: tasks: transform: - service: '@CleverAge\ProcessBundle\Task\TransformerTask' + task: transformer options: transformers: mapping: diff --git a/docs/reference/tasks/_template.md b/docs/reference/tasks/_template.md index 919390a2..1aa1c46f 100644 --- a/docs/reference/tasks/_template.md +++ b/docs/reference/tasks/_template.md @@ -7,6 +7,7 @@ Task reference -------------- * **Service**: `Fully\Qualified\ClassName` +* **Code**: `task_code` (`task: 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: task_code options: a: 1 b: 2 diff --git a/docs/reference/tasks/advanced_stat_counter_task.md b/docs/reference/tasks/advanced_stat_counter_task.md index a30924da..8425722d 100644 --- a/docs/reference/tasks/advanced_stat_counter_task.md +++ b/docs/reference/tasks/advanced_stat_counter_task.md @@ -9,6 +9,7 @@ Task reference -------------- * **Service**: `CleverAge\ProcessBundle\Task\Reporting\AdvancedStatCounterTask` +* **Code**: `advanced_stat_counter` (`task: advanced_stat_counter`) Accepted inputs --------------- @@ -43,7 +44,7 @@ Examples ```yaml # Task configuration level stats: - service: '@CleverAge\ProcessBundle\Task\Reporting\AdvancedStatCounterTask' + task: advanced_stat_counter options: num_items: 50 show_every: 100 diff --git a/docs/reference/tasks/aggregate_iterable_task.md b/docs/reference/tasks/aggregate_iterable_task.md index 246d6b0d..4a2354b8 100644 --- a/docs/reference/tasks/aggregate_iterable_task.md +++ b/docs/reference/tasks/aggregate_iterable_task.md @@ -8,6 +8,7 @@ Task reference -------------- * **Service**: `CleverAge\ProcessBundle\Task\AggregateIterableTask` +* **Code**: `aggregate_iterable` (`task: aggregate_iterable`) * **Blocking task** Accepted inputs @@ -33,10 +34,10 @@ Examples ```yaml # Task configuration level data: - service: '@CleverAge\ProcessBundle\Task\ConstantIterableOutputTask' + task: constant_iterable_output options: output: [1, 2, 3] outputs: [aggregate] aggregate: - service: '@CleverAge\ProcessBundle\Task\AggregateIterableTask' + task: aggregate_iterable ``` diff --git a/docs/reference/tasks/array_merge_task.md b/docs/reference/tasks/array_merge_task.md index 6b85199c..489a6bd0 100644 --- a/docs/reference/tasks/array_merge_task.md +++ b/docs/reference/tasks/array_merge_task.md @@ -8,6 +8,7 @@ Task reference -------------- * **Service**: `CleverAge\ProcessBundle\Task\ArrayMergeTask` +* **Code**: `array_merge` (`task: array_merge`) * **Blocking task** Accepted inputs @@ -35,14 +36,14 @@ Examples ```yaml # Task configuration level data: - service: '@CleverAge\ProcessBundle\Task\ConstantIterableOutputTask' + task: constant_iterable_output options: output: - { a: 1, b: { c: 2 } } - { b: { d: 3 } } outputs: [merge] merge: - service: '@CleverAge\ProcessBundle\Task\ArrayMergeTask' + task: array_merge options: merge_function: array_replace_recursive ``` diff --git a/docs/reference/tasks/column_aggregator_task.md b/docs/reference/tasks/column_aggregator_task.md index 5a72508d..6eaea8d7 100644 --- a/docs/reference/tasks/column_aggregator_task.md +++ b/docs/reference/tasks/column_aggregator_task.md @@ -8,6 +8,7 @@ Task reference -------------- * **Service**: `CleverAge\ProcessBundle\Task\ColumnAggregatorTask` +* **Code**: `column_aggregator` (`task: column_aggregator`) * **Blocking task** Accepted inputs @@ -47,10 +48,10 @@ Examples ```yaml # Task configuration level iterate: - service: '@CleverAge\ProcessBundle\Task\InputIteratorTask' + task: input_iterator outputs: [aggregate_a] aggregate_a: - service: '@CleverAge\ProcessBundle\Task\ColumnAggregatorTask' + task: column_aggregator options: columns: [col1] condition: diff --git a/docs/reference/tasks/command_runner_task.md b/docs/reference/tasks/command_runner_task.md index b2749b94..ce2f9047 100644 --- a/docs/reference/tasks/command_runner_task.md +++ b/docs/reference/tasks/command_runner_task.md @@ -8,6 +8,7 @@ Task reference -------------- * **Service**: `CleverAge\ProcessBundle\Task\Process\CommandRunnerTask` +* **Code**: `command_runner` (`task: command_runner`) Accepted inputs --------------- @@ -41,7 +42,7 @@ Examples ```yaml # Task configuration level count_lines: - service: '@CleverAge\ProcessBundle\Task\Process\CommandRunnerTask' + task: command_runner options: commandline: ['wc', '-l'] timeout: 30 @@ -53,7 +54,7 @@ count_lines: ```yaml # Task configuration level count_errors: - service: '@CleverAge\ProcessBundle\Task\Process\CommandRunnerTask' + task: command_runner options: commandline: 'grep "$PATTERN" | wc -l' env: diff --git a/docs/reference/tasks/constant_iterable_output_task.md b/docs/reference/tasks/constant_iterable_output_task.md index cb4c9d78..7b78323c 100644 --- a/docs/reference/tasks/constant_iterable_output_task.md +++ b/docs/reference/tasks/constant_iterable_output_task.md @@ -8,6 +8,7 @@ Task reference -------------- * **Service**: `CleverAge\ProcessBundle\Task\ConstantIterableOutputTask` +* **Code**: `constant_iterable_output` (`task: constant_iterable_output`) * **Iterable task** Accepted inputs @@ -35,7 +36,7 @@ Examples ```yaml # Task configuration level entry: - service: '@CleverAge\ProcessBundle\Task\ConstantIterableOutputTask' + task: constant_iterable_output options: output: id: 123 diff --git a/docs/reference/tasks/constant_output_task.md b/docs/reference/tasks/constant_output_task.md index 165f49c0..0faea2c3 100644 --- a/docs/reference/tasks/constant_output_task.md +++ b/docs/reference/tasks/constant_output_task.md @@ -8,6 +8,7 @@ Task reference -------------- * **Service**: `CleverAge\ProcessBundle\Task\ConstantOutputTask` +* **Code**: `constant_output` (`task: constant_output`) Accepted inputs --------------- @@ -34,7 +35,7 @@ Examples ```yaml # Task configuration level entry: - service: '@CleverAge\ProcessBundle\Task\ConstantOutputTask' + task: constant_output options: output: id: 123 diff --git a/docs/reference/tasks/counter_task.md b/docs/reference/tasks/counter_task.md index 79067612..268288d5 100644 --- a/docs/reference/tasks/counter_task.md +++ b/docs/reference/tasks/counter_task.md @@ -9,6 +9,7 @@ Task reference -------------- * **Service**: `CleverAge\ProcessBundle\Task\CounterTask` +* **Code**: `counter` (`task: counter`) * **Flushable task** Accepted inputs @@ -37,12 +38,12 @@ Examples ```yaml # Task configuration level entry: - service: '@CleverAge\ProcessBundle\Task\ConstantIterableOutputTask' + task: constant_iterable_output options: output: [1, 2, 3, 4, 5, 6, 7, 8, 9] outputs: [counter] counter: - service: '@CleverAge\ProcessBundle\Task\CounterTask' + task: counter options: flush_every: 3 outputs: [debug] diff --git a/docs/reference/tasks/csv_reader_task.md b/docs/reference/tasks/csv_reader_task.md index 4e85c2cc..efa3d5c5 100644 --- a/docs/reference/tasks/csv_reader_task.md +++ b/docs/reference/tasks/csv_reader_task.md @@ -8,6 +8,7 @@ Task reference -------------- * **Service**: `CleverAge\ProcessBundle\Task\File\Csv\CsvReaderTask` +* **Code**: `csv_reader` (`task: csv_reader`) * **Iterable task** Accepted inputs @@ -46,7 +47,7 @@ Examples ```yaml # Task configuration level entry: - service: '@CleverAge\ProcessBundle\Task\File\Csv\CsvReaderTask' + task: csv_reader options: file_path: '%kernel.project_dir%/var/data/sample.csv' delimiter: '{{ delimiter }}' @@ -58,7 +59,7 @@ entry: ```yaml # Task configuration level entry: - service: '@CleverAge\ProcessBundle\Task\File\Csv\CsvReaderTask' + task: csv_reader options: file_path: '%kernel.project_dir%/var/data/no_header.csv' delimiter: ',' diff --git a/docs/reference/tasks/csv_splitter_task.md b/docs/reference/tasks/csv_splitter_task.md index 322fa05f..328f0b47 100644 --- a/docs/reference/tasks/csv_splitter_task.md +++ b/docs/reference/tasks/csv_splitter_task.md @@ -8,6 +8,7 @@ Task reference -------------- * **Service**: `CleverAge\ProcessBundle\Task\File\Csv\CsvSplitterTask` +* **Code**: `csv_splitter` (`task: csv_splitter`) * **Iterable task** Accepted inputs @@ -44,18 +45,18 @@ Examples ```yaml # Task configuration level entry: - service: '@CleverAge\ProcessBundle\Task\ConstantOutputTask' + task: constant_output options: output: '%kernel.project_dir%/var/data/large_file.csv' outputs: [split] split: - service: '@CleverAge\ProcessBundle\Task\File\Csv\CsvSplitterTask' + task: csv_splitter options: delimiter: ';' max_lines: 500 outputs: [read_chunk] read_chunk: - service: '@CleverAge\ProcessBundle\Task\File\Csv\InputCsvReaderTask' + task: input_csv_reader options: delimiter: ';' ``` diff --git a/docs/reference/tasks/csv_writer_task.md b/docs/reference/tasks/csv_writer_task.md index c4ffb382..83cb52d4 100644 --- a/docs/reference/tasks/csv_writer_task.md +++ b/docs/reference/tasks/csv_writer_task.md @@ -8,6 +8,7 @@ Task reference -------------- * **Service**: `CleverAge\ProcessBundle\Task\File\Csv\CsvWriterTask` +* **Code**: `csv_writer` (`task: csv_writer`) * **Blocking task** Accepted inputs @@ -44,7 +45,7 @@ Examples ```yaml # Task configuration level entry: - service: '@CleverAge\ProcessBundle\Task\ConstantIterableOutputTask' + task: constant_iterable_output options: output: - column1: value1-1 @@ -53,7 +54,7 @@ entry: column2: value2-2 outputs: [write] write: - service: '@CleverAge\ProcessBundle\Task\File\Csv\CsvWriterTask' + task: csv_writer options: file_path: '%kernel.project_dir%/var/data/csv_writer_{date_time}.csv' ``` @@ -63,7 +64,7 @@ write: ```yaml # Task configuration level write: - service: '@CleverAge\ProcessBundle\Task\File\Csv\CsvWriterTask' + task: csv_writer options: file_path: '%kernel.project_dir%/var/data/export.csv' mode: 'ab' diff --git a/docs/reference/tasks/debug_task.md b/docs/reference/tasks/debug_task.md index 9dfe0d24..9df162f4 100644 --- a/docs/reference/tasks/debug_task.md +++ b/docs/reference/tasks/debug_task.md @@ -8,6 +8,7 @@ Task reference -------------- * **Service**: `CleverAge\ProcessBundle\Task\Debug\DebugTask` +* **Code**: `debug` (`task: debug`) Accepted inputs --------------- @@ -32,12 +33,12 @@ Examples ```yaml # Task configuration level entry: - service: '@CleverAge\ProcessBundle\Task\ConstantOutputTask' + task: constant_output options: output: id: 123 firstname: Test1 outputs: [debug] debug: - service: '@CleverAge\ProcessBundle\Task\Debug\DebugTask' + task: debug ``` diff --git a/docs/reference/tasks/denormalizer_task.md b/docs/reference/tasks/denormalizer_task.md index 07436b77..317e5b3f 100644 --- a/docs/reference/tasks/denormalizer_task.md +++ b/docs/reference/tasks/denormalizer_task.md @@ -8,6 +8,7 @@ Task reference -------------- * **Service**: `CleverAge\ProcessBundle\Task\Serialization\DenormalizerTask` +* **Code**: `denormalizer` (`task: denormalizer`) Accepted inputs --------------- @@ -37,7 +38,7 @@ Examples ```yaml # Task configuration level denormalize: - service: '@CleverAge\ProcessBundle\Task\Serialization\DenormalizerTask' + task: denormalizer options: class: App\Entity\Author outputs: [save] @@ -48,7 +49,7 @@ denormalize: ```yaml # Task configuration level dto: - service: '@CleverAge\ProcessBundle\Task\Serialization\DenormalizerTask' + task: denormalizer options: class: 'App\Dto\Commune[]' outputs: [debug] diff --git a/docs/reference/tasks/deserializer_task.md b/docs/reference/tasks/deserializer_task.md index 051d337d..8161aef2 100644 --- a/docs/reference/tasks/deserializer_task.md +++ b/docs/reference/tasks/deserializer_task.md @@ -7,6 +7,7 @@ Task reference -------------- * **Service**: `CleverAge\ProcessBundle\Task\Serialization\DeserializerTask` +* **Code**: `deserializer` (`task: deserializer`) Accepted inputs --------------- @@ -35,7 +36,7 @@ Examples ```yaml # Task configuration level deserialize: - service: '@CleverAge\ProcessBundle\Task\Serialization\DeserializerTask' + task: deserializer options: type: App\Entity\Author format: json diff --git a/docs/reference/tasks/die_task.md b/docs/reference/tasks/die_task.md index f11024fd..d81228c4 100644 --- a/docs/reference/tasks/die_task.md +++ b/docs/reference/tasks/die_task.md @@ -9,6 +9,7 @@ Task reference -------------- * **Service**: `CleverAge\ProcessBundle\Task\Debug\DieTask` +* **Code**: `die` (`task: die`) Accepted inputs --------------- @@ -33,10 +34,10 @@ Examples ```yaml # Task configuration level entry: - service: '@CleverAge\ProcessBundle\Task\ConstantOutputTask' + task: constant_output options: output: { id: 123 } outputs: [die] die: - service: '@CleverAge\ProcessBundle\Task\Debug\DieTask' + task: die ``` diff --git a/docs/reference/tasks/dummy_task.md b/docs/reference/tasks/dummy_task.md index e46ad30f..821dc914 100644 --- a/docs/reference/tasks/dummy_task.md +++ b/docs/reference/tasks/dummy_task.md @@ -8,6 +8,7 @@ Task reference -------------- * **Service**: `CleverAge\ProcessBundle\Task\DummyTask` +* **Code**: `dummy` (`task: dummy`) Accepted inputs --------------- @@ -32,14 +33,14 @@ Examples ```yaml # Task configuration level entry: - service: '@CleverAge\ProcessBundle\Task\DummyTask' + task: dummy outputs: [output1, output2] output1: - service: '@CleverAge\ProcessBundle\Task\ConstantOutputTask' + task: constant_output options: output: { id: 123 } output2: - service: '@CleverAge\ProcessBundle\Task\ConstantOutputTask' + task: constant_output options: output: { id: 456 } ``` diff --git a/docs/reference/tasks/error_forwarder_task.md b/docs/reference/tasks/error_forwarder_task.md index 895e63ef..4908c707 100644 --- a/docs/reference/tasks/error_forwarder_task.md +++ b/docs/reference/tasks/error_forwarder_task.md @@ -8,6 +8,7 @@ Task reference -------------- * **Service**: `CleverAge\ProcessBundle\Task\Debug\ErrorForwarderTask` +* **Code**: `error_forwarder` (`task: error_forwarder`) Accepted inputs --------------- @@ -34,13 +35,13 @@ Examples ```yaml # Task configuration level entry: - service: '@CleverAge\ProcessBundle\Task\ConstantIterableOutputTask' + task: constant_iterable_output options: output: [Error 1, Error 2, Error 3] outputs: [error_forwarder] error_forwarder: - service: '@CleverAge\ProcessBundle\Task\Debug\ErrorForwarderTask' + task: error_forwarder error_outputs: [debug] debug: - service: '@CleverAge\ProcessBundle\Task\Debug\DebugTask' + task: debug ``` diff --git a/docs/reference/tasks/event_dispatcher_task.md b/docs/reference/tasks/event_dispatcher_task.md index aedddbbc..3f1b8be9 100644 --- a/docs/reference/tasks/event_dispatcher_task.md +++ b/docs/reference/tasks/event_dispatcher_task.md @@ -9,6 +9,7 @@ Task reference -------------- * **Service**: `CleverAge\ProcessBundle\Task\Event\EventDispatcherTask` +* **Code**: `event_dispatcher` (`task: event_dispatcher`) Accepted inputs --------------- @@ -37,12 +38,12 @@ Examples ```yaml # Task configuration level data: - service: '@CleverAge\ProcessBundle\Task\ConstantIterableOutputTask' + task: constant_iterable_output options: output: [1, 2, 3] outputs: [push_data_event] push_data_event: - service: '@CleverAge\ProcessBundle\Task\Event\EventDispatcherTask' + task: event_dispatcher options: event_name: myapp.data_queue ``` diff --git a/docs/reference/tasks/file_mover_task.md b/docs/reference/tasks/file_mover_task.md index 95d20ed6..0f4fa5e4 100644 --- a/docs/reference/tasks/file_mover_task.md +++ b/docs/reference/tasks/file_mover_task.md @@ -8,6 +8,7 @@ Task reference -------------- * **Service**: `CleverAge\ProcessBundle\Task\File\FileMoverTask` +* **Code**: `file_mover` (`task: file_mover`) Accepted inputs --------------- @@ -36,7 +37,7 @@ Examples ```yaml # Task configuration level move_file: - service: '@CleverAge\ProcessBundle\Task\File\FileMoverTask' + task: file_mover options: destination: '%kernel.project_dir%/var/data/archive/' autoincrement: true diff --git a/docs/reference/tasks/file_reader_task.md b/docs/reference/tasks/file_reader_task.md index b1a05e8f..f75e31c3 100644 --- a/docs/reference/tasks/file_reader_task.md +++ b/docs/reference/tasks/file_reader_task.md @@ -7,6 +7,7 @@ Task reference -------------- * **Service**: `CleverAge\ProcessBundle\Task\File\FileReaderTask` +* **Code**: `file_reader` (`task: file_reader`) Accepted inputs --------------- @@ -32,7 +33,7 @@ Examples ```yaml # Task configuration level entry: - service: '@CleverAge\ProcessBundle\Task\File\FileReaderTask' + task: file_reader options: filename: '%kernel.project_dir%/var/data/sample.txt' outputs: [debug] diff --git a/docs/reference/tasks/file_remover_task.md b/docs/reference/tasks/file_remover_task.md index 4ee709e1..c61b8a2b 100644 --- a/docs/reference/tasks/file_remover_task.md +++ b/docs/reference/tasks/file_remover_task.md @@ -7,6 +7,7 @@ Task reference -------------- * **Service**: `CleverAge\ProcessBundle\Task\File\FileRemoverTask` +* **Code**: `file_remover` (`task: file_remover`) Accepted inputs --------------- @@ -32,10 +33,10 @@ Examples ```yaml # Task configuration level entry: - service: '@CleverAge\ProcessBundle\Task\File\FolderBrowserTask' + task: folder_browser options: folder_path: '%kernel.project_dir%/var/tmp' outputs: [cleanup] cleanup: - service: '@CleverAge\ProcessBundle\Task\File\FileRemoverTask' + task: file_remover ``` diff --git a/docs/reference/tasks/file_splitter_task.md b/docs/reference/tasks/file_splitter_task.md index a8881e0f..18282cf4 100644 --- a/docs/reference/tasks/file_splitter_task.md +++ b/docs/reference/tasks/file_splitter_task.md @@ -8,6 +8,7 @@ Task reference -------------- * **Service**: `CleverAge\ProcessBundle\Task\File\FileSplitterTask` +* **Code**: `file_splitter` (`task: file_splitter`) * **Iterable task** Accepted inputs @@ -36,13 +37,13 @@ Examples ```yaml # Task configuration level entry: - service: '@CleverAge\ProcessBundle\Task\File\FileSplitterTask' + task: file_splitter options: file_path: '%kernel.project_dir%/var/data/json_stream_reader.json' max_lines: 100 outputs: [read_chunk] read_chunk: - service: '@CleverAge\ProcessBundle\Task\File\InputLineReaderTask' + task: input_line_reader ``` Notes diff --git a/docs/reference/tasks/file_writer_task.md b/docs/reference/tasks/file_writer_task.md index d66cf076..6b8b8c4d 100644 --- a/docs/reference/tasks/file_writer_task.md +++ b/docs/reference/tasks/file_writer_task.md @@ -7,6 +7,7 @@ Task reference -------------- * **Service**: `CleverAge\ProcessBundle\Task\File\FileWriterTask` +* **Code**: `file_writer` (`task: file_writer`) Accepted inputs --------------- @@ -32,7 +33,7 @@ Examples ```yaml # Task configuration level write_file: - service: '@CleverAge\ProcessBundle\Task\File\FileWriterTask' + task: file_writer options: filename: '%kernel.project_dir%/var/data/result.txt' ``` diff --git a/docs/reference/tasks/filter_task.md b/docs/reference/tasks/filter_task.md index ed1860a5..6b28bcc8 100644 --- a/docs/reference/tasks/filter_task.md +++ b/docs/reference/tasks/filter_task.md @@ -8,6 +8,7 @@ Task reference -------------- * **Service**: `CleverAge\ProcessBundle\Task\FilterTask` +* **Code**: `filter` (`task: filter`) Accepted inputs --------------- @@ -45,7 +46,7 @@ Examples ```yaml # Task configuration level filter_active: - service: '@CleverAge\ProcessBundle\Task\FilterTask' + task: filter options: match: '[status]': active diff --git a/docs/reference/tasks/folder_browser_task.md b/docs/reference/tasks/folder_browser_task.md index 106299f9..8cdca1b0 100644 --- a/docs/reference/tasks/folder_browser_task.md +++ b/docs/reference/tasks/folder_browser_task.md @@ -8,6 +8,7 @@ Task reference -------------- * **Service**: `CleverAge\ProcessBundle\Task\File\FolderBrowserTask` +* **Code**: `folder_browser` (`task: folder_browser`) * **Iterable task** Accepted inputs @@ -41,7 +42,7 @@ Examples ```yaml # Task configuration level entry: - service: '@CleverAge\ProcessBundle\Task\File\FolderBrowserTask' + task: folder_browser options: folder_path: '%kernel.project_dir%/var/data' name_pattern: '*.csv' diff --git a/docs/reference/tasks/group_by_aggregate_iterable_task.md b/docs/reference/tasks/group_by_aggregate_iterable_task.md index a66701f2..9a37b7cb 100644 --- a/docs/reference/tasks/group_by_aggregate_iterable_task.md +++ b/docs/reference/tasks/group_by_aggregate_iterable_task.md @@ -9,6 +9,7 @@ Task reference -------------- * **Service**: `CleverAge\ProcessBundle\Task\GroupByAggregateIterableTask` +* **Code**: `group_by_aggregate_iterable` (`task: group_by_aggregate_iterable`) * **Blocking task** Accepted inputs @@ -38,7 +39,7 @@ Examples ```yaml # Task configuration level deduplicate: - service: '@CleverAge\ProcessBundle\Task\GroupByAggregateIterableTask' + task: group_by_aggregate_iterable options: group_by_accessors: - '[type]' diff --git a/docs/reference/tasks/input_aggregator_task.md b/docs/reference/tasks/input_aggregator_task.md index 103529dd..2ade9256 100644 --- a/docs/reference/tasks/input_aggregator_task.md +++ b/docs/reference/tasks/input_aggregator_task.md @@ -11,6 +11,7 @@ Task reference -------------- * **Service**: `CleverAge\ProcessBundle\Task\InputAggregatorTask` +* **Code**: `input_aggregator` (`task: input_aggregator`) Accepted inputs --------------- @@ -40,20 +41,20 @@ Examples ```yaml # Task configuration level entry: - service: '@CleverAge\ProcessBundle\Task\DummyTask' + task: dummy outputs: [branch_a, branch_b] branch_a: - service: '@CleverAge\ProcessBundle\Task\ConstantOutputTask' + task: constant_output options: output: A outputs: [aggregate] branch_b: - service: '@CleverAge\ProcessBundle\Task\ConstantOutputTask' + task: constant_output options: output: B outputs: [aggregate] aggregate: - service: '@CleverAge\ProcessBundle\Task\InputAggregatorTask' + task: input_aggregator options: input_codes: branch_a: a diff --git a/docs/reference/tasks/input_csv_reader_task.md b/docs/reference/tasks/input_csv_reader_task.md index 67a636e8..fed3844b 100644 --- a/docs/reference/tasks/input_csv_reader_task.md +++ b/docs/reference/tasks/input_csv_reader_task.md @@ -8,6 +8,7 @@ Task reference -------------- * **Service**: `CleverAge\ProcessBundle\Task\File\Csv\InputCsvReaderTask` +* **Code**: `input_csv_reader` (`task: input_csv_reader`) * **Iterable task** Accepted inputs @@ -49,13 +50,13 @@ Examples ```yaml # Task configuration level entry: - service: '@CleverAge\ProcessBundle\Task\File\FolderBrowserTask' + task: folder_browser options: folder_path: '%kernel.project_dir%/var/data' name_pattern: '*.csv' outputs: [read] read: - service: '@CleverAge\ProcessBundle\Task\File\Csv\InputCsvReaderTask' + task: input_csv_reader outputs: [dump] ``` @@ -65,7 +66,7 @@ read: ```yaml # Task configuration level read: - service: '@CleverAge\ProcessBundle\Task\File\Csv\InputCsvReaderTask' + task: input_csv_reader options: delimiter: '{{ delimiter }}' outputs: [dump] diff --git a/docs/reference/tasks/input_file_reader_task.md b/docs/reference/tasks/input_file_reader_task.md index ac9413f9..e06754b5 100644 --- a/docs/reference/tasks/input_file_reader_task.md +++ b/docs/reference/tasks/input_file_reader_task.md @@ -8,6 +8,7 @@ Task reference -------------- * **Service**: `CleverAge\ProcessBundle\Task\File\InputFileReaderTask` +* **Code**: `input_file_reader` (`task: input_file_reader`) Accepted inputs --------------- @@ -34,11 +35,11 @@ Examples ```yaml # Task configuration level entry: - service: '@CleverAge\ProcessBundle\Task\File\FolderBrowserTask' + task: folder_browser options: folder_path: '%kernel.project_dir%/var/data' outputs: [read] read: - service: '@CleverAge\ProcessBundle\Task\File\InputFileReaderTask' + task: input_file_reader outputs: [debug] ``` diff --git a/docs/reference/tasks/input_folder_browser_task.md b/docs/reference/tasks/input_folder_browser_task.md index 9d21bddc..c8126305 100644 --- a/docs/reference/tasks/input_folder_browser_task.md +++ b/docs/reference/tasks/input_folder_browser_task.md @@ -8,6 +8,7 @@ Task reference -------------- * **Service**: `CleverAge\ProcessBundle\Task\File\InputFolderBrowserTask` +* **Code**: `input_folder_browser` (`task: input_folder_browser`) * **Iterable task** * **Flushable task** @@ -48,15 +49,15 @@ Examples ```yaml # Task configuration level entry: - service: '@CleverAge\ProcessBundle\Task\ConstantOutputTask' + task: constant_output options: output: '/var/data' outputs: [directory] directory: - service: '@CleverAge\ProcessBundle\Task\File\InputFolderBrowserTask' + task: input_folder_browser options: base_folder_path: '%kernel.project_dir%' outputs: [read] read: - service: '@CleverAge\ProcessBundle\Task\File\InputFileReaderTask' + task: input_file_reader ``` diff --git a/docs/reference/tasks/input_iterator_task.md b/docs/reference/tasks/input_iterator_task.md index 2d4407ce..37cd862f 100644 --- a/docs/reference/tasks/input_iterator_task.md +++ b/docs/reference/tasks/input_iterator_task.md @@ -7,6 +7,7 @@ Task reference -------------- * **Service**: `CleverAge\ProcessBundle\Task\InputIteratorTask` +* **Code**: `input_iterator` (`task: input_iterator`) * **Iterable task** Accepted inputs @@ -32,9 +33,9 @@ Examples ```yaml # Task configuration level aggregate: - service: '@CleverAge\ProcessBundle\Task\AggregateIterableTask' + task: aggregate_iterable outputs: [iterate] iterate: - service: '@CleverAge\ProcessBundle\Task\InputIteratorTask' + task: input_iterator outputs: [next_task] ``` diff --git a/docs/reference/tasks/input_line_reader_task.md b/docs/reference/tasks/input_line_reader_task.md index a3605beb..682eff9f 100644 --- a/docs/reference/tasks/input_line_reader_task.md +++ b/docs/reference/tasks/input_line_reader_task.md @@ -8,6 +8,7 @@ Task reference -------------- * **Service**: `CleverAge\ProcessBundle\Task\File\InputLineReaderTask` +* **Code**: `input_line_reader` (`task: input_line_reader`) * **Iterable task** Accepted inputs @@ -37,11 +38,11 @@ Examples ```yaml # Task configuration level entry: - service: '@CleverAge\ProcessBundle\Task\File\FolderBrowserTask' + task: folder_browser options: folder_path: '%kernel.project_dir%/var/data' outputs: [read] read: - service: '@CleverAge\ProcessBundle\Task\File\InputLineReaderTask' + task: input_line_reader outputs: [log_line] ``` diff --git a/docs/reference/tasks/iterable_batch_task.md b/docs/reference/tasks/iterable_batch_task.md index 0762c9e0..2538923d 100644 --- a/docs/reference/tasks/iterable_batch_task.md +++ b/docs/reference/tasks/iterable_batch_task.md @@ -10,6 +10,7 @@ Task reference -------------- * **Service**: `CleverAge\ProcessBundle\Task\IterableBatchTask` +* **Code**: `iterable_batch` (`task: iterable_batch`) * **Iterable task** * **Flushable task** @@ -38,10 +39,10 @@ Examples ```yaml # Task configuration level iterator: - service: '@CleverAge\ProcessBundle\Task\InputIteratorTask' + task: input_iterator outputs: [batch] batch: - service: '@CleverAge\ProcessBundle\Task\IterableBatchTask' + task: iterable_batch options: batch_count: 2 outputs: [next_task] diff --git a/docs/reference/tasks/json_stream_reader_task.md b/docs/reference/tasks/json_stream_reader_task.md index 76871dc2..b61db0ed 100644 --- a/docs/reference/tasks/json_stream_reader_task.md +++ b/docs/reference/tasks/json_stream_reader_task.md @@ -8,6 +8,7 @@ Task reference -------------- * **Service**: `CleverAge\ProcessBundle\Task\File\JsonStream\JsonStreamReaderTask` +* **Code**: `json_stream_reader` (`task: json_stream_reader`) * **Iterable task** Accepted inputs @@ -40,12 +41,12 @@ Examples ```yaml # Task configuration level entry: - service: '@CleverAge\ProcessBundle\Task\ConstantOutputTask' + task: constant_output options: output: '%kernel.project_dir%/var/data/json_stream_reader.json' outputs: [read] read: - service: '@CleverAge\ProcessBundle\Task\File\JsonStream\JsonStreamReaderTask' + task: json_stream_reader options: json_flags: - !php/const JSON_THROW_ON_ERROR diff --git a/docs/reference/tasks/json_stream_writer_task.md b/docs/reference/tasks/json_stream_writer_task.md index 21b1150e..ffcc5c17 100644 --- a/docs/reference/tasks/json_stream_writer_task.md +++ b/docs/reference/tasks/json_stream_writer_task.md @@ -8,6 +8,7 @@ Task reference -------------- * **Service**: `CleverAge\ProcessBundle\Task\File\JsonStream\JsonStreamWriterTask` +* **Code**: `json_stream_writer` (`task: json_stream_writer`) * **Blocking task** Accepted inputs @@ -37,7 +38,7 @@ Examples ```yaml # Task configuration level entry: - service: '@CleverAge\ProcessBundle\Task\ConstantIterableOutputTask' + task: constant_iterable_output options: output: - column1: value1-1 @@ -46,7 +47,7 @@ entry: column2: value2-2 outputs: [write] write: - service: '@CleverAge\ProcessBundle\Task\File\JsonStream\JsonStreamWriterTask' + task: json_stream_writer options: file_path: '%kernel.project_dir%/var/data/json_stream_writer_{date_time}.json' json_flags: diff --git a/docs/reference/tasks/line_reader_task.md b/docs/reference/tasks/line_reader_task.md index 702690b8..a9bb8d69 100644 --- a/docs/reference/tasks/line_reader_task.md +++ b/docs/reference/tasks/line_reader_task.md @@ -7,6 +7,7 @@ Task reference -------------- * **Service**: `CleverAge\ProcessBundle\Task\File\LineReaderTask` +* **Code**: `line_reader` (`task: line_reader`) * **Iterable task** Accepted inputs @@ -36,12 +37,12 @@ Examples ```yaml # Task configuration level entry: - service: '@CleverAge\ProcessBundle\Task\File\LineReaderTask' + task: line_reader options: filename: '%kernel.project_dir%/var/data/sample.txt' outputs: [trim] trim: - service: '@CleverAge\ProcessBundle\Task\TransformerTask' + task: transformer options: transformers: trim: ~ diff --git a/docs/reference/tasks/logger_task.md b/docs/reference/tasks/logger_task.md index 814346b7..dcd1b38d 100644 --- a/docs/reference/tasks/logger_task.md +++ b/docs/reference/tasks/logger_task.md @@ -7,6 +7,7 @@ Task reference -------------- * **Service**: `CleverAge\ProcessBundle\Task\Reporting\LoggerTask` +* **Code**: `logger` (`task: logger`) Accepted inputs --------------- @@ -36,7 +37,7 @@ Examples ```yaml # Task configuration level log: - service: '@CleverAge\ProcessBundle\Task\Reporting\LoggerTask' + task: logger options: level: warning message: DEMO LOGGER @@ -48,7 +49,7 @@ log: ```yaml # Task configuration level log: - service: '@CleverAge\ProcessBundle\Task\Reporting\LoggerTask' + task: logger options: level: info message: Transformed diff --git a/docs/reference/tasks/normalizer_task.md b/docs/reference/tasks/normalizer_task.md index 988d8b6e..a07639dd 100644 --- a/docs/reference/tasks/normalizer_task.md +++ b/docs/reference/tasks/normalizer_task.md @@ -7,6 +7,7 @@ Task reference -------------- * **Service**: `CleverAge\ProcessBundle\Task\Serialization\NormalizerTask` +* **Code**: `normalizer` (`task: normalizer`) Accepted inputs --------------- @@ -35,7 +36,7 @@ Examples ```yaml # Task configuration level normalize: - service: '@CleverAge\ProcessBundle\Task\Serialization\NormalizerTask' + task: normalizer options: format: json context: diff --git a/docs/reference/tasks/object_updater_task.md b/docs/reference/tasks/object_updater_task.md index 537215af..b636c6cb 100644 --- a/docs/reference/tasks/object_updater_task.md +++ b/docs/reference/tasks/object_updater_task.md @@ -8,6 +8,7 @@ Task reference -------------- * **Service**: `CleverAge\ProcessBundle\Task\ObjectUpdaterTask` +* **Code**: `object_updater` (`task: object_updater`) Accepted inputs --------------- @@ -39,7 +40,7 @@ Examples ```yaml # Task configuration level update_object: - service: '@CleverAge\ProcessBundle\Task\ObjectUpdaterTask' + task: object_updater options: property_path: name outputs: [save] diff --git a/docs/reference/tasks/process_executor_task.md b/docs/reference/tasks/process_executor_task.md index a7a5517f..5cfdfc98 100644 --- a/docs/reference/tasks/process_executor_task.md +++ b/docs/reference/tasks/process_executor_task.md @@ -9,6 +9,7 @@ Task reference -------------- * **Service**: `CleverAge\ProcessBundle\Task\Process\ProcessExecutorTask` +* **Code**: `process_executor` (`task: process_executor`) Accepted inputs --------------- @@ -36,7 +37,7 @@ Examples ```yaml # Task configuration level run_subprocess: - service: '@CleverAge\ProcessBundle\Task\Process\ProcessExecutorTask' + task: process_executor options: process: app.import_product context: diff --git a/docs/reference/tasks/process_launcher_task.md b/docs/reference/tasks/process_launcher_task.md index cee6919b..228e0081 100644 --- a/docs/reference/tasks/process_launcher_task.md +++ b/docs/reference/tasks/process_launcher_task.md @@ -9,6 +9,7 @@ Task reference -------------- * **Service**: `CleverAge\ProcessBundle\Task\Process\ProcessLauncherTask` +* **Code**: `process_launcher` (`task: process_launcher`) * **Iterable task** * **Flushable task** @@ -51,7 +52,7 @@ Examples ```yaml # Task configuration level parallel_import: - service: '@CleverAge\ProcessBundle\Task\Process\ProcessLauncherTask' + task: process_launcher options: process: app.import_file max_processes: 5 diff --git a/docs/reference/tasks/property_getter_task.md b/docs/reference/tasks/property_getter_task.md index a24ca1b4..4d19387b 100644 --- a/docs/reference/tasks/property_getter_task.md +++ b/docs/reference/tasks/property_getter_task.md @@ -10,6 +10,7 @@ Task reference -------------- * **Service**: `CleverAge\ProcessBundle\Task\PropertyGetterTask` +* **Code**: `property_getter` (`task: property_getter`) Accepted inputs --------------- @@ -39,7 +40,7 @@ Examples ```yaml # Task configuration level get_file_path: - service: '@CleverAge\ProcessBundle\Task\PropertyGetterTask' + task: property_getter options: property: 'path' outputs: [remove_input] @@ -50,7 +51,7 @@ get_file_path: ```yaml # Task configuration level get_sku: - service: '@CleverAge\ProcessBundle\Task\PropertyGetterTask' + task: property_getter options: property: '[sku]' outputs: [next_task] diff --git a/docs/reference/tasks/property_setter_task.md b/docs/reference/tasks/property_setter_task.md index 1fcc7c83..31568bd4 100644 --- a/docs/reference/tasks/property_setter_task.md +++ b/docs/reference/tasks/property_setter_task.md @@ -10,6 +10,7 @@ Task reference -------------- * **Service**: `CleverAge\ProcessBundle\Task\PropertySetterTask` +* **Code**: `property_setter` (`task: property_setter`) Accepted inputs --------------- @@ -40,7 +41,7 @@ Examples ```yaml # Task configuration level modify: - service: '@CleverAge\ProcessBundle\Task\PropertySetterTask' + task: property_setter options: values: firstname: Gérard @@ -52,7 +53,7 @@ modify: ```yaml # Task configuration level set_defaults: - service: '@CleverAge\ProcessBundle\Task\PropertySetterTask' + task: property_setter options: values: '[status]': imported diff --git a/docs/reference/tasks/row_aggregator_task.md b/docs/reference/tasks/row_aggregator_task.md index ecd675b1..dc2071f6 100644 --- a/docs/reference/tasks/row_aggregator_task.md +++ b/docs/reference/tasks/row_aggregator_task.md @@ -9,6 +9,7 @@ Task reference -------------- * **Service**: `CleverAge\ProcessBundle\Task\RowAggregatorTask` +* **Code**: `row_aggregator` (`task: row_aggregator`) * **Blocking task** Accepted inputs @@ -39,7 +40,7 @@ Examples ```yaml # Task configuration level aggregate_rows: - service: '@CleverAge\ProcessBundle\Task\RowAggregatorTask' + task: row_aggregator options: aggregate_by: order_id aggregate_columns: [product, qty] diff --git a/docs/reference/tasks/serializer_task.md b/docs/reference/tasks/serializer_task.md index aa589256..7de1712f 100644 --- a/docs/reference/tasks/serializer_task.md +++ b/docs/reference/tasks/serializer_task.md @@ -7,6 +7,7 @@ Task reference -------------- * **Service**: `CleverAge\ProcessBundle\Task\Serialization\SerializerTask` +* **Code**: `serializer` (`task: serializer`) Accepted inputs --------------- @@ -34,7 +35,7 @@ Examples ```yaml # Task configuration level serialize: - service: '@CleverAge\ProcessBundle\Task\Serialization\SerializerTask' + task: serializer options: format: json context: diff --git a/docs/reference/tasks/simple_batch_task.md b/docs/reference/tasks/simple_batch_task.md index 4602a73b..f0677bdc 100644 --- a/docs/reference/tasks/simple_batch_task.md +++ b/docs/reference/tasks/simple_batch_task.md @@ -8,6 +8,7 @@ Task reference -------------- * **Service**: `CleverAge\ProcessBundle\Task\SimpleBatchTask` +* **Code**: `simple_batch` (`task: simple_batch`) * **Flushable task** Accepted inputs @@ -36,12 +37,12 @@ Examples ```yaml # Task configuration level data: - service: '@CleverAge\ProcessBundle\Task\ConstantIterableOutputTask' + task: constant_iterable_output options: output: [1, 2, 3] outputs: [batch] batch: - service: '@CleverAge\ProcessBundle\Task\SimpleBatchTask' + task: simple_batch options: batch_count: 2 outputs: [next_task] diff --git a/docs/reference/tasks/skip_empty_task.md b/docs/reference/tasks/skip_empty_task.md index 6003c3e2..95d11061 100644 --- a/docs/reference/tasks/skip_empty_task.md +++ b/docs/reference/tasks/skip_empty_task.md @@ -8,6 +8,7 @@ Task reference -------------- * **Service**: `CleverAge\ProcessBundle\Task\SkipEmptyTask` +* **Code**: `skip_empty` (`task: skip_empty`) Accepted inputs --------------- @@ -32,9 +33,9 @@ Examples ```yaml # Task configuration level merge: - service: '@CleverAge\ProcessBundle\Task\ArrayMergeTask' + task: array_merge outputs: [skip_if_empty] skip_if_empty: - service: '@CleverAge\ProcessBundle\Task\SkipEmptyTask' + task: skip_empty outputs: [next_task] ``` diff --git a/docs/reference/tasks/split_join_line_task.md b/docs/reference/tasks/split_join_line_task.md index 712c62cf..eebda605 100644 --- a/docs/reference/tasks/split_join_line_task.md +++ b/docs/reference/tasks/split_join_line_task.md @@ -8,6 +8,7 @@ Task reference -------------- * **Service**: `CleverAge\ProcessBundle\Task\SplitJoinLineTask` +* **Code**: `split_join_line` (`task: split_join_line`) * **Iterable task** Accepted inputs @@ -39,7 +40,7 @@ Examples ```yaml # Task configuration level split_line: - service: '@CleverAge\ProcessBundle\Task\SplitJoinLineTask' + task: split_join_line options: split_columns: [category, tag] join_column: value diff --git a/docs/reference/tasks/stat_counter_task.md b/docs/reference/tasks/stat_counter_task.md index 712deff0..70b002f3 100644 --- a/docs/reference/tasks/stat_counter_task.md +++ b/docs/reference/tasks/stat_counter_task.md @@ -8,6 +8,7 @@ Task reference -------------- * **Service**: `CleverAge\ProcessBundle\Task\Reporting\StatCounterTask` +* **Code**: `stat_counter` (`task: stat_counter`) Accepted inputs --------------- @@ -34,5 +35,5 @@ Examples ```yaml # Task configuration level count: - service: '@CleverAge\ProcessBundle\Task\Reporting\StatCounterTask' + task: stat_counter ``` diff --git a/docs/reference/tasks/stop_task.md b/docs/reference/tasks/stop_task.md index 1cb9bd5c..65ff7474 100644 --- a/docs/reference/tasks/stop_task.md +++ b/docs/reference/tasks/stop_task.md @@ -9,6 +9,7 @@ Task reference -------------- * **Service**: `CleverAge\ProcessBundle\Task\StopTask` +* **Code**: `stop` (`task: stop`) Accepted inputs --------------- @@ -33,9 +34,9 @@ Examples ```yaml # Task configuration level validate: - service: '@CleverAge\ProcessBundle\Task\Validation\ValidatorTask' + task: validator error_strategy: skip error_outputs: [abort] abort: - service: '@CleverAge\ProcessBundle\Task\StopTask' + task: stop ``` diff --git a/docs/reference/tasks/stopwatch_task.md b/docs/reference/tasks/stopwatch_task.md index 05728a2e..764ef9d3 100644 --- a/docs/reference/tasks/stopwatch_task.md +++ b/docs/reference/tasks/stopwatch_task.md @@ -8,6 +8,7 @@ Task reference -------------- * **Service**: `CleverAge\ProcessBundle\Task\Debug\StopwatchTask` +* **Code**: `stopwatch` (`task: stopwatch`) Accepted inputs --------------- @@ -32,5 +33,5 @@ Examples ```yaml # Task configuration level stopwatch: - service: '@CleverAge\ProcessBundle\Task\Debug\StopwatchTask' + task: stopwatch ``` diff --git a/docs/reference/tasks/transformer_task.md b/docs/reference/tasks/transformer_task.md index 5f9f1721..199d5f06 100644 --- a/docs/reference/tasks/transformer_task.md +++ b/docs/reference/tasks/transformer_task.md @@ -8,6 +8,7 @@ Task reference -------------- * **Service**: `CleverAge\ProcessBundle\Task\TransformerTask` +* **Code**: `transformer` (`task: transformer`) Accepted inputs --------------- @@ -37,7 +38,7 @@ Examples ```yaml # Task configuration level json_decode: - service: '@CleverAge\ProcessBundle\Task\TransformerTask' + task: transformer options: transformers: callback: @@ -51,7 +52,7 @@ json_decode: ```yaml # Task configuration level transform: - service: '@CleverAge\ProcessBundle\Task\TransformerTask' + task: transformer options: transformers: mapping: @@ -72,7 +73,7 @@ transform: ```yaml # Task configuration level transform: - service: '@CleverAge\ProcessBundle\Task\TransformerTask' + task: transformer options: transformers: - mapping: diff --git a/docs/reference/tasks/validator_task.md b/docs/reference/tasks/validator_task.md index c3a43a1a..edc537dd 100644 --- a/docs/reference/tasks/validator_task.md +++ b/docs/reference/tasks/validator_task.md @@ -7,6 +7,7 @@ Task reference -------------- * **Service**: `CleverAge\ProcessBundle\Task\Validation\ValidatorTask` +* **Code**: `validator` (`task: validator`) Accepted inputs --------------- @@ -48,7 +49,7 @@ Examples ```yaml # Task configuration level validate: - service: '@CleverAge\ProcessBundle\Task\Validation\ValidatorTask' + task: validator options: groups: [import] outputs: [save] @@ -59,7 +60,7 @@ validate: ```yaml # Task configuration level validate: - service: '@CleverAge\ProcessBundle\Task\Validation\ValidatorTask' + task: validator options: log_errors: warning error_output_violations: true diff --git a/docs/reference/tasks/xml_reader_task.md b/docs/reference/tasks/xml_reader_task.md index 0537296e..ce1324c1 100644 --- a/docs/reference/tasks/xml_reader_task.md +++ b/docs/reference/tasks/xml_reader_task.md @@ -8,6 +8,7 @@ Task reference -------------- * **Service**: `CleverAge\ProcessBundle\Task\File\Xml\XmlReaderTask` +* **Code**: `xml_reader` (`task: xml_reader`) Accepted inputs --------------- @@ -34,7 +35,7 @@ Examples ```yaml # Task configuration level read_xml: - service: '@CleverAge\ProcessBundle\Task\File\Xml\XmlReaderTask' + task: xml_reader options: file_path: '%kernel.project_dir%/var/data/file.xml' outputs: [transform] diff --git a/docs/reference/tasks/xml_stream_reader_task.md b/docs/reference/tasks/xml_stream_reader_task.md index f818ee28..810eef1b 100644 --- a/docs/reference/tasks/xml_stream_reader_task.md +++ b/docs/reference/tasks/xml_stream_reader_task.md @@ -11,6 +11,7 @@ Task reference -------------- * **Service**: `CleverAge\ProcessBundle\Task\File\Xml\XmlStreamReaderTask` +* **Code**: `xml_stream_reader` (`task: xml_stream_reader`) * **Iterable task** Accepted inputs @@ -42,13 +43,13 @@ Examples ```yaml # Task configuration level read: - service: '@CleverAge\ProcessBundle\Task\File\Xml\XmlStreamReaderTask' + task: xml_stream_reader options: file_path: '%kernel.project_dir%/var/data/products.xml' node_name: product outputs: [transform] transform: - service: '@CleverAge\ProcessBundle\Task\TransformerTask' + task: transformer options: transformers: xpath_evaluator: diff --git a/docs/reference/tasks/xml_writer_task.md b/docs/reference/tasks/xml_writer_task.md index 8064ed57..9da713a2 100644 --- a/docs/reference/tasks/xml_writer_task.md +++ b/docs/reference/tasks/xml_writer_task.md @@ -8,6 +8,7 @@ Task reference -------------- * **Service**: `CleverAge\ProcessBundle\Task\File\Xml\XmlWriterTask` +* **Code**: `xml_writer` (`task: xml_writer`) Accepted inputs --------------- @@ -34,7 +35,7 @@ Examples ```yaml # Task configuration level write_xml: - service: '@CleverAge\ProcessBundle\Task\File\Xml\XmlWriterTask' + task: xml_writer options: file_path: '%kernel.project_dir%/var/data/file.xml' ``` diff --git a/docs/reference/tasks/yaml_reader_task.md b/docs/reference/tasks/yaml_reader_task.md index c08f4e21..56bd85a8 100644 --- a/docs/reference/tasks/yaml_reader_task.md +++ b/docs/reference/tasks/yaml_reader_task.md @@ -7,6 +7,7 @@ Task reference -------------- * **Service**: `CleverAge\ProcessBundle\Task\File\Yaml\YamlReaderTask` +* **Code**: `yaml_reader` (`task: yaml_reader`) * **Iterable task** Accepted inputs @@ -33,7 +34,7 @@ Examples ```yaml # Task configuration level read_yaml: - service: '@CleverAge\ProcessBundle\Task\File\Yaml\YamlReaderTask' + task: yaml_reader options: file_path: '%kernel.project_dir%/var/data/data.yaml' outputs: [process_item] diff --git a/docs/reference/tasks/yaml_writer_task.md b/docs/reference/tasks/yaml_writer_task.md index c3e6f122..9b0a3c38 100644 --- a/docs/reference/tasks/yaml_writer_task.md +++ b/docs/reference/tasks/yaml_writer_task.md @@ -7,6 +7,7 @@ Task reference -------------- * **Service**: `CleverAge\ProcessBundle\Task\File\Yaml\YamlWriterTask` +* **Code**: `yaml_writer` (`task: yaml_writer`) Accepted inputs --------------- @@ -32,7 +33,7 @@ Examples ```yaml # Task configuration level write_yaml: - service: '@CleverAge\ProcessBundle\Task\File\Yaml\YamlWriterTask' + task: yaml_writer options: file_path: '%kernel.project_dir%/var/data/export.yaml' inline: 3 diff --git a/src/Attribute/AsTask.php b/src/Attribute/AsTask.php new file mode 100644 index 00000000..bd0ad219 --- /dev/null +++ b/src/Attribute/AsTask.php @@ -0,0 +1,30 @@ +`) + * instead of its service id or class name (`service: '@'`). + * + * Requires autoconfiguration; equivalent to a `cleverage.task` tag with a `code` attribute. The code is unique: two task + * services with the same code fail the container compilation (use a prefix for the application tasks). + */ +#[\Attribute(\Attribute::TARGET_CLASS)] +final readonly class AsTask +{ + public function __construct( + public string $code, + ) { + } +} diff --git a/src/DependencyInjection/CleverAgeProcessExtension.php b/src/DependencyInjection/CleverAgeProcessExtension.php index c51b6c31..4045cfbc 100644 --- a/src/DependencyInjection/CleverAgeProcessExtension.php +++ b/src/DependencyInjection/CleverAgeProcessExtension.php @@ -13,6 +13,7 @@ namespace CleverAge\ProcessBundle\DependencyInjection; +use CleverAge\ProcessBundle\Attribute\AsTask; use CleverAge\ProcessBundle\Attribute\AsTransformer; use CleverAge\ProcessBundle\Model\ProcessStopCheckerInterface; use CleverAge\ProcessBundle\Model\TaskInterface; @@ -48,6 +49,13 @@ public function load(array $configs, ContainerBuilder $container): void $container->registerForAutoconfiguration(TransformerInterface::class) ->addTag('cleverage.transformer') ->addTag('monolog.logger', ['channel' => 'cleverage_process_transformer']); + // Tasks referenced by code (task: ) + $container->registerAttributeForAutoconfiguration( + AsTask::class, + static function (ChildDefinition $definition, AsTask $attribute): void { + $definition->addTag('cleverage.task', ['code' => $attribute->code]); + } + ); // Lazy loading of the transformers by code $container->registerAttributeForAutoconfiguration( AsTransformer::class, diff --git a/src/DependencyInjection/Compiler/TaskLocatorCompilerPass.php b/src/DependencyInjection/Compiler/TaskLocatorCompilerPass.php index 0e8cef9b..aa8fa2ab 100644 --- a/src/DependencyInjection/Compiler/TaskLocatorCompilerPass.php +++ b/src/DependencyInjection/Compiler/TaskLocatorCompilerPass.php @@ -16,11 +16,13 @@ use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; use Symfony\Component\DependencyInjection\Compiler\ServiceLocatorTagPass; use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException; use Symfony\Component\DependencyInjection\Reference; /** * Builds the service locator of the task registry from the services referenced by the process configurations, so - * that the tasks are not fetched from the whole service container. + * that the tasks are not fetched from the whole service container. The `task` codes of the configurations are first + * resolved into the service with this code (`cleverage.task` tag, `#[AsTask]`). * * @internal */ @@ -32,10 +34,13 @@ public function process(ContainerBuilder $container): void || !$container->hasDefinition('cleverage_process.registry.process_configuration')) { return; } - - $configurations = $container->getParameterBag()->resolveValue( - $container->getDefinition('cleverage_process.registry.process_configuration')->getArgument(0) + $processConfigurationRegistry = $container->getDefinition('cleverage_process.registry.process_configuration'); + $processConfigurationRegistry->replaceArgument( + 0, + $this->resolveTaskCodes($container, $processConfigurationRegistry->getArgument(0)) ); + + $configurations = $container->getParameterBag()->resolveValue($processConfigurationRegistry->getArgument(0)); $services = []; foreach (\is_array($configurations) ? $configurations : [] as $configuration) { foreach ($configuration['tasks'] ?? [] as $task) { @@ -50,4 +55,55 @@ public function process(ContainerBuilder $container): void $container->getDefinition('cleverage_process.registry.task') ->replaceArgument(0, ServiceLocatorTagPass::register($container, $services)); } + + /** + * Sets the "service" of the tasks configured with a "task" code. The configurations are not resolved (parameters), + * only the "service" key is set. + */ + private function resolveTaskCodes(ContainerBuilder $container, mixed $configurations): mixed + { + if (!\is_array($configurations)) { + return $configurations; + } + $codes = null; + foreach ($configurations as $processCode => $configuration) { + foreach ($configuration['tasks'] ?? [] as $taskCode => $task) { + if (null === ($task['task'] ?? null)) { + continue; + } + $codes ??= $this->getTaskCodes($container); + $code = $container->getParameterBag()->resolveValue($task['task']); + if (!\is_string($code) || !isset($codes[$code])) { + $known = array_keys($codes); + sort($known); + throw new InvalidArgumentException(\sprintf('Unknown task code "%s" for the task "%s" of the process "%s". Known codes: "%s".', \is_string($code) ? $code : get_debug_type($code), $taskCode, $processCode, implode('", "', $known))); + } + $configurations[$processCode]['tasks'][$taskCode]['service'] = '@'.$codes[$code]; + } + } + + return $configurations; + } + + /** + * @return array service id by task code + */ + private function getTaskCodes(ContainerBuilder $container): array + { + $codes = []; + foreach ($container->findTaggedServiceIds('cleverage.task') as $id => $tags) { + foreach ($tags as $attributes) { + $code = $attributes['code'] ?? null; + if (!\is_string($code) || '' === $code) { + throw new InvalidArgumentException(\sprintf('The "code" attribute of the "cleverage.task" tag of the "%s" service must be a non-empty string.', $id)); + } + if (isset($codes[$code]) && $codes[$code] !== $id) { + throw new InvalidArgumentException(\sprintf('The task code "%s" is used by the "%s" and "%s" services.', $code, $codes[$code], $id)); + } + $codes[$code] = $id; + } + } + + return $codes; + } } diff --git a/src/DependencyInjection/Compiler/UnavailableServicesCompilerPass.php b/src/DependencyInjection/Compiler/UnavailableServicesCompilerPass.php index b3162e22..dbb9f0ec 100644 --- a/src/DependencyInjection/Compiler/UnavailableServicesCompilerPass.php +++ b/src/DependencyInjection/Compiler/UnavailableServicesCompilerPass.php @@ -60,7 +60,7 @@ public function process(ContainerBuilder $container): void } /** - * @param list $classes the services are registered with an alias named after their class + * @param list $classes the services are registered with their class name as id (or an alias) */ private function replace(ContainerBuilder $container, string $message, array $classes): void { diff --git a/src/DependencyInjection/Configuration.php b/src/DependencyInjection/Configuration.php index f347ff63..9fcd0f38 100644 --- a/src/DependencyInjection/Configuration.php +++ b/src/DependencyInjection/Configuration.php @@ -172,6 +172,10 @@ protected function appendProcessConfigDefinition(NodeBuilder $definition): void ->performNoDeepMerging() ->cannotBeOverwritten() ->info('Unique custom task code') + ->validate() + ->ifTrue(static fn (array $task): bool => (null === $task['service']) === (null === $task['task'])) + ->thenInvalid('A task must define either its code ("task: ") or, deprecated, its "service", not both: %s') + ->end() ->children(); $this->appendTaskConfigDefinition($taskListDefinition); @@ -180,7 +184,16 @@ protected function appendProcessConfigDefinition(NodeBuilder $definition): void protected function appendTaskConfigDefinition(NodeBuilder $definition): void { $definition->scalarNode('service') - ->isRequired(); + ->info('Deprecated, use "task": service id or alias of the task, with or without a leading "@"') + ->setDeprecated( + 'cleverage/process-bundle', + '5.4', + 'The "%node%" option of the task "%path%" is deprecated, reference the task by its code instead ("task: ", given on the reference page of each task; give a code to your own tasks with #[AsTask] or a "cleverage.task" tag). It will be removed in v6.0.' + ) + ->defaultNull(); + $definition->scalarNode('task') + ->info('Code of the task (cleverage.task tag, #[AsTask])') + ->defaultNull(); $definition->scalarNode('description') ->defaultValue(''); $definition->scalarNode('help') diff --git a/src/Registry/ProcessConfigurationRegistry.php b/src/Registry/ProcessConfigurationRegistry.php index d860b802..1e057aba 100644 --- a/src/Registry/ProcessConfigurationRegistry.php +++ b/src/Registry/ProcessConfigurationRegistry.php @@ -86,6 +86,10 @@ protected function resolveConfiguration(string $processCode): void } $rawTaskConfiguration['error_outputs'] = $rawTaskConfiguration['errors']; } + if (!\is_string($rawTaskConfiguration['service'] ?? null)) { + // The "task" codes are resolved into services when the container is compiled (TaskLocatorCompilerPass) + throw new \LogicException("The task {$taskCode} of the process {$processCode} has no service: a \"task\" code can only be used in the configurations known when the container is compiled"); + } $taskConfigurations[$taskCode] = new TaskConfiguration( $taskCode, $rawTaskConfiguration['service'], diff --git a/tests/DependencyInjection/CleverAgeProcessExtensionTest.php b/tests/DependencyInjection/CleverAgeProcessExtensionTest.php index 135958a4..fce0c464 100644 --- a/tests/DependencyInjection/CleverAgeProcessExtensionTest.php +++ b/tests/DependencyInjection/CleverAgeProcessExtensionTest.php @@ -13,6 +13,7 @@ namespace CleverAge\ProcessBundle\Tests\DependencyInjection; +use CleverAge\ProcessBundle\Attribute\AsTask; use CleverAge\ProcessBundle\Attribute\AsTransformer; use CleverAge\ProcessBundle\Context\ContextualOptionResolver; use CleverAge\ProcessBundle\DependencyInjection\CleverAgeProcessExtension; @@ -22,6 +23,7 @@ use CleverAge\ProcessBundle\Registry\ProcessConfigurationRegistry; use CleverAge\ProcessBundle\Registry\TransformerRegistry; use CleverAge\ProcessBundle\Task\DummyTask; +use CleverAge\ProcessBundle\Tests\Fixtures\AttributedTask; use CleverAge\ProcessBundle\Tests\Fixtures\AttributedTransformer; use CleverAge\ProcessBundle\Transformer\String\TrimTransformer; use CleverAge\ProcessBundle\Transformer\TransformerInterface; @@ -40,6 +42,7 @@ #[CoversClass(CleverAgeProcessExtension::class)] #[UsesClass(Configuration::class)] #[UsesClass(AsTransformer::class)] +#[UsesClass(AsTask::class)] class CleverAgeProcessExtensionTest extends TestCase { public function testEveryServiceDefinitionFileIsLoaded(): void @@ -123,6 +126,33 @@ public function testTasksAndTransformersAreAutoconfigured(): void self::assertSame([['code' => 'trim']], $container->findDefinition(TrimTransformer::class)->getTag('cleverage.transformer')); } + public function testEveryBundleTaskHasAUniqueCode(): void + { + $container = new ContainerBuilder(); + (new CleverAgeProcessExtension())->load([], $container); + + $tagged = $container->findTaggedServiceIds('cleverage.task'); + self::assertCount(58, $tagged); + foreach ($tagged as $id => $tags) { + // The id is the class name, the code its snake case without the "Task" suffix + $code = strtolower((string) preg_replace('/(? $code]], $tags, $id); + } + } + + public function testAsTaskAttributeRegistersTheCode(): void + { + $container = new ContainerBuilder(); + (new CleverAgeProcessExtension())->load([], $container); + $container->setDefinition('app.attributed_task', (new Definition(AttributedTask::class))->setAutoconfigured(true)); + + (new AttributeAutoconfigurationPass())->process($container); + (new ResolveInstanceofConditionalsPass())->process($container); + (new ResolveChildDefinitionsPass())->process($container); + + self::assertSame([['code' => 'app_attributed']], $container->getDefinition('app.attributed_task')->getTag('cleverage.task')); + } + public function testAsTransformerAttributeRegistersTheCode(): void { $container = new ContainerBuilder(); diff --git a/tests/DependencyInjection/Compiler/TaskLocatorCompilerPassTest.php b/tests/DependencyInjection/Compiler/TaskLocatorCompilerPassTest.php index 3c4b9267..431ab3c3 100644 --- a/tests/DependencyInjection/Compiler/TaskLocatorCompilerPassTest.php +++ b/tests/DependencyInjection/Compiler/TaskLocatorCompilerPassTest.php @@ -23,6 +23,7 @@ use Symfony\Component\DependencyInjection\Argument\ServiceClosureArgument; use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\DependencyInjection\Definition; +use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException; use Symfony\Component\DependencyInjection\Reference; use Symfony\Component\DependencyInjection\ServiceLocator; @@ -65,6 +66,70 @@ public function testLocatorContainsTheServicesReferencedByTheProcesses(): void } } + public function testTaskCodesAreResolvedIntoServices(): void + { + $container = new ContainerBuilder(); + (new CleverAgeProcessExtension())->load([[ + 'configurations' => [ + 'test.codes' => ['tasks' => [ + 'bundle' => ['task' => 'dummy', 'options' => ['format' => '%%s']], + 'application' => ['task' => 'app_task'], + ]], + ], + ]], $container); + $container->setDefinition('app.task', (new Definition(DummyTask::class))->addTag('cleverage.task', ['code' => 'app_task'])); + + (new TaskLocatorCompilerPass())->process($container); + + $configurations = $container->getDefinition('cleverage_process.registry.process_configuration')->getArgument(0); + self::assertIsArray($configurations); + $tasks = $configurations['test.codes']['tasks']; + self::assertSame('@'.DummyTask::class, $tasks['bundle']['service']); + self::assertSame('@app.task', $tasks['application']['service']); + // Only the service is set: the parameters of the configuration are not resolved (escaped %) + self::assertSame(['format' => '%%s'], $tasks['bundle']['options']); + + $locatorReference = $container->getDefinition('cleverage_process.registry.task')->getArgument(0); + self::assertInstanceOf(Reference::class, $locatorReference); + $services = $container->getDefinition((string) $locatorReference)->getArgument(0); + self::assertIsArray($services); + self::assertSame([DummyTask::class, 'app.task'], array_keys($services)); + } + + public function testUnknownTaskCodeThrows(): void + { + $container = $this->createContainerWithTask(['task' => 'unknown']); + $container->setDefinition('app.task', (new Definition(DummyTask::class))->addTag('cleverage.task', ['code' => 'app_task'])); + + $this->expectException(InvalidArgumentException::class); + $this->expectExceptionMessage('Unknown task code "unknown" for the task "my_task" of the process "test.process". Known codes: "app_task".'); + + (new TaskLocatorCompilerPass())->process($container); + } + + public function testDuplicateTaskCodeThrows(): void + { + $container = $this->createContainerWithTask(['task' => 'same']); + $container->setDefinition('app.first', (new Definition(DummyTask::class))->addTag('cleverage.task', ['code' => 'same'])); + $container->setDefinition('app.second', (new Definition(DummyTask::class))->addTag('cleverage.task', ['code' => 'same'])); + + $this->expectException(InvalidArgumentException::class); + $this->expectExceptionMessage('The task code "same" is used by the "app.first" and "app.second" services.'); + + (new TaskLocatorCompilerPass())->process($container); + } + + public function testInvalidTaskCodeAttributeThrows(): void + { + $container = $this->createContainerWithTask(['task' => 'app_task']); + $container->setDefinition('app.task', (new Definition(DummyTask::class))->addTag('cleverage.task')); + + $this->expectException(InvalidArgumentException::class); + $this->expectExceptionMessage('The "code" attribute of the "cleverage.task" tag of the "app.task" service must be a non-empty string.'); + + (new TaskLocatorCompilerPass())->process($container); + } + public function testNothingIsDoneWithoutTheRegistries(): void { $container = new ContainerBuilder(); @@ -73,4 +138,19 @@ public function testNothingIsDoneWithoutTheRegistries(): void self::assertFalse($container->hasDefinition('cleverage_process.registry.task')); } + + /** + * @param array $task + */ + private function createContainerWithTask(array $task): ContainerBuilder + { + $container = new ContainerBuilder(); + (new CleverAgeProcessExtension())->load([['configurations' => ['test.process' => ['tasks' => ['my_task' => $task]]]]], $container); + // Only the tasks of the test + foreach (array_keys($container->findTaggedServiceIds('cleverage.task')) as $id) { + $container->getDefinition($id)->clearTag('cleverage.task'); + } + + return $container; + } } diff --git a/tests/DependencyInjection/Compiler/UnavailableServicesCompilerPassTest.php b/tests/DependencyInjection/Compiler/UnavailableServicesCompilerPassTest.php index 137bf0d7..466cbdb0 100644 --- a/tests/DependencyInjection/Compiler/UnavailableServicesCompilerPassTest.php +++ b/tests/DependencyInjection/Compiler/UnavailableServicesCompilerPassTest.php @@ -28,6 +28,7 @@ use PHPUnit\Framework\Attributes\CoversClass; use PHPUnit\Framework\Attributes\UsesClass; use PHPUnit\Framework\TestCase; +use Symfony\Component\DependencyInjection\Compiler\ResolveClassPass; use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\DependencyInjection\Definition; @@ -57,8 +58,8 @@ public function testSerializerServicesAreReplacedWithoutSerializer(): void $definition = $container->findDefinition($id); self::assertSame(UnavailableTask::class, $definition->getClass(), $id); self::assertSame([\sprintf(UnavailableServicesCompilerPass::SERIALIZER_MESSAGE, $id)], $definition->getArguments()); - // Still referenced by the alias named after the class, and logged in the tasks channel - self::assertTrue($container->getAlias($id)->isPublic()); + // Still public (deprecated fallback on the service container), and logged in the tasks channel + self::assertTrue($definition->isPublic()); self::assertFalse($definition->isShared()); self::assertSame([['channel' => 'cleverage_process_task']], $definition->getTag('monolog.logger')); } @@ -92,7 +93,7 @@ public function testValidatorTaskIsReplacedWithoutValidator(): void $definition = $container->findDefinition(ValidatorTask::class); self::assertSame(UnavailableTask::class, $definition->getClass()); self::assertSame([\sprintf(UnavailableServicesCompilerPass::VALIDATOR_MESSAGE, ValidatorTask::class)], $definition->getArguments()); - self::assertTrue($container->getAlias(ValidatorTask::class)->isPublic()); + self::assertTrue($definition->isPublic()); self::assertFalse($definition->isShared()); self::assertSame(NormalizerTask::class, $container->findDefinition(NormalizerTask::class)->getClass()); } @@ -101,6 +102,8 @@ private function createContainer(bool $serializer, bool $validator): ContainerBu { $container = new ContainerBuilder(); (new CleverAgeProcessExtension())->load([], $container); + // The class of the services whose id is the class name, as when the container is compiled + (new ResolveClassPass())->process($container); if ($serializer) { $container->setDefinition('serializer', new Definition(\stdClass::class)); } diff --git a/tests/DependencyInjection/ConfigurationTest.php b/tests/DependencyInjection/ConfigurationTest.php index 41d0af4a..8d3ead2b 100644 --- a/tests/DependencyInjection/ConfigurationTest.php +++ b/tests/DependencyInjection/ConfigurationTest.php @@ -54,6 +54,62 @@ public function testLogLevelsCanBeConfigured(): void ); } + public function testTaskIsDefinedByAServiceOrACode(): void + { + $config = $this->process(['configurations' => ['test.process' => ['tasks' => [ + 'by_service' => ['service' => '@app.task'], + 'by_code' => ['task' => 'transformer'], + ]]]]); + + $tasks = $config['configurations']['test.process']['tasks']; + self::assertSame(['@app.task', null], [$tasks['by_service']['service'], $tasks['by_service']['task']]); + self::assertSame([null, 'transformer'], [$tasks['by_code']['service'], $tasks['by_code']['task']]); + } + + public function testServiceIsDeprecated(): void + { + $deprecations = []; + set_error_handler(static function (int $errno, string $errstr) use (&$deprecations): bool { + $deprecations[] = $errstr; + + return true; + }, \E_USER_DEPRECATED); + try { + $this->process(['configurations' => ['test.process' => ['tasks' => [ + 'by_service' => ['service' => '@app.task'], + 'by_code' => ['task' => 'transformer'], + ]]]]); + } finally { + restore_error_handler(); + } + + self::assertSame( + ['Since cleverage/process-bundle 5.4: The "service" option of the task "clever_age_process.configurations.test.process.tasks.by_service" is deprecated, reference the task by its code instead ("task: ", given on the reference page of each task; give a code to your own tasks with #[AsTask] or a "cleverage.task" tag). It will be removed in v6.0.'], + $deprecations + ); + } + + /** + * @return iterable}> + */ + public static function provideInvalidTaskDefinitions(): iterable + { + yield 'neither service nor task' => [['options' => []]]; + yield 'both service and task' => [['service' => '@app.task', 'task' => 'transformer']]; + } + + /** + * @param array $task + */ + #[\PHPUnit\Framework\Attributes\DataProvider('provideInvalidTaskDefinitions')] + public function testTaskMustDefineEitherAServiceOrACode(array $task): void + { + $this->expectException(InvalidConfigurationException::class); + $this->expectExceptionMessage('A task must define either its code ("task: ") or, deprecated, its "service", not both'); + + $this->process(['configurations' => ['test.process' => ['tasks' => ['invalid' => $task]]]]); + } + public function testInvalidDefaultLogLevelIsRejected(): void { $this->expectException(InvalidConfigurationException::class); diff --git a/tests/DependencyInjection/TransformerCodesTest.php b/tests/DependencyInjection/TransformerCodesTest.php index 4496deae..2e88d6ed 100644 --- a/tests/DependencyInjection/TransformerCodesTest.php +++ b/tests/DependencyInjection/TransformerCodesTest.php @@ -18,6 +18,7 @@ use CleverAge\ProcessBundle\Transformer\TransformerInterface; use PHPUnit\Framework\Attributes\CoversNothing; use PHPUnit\Framework\TestCase; +use Symfony\Component\DependencyInjection\Compiler\ResolveClassPass; use Symfony\Component\DependencyInjection\ContainerBuilder; /** @@ -33,6 +34,8 @@ public function testEveryTransformerIsRegisteredWithItsCode(): void (new CleverAgeProcessExtension())->load([[ 'generic_transformers' => ['app_generic' => ['transformers' => ['trim' => []]]], ]], $container); + // The class of the services whose id is the class name, as when the container is compiled + (new ResolveClassPass())->process($container); $tagged = $container->findTaggedServiceIds('cleverage.transformer'); self::assertCount(38, $tagged); diff --git a/tests/Fixtures/AttributedTask.php b/tests/Fixtures/AttributedTask.php new file mode 100644 index 00000000..dcedce82 --- /dev/null +++ b/tests/Fixtures/AttributedTask.php @@ -0,0 +1,26 @@ + [ + 'options' => [], + 'entry_point' => null, + 'end_point' => null, + 'description' => '', + 'help' => '', + 'public' => true, + 'tasks' => [ + 'my_task' => ['service' => null, 'task' => 'transformer', 'errors' => [], 'error_outputs' => []], + ], + ], + ], 'stop'); + + $this->expectException(\LogicException::class); + $this->expectExceptionMessage('The task my_task of the process test.process has no service: a "task" code can only be used in the configurations known when the container is compiled'); + + $registry->getProcessConfiguration('test.process'); + } +}