VOOZH about

URL: https://deepwiki.com/hypervel/foundation/5.2-command-discovery-and-registration

⇱ Command Discovery and Registration | hypervel/foundation | DeepWiki


Loading...
Last indexed: 7 February 2026 (101eff)
Menu

Command Discovery and Registration

Purpose and Scope

This document explains how the Console Kernel discovers and registers Artisan commands in Hypervel Foundation. It covers the multiple command sources, automatic discovery mechanisms, explicit registration methods, and the complete command loading pipeline. For information about command execution and the Console Kernel's broader responsibilities, see Console Kernel and Command Execution. For details about specific commands provided by the framework, see Server Management Commands.

Overview

The Hypervel Console Kernel provides multiple mechanisms for discovering and registering commands:

Discovery MethodDescriptionConfiguration Point
Annotation-basedCommands marked with @Command annotationAutomatic via Hyperf's AnnotationCollector
Directory scanningCommands in specified directories$commandPaths property
Config arrayCommands listed in configurationconfig/commands.php
Explicit arrayCommands in $commands propertyKernel's $commands array
Closure commandsRuntime-defined closure commandscommand() method or command route files

All discovered commands are collected, de-duplicated, and registered with the Artisan application during the bootstrap process.

Sources: src/Console/Kernel.php1-438

Command Sources Architecture


Sources: src/Console/Kernel.php149-214

Command Discovery Mechanisms

Annotation-Based Discovery

The kernel automatically discovers commands marked with the Hyperf\Command\Annotation\Command annotation. This mechanism leverages Hyperf's annotation collection system.

Discovery Process:

  1. Check if AnnotationCollector and AnnotationCommand classes exist
  2. Query AnnotationCollector::getClassesByAnnotation(AnnotationCommand::class)
  3. Extract class names and convert to reflections
  4. Filter for classes that extend Symfony\Component\Console\Command\Command

Sources: src/Console/Kernel.php163-169

Directory-Based Discovery

Commands in specified directories are automatically discovered by scanning file system paths defined in $commandPaths.

Configuration Methods:

  • Protected property: Override $commandPaths in custom kernel
  • Runtime addition: Use addCommandPaths() method
  • Explicit loading: Call load() method with paths

Discovery Implementation:


The load() method src/Console/Kernel.php332-347 accepts paths as array or string, filters for valid directories, and merges them into the $loadedPaths property. When collectCommands() executes, it uses ReflectionManager::getAllClasses() to scan these paths for command classes.

Sources: src/Console/Kernel.php332-347 src/Console/Kernel.php133-144 src/Console/Kernel.php152-155

Config-Based Discovery

Commands can be explicitly listed in Hyperf's configuration system under the commands key.

Configuration Location: The kernel reads from ConfigInterface::get('commands', []) src/Console/Kernel.php158-160

Example Configuration (typical location would be config/autoload/commands.php):


This mechanism provides compatibility with Hyperf's command registration pattern while allowing centralized command configuration.

Sources: src/Console/Kernel.php158-160

Explicit Command Registration

Commands can be explicitly registered through multiple methods:

MethodProperty/MethodUse Case
Kernel property$commands arrayDefault commands in custom kernel
Runtime additionaddCommands()Dynamic command registration
Closure commandscommand()Simple, inline commands

The $commands Property src/Console/Kernel.php41:


Application kernels can override this property to define default commands.

The addCommands() Method src/Console/Kernel.php360-369: Accepts an array of command class names and merges them with existing commands, ensuring uniqueness and maintaining array values (no associative keys).

Sources: src/Console/Kernel.php41 src/Console/Kernel.php360-369

Command Route Files and Closure Commands

Command Route Files

Command route files provide a way to define closure-based commands in dedicated files, similar to route definition files.

Configuration: The $commandRoutePaths property src/Console/Kernel.php56 stores paths to command route files.

Loading Process: During discoverCommands() src/Console/Kernel.php139-143 each path is checked for existence and then required:


Typical Usage: These files would call $kernel->command() to register closure commands.

Configuration Method: Use addCommandRoutePaths() src/Console/Kernel.php384-389 to add route file paths.

Sources: src/Console/Kernel.php56 src/Console/Kernel.php139-143 src/Console/Kernel.php384-389

Closure Command Registration

The command() method src/Console/Kernel.php311-327 provides a fluent interface for registering closure-based commands:


Key Implementation Details:

  1. Creates a ClosureCommand instance wrapping the closure
  2. If commands already loaded, registers immediately with generated container ID
  3. If commands not loaded, stores in $closureCommands for batch registration
  4. Uses spl_object_hash() to generate unique container binding keys
  5. Binds closure command to container as commands.{hash}

Sources: src/Console/Kernel.php311-327 src/Console/Kernel.php183-187

Complete Command Collection Flow

The collectCommands() method src/Console/Kernel.php149-192 aggregates commands from all sources:


Filtering Logic src/Console/Kernel.php174-180: Only classes that extend Symfony\Component\Console\Command\Command are included. This ensures invalid command classes are rejected early in the pipeline.

Sources: src/Console/Kernel.php149-192

Command Loading and Registration

Namespace Priority Sorting

The loadCommands() method src/Console/Kernel.php194-214 implements special handling for Hyperf framework commands:


Rationale: By placing Hyperf commands first, application commands can override framework commands with the same name. When Artisan registers commands, later registrations with duplicate names override earlier ones.

Implementation src/Console/Kernel.php198-208:


Sources: src/Console/Kernel.php194-214

Individual Command Registration

The registerCommand() method src/Console/Kernel.php219-226 handles the final registration step:


Process:

  1. Resolve command from container using $this->app->get($command)
  2. Process through pendingCommand() (from HasPendingCommand trait)
  3. If result is non-null, add to Artisan application
  4. The pendingCommand() method handles any pending command modifications

Container Binding: Closure commands are bound with IDs like commands.{hash}, while class-based commands use their fully qualified class name as the container key.

Sources: src/Console/Kernel.php219-226

Bootstrap Integration

The command discovery and registration process integrates with the kernel bootstrap lifecycle:


Key Points:

Sources: src/Console/Kernel.php103-120 src/Console/Kernel.php402-417

Kernel Contract and Public API

The Kernel contract src/Console/Contracts/Kernel.php1-97 defines the public interface for command management:

MethodPurposeReturn Type
bootstrap()Initialize command loadingvoid
commands()Hook for application commandsvoid
command(string, Closure)Register closure commandClosureCommand
load(array|string)Add discovery pathsvoid
addCommands(array)Add explicit commandsstatic
addCommandPaths(array)Add discovery directoriesstatic
addCommandRoutePaths(array)Add route filesstatic
getLoadedPaths()Get loaded directory pathsarray
registerCommand(string)Register single commandvoid
call(string, array, OutputInterface)Execute commandmixed
all()Get all registered commandsarray

Typical Usage in Application Kernel:


Sources: src/Console/Contracts/Kernel.php1-97

Command Path Management

Path Addition Methods

Three related methods manage command paths:

addCommandPaths(array $paths) src/Console/Kernel.php374-379:

  • Adds directories for automatic command discovery
  • Paths merged with existing $commandPaths array
  • Used during bootstrap by discoverCommands()

addCommandRoutePaths(array $paths) src/Console/Kernel.php384-389:

  • Adds files to be required for closure commands
  • Files loaded during discoverCommands()
  • Typically used for routes/console.php style files

load(array|string $paths) src/Console/Kernel.php332-347:

  • Immediately processes and stores paths in $loadedPaths
  • Filters for valid directories only
  • Used for dynamic path addition during commands() hook

Path Processing Logic

The load() method includes validation and de-duplication:


Processing Steps:

  1. Wrap single paths in array
  2. Remove duplicates within input
  3. Filter for directories only (non-directories ignored)
  4. Merge with existing loaded paths
  5. De-duplicate merged result
  6. Re-index array with array_values()

Sources: src/Console/Kernel.php332-347 src/Console/Kernel.php374-389

Discovery Conditions

The shouldDiscoverCommands() method src/Console/Kernel.php125-128 determines whether automatic discovery runs:


Behavior:

  • Returns true only when the exact Hypervel\Foundation\Console\Kernel class is used
  • Returns false for any subclass
  • Allows applications to disable discovery by extending the kernel
  • Applications can override this method to enable discovery in subclasses

Design Rationale: This prevents unintended command discovery in production applications where explicit command registration is preferred for performance and control.

Sources: src/Console/Kernel.php125-128