rougin/blueprint

A bootstrap for PHP console projects.

v0.7.0 2024-10-20 16:32 UTC

This package is auto-updated.

Last update: 2024-11-20 16:38:46 UTC


README

Latest Version on Packagist Software License Build Status Coverage Status Total Downloads

Blueprint is a PHP package for bootstrapping console applications.

Installation

Install Blueprint via Composer:

$ composer require rougin/blueprint

Basic Usage

Creating a new blueprint.yml

Create a blueprint.yml file by running the initialize command:

$ vendor/bin/blueprint initialize
# blueprint.yml

name: Blueprint
version: 0.7.0

paths:
  templates: %%CURRENT_DIRECTORY%%/src/Templates
  commands: %%CURRENT_DIRECTORY%%/src/Commands

namespaces:
  commands: Rougin\Blueprint\Commands

Note

  • Replace the values specified in the blueprint.yml file.
  • Add commands and templates (if applicable) to their respective directories.

Creating a command

Prior to creating a command, the commands property in blueprint.yml must be updated:

# blueprint.yml

# ...

namespaces:
  commands: Acme\Commands

Then create the command (e.g., TestCommand) to the specified directory:

// src/Commands/TestCommand.php

namespace Acme\Commands;

use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;

class TestCommand extends Command
{
    protected function configure()
    {
        $this->setName('test')->setDescription('Returns a "Test" string');
    }

    protected function execute(InputInterface $input, OutputInterface $output)
    {
        $output->writeln('<info>Test</info>');
    }
}

Updating the composer.json

After creating the command (e.g., TestCommand), kindly check if its namespace is defined in Composer:

// composer.json

// ...

"autoload":
{
  "psr-4":
  {
    "Acme\\": "src"
  }
}

// ...
$ composer dump-autoload

Running the command

The created commands will be recognized automatically by Blueprint. With this, it could be executed in the same blueprint command:

$ vendor/bin/blueprint test

Test

Extending Blueprint

The v0.7.0 version introduces a way to extend the Blueprint package to use it as the console application for specified projects.

Initializing the instance

To initialize a console application, the Blueprint class must be created first:

// bin/app.php

use Rougin\Blueprint\Blueprint;

// Return the root directory of the project ----------
$root = (string) __DIR__ . '/../../../../';

$exists = file_exists($root . '/vendor/autoload.php');

$root = $exists ? $root : __DIR__ . '/../';
// ---------------------------------------------------

require $root . '/vendor/autoload.php';

$app = new Blueprint;

After creating the Blueprint class, the following details can now be updated:

// bin/app.php

// ...

// Set the name of the console application. ----
$app->setName('Acme');
// ---------------------------------------------

// Set the version of the console application. ----
$app->setVersion('0.1.0');
// ------------------------------------------------

// Set the directory for the defined commands. ----
$app->setCommandPath(__DIR__ . '/../src/Commands');
// ------------------------------------------------

// Set the directory for the templates. Might be useful ------
// if creating commands with template engines (e.g., Twig) ---
$app->setTemplatePath(__DIR__ . '/../src/Templates');
// -----------------------------------------------------------

// Set the namespace for the "commands" path. ----
$namespace = 'Acme\Simplest\Commands';
$app->setCommandNamespace($namespace);
// -----------------------------------------------

// Run the console application ---
$app->run();
// -------------------------------

Note

Using this approach means the blueprint.yml can now be omitted. This approach is also applicable to create customized console applications without the Blueprint branding.

Then run the console application in the terminal:

$ php bin\app.php

Acme 0.1.0

Usage:
  command [options] [arguments]

Options:
  -h, --help            Display help for the given command. When no command is given display help for the list command
  -q, --quiet           Do not output any message
  -V, --version         Display this application version
      --ansi|--no-ansi  Force (or disable --no-ansi) ANSI output
  -n, --no-interaction  Do not ask any interactive question
  -v|vv|vvv, --verbose  Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug

Available commands:
  completion  Dump the shell completion script
  help        Display help for a command
  list        List commands

Customized Command class

Blueprint also provides an alternative Command class for creating commands with descriptive methods and less code:

// src/Commands/TestCommand.php

namespace Acme\Commands;

use Rougin\Blueprint\Command;

class TestCommand extends Command
{
    protected $name = 'test';

    protected $description = 'Returns a "Test" string';

    public function execute()
    {
        $this->showPass('Test');
    }
}

Note

All of the functionalities for the Command class is derived from the Symfony's Console component.

Injecting dependencies

To perform automagic resolutions in each defined commands, the addPackage can be used with the additional functionality from the Container class from Slytherin:

// src/Sample.php

namespace Acme;

class Sample
{
    protected $name;

    public function __construct($name)
    {
        $this->name = $name;
    }

    public function getName()
    {
        return $this->name;
    }
}
// src/Packages/SamplePackage.php

namespace Acme\Packages;

use Acme\Sample;
use Rougin\Slytherin\Container\ContainerInterface;
use Rougin\Slytherin\Integration\Configuration;
use Rougin\Slytherin\Integration\IntegrationInterface;

class SamplePackage implements IntegrationInterface
{
    public function define(ContainerInterface $container, Configuration $config)
    {
        return $container->set(Sample::class, new Sample('Blueprint'));
    }
}
// bin/app.php

use Acme\Packages\SamplePackage;
use Rougin\Slytherin\Container\Container;

// ...

// Add the specified integration (or package) to the container ---
$container = new Container;

$container->addPackage(new SamplePackage);
// ---------------------------------------------------------------

// Set the container to the console application ---
$app->setContainer($container);
// ------------------------------------------------

With the above-mentioned integration, for any command that uses the Sample class will get the text value as the $name property:

namespace Acme\Commands;

use Acme\Sample;
use Rougin\Blueprint\Command;

class TextCommand extends Command
{
    protected $name = 'text';

    protected $description = 'Shows a sample text';

    protected $sample;

    public function __construct(Sample $sample)
    {
        $this->sample = $sample;
    }

    public function run()
    {
        $this->showText('Hello, ' . $this->sample->getName() . '!');

        return self::RETURN_SUCCESS;
    }
}
$ php bin/app.php text

Hello, Blueprint!

Changelog

Please see CHANGELOG for more information what has changed recently.

Testing

$ composer test

Credits

License

The MIT License (MIT). Please see LICENSE for more information.