Console Applications
Console applications in li3 allow you to access your application
infrastructure from the command line. The Console
libraries li3
features also allow you to perform oft-used features in a shell
environment.
The li3
Shell Command
Before we get started, you'll want to make sure that your shell knows
where the li3
command is.
If my li3 installation was at /usr/local/lithium
, I'd add the
following to my Bash configuration to make sure the li3
command was
universally available to me:
PATH=$PATH:/usr/local/lithium/console
Creating a new Command
User-defined commands are located in extensions/command
by
default. Let's create a simple application that list the repositories of
a given organization.
First, create the new file at extensions/command/Repos.php
. This
is what we'll start with:
namespace app\extensions\command;
class Repos extends \lithium\console\Command {}
If you run $ li3
now, you'll see that li3 can already see your
command. Look towards the end of the output, just after "COMMANDS via
app."
COMMANDS via app
repos
If you document the Repos class with a comment, it will be shown when li3 is executed without any arguments.
Command I/O
By default, the run()
method of your newly created Command is called
when a user executes li3 <command name>
from a shell. The easiest way
to get input from a user is via command-line arguments. Arguments passed
to the Command are supplied as arguments to run()
.
namespace app\extensions\command;
class Repos extends \lithium\console\Command {
public function run($org = '') {
echo "Org: $org\n";
}
}
You can also use in()
to ask the user for input:
namespace app\extensions\command;
class Repos extends \lithium\console\Command {
public function run($org = '') {
if($org == '') {
$org = $this->in("Organization?");
}
echo "Org: $org\n";
}
}
And rather than using echo
to send output to the user, we can use
out()
or error()
to send to STDOUT and STDERR. Apart from adding
newlines automatically, these methods can also send colored output by using style tags.
namespace app\extensions\command;
class Repos extends \lithium\console\Command {
public function run($org = '') {
if($org == '') {
$this->error("{:red}No organization supplied.{:end}");
$org = $this->in("Organization?");
}
$this->out("{:green}Org: $org{:end}");
}
}
Adding Functionality
Finally, let's add a bit of functionality to interact with the GitHub
API. Because we have full access to li3 classes, we declare them via
uses
above the class definition like we normally would and use those
classes in our Command logic:
namespace app\extensions\command;
use lithium\net\http\Service;
class Repos extends \lithium\console\Command {
public function run($org = '') {
if($org == '') {
$this->error("{:red}No organization supplied.{:end}");
$org = $this->in("Organization?");
}
$this->out("{:green}Org: $org{:end}");
$service = new Service([
'scheme' => 'https',
'host' => 'api.github.com'
]);
$repos = $service->get('/orgs/' . $org . '/repos');
$this->header("$org Repos:");
foreach($repos as $repo) {
$this->out($repo['full_name']);
}
}
}
Here's a sample of the output:
$ li3 repos UnionOfRad
Org: UnionOfRad
/-----------------
UnionOfRad Repos:
/-----------------
UnionOfRAD/phpca
UnionOfRAD/li3_sqlsrv
UnionOfRAD/framework
UnionOfRAD/li3_docs
UnionOfRAD/lithium_bin
UnionOfRAD/li3_design
UnionOfRAD/manual
UnionOfRAD/lithium
UnionOfRAD/li3_qa
UnionOfRAD/li3_cldr
UnionOfRAD/li3_lab
UnionOfRAD/li3_bot
UnionOfRAD/li3_lldr
UnionOfRAD/li3_quality
UnionOfRAD/li3_queue
UnionOfRAD/sphere
UnionOfRAD/li3_couchbase
UnionOfRAD/li3_sqltools
UnionOfRAD/li3_fixtures