Console Applications

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:

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.

  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. $org = $this->in("Organization?");
  5. }
  6. echo "Org: $org\n";
  7. }

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:

Here’s a sample of the output:

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