classes/CLI.md

CLI

Overview:

CLI is a lightweight command router for CLI scripts. It parses argv, supports flags, and dispatches to named command handlers.

Use CLI for project commands, maintenance scripts, and deployment tasks where argument parsing, help output, and command dispatch should stay uniform.

Key behavior:

Public API:

Example:

CLI::on('greet :name', function ($name) {
  CLI::writeln("Hello $name");
}, 'Print a greeting');
CLI::run();

TUI (CLI::UI)

---

The TUI facade provides gum-like prompts and styling without external dependencies.

Core methods:

Example:

$ui = CLI::UI();
$name = $ui->input('Your name', [
  'placeholder' => 'Rick',
  'inline' => true,
  'card' => true,
  'title' => 'Input',
  'theme' => 'lipgloss',
  'border' => 'rounded',
]);

$color = $ui->select('Pick a color', ['Red', 'Green', 'Blue'], [
  'card' => true,
  'card_prompt' => false,
  'title' => 'Select',
  'theme' => 'lipgloss',
  'border' => 'rounded',
]);

Scripted and debug options:

CLI TUI Demo

---

Demo tool:

php tools/cli-demo.php demo

Composer script:

composer cli-demo

Scripted demo (non-interactive):

CORE_CLI_FORCE_TTY=1 CORE_CLI_SCRIPTED=1 CORE_CLI_SNAPSHOT=1 php tools/cli-demo.php demo

You can define a command line interface via "command routes".

Similar to the Route module, the CLI module is responsible for this feature.

Create a simple CLI app

---

Create a new file and give execution permissions:

$ touch myapp && chmod +x myapp

Write this stub into myapp file :

#!/usr/bin/env php
<?php
// Load Core and vendors
include 'vendor/autoload.php';

// Define commands routes here...

// Run the CLI dispatcher
CLI::run();

Define a command route

---

CLI routes are defined by whitespace separated fragments.

CLI::on('hello',function(){
  echo "Hello, friend.",PHP_EOL;
});
$ ./myapp hello
Hello, friend.

Other "static" parameters, if passed are required for the command execution.

CLI::on('hello friend',function(){
  echo "Hello, friend.",PHP_EOL;
});
$ ./myapp hello
Error: Command [hello] is incomplete.
$ ./myapp hello friend
Hello, friend.

You can extract parameter from the route by prefixing the fragment name by a semicolon ":". Extracted fragments are required and will be passed to the route callback by left-to-right position.

CLI::on('hello :name',function($name){
  echo "Hello, $name.",PHP_EOL;
});
$ ./myapp hello
Error: Command [hello] needs more parameters.
$ ./myapp hello "Gordon Freeman"
Hello, Gordon Freeman.

Read options

---

Options are position free parameters, they can be passed everywhere in the command route and are optional.

You can retrieve their value with the CLI::input($name, $default = null) method.

CLI::on('process :filename',function($filename){
  $optimize   = CLI::input('optimize',false);
  $outputfile = CLI::input('output',$filename.'.out');
  
  $data = file_get_contents($filename);
  /* process $data */
  if ($optimize) { /* optimize data */ };
  file_put_contents($outputfile,$data);
});
./myapp process --optimize ./test.html --output=test_opt.html

If you don't pass an argument for an option --optimize, the true value will be used.