Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Cli Executor Laravel Package

keradus/cli-executor

Execute CLI commands from PHP with a simple, lightweight wrapper. Run processes, capture output, handle exit codes, and manage arguments for reliable command execution in scripts and Laravel apps.

View on GitHub
Deep Wiki
Context7

Getting Started

Start by installing the package via Composer:

composer require --dev keradus/cli-executor

This lightweight wrapper around symfony/process is designed for executing CLI commands reliably in development tooling—especially testing scenarios. Its sole public class, ScriptExecutor, provides minimal boilerplate around command execution, result capture, and error handling.

Begin by reviewing the ScriptExecutor class directly in the source (it’s under 100 lines). Look for usage examples in the PHP-CS-Fixer test suite (since this package originates from that project). Its niche is not general-purpose CLI orchestration, but rather consistent, repeatable execution of external binaries within controlled environments (e.g., tests, automated scripts).

Implementation Patterns

  • Testing CLI tools with confidence: Use ScriptExecutor to drive real CLI binaries (e.g., php-cs-fixer, phpunit, phpstan) in integration tests—avoiding mocks of external tool behavior:
    use Keradus\CliExecutor\ScriptExecutor;
    
    $executor = new ScriptExecutor();
    $result = $executor->execute('php-cs-fixer', ['check', 'src', '--dry-run']);
    
    $this->assertSame(0, $result->getExitCode());
    $this->assertStringNotContainsString('found', $result->getOutput());
    
  • CI/CD or script orchestration: Run sequential CLI steps with early failure exit, e.g., lint → test → fix:
    $executor->execute('php', ['-l', 'src']) || throw new RuntimeException('Lint failed');
    $executor->execute('phpunit') || throw new RuntimeException('Tests failed');
    $executor->execute('php-cs-fixer', ['fix', 'src']) || throw new RuntimeException('Format failed');
    
  • Scoped execution context: Override working directory and environment variables per executor instance to isolate test runs or simulate deployment states:
    $executor = new ScriptExecutor([
        'cwd' => sys_get_temp_dir() . '/my-test-project',
        'env' => ['SYMFONY_DOTENV_VARS' => 'APP_SECRET,DB_URL'],
    ]);
    

The package shines where you need deterministic CLI invocation without extra abstraction layers—ideal for tool authors or test suites needing binary fidelity.

Gotchas and Tips

  • Timeouts are not configured by default: The underlying Process has no timeout unless set via constructor option. Add it for safety:
    $executor = new ScriptExecutor(['timeout' => 30]); // seconds
    
    Otherwise, long-running commands (e.g., Composer installs) may hang.
  • exitCode === 0 ≠ success: Many tools exit cleanly while logging warnings to stderr. Always inspect both outputs:
    $exitCode = $result->getExitCode();
    $stderr = $result->getErrorOutput();
    if ($exitCode !== 0 || !empty($stderr)) {
        // Handle partial failures, e.g., lint warnings with exit 0
    }
    
  • Binary path sensitivity: If the binary isn’t in PATH, use absolute paths (e.g., /usr/bin/php-cs-fixer), or manually resolve via which first.
  • Minimal testability: No interfaces or DI hooks—testability is intentionally thin. Mocking requires direct class override or wrapper. Consider wrapping ScriptExecutor in your own CliRunner for testability.
  • Maturity caveats: With 22.81 score and only PHP-CS-Fixer itself as a likely user, this is not battle-tested for high-volume production CLI orchestration. Avoid for critical workflows—use for local tooling, tests, or low-stakes automation.
  • Debug swiftly: In tests or scripts, dump raw ScriptResult to understand payload structure:
    dd([
        'exitCode' => $result->getExitCode(),
        'signalCode' => $result->getSignalCode(),
        'stdout' => $result->getOutput(),
        'stderr' => $result->getErrorOutput(),
    ]);
    
    Output format is stable but undocumented—source inspection is your best reference.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
davejamesmiller/laravel-breadcrumbs
artisanry/parsedown
christhompsontldr/phpsdk
enqueue/dsn
bunny/bunny
enqueue/test
enqueue/null
enqueue/amqp-tools
milesj/emojibase
bower-asset/punycode
bower-asset/inputmask
bower-asset/jquery
bower-asset/yii2-pjax
laravel/nova
spatie/laravel-mailcoach
spatie/laravel-superseeder
laravel/liferaft
nst/json-test-suite
danielmiessler/sec-lists
jackalope/jackalope-transport