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

Build Bundle Laravel Package

massive/build-bundle

Symfony bundle providing a massive:build command to run tagged build targets. Define virtual targets in config, declare dependencies between targets, and implement builders to execute custom environment/setup steps—ideal for chaining app-specific commands in development.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Steps

  1. Install the Package:

    composer require massive/build-bundle
    

    For Laravel, ensure compatibility by adding to config/app.php under providers:

    Massive\Bundle\BuildBundle\MassiveBuildBundle::class,
    
  2. Register a Basic Builder: Create a builder class implementing BuilderInterface:

    namespace App\Builders;
    
    use Massive\Bundle\BuildBundle\Build\BuilderInterface;
    use Massive\Bundle\BuildBundle\Build\BuilderContext;
    
    class DatabaseBuilder implements BuilderInterface
    {
        public function getName() { return 'database'; }
        public function getDependencies() { return []; }
        public function build() { artisan('migrate:fresh'); }
        public function setContext(BuilderContext $context) {}
    }
    
  3. Tag the Builder in DI: In config/services.php (Laravel) or resources/config/services.xml (Symfony):

    <service id="app.database_builder" class="App\Builders\DatabaseBuilder">
        <tag name="massive_build.builder" />
    </service>
    
  4. Run the Build:

    php artisan massive:build database
    

First Use Case

Automate Laravel Environment Setup: Define a dev target in config/massive_build.php:

'massive_build' => [
    'targets' => [
        'dev' => [
            'dependencies' => ['database', 'assets', 'fixtures'],
        ],
    ],
],

Then run:

php artisan massive:build dev

This executes migrations, compiles assets, and loads fixtures in order.


Implementation Patterns

Core Workflows

  1. Dependency Chaining:

    • Define builders with explicit dependencies (e.g., FixturesBuilder depends on DatabaseBuilder).
    • Use --nodeps to skip dependencies for debugging:
      php artisan massive:build fixtures --nodeps
      
  2. Configuration-Driven Targets:

    • Define virtual targets in config/massive_build.php to group builders:
      'targets' => [
          'deploy' => ['database', 'assets', 'cache:clear'],
          'test'   => ['database:refresh', 'tests:run'],
      ],
      
    • Run with:
      php artisan massive:build deploy
      
  3. Context Utilization:

    • Access Symfony/Laravel services in builders via BuilderContext:
      public function build()
      {
          $this->context->get('cache')->clear();
      }
      

Integration Tips

  • Laravel Artisan Integration: Use artisan() helper in builders to run Laravel commands:

    public function build() { artisan('queue:work'); }
    
  • Symfony Console Commands: Extend BuildCommand to add project-specific options:

    class CustomBuildCommand extends BuildCommand
    {
        protected function configure()
        {
            $this->addOption('force', null, InputOption::VALUE_NONE, 'Force rebuild');
        }
    }
    

    Register in config/services.php:

    Massive\Bundle\BuildBundle\Command\BuildCommand::class => App\Commands\CustomBuildCommand::class,
    
  • CI/CD Pipelines: Use targets for environment-specific builds:

    # .github/workflows/build.yml
    jobs:
      build:
        runs-on: ubuntu-latest
        steps:
          - run: php artisan massive:build test
    

Laravel-Specific Patterns

  1. Service Container Access: Resolve Laravel services in builders:

    public function build()
    {
        $mailer = $this->context->get('mailer');
        $mailer->send(...);
    }
    
  2. Artisan Command Wrapping: Create builders for complex Artisan workflows:

    class QueueWorkerBuilder implements BuilderInterface
    {
        public function build()
        {
            artisan('queue:work --once');
        }
    }
    
  3. Environment Awareness: Use app()->environment() in builders to conditionally execute steps:

    public function build()
    {
        if (app()->environment('local')) {
            artisan('tinker');
        }
    }
    

Gotchas and Tips

Pitfalls

  1. Circular Dependencies:

    • Issue: Builders A → B → C → A causes infinite loops.
    • Fix: Use --nobuild to inspect dependencies:
      php artisan massive:build --nobuild
      
    • Solution: Refactor dependencies or use virtual targets to break cycles.
  2. Builder Context Not Injected:

    • Issue: Forgetting to implement setContext() leads to NullContextException.
    • Fix: Always implement the interface method:
      public function setContext(BuilderContext $context) { $this->context = $context; }
      
  3. Symfony/Laravel Service Mismatch:

    • Issue: Builders fail when accessing non-existent services.
    • Fix: Verify service IDs in BuilderContext:
      $this->context->has('service.id') ? $this->context->get('service.id') : null;
      
  4. Exit Code Handling:

    • Issue: Builders may silently fail without propagating exit codes.
    • Fix: Use --keep-exit-code to preserve failure states:
      php artisan massive:build --keep-exit-code
      

Debugging Tips

  1. Verbose Output: Enable debug mode for detailed logs:

    php artisan massive:build --verbose
    
  2. Builder Isolation: Test builders in isolation by using --nodeps:

    php artisan massive:build mybuilder --nodeps
    
  3. Dependency Graph: Visualize dependencies with --nobuild:

    php artisan massive:build --nobuild
    

    Output:

    +---+----------+--------------------+
    | # | Builder  | Deps               |
    +---+----------+--------------------+
    | 0 | database |                    |
    | 1 | fixtures | database           |
    +---+----------+--------------------+
    

Extension Points

  1. Custom Build Command: Override BuildCommand to add project-specific logic:

    class AppBuildCommand extends BuildCommand
    {
        protected function execute(InputInterface $input, OutputInterface $output)
        {
            if ($input->getOption('custom-flag')) {
                // Custom logic
            }
            parent::execute($input, $output);
        }
    }
    
  2. Dynamic Builders: Register builders dynamically via events:

    use Symfony\Component\HttpKernel\KernelEvents;
    use Symfony\Component\EventDispatcher\EventSubscriberInterface;
    
    class BuilderSubscriber implements EventSubscriberInterface
    {
        public static function getSubscribedEvents()
        {
            return [KernelEvents::BOOT => 'registerBuilders'];
        }
    
        public function registerBuilders()
        {
            $container->register('dynamic_builder', DynamicBuilder::class)
                       ->addTag('massive_build.builder');
        }
    }
    
  3. Builder Factories: Use factories to conditionally create builders:

    class BuilderFactory
    {
        public function create(string $name): BuilderInterface
        {
            return match ($name) {
                'database' => new DatabaseBuilder(),
                'assets'   => new AssetBuilder(),
                default    => throw new \RuntimeException("Unknown builder: $name"),
            };
        }
    }
    

Laravel-Specific Quirks

  1. Artisan Command Conflicts:

    • Issue: massive:build may conflict with custom Artisan commands.
    • Fix: Rename the command in your extended BuildCommand:
      $this->setName('app:build');
      
  2. Service Provider Registration:

    • Issue: Builders may not register if the bundle isn’t loaded early.
    • Fix: Ensure MassiveBuildBundle is loaded before your app’s providers in config/app.php.
  3. Laravel Mix Integration:

    • Tip: Use builders to trigger Mix builds:
      public function build()
      {
          artisan('mix');
      }
      

Performance Considerations

  1. Avoid Heavy Operations:

    • Issue: Builders running long tasks (e.g., composer install) block the CLI.
    • Fix: Offload to background jobs or use --timeout in Symfony.
  2. Caching Builders:

    • Tip: Cache builder instances if they’re stateless:
      $container->register('cached_builder', function () {
          return new CachedBuilder($container->get('cache'));
      });
      
  3. Parallelization:

    • Workaround: Use Symfony’s ParallelCommand to run independent builders concurrently (requires custom integration).
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.
testo/facade
headercat/phpstan-extension-ide-helper
yosymfony/parser-utils
innmind/black-box
babenkoivan/elastic-migrations
babenkoivan/elastic-adapter
sandermuller/package-boost-php
sandermuller/boost-core
depa/sulu-google-reviews-bundle
croct/plug-symfony
develia/commons
dmstr/symfony-system-resources-bundle
cuci/prototurk-sdk
cuci/prototurk-sdk-symfony
renatomarinho/laravel-page-speed
develia/geo-bundle
austinheap/laravel-database-encryption
dreamzy/livewire-charts
touchestate-sdk/php-sdk
22h/doctrine-garbage-collection-bundle