Coordinate execution of one-time commands
This library can be used to enqueue arbitrary commands that need to be executed on all stages, this includes:
- database migrations
- data fixtures / transformations
- one-time bug fixes
- ...
Install via composer:
composer require wwwision/command-jobsand run pending command jobs via
vendor/bin/command-jobs runUpon first run, the CLI will create a config.yaml file in the root folder with the following contents:
commandResults:
storage: filesystem
options:
path: /some/path/to/commandResults.yamlNote
All configuration options allow to refer to environment variables in the form %env(SOME_VARIABLE)%
To store command results in a MySQL/MariaDB database, the following configuration can be used:
commandResults:
storage: database
options:
dsn: '%env(DATABASE_URL)%'
tableName: command_jobs_resultsNote
If the database storage is configured, the doctrine/dbal package has to be installed
By default, the run command will create a command-jobs folder in the current directory, that contains YAML files for Command Definitions, Command Jobs, Command Results and a .gitignore file that excludes Command Results from being added to VCS.
The --root option allows to specify a different root directory for those three files:
vendor/bin/command-jobs run --root=/some/other/folderCommands that fail or return an exit code other than 0 lead to an error (and the run command to exit with an error code as well). By default, remaining pending Command Jobs will still be executed.
It might make sense to stop processing of those jobs entirely in this case:
vendor/bin/command-jobs run --stop-on-errorThe run command supports default options that control verbosity and styling of the output:
Usage:
vendor/bin/command-jobs run [options]
Options:
-r, --root=ROOT Root directory
--stop-on-error Intercept execution upon errors
-h, --help Display help for the given command. When no command is given display help for the list command
--silent Do not output any message
-q, --quiet Only errors are displayed. All other output is suppressed
-V, --version Display this application version
--ansi|--no-ansi Force (or disable --no-ansi) ANSI output
-n, --no-interaction Do not ask any interactive question
-v|vv|vvv, --verbose Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug
In order for commands to be enqueued/executed, they have to be explicitly defined. This prevents invalid or potentially dangerous commands to be executed automatically. Furthermore, it allows commands to have a description and to be reused. A Command Definition consists of:
id– a unique string, that identifies it. It might make sense to use dots for namespaces to group definitions (e.g."db.migrate.products-initial")description– a string, that explains the intention of a command (e.g."Creates required product tables – this command is idempotent")cmd– the actual command to execute. This is represented as an array that consists of an element for the command itself and one for each argument (e.g.["some-command", "arg1", "\"arg2 with spaces\""])
The add-definition CLI command can be used to add Command Definitions:
Usage:
vendor/bin/command-jobs add-definition [options] [--] [<id> [<description> [<cmd>...]]]
Arguments:
id ID of the command definition
description Description of the command definition
cmd The command to execute (command and arguments, separated by spaces)
Options:
-r, --root=ROOT Root directory
--timeout=TIMEOUT Timeout (in seconds) for the command to run
-h, --help Display help for the given command. When no command is given display help for the list command
--silent Do not output any message
-q, --quiet Only errors are displayed. All other output is suppressed
-V, --version Display this application version
--ansi|--no-ansi Force (or disable --no-ansi) ANSI output
-n, --no-interaction Do not ask any interactive question
-v|vv|vvv, --verbose Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug
To enqueue commands, a corresponding Command Job has to be added. Each Command Job is executed once (unless if fails) when vendor/bin/command-jobs run is invoked.
A Command Job consists of:
id– a unique string, that identifies it. This is the timestamp at the time of creation in the formatYmdHis(e.g.20250925151814)commandDefinitionId– the id of an existing Command Definition
The add-job CLI command can be used to add Command Jobs:
Usage:
vendor/bin/command-jobs add-job [options] [--] [<definition>]
Arguments:
definition ID of the command definition
Options:
-r, --root=ROOT Root directory
-h, --help Display help for the given command. When no command is given display help for the list command
--silent Do not output any message
-q, --quiet Only errors are displayed. All other output is suppressed
-V, --version Display this application version
--ansi|--no-ansi Force (or disable --no-ansi) ANSI output
-n, --no-interaction Do not ask any interactive question
-v|vv|vvv, --verbose Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug
The result of any execution of a Command Jobs is stored as a Command Result.
By default, the results are stored in a commandResults.yaml file.
Important
The commandResults.yaml file is specific to a single installation, it must not be added to the VCS
It is therefore excluded via .gitignore file by default
A Command Result consists of:
commandJobId– the id of the Command Jobs that was executedcommandDefinitionId– the id of the corresponding Command DefinitionexecutionTime– date and time of the executionexecutionDurationInMilliseconds– execution runtime in millisecondssuccess– a boolean flag that istrueif the exit code of the command was0and otherwisefalseoutput- the string output of the command – or the exception message if it failed
Contributions in the form of issues or pull requests are highly appreciated
See LICENSE