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:

  1. PATH=$PATH:/usr/local/lithium/console

Creating a new Command

User-defined commands are located in /app/extensions/command/ by
default. Let’s create a simple application that list the repositories of
a given organization.

First, create the new file at /app/extensions/command/Repos.php. This
is what we’ll start with:

  1. namespace app\extensions\command;
  2. 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.”

  1. COMMANDS via app
  2. 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().

  1. namespace app\extensions\command;
  2. class Repos extends \lithium\console\Command {
  3. public function run($org = '') {
  4. echo "Org: $org\n";
  5. }
  6. }

You can also use in() to ask the user for input:

  1. namespace app\extensions\command;
  2. class Repos extends \lithium\console\Command {
  3. public function run($org = '') {
  4. if($org == '') {
  5. $org = $this->in("Organization?");
  6. }
  7. echo "Org: $org\n";
  8. }
  9. }

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.

  1. namespace app\extensions\command;
  2. class Repos extends \lithium\console\Command {
  3. public function run($org = '') {
  4. if($org == '') {
  5. $this->error("{:red}No organization supplied.{:end}");
  6. $org = $this->in("Organization?");
  7. }
  8. $this->out("{:green}Org: $org{:end}");
  9. }
  10. }

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:

  1. namespace app\extensions\command;
  2. use lithium\net\http\Service;
  3. class Repos extends \lithium\console\Command {
  4. public function run($org = '') {
  5. if($org == '') {
  6. $this->error("{:red}No organization supplied.{:end}");
  7. $org = $this->in("Organization?");
  8. }
  9. $this->out("{:green}Org: $org{:end}");
  10. $service = new Service([
  11. 'scheme' => 'https',
  12. 'host' => 'api.github.com'
  13. ]);
  14. $repos = $service->get('/orgs/' . $org . '/repos');
  15. $this->header("$org Repos:");
  16. foreach($repos as $repo) {
  17. $this->out($repo['full_name']);
  18. }
  19. }
  20. }

Here’s a sample of the output:

  1. $ li3 repos UnionOfRad
  1. Org: UnionOfRad
  2. /-----------------
  3. UnionOfRad Repos:
  4. /-----------------
  5. UnionOfRAD/phpca
  6. UnionOfRAD/li3_sqlsrv
  7. UnionOfRAD/framework
  8. UnionOfRAD/li3_docs
  9. UnionOfRAD/lithium_bin
  10. UnionOfRAD/li3_design
  11. UnionOfRAD/manual
  12. UnionOfRAD/lithium
  13. UnionOfRAD/li3_qa
  14. UnionOfRAD/li3_cldr
  15. UnionOfRAD/li3_lab
  16. UnionOfRAD/li3_bot
  17. UnionOfRAD/li3_lldr
  18. UnionOfRAD/li3_quality
  19. UnionOfRAD/li3_queue
  20. UnionOfRAD/sphere
  21. UnionOfRAD/li3_couchbase
  22. UnionOfRAD/li3_sqltools
  23. UnionOfRAD/li3_fixtures