## Galleon CLI tool
This command line tool (_bin/galleon.[sh|bat]_) allows you to provision/manage any products/installations that comply with galleon feature-packs.
Although being a generic tool, a builtin support is offered for products available from maven jboss community universe (eg: wildfly). +
Possible actions that you can operate from the tool: install, uninstall, check for updates, patch, update, undo last provisioning command.

Launching the tool without any argument starts an interactive shell. Type _exit_ to exit the tool. +
Launching the tool with a command as argument will execute the command and exit, eg: _galleon.sh install wildfly-core:current --dir=myinstallation_ +
Launching the tool with _--file=<path to script file>_ will execute the set of commands and exit. +
Launching the tool with _--help_ will display the descriptions of all available options and commands.

### Feature-pack
A key concept in galleon system is the notion of feature-pack. A feature-pack is a content container. It can be a full product (eg: wildfly) 
or part of a product (eg: a wildfly subsystem packaged as a feature-pack). With the tool you are going to install/uninstall/update/... feature-packs. +
NB: A galleon installation can be composed of 1 or more feature-packs.

A feature-pack can be a file on your local file system or located inside a universe (a product catalog).

The tool helps you identify the feature-pack that you can use for the task you want to achieve. In order to take benefit of the full capabilities
offered by the tool, one needs to understand how products are identified inside a universe.

### Universe feature-pack location (FPL)
A feature-pack location (FPL) is the way to identify a product inside a universe without actually expressing any build numbers. 
A lot to commands require that you provide FPL. 

The main (non exhaustive) FPL syntax is: _<product>[@universe]:[version]/[qualifier]_ +
Some examples of FPL to identify wildfly products:

* _wildfly:current_ ==> Final (released) wildfly product current version
* _wildfly:current/alpha_ ==> The latest release of wildfly product current version that is at least of alpha quality.

The things to notice:

* Universe (from where the product comes from) is optional for products located in jboss maven community universe.
* No actual version nor build (eg: 1.0.0-Alpha1-SNAPHOT) is provided. The syntax of FPL is abstract it allows you to express a level of expected quality without
hard-coding any version number.
* Pointed by an FPL is an actual feature-pack artifact (a zipped file) that the tool will download/install,...
* A completer helps you compose FPL when the command you are calling expect one (eg: install).
 
For example, if one installs wildfly product using the following command:

_install wildfly:current/alpha --dir=myInstallation_ 

Then, later, when checking for updates or upgrading _myInstallation_ directory, 
the latest build that is at least of quality alpha will be used to update. 
If a final release is available then it will be installed when upgrading.

NB: Products being unique inside an installation, some commands (eg: _state update_) 
only require the product part (_<product>[@universe]_) of an FPL. For example:

_update --feature-packs=wildfly_

### Universe feature-pack id (FPID)
A feature-pack id (FPID) is the way to identify a product inside a universe by expressing a build number. 
This is the syntax to use when you want to deal with specific builds of a product.

The FPID syntax is: _<product>[@universe]:[version]#[buildID]_ +
Some examples of FPID to identify wildfly products:

* _wildfly:current#1.0.0-Final_
* _wildfly:current#1.0.0-Alpha1_

The things to notice:

* Universe (from where the poduct comes from) is optional for products located in jboss maven community universe.
* Pointed by an FPID is an actual feature-pack artifact (a zipped file)
* A completer helps you compose your FPID when the command you are calling expect one (eg: install).
 
For example, to retrieve the informations of alpha1 build:

_feature-pack get-info wildfly:current#1.0.0-Alpha1_ 

### Listing latest available feature-packs

_[/]$ list-feature-packs [--all-frequencies] [--universe=<universe id>]_ + 

This command lists all the final feature packs present in all the installed universes. +
The command looks in the current directory and its parent hierarchy for a possible installation 
in which some universes would have been added. By default the builtin universe is used. +
If _--all-frequencies_ option is set, then the latest build of all frequencies are displayed. +
If _--universe_ option is set, the command lists the feature packs of this universe. +

TIP: The information displayed by this command can be re-used when installing, updating features-packs.

### Searching for feature-packs

_[/]$ find <pattern> [--universe=<universe id>] [--resolved-only]_ + 

This command searches for all the feature pack builds present in all the installed 
universes that match the provided pattern. +
The command looks in the current directory and its parent hierarchy for a possible installation 
in which some universes would have been added. By default the builtin universe is used. +
If _--universe_ option is set, the command searches for feature packs inside this universe. +
If _--resolved-only_ option is set, the command only searches for feature packs installed in local repositories. +

TIP: The information displayed by this command can be re-used when installing, updating features-packs.

### Installing a feature-pack

_install <[FPL|FPID] | [--file=<path to fp zip file>]> [--dir=<installation dir>] [--verbose] [feature-pack specific options]_

This creates a directory containing the installed feature-pack content (binaries, configs). +

NB: Using completion, when an installation directory has been identified, the options that
are specific to the feature-pack to install are proposed. When installing for the first time
a feature-pack this can take some time (a matter of few seconds up to minutes 
if the feature-pack needs to be downloaded from a remote location).

You can retrieve the set of feature-pack specific options without relying on completion, to do so call: +
_feature-pack get-info <[FPL|FPID] | [--file=<path to fp zip file>]> --type=options_ +
You can then use the listed options (if any) to customize your install command.

### Installing a subset of feature-pack configurations

When installing a feature-pack, all its default configurations are installed. 
Use the _--default-configs=<comma separated list of config_model/config_name>_ option
to specify the subset of configurations to install.

### Installing feature-pack layers

The _install_ command can be used to install a subset of feature-pack features. Such subset are called layers.
When installing layers, a custom configuration is generated.

_install <[FPL|FPID] | [--file=<path to fp zip file>]> [--dir=<installation dir>] [--layers=<comma separated list of layers>] 
[--config=<layers_model/configuration_name>]_

In order to exclude an optional layer on which a layer from the list depends on, 
prefix the excluded layer with '-'. In order to un-exclude a layer already excluded 
in the current installation, prefix the layer with '+'.

NB: When installing layers, the existing provisioned installation (if any) is updated with the set of layers.

* If some layers to install are already installed, they are ignored.
* If some layers to exclude are already excluded, they are ignored.
* If some layers to install are excluded from the existing installation, they are first un-excluded and installed.
* If some layers to exclude are included in the existing installation, the command will fail. You can only exclude not directly included layers.
* If some layers to un-exclude are not excluded, the command will fail.
* If some layers to exclude are not optional dependencies of the layers to install (or from already installed layers), the command will fail.
You can only exclude layers that are optional dependencies.

If no model name is provided, the CLI tries to identify the default model contained in the feature-pack.
If no configuration name is provided, the <layers_model>.xml is used as the generated configuration file name.

You can retrieve the set of feature-pack defined layers without relying on completion, to do so call: +
_feature-pack get-info <[FPL|FPID] | [--file=<path to fp zip file>]> --type=layers_ +
You can then use the listed layers (if any) to customize your install command.

### Un-installing a feature-pack

_uninstall [FPID] [--dir=<installation dir>] [--verbose] [feature-pack specific options]_

This will remove the content installed by the feature-pack identified by the FPID. Some feature-pack specific options
can be provided, they will be used when re-provisioning the remaining (if any) feature-packs.

NB: Completer proposes the FPID you can un-install from the installation (products and patches). Completion
of feature-pack specific options are handled the same way as in the install command.

### Un-doing the last provisioning command

_undo [--dir=<installation dir>] [--verbose]_

This will revert the installation to the previous installed state.

### Patching an installation

Use the _install_ command to patch an existing installation.

_install <[FPL|FPID] | [--file=<path to patch zip file>]> [--dir=<installation dir>] [--verbose] [feature-pack specific options]_

### Un-installing a patch

Use the _uninstall_ command to remove a given patch or use _state undo_ if the last provisioning command has been a patch installation.

### Checking for updates

_check-updates [--dir=<installation dir>] [--include-all-dependencies] [--feature-packs=<list of feature-pack producers>]_

If no products are provided, all installed products are checked for updates.

### Updating an installation

The _update_ command allows to update an installation to the latest available versions of installed feature-packs.

_update [--dir=<installation dir>] [--include-all-dependencies] [--yes] [--feature-packs=<list of feature-pack producers or locations>] [feature-pack specific options]_

Display the list of available updates/patches then update.
If _--yes_ is provided, the command will proceed without asking for confirmation.

NB: If the option _--feature-packs_ contains feature-pack locations with versions, then these versions are used to update the feature-packs.

NB: Using completion, when an installation directory has been identified, the options that
are specific to the installed feature-pack(s) are proposed. When updating an installation for the first time 
this can take some time (a matter of few seconds up to minutes if the feature-pack 
needs to be downloaded from a remote location).

You can retrieve the set of feature-pack specific options without relying on completion, to do so call: +
_installation get-info [--dir=<installation dir>] --type=options_ +
You can then use the listed options (if any) to customize your update command.

### Retrieving changes applied to an installation
In order to visualize files you have added, removed or modified, use the command _get-changes [--dir=<installation>]_. +
In the CLI output added files are prefixed by '+', removed ones by '-' and modified ones by 'M'.

### Persisting changes applied to an installation
Installed feature-packs optionally support persistence of changes into the provisioning configuration. As an example, 
wildfly feature-packs persist configuration changes into the provisioning config.

Use the command _persist-changes [--dir=<installation>]_ to persist the changes. +
  
NB: If the installed feature-packs don't support the ability to merge changes 
into the provisioning configuration, this operation has no side effect.

### Observing an installation

_[my-dir]$ installation get-info [--dir=installation] --type=[all|configs|dependencies|layers|optional-packages|options|patches|universes]_

Display the set of installed feature-packs FPID. In addition can display configurations, dependencies layers and patches. + 
NB: If some patches are applied, the applied patches information is displayed.

### Observing a feature-pack

_[my-dir]$ feature-pack get-info <[FPL|FPID] | [--file=<path to fp zip file>]> --type=[all|configs|dependencies|layers|optional-packages|options]_

Display the FPID of a feature-pack. In addition can display dependencies, configurations, 
layers and options usable when installing/provisioning/upgrading.

### Optional packages

When getting information on an installation or a feature-pack, using _--type=optional-packages_ option, you can retrieve the list of
optional packages. At installation time the set of optional packages installed is controlled by the option _--optional-packages=<all|none|passive|passive+>_. 

There are 2 kind of optional packages. _passive_ ones, that are installed only if all their dependencies are installed and _optional_ 
ones that have no requirements on their dependencies. Generally passive optional packages shouldn't be excluded from an installation. They
are needed for the package to properly operate when the other packages on which it depends are provisioned. Optional packages that are not passive
can be excluded if not needed (according to the execution context). 

When installing a complete feature-pack or installing a default configuration, the default value for _--optional-packages_ is 
_all_ (all optional and passive packages are installed).

When installing layers with the install commands the default value for _--optional-packages_ is 
_passive+_ (all optional and passive packages that have all their dependencies installed are installed).

You can override these default values by using the _--optional-packages_ option. 
Use _none_ value to not install any optional nor passive packages, _passive_ value to only install passive packages that have all their dependencies installed.

### Managing the local cache of feature-packs

When a feature-pack is internally resolved (at install time, to expose information, 
to retrieve plugin options, ...). The feature-pack is added to a local cache. 
This cache is re-used to speed-up future resolutions. The CLI cleanup un-used feature-pack from the cache
that are older than one month. 

You can import (and optionally install in the universe for later resolution) a feature-pack zip file in the cache.

_[my-dir]$ feature-pack import <path to fp zip file> [--install-in-universe=<true|false>]_

You can clear the cache fully (NB: this will have a performance impact for future resolution).

_[my-dir]$ feature-pack clear-cache_

### Exporting an installation to xml

_[my-dir]$ installation export <new generated xml file> --dir=<installation>_

###  Provisioning an installation from xml

_[my-dir]$ provision <xml file> --dir=<target installation directory> [feature-pack specific options]_

NB: Using completion, when an installation directory has been identified, the options that
are specific to the feature-pack(s) located in the XML configuration file are proposed. 
When provisioning an installation for the first time this can take some time 
(a matter of few seconds up to minutes if the feature-pack needs to be downloaded from a remote location).

### Managing the history of an installation

By default the history keeps the state of the last 100 provisioning operations. This should be enough to cover 
simple undo of provisioned state. Nevertheless you can increase/decrease this
value by using the following command: +

_installation set-history-limit <history size limit> [--dir=<installation dir>]_

To retrieve the history size limit do:

_installation get-history-limit [--dir=<installation dir>]_ +

### Managing installation universes
A universe can be added/removed to/from an existing installation. +
 
Add a named or default (without using the --name option) universe to an installation. +
_[/]$ installation add-universe [--dir=<installation dir>] [--name=<universe name>] --factory=<universe factory> --location=<universe location>_

Remove a named or default (without using the --name option) universe from an installation. + 
_[/]$ installation remove-universe [--dir=<installation dir>] [--name=<universe name>]_


### Directory option
Some commands (eg: install, get-info, check-updates, ...) allow you to optionally provide a target directory thanks to the _--dir=<path>_ option. 
If no directory is provided, the command will lookup for an existing installation in the 
current directory (that you can change with the _cd_ command) and its parent directories hierarchy. 
If no installation exists, the command will abort.

There are some exceptions to this installation lookup. _install and provision_ commands expect the current directory 
to be empty or to be the root of an installation. _uninstall, undo and update_ commands expect 
the current directory to be the root of an installation.

### Exploring an installation or a feature-pack.

The tool allows you to switch to a state edit mode in which you can observe and 
edit a provisioning state in memory (without actually impacting the installation files).

To explore an installation: +
_[my-dir]$ state edit [<installation dir>]_ +
_[!edit!my-dir!/]$_ +
After this point, the tool switched to edit mode with a set of new commands available. +

TIP: Type _help_ to list the set of available commands in this mode.

To explore a feature-pack: +
_[my-dir]$ state new_ +
_[!edit!/]$ add-dependency <[FPL|FPID] --default-configs-inherit --packages-inherit_ +

Once exploring, prompt, ls, cd and pwd commands are bound to the feature-pack (or installation) exposed file-system. +
Use _leave-state_ to switch the tool back to its nominal mode.

_[!edit!/]$ ls +
configs +
dependencies +
feature-specs +
packages +
[!edit!/]$ leave-state +
[my-dir]$_ +

The fs is composed of: +
/configs/final/<model>/<name>/<features> +
/feature-specs/<origin>/<feature-specs> +
/packages/<origin>/<packages> + 
Features and feature-specs are organized as a file system with containment. +

TIP: Use ‘ls’ to visualize any item. Use ‘cd’ to navigate to a given node.

### Searching the current state

When in edit mode, one can search for packages and features.

_[!edit!/]$ search [--query=<some text> | --package=<package name>]_

When searching with _--query_ all packages and features are looked-up for a match. If packages are matched, the features
that depend directly or indirectly on these packages will be shown in the result.

When searching with _--package_, the package completer can be used. The features that depend directly or 
indirectly on this package will be shown in the result.

### Creating a new state (or editing an existing state from an installation or provisioning XML file)

This allow to start from an empty installation or re-use an installation and iteratively add/suppress content. +

_[my-dir]$ state new  | state edit <path to installation dir | path to provisioning XML file> +
[!edit!/]$ ls +
configs +
dependencies +
feature-specs +
packages_

NB: Each action as the effect to build a runtime with the current state. The filesystem reflects the current state.

NB: Each action applied to a state in edition can be undone: _undo_. 

NB: Use _leave-state_ to leave the edit mode.

NB: The set of completer exposed commands is dynamic and is adjusted according to the current state.

### Exporting or provisioning the current state

In edit mode, one can export the provisioning XML file or directly provision from the current state:

_[!edit!/]$ export [<path to generated xml file>]_ +
_[!edit!/]$ provision <dir of new installation>_

TIP: Use _export_ to validate that what you get in the XML is in sync with the expose state.

TIP: Exporting a state without any XML target file will display the XML content in the CLI console.

TIP: The command 'get-info' can be used to get high level information.

### Adding a feature-pack

_[!edit!/]$ add-dependency <FPL|FPID> [--default-configs-inherit] [--packages-inherit]_ +

By default nothing is inherited. Once at least one feature-pack has been added, configurations or packages can be handled. 

### Removing a feature-pack

_[!edit!/]$ remove-dependency <FPL|FPID>_

### Including a default configuration

_[!edit!/]$ include-config <model>/<name> [--origin=<fp origin>]_

Origin is optional, by default will be included from all fp that expose it.

### Removing an included default configuration

_[!edit!/]$ remove-included-config <model>/<name> [--origin=<fp origin>]_

The completer only proposes the set of configurations that have been previously included.
Origin is optional, by default will be remove from all fp that include it.

### Excluding a default configuration

_[!edit!/]$ exclude-config <model>/<name> [--origin=<fp origin>]_

Origin is optional, by default will be excluded from all feature-packs that expose it.

### Removing an excluded default configuration

_[!edit!/]$ remove-excluded-config <model>/<name> [--origin=<fp origin>]_

The completer only proposes the set of configurations that have been previously excluded.
Origin is optional, by default will be removed from all feature-packs that exclude it.

### Including layers into a configuration

NB: Prior to be able to include layers into a configuration you need an included default or locally defined configuration.
To define a new configuration call _define-config --model=<config model> --name=<config name>_

_[!edit!/]$ include-layers <config model/config name> --layers=<comma separated list of layers>_

NB: The completers for both configuration and layers propose you with the existing configurations and layers not already included.

### Removing included layers from a configuration

_[!edit!/]$ remove-included-layers <config model/config name> --layers=<comma separated list of included layers>_

NB: You can only remove layers that have been explicitly included in your local configuration. Layers included in a default configuration
can be excluded but their inclusion can't be removed. 

### Excluding layers from a configuration

NB: Prior to be able to exclude layers from a configuration you need an included default or locally defined configuration that contain layers.

_[!edit!/]$ exclude-layers <config model/config name> --layers=<comma separated list of layers>_

NB: The completers for both configuration and layers propose you with the existing configurations and included layers.

### Removing excluded layers from a configuration

_[!edit!/]$ remove-excluded-layers <config model/config name> --layers=<comma separated list of excluded layers>_

NB: You can only remove layers that have been explicitly excluded in your local configuration.

### Reseting a configuration

_[!edit!/]$ reset-config <model>/<name>_

The custom content of this configuration is removed.

NB: This has no effect on included/excluded configurations.

### Including a default package

_[!edit!/]$ include-package <fp origin>/<package name>_

### Removing an included default package

_[!edit!/]$ remove-included-package <package name> [--origin=<fp origin>]_

The completer only proposes the set of packages that have been previously included.
The origin is optional, the package will be removed from all feature-packs that exclude it.

### Excluding a default package

_[!edit!/]$ exclude-package <fp origin>/<package name>_

### Removing an excluded default package

_[!edit!/]$ remove-excluded-package <package name> [--origin=<fp origin>]_

The completer only proposes the set of packages that have been previously excluded.
The origin is optional, the package will be removed from all feature-packs that exclude it.

### Adding a new feature

_[!edit!/]$ add-feature <config model/name> <path to feature-spec>  <dynamic set of feature param=<value>>_

For example: +
_add-feature standalone/standalone.xml org.wildfly.core:wildfly-core-galleon-pack/interface --interface=toto --inet-address=127.0.0.1_

NB: All parameters are exposed as command option.
 
NB: All parameters that are not nillable and have no default values are required. The command being aborted if there are missing required parameters. 

NB: If the parameter is not present, its default value is injected when creating the feature.

NB: The current location (thanks to cd) is not yet taken into account when completing/adding the feature. That is a TODO.

NB: A feature with the same feature-id can’t exist. A single feature with the given feature-id per config.

### Removing a feature
_[!edit!/]$ remove-feature <full path to feature inside a configuration>_

For example: +
_remove-feature standalone/standalone.xml/interface/toto_

### Managing universes
A universe can be added/removed to/from a state. +
 
Add a named or default (without using the --name option) universe to the state. +
_[!edit!/]$ add-universe [--name=<universe name>] --factory=<universe factory> --location=<universe location>_

Remove a named or default (without using the --name option) universe from the state. + 
_[!edit!/]$ remove-universe [--name=<universe name>]_
