/minicli

A minimalist framework for command-line applications in PHP

Primary LanguagePHPMIT LicenseMIT

logo

Latest Stable Version Total Downloads License Documentation Status

Minicli

Minimalist, dependency-free framework for building CLI-centric PHP applications


Minicli is a minimalist, dependency-free framework for building CLI-centric PHP applications. It provides a structured way to organize your commands, as well as various helpers to facilitate working with command arguments, obtaining input from users, and printing colored output.

Quick links:

Dependency-free: What Does it Mean

What does it mean to be dependency-free? It means that you can build a working CLI PHP application without dozens of nested user-land dependencies. The basic minicli/minicli package has only testing dependencies, and a single system requirement:

  • PHP >= 8.1

Note: If you want to obtain user input, then the readline PHP extension is required as well.

It gives you a lot of room to choose your own dependencies.

Getting Started

There are two ways to get started. If you want the bare minimum, what we'll call "Minimalist App", you can create a single PHP script with your whole application. If you want a more structured application, with commands and subcommands, then you should use Command Namespaces to organize your commands into Controllers.

Minimalist App

If you just want to set up a few simple commands to run through minicli, all you need to do is to create an App and register your commands as anonymous functions.

  1. Create an empty project
  2. Run composer require minicli/minicli - this will generate a new composer.json file.
  3. Create a minicli script with the following content:
#!/usr/bin/env php
<?php

if (php_sapi_name() !== 'cli') {
    exit;
}

require __DIR__ . '/vendor/autoload.php';

use Minicli\App;
use Minicli\Command\CommandCall;

$app = new App();
$app->setSignature('./minicli mycommand');

$app->registerCommand('mycommand', function(CommandCall $input) {
    echo "My Command!";

    var_dump($input);
});

$app->runCommand($argv);

Then, make it executable and run minicli with your command:

chmod +x minicli
./minicli mycommand

Structured App (Recommended)

For a more structured application using Controllers and Services, it's best to use Command Namespaces. Our application template repository is a great starting point / template to set up Minicli that way.

To create a new project using the minicli/application template, run:

composer create-project --prefer-dist minicli/application myapp

This will generate a directory structure like the following:

.
app
└── Command
    └── Help
        ├── DefaultController.php
        ├── TableController.php
        └── TestController.php
├── composer.json
├── docs
├── LICENSE
├── minicli
├── mkdocs.yml
└── README.md

Each directory inside app/Command represents a Command Namespace. The classes inside app/Command/Help represent subcommands that you can access through the main help command.

You can now run the boostrapped application with:

./minicli help

The documentation contains more detailed information about creating commands and working with output.

Color Themes

Minicli supports the use of color themes to change the style of command line output. There is currently 3 built-in themes other than the default theme:

  • Unicorn: a more colorful theme.
  • Dalton: a color-blind friendly theme.
  • Dracula: a popular dark theme.

To set the theme, pass in a configuration array with a theme value when initializing App in the script. Built-in themes need a leading \ character:

$app = new App([
    'theme' => '\Unicorn'
]);

To use the default built-in theme, do not include the theme configuration setting, or set it to an empty string.

User-defined themes can also be created and defined in your project. In this case, set the theme name including its namespace without a leading \:

$app = new App([
    'theme' => 'App\Theme\Blue'
]);

The above setting would use the following example theme:

<?php
// File: app/Theme/BlueTheme.php

namespace App\Theme;

use Minicli\Output\Theme\DefaultTheme;
use Minicli\Output\CLIColors;

class BlueTheme extends DefaultTheme
{
    public function getThemeColors(): array
    {
        return [
            'default'     => [ CLIColors::$FG_BLUE ],
            'alt'         => [ CLIColors::$FG_BLACK, CLIColors::$BG_BLUE ],
            'info'        => [ CLIColors::$FG_WHITE],
            'info_alt'    => [ CLIColors::$FG_WHITE, CLIColors::$BG_BLUE ]
        ];
    }
}

User-defined themes only need to define styles which will override those in the default theme.

Contributing

Contributions are very welcome! You can contribute with code, documentation, filing issues... Please refer to our contributing doc for more information on the contribution process and what we expect from you.

Running the Test Suite

Minicli uses Pest PHP as testing framework. Once you have all dependencies installed via composer install, you can run the test suite with:

./vendor/bin/pest

To obtain the code coverage report, you'll need to have xdebug installed. Then, you can run:

./vendor/bin/pest --coverage

And this will give you detailed information about code coverage.

Building Minicli

The following tutorials on dev.to compose a series named "Building Minicli", where we create minicli from scratch:

Note: Minicli has evolved a lot since that series was initially written, but that was the base for what Minicli is today.