Creating a new CLI task

This topic contains information about providing new command line tasks.

Creating a cli task

Any module can provide a command line task by registering a handler for the cliTask event.

Task handler

The preferred way to create a cliTask handler is place a Groovy script in the app/tasks directory. The virtual directory feature of IBM® WebSphere® sMash automatically find the new cliTasks. The groovy script provides an implementation of onCliTask.

If the task handler is written in Java™, then the handler is added to the configuration handlers using the cliTask event.

# MyTask
/config/handlers += [{
   "events": "cliTask",
   "handler" : "zero.simple.task.MyTask.class",
   "conditions" : "/event/task =~ mytask"	
}]

The Java based task must provide an implementation of the method onCliTask and the GlobalContext is used to obtain the event args.

public void onCliTask() {
   List<String> args = GlobalContext.zget("/event/args");
   ... 
}	

A cliTask handler might need know what the current directory is. This can be obtained from the system property user.dir.

Creating subtasks

The command line task support also supports grouping a set of tasks as subtasks. The following snippet shows how to define a subtask. The event/task is used to define the task name, and then event/subTask defines the subtask. The condition match will case the onCliSubTask method of the handler to be invoked.

# MySubTask
/config/handlers += [{
    "events": "cliSubTask",
    "handler" : "zero.simple.task.MySubTask.class",
    "conditions" : "(/event/task =~ mytask) && (/event/subTask =~ mysubtask)"
}]

Invoking the task directly, zero mytask, displays the help for the task and all of the subtasks. Each subtask is invoked through the command line using zero mytask subtask.

Task implementations

The task implementation might need access to where the task was invoked from and where the WebSphere sMash home is. The system property user.dir can be used to determine where the task was invoked from, but this might not be desired information. The command line supports a walk up feature where tasks for a module can be invoked from any directory under the module. The apphome is the root directory of the module and can be obtained from the event zone, event/apphome. The root directory of the module is probably more useful to find artifacts like the config directory.

static public File getAppRoot() {
    File app = zget("/event/apphome");
    return app;
}

Some tasks might also need know where the command line was installed, also referred to as zerohome. The command line scrips set zerohome as an environment property.

String zerohome = System.getenv("ZERO_HOME");

A task should implement the -json option, which allows a structured output that can be reliably parsed by applications like the Application Builder. In general, a task displays messages with the LogHelper with level INFO, which writes to stderr. When -json is specified a json structure result should be displayed to stdout. This allows programmatically invoking commands and using the exit code and -json option to determine the results.

The version command in zero.cli.tasks has a -full option that will display more comprehensive results for problem determination. The -full option will fire a collectInfo event that will allow other components to provide additional detailed information that will be aggregated. The collectInfo task implementors should check for the -json option, and if specified add their results to the map that can be obtained from /event/collectResults. The results should be placed in the map under a module label, for example, zero.cli.tasks. If -json is not specified, then the results should be displayed using the LogHelper.

The map found in the event zone /event/collectResults can not be replaced. The version task requires that this map is updated with the additional information.

The following snippets should registering a handler for the collectInfor event, and providing results. The -json option can be tested by parsing the args passed in /event/args.

/config/handlers += [{
    "events": "cliTask",
    "handler" : "my.component.Dump.class",
    "conditions" : "/event/task =~ collectInfo"
}]
public void onCliTask() {
    Object obj = zget("/event/collectResults");
    if (obj != null && obj instanceof Map ) {
       ((Map)obj).put("my.component", "my.results");
    }

Task help

The task support includes a help component that allows displaying help text for each of the tasks. The help component is implemented using property files that are placed under the app/tasks/help folder. The naming convention for the help property file is taskname.properties. A task can also supply help for all supported locales by providing properties files with language, country and variants specified.

The following list is the search order used to find the appropriate help property file for a task using the user’s locale:

  • taskname_language_country_variant.properties
  • taskname_language_country.properties
  • taskname_language.properties
  • taskname.properties

An example to provide help properties file for the resolve task for english ( default ) and japanese could be to provide the following two properties files. Additional property files could be supplied to support other locale variants as well.

resolve_ja.properties
resolve.properties

The help component also supports displaying help for subtasks by placing those help property files under the app/tasks/help/${subtask} folder, where ${subtask} is the name of the subtask.

The help property file supports both short and full help text. The short help is displayed when help for all tasks, including subtasks, is requested. Full help is displayed when the help is requested for a single task.

Short text should be limited to one line and is specified in help property file for a task with the label short.

The full text is specified with a label of full and allows multiple lines. Each specified line is printed with a new line to allow some control over formatting.

The following is an example of help properties file for a task.

short=Prints the documentation for the given command.
full.1=Usage:
full.2=
full.3=zero help [<command>]
full.4=
full.5=The command will print the documentation for the given command. If no command is provided, it will print a short summary of all commands currently available to the command line.