Subcommands
Functionality in the CLI is provided through subcommands. Bundles may supply
new subcommands with the
com.ibm.team.filesystem.cli.core/subcommand extension point.
The extension point requires two classes: one to provide the options to parse
the command-line (an implementor of IOptionSource), and another (implementing
ISubcommand) to do the actual work.
Subcommand lifecycle
- Application is instantiated and parses the command-line passed to the
application. This includes everything up to and including the name of the
subcommand.
- Application checks the
subcommand extension point, trying to
find the subcommand the user requested.
- The subcommand bundle is found, and the IOptionSource for the subcommand
is loaded. This allows the Application to dig through the arguments passed
to the subcommand before deciding on a workspace root.
- The Application asks the subcommands bundle how the workspace should be
initialized (specified by the
initpolicy attribute of the
extension point). The subcommand will likely request to use an ancestor
of the current directory, or the value of the '-d/--directory' option on
the subcommandline.
- Assuming initialization succeeds, the implementor
ISubcommand
is instantated, and control passes to its run() method.
- The subcommand executes, and, if all goes well, returns quietly. If
something goes wrong, it throws an instance of
FileSystemClientException. The application catches the
exception and checks to see if the stack trace should be shown
(with Constants#showStackTraceFor()). Finally, it returns the status code
as a return value from the app.
Creating New Subcommands
When creating a new subcommand, keep in mind:
- Many bundles require the OSGi instance area to be set. If the
org.eclipse.core.resources bundle (or one of its dependents)
is loaded before the instance area, classloading may fail. Place
breakpoints in bundle activators to track down class loading problems.
- Where possible, reuse option names. Many options are defined in
CommonOptions.
- Make the application's return value meaningful.
Constants
defines a number of error conditions. Reuse those if possible.
- The data emitted on the standard out should be easy to parse. Where
possible, fail with a meaningful return value, and write a
human-readable description of the problem to the standard error.
- Option names may change over time. Treat the long option names as API and
avoid changing them. Short options may change if need be.