The Batch system uses a flexible Action pattern that allows different types of commands and operations to be executed in sequence. Each action type implements a common interface and can be mixed within a single batch.
Action Interface
All action types implement EFrane\ConsoleAdditions\Batch\Action:
interface Action {
public function getName(): string;
public function setOutput(OutputInterface $output): void;
public function execute(Style\SymfonyStyle $io): int;
}
Available Action Types
StringCommandAction
The simplest action type — represents a command by its name as a string.
use EFrane\ConsoleAdditions\Batch\StringCommandAction;
$action = new StringCommandAction('cache:clear');
$batch->addAction($action);
// Or simply use the shorthand:
$batch->add('cache:clear'); // Creates StringCommandAction internally
Use when: You have a command name and want to execute it with its default behavior.
InstanceCommandAction
Wraps an actual Symfony Command instance for direct execution.
use EFrane\ConsoleAdditions\Batch\InstanceCommandAction;
$command = $application->find('my:command');
$action = new InstanceCommandAction($command, ['--option' => 'value']);
$batch->addAction($action);
// Or use the shorthand:
$batch->addCommand($command, ['--option' => 'value']);
Use when: You need to pass a Command instance directly, or configure the command before adding it to the batch.
ShellAction
Executes a shell command. Requires symfony/process package.
use EFrane\ConsoleAdditions\Batch\ShellAction;
$action = new ShellAction('ls -la');
$batch->addAction($action);
// Or use the shorthand:
$batch->addShell('ls -la');
Constructor:
ShellAction::__construct(
string $command,
?Closure $callback = null,
?Style\SymfonyStyle $io = null
)
Use when: You need to run system-level commands as part of your batch.
ProcessAction
A lower-level action that wraps a Symfony Process. Requires symfony/process package.
This gives you full control over the process configuration.
use EFrane\ConsoleAdditions\Batch\ProcessAction;
use Symfony\Component\Process\Process;
$process = new Process(['git', 'pull']);
$process->setTimeout(300);
$process->setWorkingDirectory('/path/to/repo');
$action = new ProcessAction($process);
$batch->addAction($action);
Use when: You need fine-grained control over process execution (timeout, working directory, environment variables, TTY, etc.).
MessageAction
Outputs a message without executing any command. Useful for adding informative text between commands.
use EFrane\ConsoleAdditions\Batch\MessageAction;
$action = new MessageAction('Running migrations...');
$batch->addAction($action);
// Or use the shorthand:
$batch->addMessage('Running migrations...');
Constructor:
MessageAction::__construct(
string $message,
string $type = 'info' // 'info', 'comment', 'question', 'success', 'warning', 'error'
)
Example with different message types:
$batch
->addMessage('Starting deployment', 'info')
->add('deploy:prepare')
->addMessage('Clearing cache...', 'comment')
->add('cache:clear')
->addMessage('Deployment complete!', 'success');
Combining Action Types
All action types can be freely mixed within a single batch:
use EFrane\ConsoleAdditions\Command\Batch;
$batch = Batch::create($application, $output);
$batch
->addMessage('Starting deployment sequence', 'info')
->add('deploy:prepare')
->addShell('composer install --no-dev')
->addMessage('Running database migrations', 'comment')
->add('database:migrations:migrate')
->addShell('npm run build')
->addMessage('Deployment finished!', 'success');
Custom Actions
You can create your own action types by implementing the Action interface:
use EFrane\ConsoleAdditions\Batch\Action;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Style\SymfonyStyle;
class CustomAction implements Action {
private $name;
public function __construct(string $name) {
$this->name = $name;
}
public function getName(): string {
return $this->name;
}
public function setOutput(OutputInterface $output): void {
// Store output for later use
}
public function execute(SymfonyStyle $io): int {
$io->writeln('Executing custom action: ' . $this->name);
// Do your custom logic here
return 0; // Return code
}
}
// Use it in a batch
$batch->addAction(new CustomAction('my-custom-action'));
Action Lifecycle
- Creation: Action is created and added to the batch
- Output Injection:
setOutput()is called with the batch’s output - Execution:
execute()is called when the batch runs - Return Code: The action returns an integer exit code (0 = success)
The batch collects all return codes and can be configured to stop on failure or continue regardless.