Blueprint
![Software License][ico-license]
![Coverage Status][ico-coverage]
, (*1)
Blueprint is a PHP package for bootstrapping console applications., (*2)
Installation
Install Blueprint
via Composer:, (*3)
``` bash
$ composer require rougin/blueprint, (*4)
## Basic Usage
### Creating a new `blueprint.yml`
Create a `blueprint.yml` file by running the `initialize` command:
``` bash
$ vendor/bin/blueprint initialize
``` yml, (*5)
blueprint.yml
name: Blueprint
version: 0.7.0, (*6)
paths:
templates: %%CURRENT_DIRECTORY%%/src/Templates
commands: %%CURRENT_DIRECTORY%%/src/Commands, (*7)
namespaces:
commands: Rougin\Blueprint\Commands, (*8)
> [!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:
``` yml
# blueprint.yml
# ...
namespaces:
commands: Acme\Commands
Then create the command (e.g., TestCommand
) to the specified directory:, (*9)
``` php
// src/Commands/TestCommand.php, (*10)
namespace Acme\Commands;, (*11)
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;, (*12)
class TestCommand extends Command
{
protected function configure()
{
$this->setName('test')->setDescription('Returns a "Test" string');
}, (*13)
protected function execute(InputInterface $input, OutputInterface $output)
{
$output->writeln('<info>Test</info>');
}
}, (*14)
### Updating the `composer.json`
After creating the command (e.g., `TestCommand`), kindly check if its namespace is defined in `Composer`:
``` json
// composer.json
// ...
"autoload":
{
"psr-4":
{
"Acme\\": "src"
}
}
// ...
``` bash
$ composer dump-autoload, (*15)
### Running the command
The created commands will be recognized automatically by Blueprint. With this, it could be executed in the same `blueprint` command:
``` bash
$ 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., (*16)
Initializing the instance
To initialize a console application, the Blueprint
class must be created first:, (*17)
``` php
// bin/app.php, (*18)
use Rougin\Blueprint\Blueprint;, (*19)
// Return the root directory of the project ----------
$root = (string) DIR . '/../../../../';, (*20)
$exists = file_exists($root . '/vendor/autoload.php');, (*21)
$root = $exists ? $root : DIR . '/../';
// ---------------------------------------------------, (*22)
require $root . '/vendor/autoload.php';, (*23)
$app = new Blueprint;, (*24)
After creating the `Blueprint` class, the following details can now be updated:
``` php
// 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., (*25)
Then run the console application in the terminal:, (*26)
``` bash
$ php bin\app.php, (*27)
Acme 0.1.0, (*28)
Usage:
command [options] [arguments], (*29)
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, (*30)
Available commands:
completion Dump the shell completion script
help Display help for a command
list List commands, (*31)
### Customized `Command` class
`Blueprint` also provides an alternative `Command` class for creating commands with descriptive methods and less code:
``` php
// 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., (*32)
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
:, (*33)
``` php
// src/Sample.php, (*34)
namespace Acme;, (*35)
class Sample
{
protected $name;, (*36)
public function __construct($name)
{
$this->name = $name;
}
public function getName()
{
return $this->name;
}
}, (*37)
``` php
// 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'));
}
}
``` php
// bin/app.php, (*38)
use Acme\Packages\SamplePackage;
use Rougin\Slytherin\Container\Container;, (*39)
// ..., (*40)
// Add the specified integration (or package) to the container ---
$container = new Container;, (*41)
$container->addPackage(new SamplePackage);
// ---------------------------------------------------------------, (*42)
// Set the container to the console application ---
$app->setContainer($container);
// ------------------------------------------------, (*43)
With the above-mentioned integration, for any command that uses the `Sample` class will get the `text` value as the `$name` property:
``` php
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;
}
}
``` bash
$ php bin/app.php text, (*44)
Hello, Blueprint!, (*45)
## Changelog
Please see [CHANGELOG][link-changelog] for more information what has changed recently.
## Testing
``` bash
$ composer test
Credits
License
The MIT License (MIT). Please see LICENSE for more information., (*46)