Clad User Manual: Difference between revisions

From NovaOrdis Knowledge Base
Jump to navigation Jump to search
 
(10 intermediate revisions by the same user not shown)
Line 7: Line 7:
The framework scans the command line looking for the first argument that can be mapped to a command.  
The framework scans the command line looking for the first argument that can be mapped to a command.  


The mapping process involves scanning the classpath and looking for classes implementing the [https://github.com/NovaOrdis/clad/blob/master/src/main/java/io/novaordis/clad/command/Command.java Command interface]. The current version does not introspect all classes, but just those whose simple class name match the following pattern: <tt><commandName>Command</tt>.  
The mapping process involves scanning the classpath and looking for classes implementing the [https://github.com/NovaOrdis/clad/blob/master/src/main/java/io/novaordis/clad/command/Command.java Command interface]. The current version does not introspect all classes, but just those whose simple class name match the following pattern: <tt><commandName>Command</tt>. All arguments between the wrapper name and the command name are interpreted as global options. All arguments following the command name are interpreted as command options.
 
All arguments between the wrapper name and the command name are interpreted as global options.
 
All arguments following the command name are interpreted as command options.


<pre>
<pre>
 
wrapper [global-options] command [command-options]
  wrapper [global-options] command [command-options]
 
</pre>
</pre>


=Concepts=
=Subjects=


<blockquote style="background-color: #f9f9f9; border: solid thin lightgrey;">
<blockquote style="background-color: #f9f9f9; border: solid thin lightgrey;">
:[[clad User Manual - Concepts]]
:[[clad User Manual - Concepts|Concepts]]
</blockquote>
:[[clad User Manual - How to Implement a Command Line Application|How to Implement a Command Line Application]]
 
=Configuration File=
 
Each command line option has a configuration file correspondent. Command line value takes precedence over the configuration file value.
 
=Implementing a Command Line Application=
 
==Declare the Maven Dependency==
 
<pre>
<dependency>
    <groupId>io.novaordis.clad</groupId>
    <artifactId>novaordis-clad</artifactId>
    <version>...</version>
</dependency>
</pre>
 
==Provide an ApplicationRuntime Implementation==
 
Extend  <tt>[https://github.com/NovaOrdis/clad/blob/master/src/main/java/io/novaordis/clad/application/ApplicationRuntimeBase.java ApplicationRuntimeBase]</tt>, into a "clad" sub-package. This is the recommended approach. If you need more flexibility, you can implement <tt>[https://github.com/NovaOrdis/clad/blob/master/src/main/java/io/novaordis/clad/application/ApplicationRuntime.java ApplicationRuntime]</tt> interface.
 
The application runtime functionality is related to the following aspects:
 
===Default Command===
 
To provide a default command, implement <tt>public String getDefaultCommandName()</tt>. For more details on the default command, see "[[Clad_User_Manual_-_Concepts#Default_Command|Default Command]]" section.
 
===Global Options===
 
For more details on the default command, see "[[Clad_User_Manual_-_Concepts#Global_Options|Global Options]]" section.
 
<font color=red>
 
 
Package the application runtime implementation class and the commands in a JAR (or place them in a directory).
 
Set “<tt>application.name</tt>” as a system property. If the application runtime implementation class is <tt>BlueApplicationRuntime</tt>, the application.name must be “blue”.
 
Make sure the JAR or the directory is first on the class path (otherwise other <tt><your-command-name>Command.class</tt>, if exist, will be instantiated first).
 
</font>
 
==In-line Application Help==
 
If a text file named <tt><application-name>.txt</tt> is placed in the same package as the <tt>ApplicationRuntime</tt> implementation class, its content is rendered to <tt>stdout</tt> every time the in-line application help is invoked with no-argument "help" command:
 
<pre>
  <app-name> help|--help|-h
</pre>
 
The length of a text line should not be larger than 99.
 
===Macros===
 
The help renderer recognizes several macros, which are replaced by dynamically generated content at runtime.
 
@COMMANDS@ - inserts the list of commands available to the application. The runtime builds that list via introspection looking for classes that implement the Command interface.
 
=Implementing a Command=
 
Implement the <tt>[https://github.com/NovaOrdis/clad/blob/master/src/main/java/io/novaordis/clad/command/Command.java Command]</tt> interface or extend <tt>[https://github.com/NovaOrdis/clad/blob/master/src/main/java/io/novaordis/clad/command/CommandBase.java CommandBase]</tt> (recommended).
 
The implementation class must be named <tt><command-name>Command</tt>.
 
Example: <tt>PrintCommand</tt> will be matched to the "<tt>print</tt>" command. <tt>BusinessScenarioCommand</tt> will be matched to the "<tt>business-scenario</tt>" command.
 
==Relationship between Command and ApplicationRuntime==
 
If a specific command does not need an application runtime instance (thus the framework is not required to instantiate an application runtime for it), the <tt>Command.needsRuntime()</tt> implementation must return <tt>false</tt>. By default <tt>CommandBase.needsRuntime()</tt> returns <tt>true</tt>.
 
==In-Line Command Help==
 
If a text file named <tt><command-name>.txt</tt> is placed in the same package as the command implementation class, the framework will send the content of the file to <tt>stdout</tt> when in-line command help is requested:
 
<pre>
    <wrapper> help|--help|-h <command>
</pre>
 
For a command whose name is <tt>blue</tt>, the in-line command help file should be named <tt>blue.txt</tt>.
 
For a command whose name is <tt>business-scenario</tt>, the in-line command help file should be named <tt>business-scenario.txt</tt>.
 
The length of a text line should not be larger than 99.
 
==Command Options==
 
To declare that a command requires a specific option, override <tt>Command.requiredOptions()</tt>.
 
To declare that a command accepts a specific option, override <tt>Command.optionalOptions()</tt>.
 
In both cases, the set should contain option definitions only, the command instance is not expected to maintain any state inside the option instances, they can be recreated on each invocation. Example:
 
<pre>
@Override
public Set<Option> optionalOptions() {
    return new HashSet<>(Collections.singletonList(new BooleanOption("ignore-faults")));
}
</pre>
 
Implementation Examples:
 
<blockquote style="background-color: AliceBlue; border: solid thin LightSteelBlue;">
:https://github.com/NovaOrdis/esa/blob/master/src/main/java/io/novaordis/esa/extensions/bscenarios/BusinessScenarioCommand.java<br>
</blockquote>
</blockquote>
==Default Command==
If no command is specified, the framework will use the “default command”, if there is one. If not, the application should display:
<pre>
[error]: no command specified on command line and no default command was configured.
</pre>
<font color=red>
Instructions on how to configure the default command.
</font>
==Command Execution==
<tt>execute()</tt> will be called on the main thread.
==Universal Commands==
The framework comes with a set of universal commands that are available to any application:
===Version and Release Date===
The framework supports the "<tt>version</tt>" command by default. The "<tt>version</tt>" command pulls version and release date from the underlying application and displays it in a standard format:
<pre>
version 1.0
release date 01/26/16
</pre>
=Error Handling=
If a processing error is caused by what the user did, or by the input data, and it can be corrected by user input (or by data correction), throw an UserErrorException with a human-readable message. The upmost runtime layer must be designed so it displays the error message at stderr and System.exit()s.

Latest revision as of 18:17, 8 November 2016

Internal

Overview

The framework scans the command line looking for the first argument that can be mapped to a command.

The mapping process involves scanning the classpath and looking for classes implementing the Command interface. The current version does not introspect all classes, but just those whose simple class name match the following pattern: <commandName>Command. All arguments between the wrapper name and the command name are interpreted as global options. All arguments following the command name are interpreted as command options.

wrapper [global-options] command [command-options]

Subjects

Concepts
How to Implement a Command Line Application