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

Auto Shell Laravel Package

pmjones/auto-shell

AutoShell auto-maps CLI command names to PHP command classes in a namespace. It reflects a command’s main method to parse args/options (scalars or arrays), then returns an Exec to run. Zero dependencies—add a class and it becomes a command.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation:
    composer require pmjones/auto-shell
    
  2. Create bin/console.php:
    <?php
    use AutoShell\Console;
    
    require dirname(__DIR__) . '/vendor/autoload.php';
    
    $console = Console::new(
        namespace: 'App\\Cli\\Command',
        directory: __DIR__ . '/../src/Cli/Command',
    );
    
    exit($console($_SERVER['argv']));
    
  3. Create a command class (e.g., src/Cli/Command/Greet.php):
    <?php
    namespace App\Cli\Command;
    
    class Greet
    {
        public function __invoke(string $name): int
        {
            echo "Hello, {$name}!\n";
            return 0;
        }
    }
    
  4. Run the command:
    php bin/console.php greet Alice
    

First Use Case: CLI Command with Arguments

  • Goal: Create a command that accepts a name and greets the user.
  • Steps:
    1. Define the command class with __invoke() method.
    2. Type-hint parameters (e.g., string $name).
    3. Run the command via php bin/console.php greet Alice.

Implementation Patterns

1. Command Structure

  • Convention: Command classes live in src/Cli/Command (or custom directory).
  • Naming: Class names map to command names (e.g., UserCreateuser:create).
  • Method: Defaults to __invoke(), but can be customized (e.g., execute()).

2. Options Handling

  • Pattern: Use Options interface + #[Option] attributes.
    class GreetOptions implements Options
    {
        public function __construct(
            #[Option('f,force')]
            public readonly ?bool $force
        ) {}
    }
    
  • Integration: Pass options as a parameter to __invoke():
    public function __invoke(GreetOptions $options, string $name): int
    

3. Dependency Injection

  • Factory Pattern: Inject a factory for complex dependencies:
    $console = Console::new(
        namespace: 'App\\Cli\\Command',
        directory: __DIR__ . '/../src/Cli/Command',
        factory: fn(string $class) => $container->get($class),
    );
    

4. Help Text

  • Class-level Help: Use #[Help] on the class.
    #[Help("Greets a user.")]
    class Greet {}
    
  • Parameter Help: Add help text to parameters:
    public function __invoke(
        #[Help("Name to greet.")]
        string $name
    ): int {}
    

5. Advanced: Composing Options

  • Shared Options: Reuse options across commands by passing multiple Options parameters:
    public function __invoke(
        CommonOptions $common,
        GreetOptions $options,
        string $name
    ): int {}
    

6. Error Handling

  • Exit Codes: Return 0 for success, non-zero for errors (e.g., 1 for failures).
  • Custom Errors: Use throw new \RuntimeException() in __invoke() to propagate errors.

Gotchas and Tips

Pitfalls

  1. Namespace/Directory Mismatch:

    • Ensure namespace and directory in Console::new() match your PSR-4 structure.
    • Example: namespace: 'App\\Cli\\Command'directory: __DIR__ . '/../src/Cli/Command'.
  2. Option Conflicts:

    • Avoid defining the same option (e.g., -v) in multiple Options classes. Use OptionAlreadyDefined exception as a hint.
  3. Type Casting Quirks:

    • bool options default to true if present (even without a value). Use default: false to override:
      #[Option('v,verbose', default: false)]
      
  4. Variadic Parameters:

    • Trailing parameters are treated as variadic. Example:
      public function __invoke(string ...$names): int {}
      
      Runs as: php bin/console.php greet Alice Bob Charlie.
  5. Help Text Parsing:

    • Extended help text (e.g., <<<HELP) must use HELP as the closing tag (case-sensitive).

Debugging Tips

  1. Check Command Discovery:

    • Run php bin/console.php to list available commands. If empty, verify:
      • The directory path is correct.
      • Classes are autoloadable (check composer dump-autoload).
  2. Option Parsing Issues:

    • Use php bin/console.php help <command> to validate option definitions.
    • Check for typos in #[Option] names (e.g., -v vs --verbose).
  3. Factory Debugging:

    • If commands fail to instantiate, ensure the factory returns the correct class:
      factory: fn(string $class) => new $class(), // Fallback to `new` if DI fails.
      

Extension Points

  1. Custom Command Naming:

    • Override naming logic by extending AutoShell\Shell and injecting it:
      $shell = new CustomShell();
      $console = Console::new(..., shell: $shell);
      
  2. Custom Help Rendering:

    • Replace the default help output by passing a custom help callable to Console::new():
      help: fn(string $text) => echo "<pre>{$text}</pre>\n",
      
  3. Pre/Post-Execution Hooks:

    • Wrap the console execution in middleware:
      $console = fn(array $argv) => {
          // Pre-execution logic
          $code = $console($argv);
          // Post-execution logic
          return $code;
      };
      

Performance Notes

  • Reflection Overhead: AutoShell uses reflection to inspect command classes. For large projects, cache the Console instance:
    $console = Console::new(...);
    // Reuse $console across requests (e.g., in a long-running process).
    
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