Verified Commit 106d0215 authored by Lee Rowlands's avatar Lee Rowlands
Browse files

feat: #3453474 CLI entry point in Drupal Core

By: dpi
By: chi
By: andypost
By: mradcliffe
By: acbramley
By: aaronmchale
By: bhanu951
By: greg.1.anderson
By: moshe weitzman
By: gábor hojtsy
By: bircher
By: catch
By: franksj
By: rymo
By: godotislate
By: rfay
By: xjm
By: dww
By: longwave
By: alexpott
By: arrow
By: larowlan
By: kingdutch
(cherry picked from commit 21e3ddfe)
parent f7c6fbe7
Loading
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -715,7 +715,7 @@ default:
    # Composer-install Drush & the Config Inspector module.
    - composer require drush/drush drupal/config_inspector || exit 100
    # Install Drupal's Standard install profile + all core modules (except obsolete ones) + the config inspector module.
    - php core/scripts/drupal install standard
    - vendor/bin/dr install standard
    - ls core/modules | grep -v sdc | xargs vendor/bin/drush pm:install --yes
    - vendor/bin/drush pm:install config_inspector --yes --quiet || exit 101
    # Compute statistics for coverage of validatable config for HEAD.
+4 −1
Original line number Diff line number Diff line
@@ -368,7 +368,7 @@
            "dist": {
                "type": "path",
                "url": "core",
                "reference": "154e8ed951857b1ee8c75e4e43f75691c13f920a"
                "reference": "a8d26b420c8e9972abe2e6dde3dca88a29451d49"
            },
            "require": {
                "asm89/stack-cors": "^2.3",
@@ -460,6 +460,9 @@
            "suggest": {
                "ext-zip": "Needed to extend the plugin.manager.archiver service capability with the handling of files in the ZIP format."
            },
            "bin": [
                "scripts/dr"
            ],
            "type": "drupal-core",
            "extra": {
                "branch-alias": {
+2 −2
Original line number Diff line number Diff line
@@ -24,14 +24,14 @@ Prerequisites:
1. Run the following commands

- composer create-project drupal/recommended-project drupal
- cd drupal && php -d memory_limit=256M web/core/scripts/drupal quick-start standard
- cd drupal && php -d memory_limit=256M vendor/bin/dr quick-start standard

Wait… installation can take a minute or two. A successful installation will
result in opening the new site in your browser.

Run the following command for a list of available options that you may need to
configure quick-start:
- php core/scripts/drupal quick-start --help
- vendor/bin/dr quick-start --help

Follow the instructions in the REINSTALL section below to start over.

+4 −1
Original line number Diff line number Diff line
@@ -29,6 +29,7 @@
        "symfony/mailer": "^7.4.12",
        "symfony/mime": "^7.4.12",
        "symfony/routing": "^7.4.13",
        "symfony/runtime": "^7.4",
        "symfony/serializer": "^7.4",
        "symfony/validator": "^7.4",
        "symfony/process": "^7.4.5",
@@ -36,7 +37,6 @@
        "symfony/polyfill-php84": "^1.32",
        "symfony/polyfill-php85": "^1.32",
        "symfony/polyfill-php86": "^1.37",
        "symfony/runtime": "^7.4",
        "symfony/yaml": "^7.4.12",
        "revolt/event-loop": "^1.0",
        "twig/twig": "^3.27.0",
@@ -125,6 +125,9 @@
            "includes/bootstrap.inc"
        ]
    },
    "bin": [
        "scripts/dr"
    ],
    "config": {
        "preferred-install": "dist"
    },
+120 −0
Original line number Diff line number Diff line
@@ -2871,3 +2871,123 @@ function hook_validation_constraint_alter(array &$definitions) {
 * longer needed (see @ref sec_intro above).
 * @}
 */

/**
 * @defgroup console_commands CLI Commands
 * @{
 * Providing CLI commands for the Drupal CLI.
 *
 * Drupal includes a CLI tool (invoked as `vendor/bin/dr`) built on the Symfony
 * Console component. Modules can provide their own commands that are
 * automatically discovered.
 *
 * @section sec_creating Creating a command
 * To provide a command, place a class in your module's `src/Command/` directory
 * and apply the `#[AsCommand]` attribute to declare the command name and
 * description. Command names follow the convention `module:action`
 * (e.g. `my_module:hello`).
 *
 * There are two types of commands:
 *
 * @subsection sec_command_class Extending Symfony's Command class
 * One style extends `\Symfony\Component\Console\Command\Command` and implements
 * `execute()`:
 * @code
 * use Drupal\Component\Datetime\TimeInterface;
 * use Symfony\Component\Console\Attribute\AsCommand;
 * use Symfony\Component\Console\Command\Command;
 * use Symfony\Component\Console\Input\InputInterface;
 * use Symfony\Component\Console\Output\OutputInterface;
 * use Symfony\Component\Console\Style\SymfonyStyle;
 *
 * #[AsCommand(
 *   name: 'my_module:hello',
 *   description: 'Say hello.',
 * )]
 * class HelloCommand extends Command {
 *
 *   public function __construct(
 *     private readonly TimeInterface $time,
 *   ) {
 *     parent::__construct();
 *   }
 *
 *   protected function execute(InputInterface $input, OutputInterface $output): int {
 *     $io = new SymfonyStyle($input, $output);
 *     $now = new \DateTimeImmutable('@' . $this->time->getRequestTime());
 *     $io->success('Hello! The time is ' . $now->format('r'));
 *     return Command::SUCCESS;
 *   }
 *
 * }
 * @endcode
 *
 * @subsection sec_invokable_command Invokable command classes
 * As an alternative, a plain class can define a single `__invoke()` method
 * instead of extending `\Symfony\Component\Console\Command\Command`. Symfony
 * Console attributes such as `#[Argument]`, `#[Option]`, and `#[Ask]` can be
 * applied to individual parameters to declare arguments, options, and
 * interactive prompts, removing the need for a `configure()` method. Drupal
 * services can be injected via the constructor as normal.
 * @code
 * use Drupal\Component\Datetime\TimeInterface;
 * use Symfony\Component\Console\Attribute\Argument;
 * use Symfony\Component\Console\Attribute\Ask;
 * use Symfony\Component\Console\Attribute\AsCommand;
 * use Symfony\Component\Console\Attribute\Option;
 * use Symfony\Component\Console\Output\OutputInterface;
 *
 * #[AsCommand(
 *   name: 'my_module:greet',
 *   description: 'Greet someone.',
 * )]
 * class GreetCommand {
 *
 *   public function __construct(
 *     protected readonly TimeInterface $time,
 *   ) {}
 *
 *   public function __invoke(
 *     OutputInterface $output,
 *     #[Argument('The name to greet.')]
 *     #[Ask('Who should be greeted?', 'World')]
 *     string $name,
 *     #[Option('Shout the greeting.')]
 *     bool $shout = FALSE,
 *   ): int {
 *     $now = new \DateTimeImmutable('@' . $this->time->getRequestTime());
 *     $greeting = "[$now] Hello, $name!";
 *     $output->writeln($shout ? strtoupper($greeting) : $greeting);
 *     return Command::SUCCESS;
 *   }
 *
 * }
 * @endcode
 *
 * @section sec_discovery Auto-discovery and dependency injection
 * `\Drupal\Core\DependencyInjection\Compiler\ConsoleCompilerPass` scans each
 * installed module's `src/Command/` directory at container compile time. Any
 * class carrying the `#[AsCommand]` attribute is automatically registered as an
 * autowired service tagged `console.command` — no service YAML entry is
 * needed. Constructor dependencies are resolved from the service container
 * automatically.
 *
 * After Drupal bootstraps, `\Drupal\Core\Command\DrupalApplication` registers
 * all tagged commands.
 *
 * @section sec_service_tag Registering via service tag
 * Commands that do not use `#[AsCommand]` — for example, those that declare
 * their name only via `configure()` — are not auto-discovered and must be
 * registered explicitly as a service tagged `console.command` in a module's
 * `*.services.yml` file:
 * @code
 * my_module.hello_command:
 *   class: Drupal\my_module\Command\HelloCommand
 *   tags:
 *     - { name: console.command }
 * @endcode
 *
 * @see \Drupal\Core\Command\DrupalApplication
 * @see \Drupal\Core\DependencyInjection\Compiler\ConsoleCompilerPass
 * @}
 */
Loading