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

Embedded Composer Console Laravel Package

dflydev/embedded-composer-console

Embed a Composer console in your app using dflydev’s embedded Composer. Provides a programmatic, in-process way to run Composer commands and capture output, useful for tooling, installers, and automation without shelling out.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation Add the package via Composer:

    composer require dflydev/embedded-composer-console
    

    Register the service in your Laravel service provider (e.g., AppServiceProvider):

    use Dflydev\EmbeddedComposerConsole\ComposerConsole;
    
    public function register()
    {
        $this->app->singleton(ComposerConsole::class, function ($app) {
            return new ComposerConsole($app['path.base'], $app['composer.json']);
        });
    }
    
  2. First Use Case Embed a Composer command in a Laravel Artisan command:

    use Dflydev\EmbeddedComposerConsole\ComposerConsole;
    use Symfony\Component\Console\Input\ArrayInput;
    use Symfony\Component\Console\Output\BufferedOutput;
    
    class RunComposerCommand extends Command
    {
        protected $composer;
    
        public function __construct(ComposerConsole $composer)
        {
            parent::__construct();
            $this->composer = $composer;
        }
    
        protected function execute(InputInterface $input, OutputInterface $output)
        {
            $command = $this->composer->getApplication();
            $command->setAutoExit(false);
    
            $outputBuffer = new BufferedOutput();
            $inputBuffer = new ArrayInput(['command' => 'update']);
    
            $exitCode = $command->run($inputBuffer, $outputBuffer);
            $output->writeln($outputBuffer->fetch());
    
            return $exitCode;
        }
    }
    

Implementation Patterns

Workflows

  1. Embedding Composer in Artisan Commands Use the ComposerConsole service to execute Composer commands programmatically:

    $composer = app(ComposerConsole::class);
    $app = $composer->getApplication();
    $app->run(new ArrayInput(['command' => 'install']), new BufferedOutput());
    
  2. Integration with Laravel Tasks Chain Composer commands with Laravel tasks (e.g., post-deploy):

    // In a service or command
    $composer->getApplication()->run(
        new ArrayInput(['command' => 'dump-autoload']),
        new NullOutput()
    );
    
  3. Customizing Composer Configuration Override Composer’s global config (e.g., repositories) via Laravel config:

    $composerConfig = [
        'config' => [
            'github-protocols' => ['https'],
        ],
    ];
    $composer->setConfig($composerConfig);
    
  4. Handling Output Streams Redirect Composer output to Laravel’s logging or notifications:

    $output = new StreamOutput(fopen('php://temp', 'w+'));
    $composer->getApplication()->run(
        new ArrayInput(['command' => 'validate']),
        $output
    );
    rewind($output->getStream());
    $log = stream_get_contents($output->getStream());
    

Integration Tips

  • Dependency Management: Use this package to automate Composer tasks in CI/CD pipelines (e.g., composer install --no-dev).
  • Laravel Packages: Embed Composer commands in package bootstrapping (e.g., post-update-cmd).
  • Event-Driven Workflows: Trigger Composer actions on Laravel events (e.g., Illuminate\Foundation\Bootstrapped):
    event(new ComposerUpdateEvent());
    // In listener:
    $composer->getApplication()->run(new ArrayInput(['command' => 'update']));
    

Gotchas and Tips

Pitfalls

  1. Path Resolution Ensure $app['path.base'] points to the root of your project (not vendor/ or storage/). Composer commands fail if paths are misconfigured.

    // Wrong: $app['path.storage']
    // Right: $app['path.base']
    
  2. Composer Lock Conflicts Embedded Composer may ignore your composer.lock if not explicitly passed. Always use:

    $composer = new ComposerConsole($projectDir, $composerJson, $lockFilePath);
    
  3. Output Buffering BufferedOutput captures only stdout. For full Composer output (including stderr), use:

    $output = new CompositeOutput([
        new BufferedOutput(),
        new StreamOutput(fopen('php://stderr', 'w')),
    ]);
    
  4. Auto-Exit Behavior ComposerConsole’s getApplication() returns a Symfony Application with autoExit enabled by default. Disable it:

    $app = $composer->getApplication();
    $app->setAutoExit(false); // Critical for programmatic use!
    

Debugging

  • Dry Runs: Test commands with --dry-run to avoid side effects:
    $input = new ArrayInput(['command' => 'update', '--dry-run' => true]);
    
  • Verbose Mode: Enable Composer’s verbose output for debugging:
    $input = new ArrayInput(['command' => 'diagnose', '-v' => true]);
    
  • Logging: Redirect output to Laravel’s log:
    $output = new StreamOutput(fopen('php://temp', 'w+'));
    $composer->getApplication()->run($input, $output);
    Log::info('Composer Output: ' . stream_get_contents($output->getStream()));
    

Extension Points

  1. Custom Composer Commands Extend the embedded Composer by adding custom commands to your project’s composer.json:

    {
        "scripts": {
            "post-autoload-dump": "your:custom-command"
        }
    }
    

    Then trigger them via:

    $composer->getApplication()->find('your:custom-command')->run();
    
  2. Environment-Specific Config Load Composer config dynamically based on Laravel’s environment:

    $config = config("composer.{$app->environment()}");
    $composer->setConfig($config);
    
  3. Parallel Execution Use Laravel’s queues to run Composer commands asynchronously (e.g., for dump-autoload):

    RunComposerJob::dispatch('dump-autoload')->onQueue('composer');
    
    class RunComposerJob implements ShouldQueue
    {
        use Dispatchable, InteractsWithQueue, Queueable;
    
        public function handle(ComposerConsole $composer)
        {
            $composer->getApplication()->run(new ArrayInput(['command' => $this->command]));
        }
    }
    
  4. Security

    • Restrict Commands: Whitelist allowed Composer commands in your Laravel middleware:
      if (!in_array($input->get('command'), ['install', 'update', 'validate'])) {
          throw new \RuntimeException('Composer command not allowed.');
      }
      
    • User Permissions: Ensure the PHP process has write access to composer.json and vendor/. Use chmod or Laravel’s filesystem permissions.
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.
besmartand-pro/php-quality-config
sentix/ai-chatbot
codifyo/ts-generator-bundle
mintobit/jobqueue
a4sex/maintenance-bundle
a4sex/entity-date-update
a4sex/client-identifier
a4sex/base-utilites
a4sex/key-value-storage
a4sex/micro-status
chilldev/dependency-injection-extra
datinglibre/datinglibre-app-api
biberltd/corebundle
bricre/symfony-bundle-test
biberltd/logbundle
dominium/http-adapter-bundle
dominium/google-analytics
a4sex/auto-clean-entity
christhompsontldr/laravel-inky
spatie/mailcoach-vapor