Skip to content
/ conso Public

💢 PHP console applications for cool kids 💢

License

Notifications You must be signed in to change notification settings

lotfio/conso

Repository files navigation

Conso Preview

License PHP version Version Coverage Build Status StyleCi Downloads

Conso (PHP console applications for cool kids).

🔥 Introduction :

Conso is a simple, lightweight PHP package that helps you create (executable, .phar, shareable) command line applications easily.

conso

💥 Is it really lightweight ?

Screen Shot 2020-07-27 at 6 12 41 PM

📌 Requirements :

  • PHP >= 7.2 or newer versions
  • PHPUnit >= 8 (for testing purpose)

🚀 Installation :

  • Via composer :
composer require lotfio/conso
  • for testing
composer test

🎉 Write your first command

  • create a commands.php file.
  • create a conso file (you can change the name as you like).
  • include your commands.php file into conso executable file.
  • it should look something like this.
#!/usr/bin/env php
<?php declare(strict_types=1);

use Conso\{
    Conso,Input,Output
};

require 'vendor/autoload.php';

$conso = new Conso(new Input, new Output);

// include your commands
require_once 'commands.php';

$conso->run();

⭐ Available config methods :

<?php

$conso->setSignature(); // set application signature (top logo)
$conso->setName();     // set application name
$conso->setVersion(); // set application version
$conso->setAuthor(); // set application author
$conso->disableBuiltInCommands(); // disable builtin commands
  • now define a new test command in your commands.php :
<?php
// this is your commands file

// test command
$conso->command("test", function($input, $output){
    $output->writeLn("\n hello from test \n", 'red');
});
  • now your command has been registered.
  • run php conso --commands or ./conso --commands in your terminal and you should see your command.

test-command

  • command test is registered now (no description is shown you can add this later on).
  • run your command php conso test or ./conso test.

run-test

⭐ Add description

  • ->description(string $description);
<?php
// test command
$conso->command("test", function($input, $output){
    $output->writeLn("\n hello from test \n", 'red');

})->description("This is test command description :) ^^");

description

⭐ Define sub commands

  • ->sub(string|array $subCommand);
<?php
// test command
$conso->command("test", function($input, $output){

    if($input->subCommand() == 'one')
        exit($output->writeLn("\n hello from one \n", 'yellow'));

    if($input->subCommand() == 'two')
        $output->writeLn("\n hello from two \n", 'green');

})->description("This is test command description :) ^^")->sub('one', 'two');

image

image

⭐ Define command flags

  • you can define flags using the flag method ->flags(string|array $flag)
  • this is a list of reserved flags ['-h', '--help', '-v', '--version', '-c', '--commands', '-q', '--quiet', '--ansi', '--no-ansi']
  • for debug you can use -vv or --verbose flags to get more details about the error
  • you can also pass values to flags --flag=value or -f=value
<?php
// test command
$conso->command("test", function($input, $output){

    if($input->flag('-t') !== false)
        $output->writeLn("\n flag -t is defined for this command.\n", 'red');

    // you can get flag values
    // $output->writeLn($input->flag('-t'));

})->description("This is test command description :) ^^")->flags('-t');

image

⭐ Add command alias

  • you can add an alias to a command with the alias method ->alias(string $alias)
<?php
// test command
$conso->command("test", function($input, $output){

    $output->writeLn("\n test called by alias \n", 'red');

})->description("This is test command description :) ^^")->alias('alias');

image

⭐ Define command help

  • you can add help instructions to a command using the help method ->help(array $help)
  • command help can be displayed using the -h or --help flags
  • help array must be an array of sub commands, options and flags with their descriptions
<?php
// test command
$conso->command("test", function($input, $output){

    $output->writeLn("\n test called by alias \n", 'red');

})->description("This is test command description :) ^^")->sub('one')->flags('-t')

  ->help([
      "sub commands" => [
          "one" => " help text for sub command goes here"
        ],
      "flags" => [
          "-t" => "help text for flag goes here"
        ]
  ]);

image

⭐ Group commands

  • you can group commands using the group() method
<?php

$conso->group('my group of commands:', function($conso){

    $conso->command("command", function(){})->description('This is command description');
    $conso->command("test",    function(){})->description('This is command description');
    $conso->command("make",    function(){})->description('This is command description');

});

image

⭐ Class commands

  • class commands are very helpful for big commands
  • first you need to create an app/Commands folder.
  • you can also move your commands definitions file commands.php to app folder to clean up things.
  • don't forget to autoload your commands with composer psr-4{ "App\\" : "app" }
  • now you need add commands paths and namespaces to conso to allow the build in command (command) to automatically create commands for you.
    // add this to your conso file before run method
    $conso->setCommandsPath('app/Commands');
    $conso->setCommandsNamespace('App\\Commands');
  • to create a class command run php conso command:make {command name}
  • for example lets create a test class command php conso command:make test
  • this will generate a Test command class like this:
<?php

namespace App\Commands;

use Conso\{Conso, Command};
use Conso\Contracts\{CommandInterface,InputInterface,OutputInterface};

class Test extends Command implements CommandInterface
{
    /**
     * sub commands
     *
     * @var array
     */
    protected $sub  = [

    ];

    /**
     * flags
     *
     * @var array
     */
    protected $flags = [

    ];

    /**
     * command help
     *
     * @var array
     */
    protected $help  = [

    ];

    /**
     * command description
     *
     * @var string
     */
    protected $description = 'This is Test command description.';

    /**
     * execute method
     *
     * @param  InputInterface  $input
     * @param  OutputInterface $output
     * @return void
     */
    public function execute(InputInterface $input, OutputInterface $output) : void
    {
        commandHelp($this->app->invokedCommand, $output);
    }
}
  • now you need to register this command in your commands.php file:
$conso->command('test', Your\NameSpace\Test::class);
  • by default test command will run the execute method if no sub command is provided
  • each sub command is a separate method

⭐ Accessing app from commands :

  • from a callback command
<?php

// test command
$conso->command("test", function($input, $output){

    // get app config
    $this->getName();
    $this->getVersion();
    $this->getAuthor();
    $this->getCommandsPath();
    $this->getCommandsNamespace();

    // calling another command
    $this->call('command:subcommand -f --flags');
});
  • from a class command
<?php

    /**
     * execute method
     *
     * @param  InputInterface  $input
     * @param  OutputInterface $output
     * @return void
     */
    public function execute(InputInterface $input, OutputInterface $output) : void
    {
        // get app config
        $this->app->getName();
        $this->app->getVersion();
        $this->app->getAuthor();
        $this->app->getCommandsPath();
        $this->app->getCommandsNamespace();

        // calling another command
        $this->app->call('command:subcommand -f --flags');
    }

⭐ Commands namespace

  • you can wrap commands in the same namespace with namespace() method which makes things cleaner
<?php

$conso->namespace('Conso\\Commands', function($conso){

    // all commands withing Conso\Commands namespace
    $conso->command("command", Command::class);
    $conso->command("test",    Test::class);
    $conso->command("make",    Make::class);

});

⭐ Http support

  • you can invoke conso from the browser or any http client just by passing commands to the input instance
<?php declare(strict_types=1);

use Conso\{
    Conso,Input,Output
};

require 'vendor/autoload.php';

// you can sanitize and pass your command her
$command = 'command:make HttpCommand';

$input   = new Input($command);

$conso   = new Conso($input, new Output);

require 'commands.php';

$conso->run();

⭐ Compile your app to an executable shareable single .phar file :

  • you can use this feature from version 2.0 and above.
  • to compile your application and create a shareable .phar file use the built in compile command.
  • run php conso compile:init to create a conso.json build file.

compile:init

  • this will generate a json file like follow:
{
    "src": [ /* your pacakge directories to compile should be added here */
        "src\/Conso", 
        "vendor" /* package dependencies if any */
    ],
    "build": "build", /* build location */
    "stub": "conso",  /* stub file (the entry point of your phar) */
    "phar": "conso.phar" /* output (your phar file name) */
}
  • your stub file should look something like this:
<?php // no need for shebang it will be added automatically 

declare(strict_types=1);

use Conso\{
    Conso,Input,Output
};

require 'vendor/autoload.php';

$conso = new Conso(new Input, new Output);

$conso->setName("app name");
$conso->setVersion("2.0.0");

$conso->setSignature(" app signature ");

$conso->disableBuiltInCommands(); // disable conso built in commands

// include your commands
// require 'app/commands.php';

$conso->run();
  • now you can run php conso compile and you will get your package compiled to a phar file.

compiled

  • you can use --no-shebang flag to avoid adding shebang to your phar file (this is useful if you want to invoke your phar file from http)

⭐ Testing helpers:

  • you can use Conso\Testing\TestCase test helper class for testing which helps you to :
    • turn on testing mode for you (return results instead of outputing to STDOUT).
    • disable ansi colors which is not needed when testing.

✨ Todo

  • improve code quality.

✨ Contributing

Thank you for considering to contribute to Conso. All the contribution guidelines are mentioned Here.

💖 Support

If this project helped you reduce time to develop, you can give me a cup of coffee :) : Paypal.

✨ License

Conso is an open-source software licensed under the MIT license.