Moved manual installation instructions in docs

= APOC User Guide {apoc-release}
:toc: left
:experimental:
:sectid:
:sectlinks:
:toclevels: 3
:img: https://raw.githubusercontent.com/neo4j-contrib/neo4j-apoc-procedures/{branch}/docs/img
:script: https://raw.githubusercontent.com/neo4j-contrib/neo4j-apoc-procedures/{branch}/docs/script

== Introduction

NOTE: Go here for documentation for APOC for Neo4j version link:index30.html[3.0.x] link:index31.html[3.1.x] link:index32.html[3.2.x] link:index33.html[3.3.x]

++++

++++

include::../readme.adoc[tags=intro,leveloffset=1]

++++

++++

include::../readme.adoc[tags=signature,leveloffset=1]

== Help and Usage

include::overview.adoc[tags=help,leveloffset=-1]

To generate the help output, apoc utilizes the built in `dbms.procedures()` and `dbms.functions()` utilities.

== Installation in Neo4j Server & Docker

include::../readme.adoc[tags=install,leveloffset=1]

include::../readme.adoc[tags=warnings,leveloffset=0]

include::../readme.adoc[tags=docker,leveloffset=0]

// include::overview.adoc[tags=overview,leveloffset=1]

== Overview of APOC Procedures & Functions

[[table-all]]
[separator=¦,opts=header]
|===
include::../build/generated-documentation/documentation.csv[]
|===

include::functions.adoc[leveloffset=+1]

== Text and Lookup Indexes

=== Index Queries

Procedures to add to and query manual indexes

NOTE: Please note that there are (case-sensitive) http://neo4j.com/docs/developer-manual/current/#cypher-schema[automatic schema indexes], for equality, non-equality, existence, range queries, starts with, ends-with and contains!

[separator=¦,opts=header,cols="1,1m,5"]
|===
include::../build/generated-documentation/apoc.index.csv[]
|===

////
[cols="1m,5"]
|===
| apoc.index.addAllNodes('index-name',{label1:['prop1',...],...}, {options}) | add all nodes to this full text index with the given fields, additionally populates a 'search' index field with all of them in one place
| apoc.index.addNode(node,['prop1',...]) | add node to an index for each label it has
| apoc.index.addNodeByLabel('Label',node,['prop1',...]) | add node to an index for the given label
| apoc.index.addNodeByName('name',node,['prop1',...]) | add node to an index for the given name
| apoc.index.addRelationship(rel,['prop1',...]) | add relationship to an index for its type
| apoc.index.addRelationshipByName('name',rel,['prop1',...]) | add relationship to an index for the given name
| apoc.index.removeNodeByName('name',node) remove node from an index for the given name
| apoc.index.removeRelationshipByName('name',rel) remove relationship from an index for the given name
|===
////

image::{img}/apoc.index.nodes-with-score.jpg[width=600]

////

[cols="1m,5"]
|===
| apoc.index.search('index-name', 'query') YIELD node, weight | search for the first 100 nodes in the given full text index matching the given lucene query returned by relevance
| apoc.index.nodes('Label','prop:value*') YIELD node, weight | lucene query on node index with the given label name
| apoc.index.relationships('TYPE','prop:value*') YIELD rel, weight | lucene query on relationship index with the given type name
| apoc.index.between(node1,'TYPE',node2,'prop:value*') YIELD rel, weight | lucene query on relationship index with the given type name bound by either or both sides (each node parameter can be null)
| apoc.index.out(node,'TYPE','prop:value*') YIELD node, weight | lucene query on relationship index with the given type name for *outgoing* relationship of the given node, *returns end-nodes*
| apoc.index.in(node,'TYPE','prop:value*') YIELD node, weight | lucene query on relationship index with the given type name for *incoming* relationship of the given node, *returns start-nodes*
|===
////

=== Index Management

////
[cols="1m,5"]
|===
| CALL apoc.index.list() YIELD type,name,config | lists all manual indexes
| CALL apoc.index.remove('name') YIELD type,name,config | removes manual indexes
| CALL apoc.index.forNodes('name',{config}) YIELD type,name,config | gets or creates manual node index
| CALL apoc.index.forRelationships('name',{config}) YIELD type,name,config | gets or creates manual relationship index
|===
////

.Add node to index example
[source,cypher]
----
match (p:Person) call apoc.index.addNode(p,["name","age"]) RETURN count(*);
// 129s for 1M People
call apoc.index.nodes('Person','name:name100*') YIELD node, weight return * limit 2
----

// include::overview.adoc[tags=fulltext]

include::manual-indexes.adoc[leveloffset=2]

include::fulltext.adoc[leveloffset=2]

== Utility Functions

include::phonetic.adoc[leveloffset=2]
include::extract.adoc[leveloffset=2]

include::ttl.adoc[leveloffset=2]

include::datetime.adoc[leveloffset=2]

include::number.adoc[leveloffset=2]

include::exact.adoc[leveloffset=2]

include::diff.adoc[leveloffset=2]

== Graph Algorithms

include::algo.adoc[leveloffset=2]
include::expand.adoc[leveloffset=2]
include::centrality.adoc[leveloffset=2]
include::pagerank.adoc[leveloffset=2]

== Spatial

include::spatial.adoc[leveloffset=2]

== Data Integration

include::loadjson.adoc[leveloffset=2]
include::loadjdbc.adoc[leveloffset=2]
include::loadcsv.adoc[leveloffset=2]
include::gephi.adoc[leveloffset=2]
include::elasticsearch.adoc[leveloffset=2]
include::loadxml.adoc[leveloffset=2]
include::loadhtml.adoc[leveloffset=2]over

== Graph Refactorings

include::refactor.adoc[leveloffset=2]

== Cypher Operations

include::cypher.adoc[leveloffset=2]
include::periodic.adoc[leveloffset=2]

++++
<link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/1.10.13/css/jquery.dataTables.min.css">

++++

== Virtual

include::create-virtual-nodes-rels.adoc[leveloffset=1]

include::virtual-graph.adoc[leveloffset=1]

include::grouping.adoc[leveloffset=1]

== Graph Refactoring

include::graph-refactor.adoc[leveloffset=1]

== Triggers

include::trigger.adoc[leveloffset=2]

== Schema

include::schema.adoc[leveloffset=2]

== Atomic

include::atomic.adoc[leveloffset=1]

== Bolt

include::bolt.adoc[leveloffset=1]

== Appendix: Complete Overview

include::overview.adoc[tags=overview,leveloffset=1]

== Performance Tests

include::big-graph-from-cypher.adoc[leveloffset=1]

include::graphml-tests.adoc[leveloffset=1]

= APOC User Guide {apoc-release}
:toc: left
:experimental:
:sectid:
:sectlinks:
:toclevels: 3
:img: https://raw.githubusercontent.com/neo4j-contrib/neo4j-apoc-procedures/{branch}/docs/img
:script: https://raw.githubusercontent.com/neo4j-contrib/neo4j-apoc-procedures/{branch}/docs/script

== Introduction

NOTE: Go here for documentation for APOC for Neo4j version link:index30.html[3.0.x] link:index31.html[3.1.x] link:index32.html[3.2.x] link:index33.html[3.3.x]

++++

++++

include::../readme.adoc[tags=intro,leveloffset=1]

++++

++++

include::../readme.adoc[tags=signature,leveloffset=1]

== Help and Usage

include::overview.adoc[tags=help,leveloffset=-1]

To generate the help output, apoc utilizes the built in `dbms.procedures()` and `dbms.functions()` utilities.

== Overview of APOC Procedures & Functions

[[table-all]]
[separator=¦,opts=header]
|===
include::../build/generated-documentation/documentation.csv[]
|===

include::functions.adoc[leveloffset=+1]

include::../readme.adoc[tags=install,leveloffset=1]

=== Notices

include::../readme.adoc[tags=warnings,leveloffset=1]

include::../readme.adoc[tags=docker,leveloffset=1]

// include::overview.adoc[tags=overview,leveloffset=1]

== Text and Lookup Indexes

=== Index Queries

Procedures to add to and query manual indexes

NOTE: Please note that there are (case-sensitive) http://neo4j.com/docs/developer-manual/current/#cypher-schema[automatic schema indexes], for equality, non-equality, existence, range queries, starts with, ends-with and contains!

[separator=¦,opts=header,cols="1,1m,5"]
|===
include::../build/generated-documentation/apoc.index.csv[]
|===

////
[cols="1m,5"]
|===
| apoc.index.addAllNodes('index-name',{label1:['prop1',...],...}, {options}) | add all nodes to this full text index with the given fields, additionally populates a 'search' index field with all of them in one place
| apoc.index.addNode(node,['prop1',...]) | add node to an index for each label it has
| apoc.index.addNodeByLabel('Label',node,['prop1',...]) | add node to an index for the given label
| apoc.index.addNodeByName('name',node,['prop1',...]) | add node to an index for the given name
| apoc.index.addRelationship(rel,['prop1',...]) | add relationship to an index for its type
| apoc.index.addRelationshipByName('name',rel,['prop1',...]) | add relationship to an index for the given name
| apoc.index.removeNodeByName('name',node) remove node from an index for the given name
| apoc.index.removeRelationshipByName('name',rel) remove relationship from an index for the given name
|===
////

image::{img}/apoc.index.nodes-with-score.jpg[width=600]

////

[cols="1m,5"]
|===
| apoc.index.search('index-name', 'query') YIELD node, weight | search for the first 100 nodes in the given full text index matching the given lucene query returned by relevance
| apoc.index.nodes('Label','prop:value*') YIELD node, weight | lucene query on node index with the given label name
| apoc.index.relationships('TYPE','prop:value*') YIELD rel, weight | lucene query on relationship index with the given type name
| apoc.index.between(node1,'TYPE',node2,'prop:value*') YIELD rel, weight | lucene query on relationship index with the given type name bound by either or both sides (each node parameter can be null)
| apoc.index.out(node,'TYPE','prop:value*') YIELD node, weight | lucene query on relationship index with the given type name for *outgoing* relationship of the given node, *returns end-nodes*
| apoc.index.in(node,'TYPE','prop:value*') YIELD node, weight | lucene query on relationship index with the given type name for *incoming* relationship of the given node, *returns start-nodes*
|===
////

=== Index Management

////
[cols="1m,5"]
|===
| CALL apoc.index.list() YIELD type,name,config | lists all manual indexes
| CALL apoc.index.remove('name') YIELD type,name,config | removes manual indexes
| CALL apoc.index.forNodes('name',{config}) YIELD type,name,config | gets or creates manual node index
| CALL apoc.index.forRelationships('name',{config}) YIELD type,name,config | gets or creates manual relationship index
|===
////

.Add node to index example
[source,cypher]
----
match (p:Person) call apoc.index.addNode(p,["name","age"]) RETURN count(*);
// 129s for 1M People
call apoc.index.nodes('Person','name:name100*') YIELD node, weight return * limit 2
----

// include::overview.adoc[tags=fulltext]

include::manual-indexes.adoc[leveloffset=2]

include::fulltext.adoc[leveloffset=2]

== Utility Functions

include::phonetic.adoc[leveloffset=2]
include::extract.adoc[leveloffset=2]

include::ttl.adoc[leveloffset=2]

include::datetime.adoc[leveloffset=2]

include::number.adoc[leveloffset=2]

include::exact.adoc[leveloffset=2]

include::diff.adoc[leveloffset=2]

== Graph Algorithms

include::algo.adoc[leveloffset=2]
include::expand.adoc[leveloffset=2]
include::centrality.adoc[leveloffset=2]
include::pagerank.adoc[leveloffset=2]

== Spatial

include::spatial.adoc[leveloffset=2]

== Data Integration

include::loadjson.adoc[leveloffset=2]
include::loadjdbc.adoc[leveloffset=2]
include::loadcsv.adoc[leveloffset=2]
include::gephi.adoc[leveloffset=2]
include::elasticsearch.adoc[leveloffset=2]
include::loadxml.adoc[leveloffset=2]
include::loadhtml.adoc[leveloffset=2]over

== Graph Refactorings

include::refactor.adoc[leveloffset=2]

== Cypher Operations

include::cypher.adoc[leveloffset=2]
include::periodic.adoc[leveloffset=2]

++++
<link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/1.10.13/css/jquery.dataTables.min.css">

++++

== Virtual

include::create-virtual-nodes-rels.adoc[leveloffset=1]

include::virtual-graph.adoc[leveloffset=1]

include::grouping.adoc[leveloffset=1]

== Graph Refactoring

include::graph-refactor.adoc[leveloffset=1]

== Triggers

include::trigger.adoc[leveloffset=2]

== Schema

include::schema.adoc[leveloffset=2]

== Atomic

include::atomic.adoc[leveloffset=1]

== Bolt

include::bolt.adoc[leveloffset=1]

== Appendix: Complete Overview

include::overview.adoc[tags=overview,leveloffset=1]

== Performance Tests

include::big-graph-from-cypher.adoc[leveloffset=1]

include::graphml-tests.adoc[leveloffset=1]


simplified sample code

simplified sample code

= picocli - a mighty tiny Command Line Interface
Remko Popma <rpopma@apache.org>
v0.3.0, 2017-03-25
:toc: left
:numbered:
:toclevels: 2
:toc-title: Features

A Java command line parsing framework in a single file, so you can include it _in source form_
and let users run your application without an external dependency.
Produces clean and easily tailored usage help messages.

How it works: annotate your class and picocli initializes it from the command line arguments,
converting the input to strongly typed values in the fields of your class.

== Example

[source,java]
----
import picocli.CommandLine.Option;
import picocli.CommandLine.Parameters;
import java.io.File;

public class Example {
    @Option(names = { "-v", "--verbose" }, description = "Be verbose.")
    private boolean verbose = false;

    @Option(names = { "-h", "--help" }, help = true,
            description = "Displays this help message and quits.")
    private boolean helpRequested = false;

    @Parameters(arity = "1..*", paramLabel = "FILE", description = "File(s) to process.")
    private File[] inputFiles;
    ...
}
----

Then invoke `CommandLine.parse` with the command line parameters and an object you want to initialize.

[source,java]
----
String[] args = { "-v", "inputFile1", "inputFile2" };
Example app = CommandLine.parse(new Example(), args);
assert !app.helpRequested;
assert  app.verbose;
assert  app.inputFiles != null && app.inputFiles.length == 2;
----

== Options and Parameters
Command line arguments can be separated into _options_ (sometimes called _flags_ or _switches_), and _parameters_ (sometimes called _positional parameters_ or _operands_).
Options have a name, parameters are the values that follow the options.

[source]
----
<command> -cvf=file1.txt --out result.txt abc def 123 45.6
            |      |        |       |      |   |   |   |
            |      |        |       |      +---+---+---+--- positional parameters
            |      |        |       |
            |      |        |       +--- option-parameter for "--out"
            |      |        |
            |      |        +--- option
            |      |
            |      +--- option-parameter for "-f"
            |
            +--- clustered options "-c", "-v", and "-f"
----
Picocli has separate annotations for options and positional parameters because they work slightly differently.

.Best Practices
[TIP]
The https://www.gnu.org/prep/standards/html_node/Command_002dLine-Interfaces.html#Command_002dLine-Interfaces[GNU recommendations] for command line interfaces and http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap12.html#tag_12_02[POSIX Utility Guidelines] may be useful. Generally, many applications use options for optional values and parameters for mandatory values.
However, picocli lets you make options required if you want to, see <<Required Options>>.

=== Options
An option must have one or more `names`. Option names usually have a prefix to distinguish them from parameters. Different operating systems and applications use https://en.wikipedia.org/wiki/Command-line_interface#Command-line_option[different prefixing] styles. Picocli lets you use any option name you want.

TIP: You may be interested in this http://catb.org/~esr/writings/taoup/html/ch10s05.html#id2948149[list of common option names]. Following these conventions may make your application more intuitive to use.

The below example shows options with one or more names, options that take an option parameter, and "help" options.
[source,java]
----
class Tar {
    @Option(names = { "-c", "--create" }, description = "create a new archive")
    boolean create;

    @Option(names = "-x", description = "extract files from an archive")
    boolean extract;

    @Option(names = { "-f", "--file" }, paramLabel = "ARCHIVE",
            description = "use archive file or device ARCHIVE")
    File archive;

    @Parameters(paramLabel = "FILE", description = "one ore more files to archive")
    File[] files;
}
----
Picocli matches the option names to set the field values.
[source,java]
----
String[] args = { "-cf", "result.tar", "file1.txt", "file2.txt" };
Tar tar = CommandLine.parse(new Tar(), args);
assert  tar.create;
assert !tar.extract;
assert  tar.archive.equals(new File("result.tar"));
assert  Arrays.equals(tar.files, new File[] {new File("file1.txt"), new File("file2.txt")});
----

Picocli supports http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap12.html#tag_12_02[POSIX clustered short options]:
One or more options without option-arguments, followed by at most one option that takes an option-argument, should be accepted when grouped behind one '-' delimiter.

For example, given this annotated class:
[source,java]
----
class ClusteredShortOptions {
    @Option(names = "-a") boolean a;
    @Option(names = "-b") boolean b;
    @Option(names = "-c") boolean c;
    @Option(names = "-f") String  f;
}
----
The following command line arguments are all equivalent and parsing them will give the same result:

[source,java]
----
<command> -abcfInputFile.txt
<command> -a -b -c -fInputFile.txt
<command> -a -b -c -f InputFile.txt
<command> -a -b -c -f=InputFile.txt
<command> -abc -f=InputFile.txt
<command> -ab -cf=InputFile.txt
...
----

=== Positional Parameters
Positional parameters (also called operands) are the command line arguments following the options.

Use the (zero-based) `index` attribute to specify exactly which parameters to capture. Omitting the `index` attribute means the field is initialized with all positional parameters (so the field should be a multi-value type like an array or a collection).

The `index` attribute accepts "range" values, so an annotation like `@Parameters(index="2..4")` captures arguments at index 2, 3 and 4. Range values can be open-ended. For example, `@Parameters(index="3..*")` captures all arguments from index 3 and up.

The advantage of capturing individual parameters in separate fields is that you can enforce strong typing. For example:

[source,java]
----
class PositionalParameters {
    @Parameters(hidden = true)  // "hidden": don't show this parameter in usage help message
    List<String> allParameters; // no "index" attribute: captures _all_ arguments (as Strings)

    @Parameters(index = "0",    // index=0: the first positional parameter
                description = "Host name or IP address to connect to")
    InetAddress host;

    @Parameters(index = "1",    // index=1: the second positional parameter
                description = "Port number to connect to")
    int port;

    @Parameters(index = "2..*", description = "the files to process")
    File[] files;
}
----

Picocli initializes fields with the values at the specified index in the arguments array.
[source,java]
----
String[] args = { "localhost", "12345", "file1.txt", "file2.txt" };
PositionalParameters params = CommandLine.parse(new PositionalParameters(), args);
assert params.host.getHostName().equals("localhost");
assert params.port == 12345;
assert Arrays.equals(params.files, new File[] {new File("file1.txt"), new File("file2.txt")});
assert params.allParameters.equals(Arrays.asList("localhost", "12345", "file1.txt", "file2.txt"));
----

See <<Type Conversion>> for which types are supported out of the box and how to add custom types.

=== Double dash (`--`)
When one of the command line arguments is two dashes without any characters attached (`--`), picocli interprets all following arguments as positional parameters, even arguments that match an option name.

[source,java]
----
class DoubleDash {
    @Parameters
    List<String> params;

    @Option(names = "--files")
    List<String> files;

    @Option(names = { "-v", "--verbose" })
    boolean verbose;
}
----

The `--` clarifies which of the arguments are positional parameters:
[source,java]
----
String[] args = { "-v", "--", "--files", "file1", "file2" };
DoubleDash doubleDash = CommandLine.parse(new DoubleDash(), args);

assert doubleDash.verbose;
assert doubleDash.files == null;
assert doubleDash.params != null && doubleDash.params.length == 3;
assert doubleDash.params.equals(Arrays.asList("--files", "file1", "file2"));
----

=== Option-Parameter Separators
==== Default Separators
Options may take an _option parameter_ (also called _option-argument_).
For POSIX-style short options (like `-f` or `-c`), the option parameter may be attached to the option,
or it may be separated by a space or the _separator string_ (`=` by default).
That is, all of the below are equivalent:
[source,java]
----
<command> -foutput.txt
<command> -f output.txt
<command> -f=output.txt
----

Long option names (like `--file`) must be separated from their option parameter by a space or the
_separator string_ (`=` by default). That is, the first two below examples are valid but the last example is invalid:
[source,java]
----
// valid
<command> --file output.txt
<command> --file=output.txt

// invalid (picocli will not recognize the --file option)
<command> --fileoutput.txt
----

==== Custom Separators
The separator string can be customized programmatically or declaratively.

Use the `separator` attribute of the `@Command` annotation to declaratively set a separator string:
[source,java]
----
@Command(separator = ":")  // declaratively set a separator
class OptionArg {
    @Option(names = { "-f", "--file" }) String file;
}
----
[source,java]
----
OptionArg optionArg = CommandLine.parse(new OptionArg(), "-f:output.txt");
assert optionArg.file.equals("output.txt");
----

Alternatively, the separator string can be changed programmatically with the `CommandLine.setSeparator(String separator)` method.
For example:
[source,java]
----
OptionArg optionArg     = new OptionArg();
CommandLine commandLine = new CommandLine(optionArg);

commandLine.setSeparator(":"); // programmatically set a separator
commandLine.parse("-f:output.txt");
assert optionArg.file.equals("output.txt");
----

== Type Conversion
When command line options and parameters are mapped to the annotated fields,
the text value is converted to the type of the annotated field.

=== Built-in Type Converters
Out of the box, picocli can convert command line argument strings to any Java primitive type or their wrapper,
File, BigDecimal, BigInteger, InetAddress, URL, URI, Charset, UUID, regex Pattern, String, StringBuilder, CharSequence,
`java.sql.Time` (for values in any of the `"HH:mm"`, `"HH:mm:ss"`, `"HH:mm:ss.SSS"`, or `"HH:mm:ss,SSS"` formats), and
`java.util.Date` (for values in `"yyyy-MM-dd"` format).

=== Custom Type Converters
Register a custom converter to handle data types other than the above built-in ones.

Custom converters need to implement the `picocli.CommandLine.ITypeConverter` interface:

[source,java]
----
public interface ITypeConverter<K> {
    /**
     * Converts the specified command line argument value to some domain object.
     * @param value the command line argument String value
     * @return the resulting domain object
     * @throws Exception an exception detailing what went wrong during the conversion
     */
    K convert(String value) throws Exception;
}
----

Custom type converters can be registered with the `CommandLine.registerConverter(Class<K> cls, ITypeConverter<K> converter)`
method.

NOTE: Picocli works with Java 5 and higher, so it does not have default converters for Java 8 types like `Path` or
`Duration`. Lambdas make it easy to register custom converters for these types:

[source,java]
----
commandLine.registerConverter(java.nio.file.Path.class, s -> java.nio.file.Paths.get(s));
commandLine.registerConverter(java.time.Duration.class, s -> java.time.Duration.parse(s));
----

After registering custom converters, call the `parse(String...)` method on the `CommandLine` instance where the converters are registered. The static `parse` method cannot be used. For example:

[source,java]
----
class App {
    @Parameters Path path;
    @Option(names = "-d") Duration duration;
}
----

[source,java]
----
App app = new App();
CommandLine commandLine = new CommandLine(app);
commandLine.registerConverter(Path.class,     s -> Paths.get(s));
commandLine.registerConverter(Duration.class, s -> Duration.parse(s));

commandLine.parse("-d", "PT15M", "file1.txt");
assert app.path.equals(Paths.get("file1.txt"));
assert app.duration.equals(Duration.parse("PT15M"));
----

=== Arrays and Collections

IMPORTANT: With array fields picocli uses reflection to discover the array element type, but with collections, Java type erasure means picocli cannot find out the generic type of the collection. For non-String collections, use the `type` attribute to explicitly tell picocli what type to convert the command line arguments to.

Multiple parameters can be captured together in a single array or `Collection` field. When using a collection, use the `type` attribute to specify the collection element type. For example:

[source,java]
----
class Convert {
    @Option(type = java.util.regex.Pattern.class, // List elements are Pattern objects
            names = "-patterns",
            description = "the regular expressions to use for the conversion");
    List<Pattern> patterns;

    @Parameters(type = File.class, // convert arguments to File before adding to the List
                description = "files to convert")
    List<File> files;
}
----

[source,java]
----
String[] args = { "-patterns", "a*b", "[a-e][i-u]", "--", "file1.txt", "file2.txt" };
Convert convert = CommandLine.parse(new Convert(), args);

// convert.patterns now has two Pattern objects
// convert.files now has two File objects
----

NOTE: If a collection is returned from a type converter, picocli will add the values to the field, not the collection itself.

=== Numeric Arguments
Numeric values are interpreted as decimal numbers by default. If you want picocli to be more flexible, you can
register a custom type converter that delegates to the https://docs.oracle.com/javase/8/docs/api/java/lang/Integer.html#decode-java.lang.String-[decode] method to convert strings to numbers.

NOTE: The `decode` method looks at the prefix to determine the radix, so numbers
starting with `0x`, `0X` or `#` are interpreted as hexadecimal numbers, numbers starting with `0` are interpreted
as octal numbers, and otherwise the number is interpreted as a decimal number.

Java 8-style lambdas:
[source,java]
----
commandLine.registerConverter(Byte.class,    s -> Byte::decode);
commandLine.registerConverter(Byte.TYPE,     s -> Byte::decode);
commandLine.registerConverter(Short.class,   s -> Short::decode);
commandLine.registerConverter(Short.TYPE,    s -> Short::decode);
commandLine.registerConverter(Integer.class, s -> Integer::decode);
commandLine.registerConverter(Integer.TYPE,  s -> Integer::decode);
commandLine.registerConverter(Long.class,    s -> Long::decode);
commandLine.registerConverter(Long.TYPE,     s -> Long::decode);
----

In Java 5 this becomes a bit more verbose:
[source,java]
----
ITypeConverter<Integer> intConverter = new ITypeConverter<Integer>() {
    public Integer convert(String s) {
        return Integer.decode(s);
    }
};
commandLine.registerConverter(Integer.class, intConverter);
commandLine.registerConverter(Integer.TYPE,  intConverter);
...
----

== Arity
Arity is the number of parameters that will be consumed by an option.
Most of the time picocli will consume the right number of parameters automatically and you don't need to worry about this.

When an option or parameters field has a type that can hold multiple values (an array or a collection),
the `arity` attribute lets you control exactly how many parameters are captured by this field.

=== Default Arity
The default arity value of a field annotated with `@Option` or `@Parameters` depends on the field's type.

* Boolean fields: arity is zero (no parameter is consumed - the field is set to `true` when the option name is recognized).
* Single-valued types like `int`, `String`, `File`: arity is one (consume one parameter). Omitting the option parameter results in a ParameterException: "Missing required parameter for field '<field-name>'".
* Multi-valued types like arrays or collections: consume from zero up to all available parameters.

=== Boolean Options with Explicit Parameters
It is possible to explicitly specify "true" or "false" as a parameter for a boolean option by defining an explicit <<Arity: Minimum and Maximum Number of Parameters,`arity`>> attribute. A boolean option with `arity = "0..1"` accepts zero to one parameters, `arity = "1"` means the option _must_ have one parameter. For example:

[source, java]
----
class BooleanOptionWithParameters {
    @Option(names = "-x", arity = "1", description = "1 mandatory parameter")
    boolean x;

    @Option(names = "-y", arity = "0..1", description = "min 0 and max 1 parameter")
    boolean y;
}
----

The following ways to invoke the program will be accepted (values are not case sensitive):
----
<command> -x true
<command> -x FALSE
<command> -x TRUE -y
<command> -x True -y False
----

But trying to specify the `-x` option without a parameter, or with a value other than "true" or "false" (case insensitive) will result in a `ParameterException`.

=== Arrays and Collections
Option fields of type array or `List` (or any class extending `Collection`) will be able to hold multiple values.
By default, picocli will capture arguments into these fields until it encounters a command line argument that is
an option name or a registered command name.

The `arity` attribute can be used to specify the exact number of required parameters, or a range with a minimum and a maximum number of parameters. The maximum can be a fixed number, or can be `"*"` to denote "any number" of parameters. For example:
[source, java]
----
class MyProgram {
    @Parameters(arity = "3", descriptions = "exactly three Files")
    File[] files;

    @Option(names = "-f", arity = "2..4", description = "two to four floating point numbers")
    double[] doubles;

    @Option(names = "-s", arity = "1..*", description = "at least one string")
    String[] strings;
}
----
A `MissingParameterException` is thrown when fewer than the miminum number of required parameters is specified as command line arguments. Options with an exact number or an exact range will consume up to the maximum number of parameters.

Once the minimum number of parameters is consumed, picocli will check for each subsequent command line argument whether it is another parameter, or a new option. For example:

----
<command> -s A B C -f 1.0 2.0 3.0
----
The above command line arguments will be parsed as three parameters for the `-s` option, followed by three parameters for the `-f` option.

=== Ambiguous Input
Positional parameters do not have an option name, so it is not always easy to decide where they start. The below example command line arguments will be parsed as six parameters for the `-s` option, not as three strings and three files:
----
<command> -s A B C file1 file2 file3
----

Users can disambiguate the input by specifying a double dash (`--`) after the option parameters.
The argument `--` is interpreted as a delimiter indicating the end of options. Any following arguments are treated as positional parameters. For example, the following command line arguments will be parsed as three strings and three files:
----
<command> -s A B C -- file1 file2 file3
----

=== Option-Parameter Separators and Arity

IMPORTANT: A separator clarifies that a parameter belongs to an option, but does not prevent subsequent parameters from also being assigned to the same option. For example:

[source,java]
----
@Option(names = "-opt", arity = "2") List<String> values;
@Parameters                          List<String> remainder;
----
Because arity is 2, both parameters in the below example are assigned to the `-opt` option:
----
<command> -opt=val1 val2
----

== Required Options
=== Options
Options can be marked `required` to make it mandatory for the user to specify them on the command line. When a required option is not specified, a `MissingParameterException` is thrown from the `parse` method. For example:
[source, java]
----
class MandatoryOption {
    @Option(names = "-n", required = true, description = "mandatory number")
    int number;

    @Parameters
    File[] files;
}
----
The following command line arguments would result in an exception complaining that `number` is missing:
----
// invalid: missing option -n
<command> file1 file2 file3
----
The following command line arguments would be accepted:
----
// valid: required option -n has a value
<command> -n 123 file1 file2 file3
----

=== Parameters
Use the `arity` attribute to make `@Parameters` mandatory:
[source, java]
----
class BothOptionAndParametersMandatory {
    @Parameters(arity = "1..*", descriptions = "at least one File")
    File[] files;

    @Option(names = "-n", required = true, description = "mandatory number")
    int number;
}
----
The following command line arguments would result in an exception complaining that `files` are missing:
----
// invalid: missing file parameters
<command> -n 123
----
The following command line arguments would be accepted:
----
// valid: both required fields have a value
<command> -n 123 file1
----

== Help Options
Options with the attribute `help = true` are special: if one of the command line arguments is a "help" option, picocli will stop parsing the remaining arguments and will not check for required options.

[source,java]
----
@Option(names = {"-h", "--help"}, help = true, description = "display this help message")
boolean helpRequested;
----
This is suitable for options that should trigger the usage help message or application version information being shown on the console.

It is the responsibility of the application to check the field and show the usage help message:
[source,java]
----
Compress app = CommandLine.parse(new App(), args);
if (app.helpRequested) {
   CommandLine.usage(new App(), System.err);
   return;
}
----

== Usage Help
=== Example
A default picocli usage help message looks like this:
----
Usage: cat [-AbeEnstTuv] [--help] [--version] [FILE...]
Concatenate FILE(s), or standard input, to standard output.
      FILE                    Files whose contents to display
  -A, --show-all              equivalent to -vET
  -b, --number-nonblank       number nonempty output lines, overrides -n
  -e                          equivalent to -vET
  -E, --show-ends             display $ at end of each line
  -n, --number                number all output lines
  -s, --squeeze-blank         suppress repeated empty output lines
  -t                          equivalent to -vT
  -T, --show-tabs             display TAB characters as ^I
  -u                          (ignored)
  -v, --show-nonprinting      use ^ and M- notation, except for LDF and TAB
      --help                  display this help and exit
      --version               output version information and exit
Copyright(c) 2017
----

The usage help message is generated from annotation attributes, like below:
[source,java]
----
@Command(name = "cat", footer = "Copyright(c) 2017",
         description = "Concatenate FILE(s), or standard input, to standard output.")
class Cat {

  @Parameters(paramLabel = "FILE", description = "Files whose contents to display")
  List<File> files;

  @Option(names = "--help", help = true, description = "display this help and exit")
  boolean help;

  @Option(names = "-t",                 description = "equivalent to -vT")  boolean t;
  @Option(names = "-e",                 description = "equivalent to -vET") boolean e;
  @Option(names = {"-A", "--show-all"}, description = "equivalent to -vET") boolean all;

  // ...
}
----

=== Command Name
In the above example, the program name is taken from the `name` attribute of the `Command` annotation:
[source,java]
----
@Command(name = "cat")
----
Without a `name` attribute, picocli will show a generic `<main class>` in the synopsis:
----
Usage: <main class> [-AbeEnstTuv] [--help] [--version] [FILE...]
----
=== Parameter Labels
Non-boolean options require a value. The usage help should explain this, and picocli shows the option parameter
in the synopsis and in the option list. By default, the field name is shown in `<` and `>` fish brackets.
Use the `paramLabel` attribute to display a different name. For example:
----
Usage: <main class> [-f=FILE] [-n=<number>] NUM <host>
      NUM                     number param
      host                    the host parameter
  -f= FILE                    a file
  -n= <number>                a number option
----
Some annotated fields in the below example class have a `paramLabel` attribute and others don't:
[source,java]
----
@Command(showDefaultValues = false)
class ParamLabels {
    @Option(names = "-f",    paramLabel = "FILE", description = "a file")      File f;
    @Option(names = "-n",    description = "a number option")                  int number;
    @Parameters(index = "0", paramLabel = "NUM", description = "number param") int n;
    @Parameters(index = "1", description = "the host parameter")               InetAddress host;
}
----
NOTE: For demonstration purposes the above example mixes the all-uppercase (e.g., `NUM`) style label and the fish bracket (e.g., `<number>`) style labels. For real applications, mixing these label styles should be avoided. An application should consistently use only one style.

=== Hidden Options and Parameters
Options and Parameters with the `hidden` attribute set to `true` will not be shown in the usage help message.
This is useful for example when a parameter at some index is captured into multiple fields:
by default each of these fields would be shown in the usage message, which would be confusing for users.

For example, the `all` field below is annotated as `hidden = true`:
[source,java]
----
@Command(showDefaultValues = false)
class App {
    @Parameters(index = "0",    description = "destination host")  InetAddress host;
    @Parameters(index = "1",    description = "destination port")  int port;
    @Parameters(index = "2..*", description = "files to transfer") String[] files;

    @Parameters(hidden = true) String[] all;
}
----
The above will generate the following usage help message, where the `all` field is not shown:
----
Usage: <main class> <host> <port> [<files>...]
      host                    destination host
      port                    destination port
      files                   files to transfer
----

== Customizing Usage Help
=== Example
The below example demonstrates what a customized usage message can look like.
Note how section headings with line separators can create a more spacious usage message,
and also that options are listed in declaration order (instead of in alphabetic order).
----
Usage:

Record changes to the repository.

git-commit [-ap] [--fixup=<commit>] [--squash=<commit>] [-c=<commit>]
           [-C=<commit>] [-F=<file>] [-m[=<msg>...]] [<files>...]

Description:

Stores the current contents of the index in a new commit along with a log
message from the user describing the changes.

Parameters:
      <files>                 the files to commit

Options:
  -a, --all                   Tell the command to automatically stage files
                                that have been modified and deleted, but new
                                files you have not told Git about are not
                                affected.
  -p, --patch                 Use the interactive patch selection interface to
                                chose which changes to commit
  -C, --reuse-message=<commit>
                              Take an existing commit object, and reuse the log
                                message and the authorship information
                                (including the timestamp) when creating the
                                commit.
  -c, --reedit-message=<commit>
                              Like -C, but with -c the editor is invoked, so
                                that the user canfurther edit the commit
                                message.
      --fixup=<commit>        Construct a commit message for use with rebase
                                --autosquash.
      --squash=<commit>        Construct a commit message for use with rebase
                                --autosquash. The commitmessage subject line is
                                taken from the specified commit with a prefix
                                of "squash! ". Can be used with additional
                                commit message options (-m/-c/-C/-F).
  -F, --file=<file>           Take the commit message from the given file. Use
                                - to read the message from the standard input.
  -m, --message[=<msg>...]     Use the given <msg> as the commit message. If
                                multiple -m options are given, their values are
                                concatenated as separate paragraphs.
----

=== Section Headings
The above spacious layout is mainly due to the section headings:
[code,java]
----
@CommandLine.Command(name = "git-commit",
        sortOptions = false,
        headerHeading = "Usage:%n%n",
        synopsisHeading = "%n",
        descriptionHeading = "%nDescription:%n%n",
        parameterListHeading = "%nParameters:%n",
        optionListHeading = "%nOptions:%n",
        header = "Record changes to the repository.",
        description = "Stores the current contents of the index in a new commit " +
                "along with a log message from the user describing the changes.")
class GitCommit { ... }
----

=== Unsorted Option List
By default the options list displays options in alphabetical order. Use the `sortOptions = false` attribute to display options in the order they are declared in your class.

=== Show Default Values
Use the `showDefaultValues = true` attribute to append the default value of the options and positional parameters to the description column.

=== Abbreviated Synopsis
=== Custom Synopsis
=== Command Header and Description
=== Footer
=== Option-Parameter Separators

=== Reordering Sections
To reorder sections of the usage message, you need to use the `CommandLine.Help` class directly. The `CommandLine::usage` method implementation looks like this:

[source,java]
----
Help help = new Help(new MainClass());
StringBuilder sb = new StringBuilder()
        .append(help.headerHeading())
        .append(help.header())
        .append(help.synopsisHeading())      //e.g. Usage:
        .append(help.synopsis())             //e.g. <main> [OPTIONS] [ARGUMENTS]
        .append(help.descriptionHeading())   //e.g. %nDescription:%n%n
        .append(help.description())          //e.g. "application description"
        .append(help.parameterListHeading()) //e.g. %nPositional parameters:%n%n
        .append(help.parameterList())        //e.g. [FILE...] the files to convert
        .append(help.optionListHeading())    //e.g. %nOptions:%n%n
        .append(help.optionList())           //e.g. -h, --help   displays this help
        .append(help.commandListHeading())   //e.g. %nCommands:%n%n
        .append(help.commandList())          //e.g.    add       adds a to b
        .append(help.footerHeading())
        .append(help.footer());
----
In your application, instead of calling `CommandLine.usage(new MainClass(), System.err)`, you can alter the above code to, for example, list subcommands first, then global options and finally the parameters.

=== Formatted Headings
By using the `Help` class directly as explained in the previous section,
the `xxxHeading()` methods can be passed arguments.
These arguments can be referenced by the format specifiers in the heading https://docs.oracle.com/javase/8/docs/api/java/util/Formatter.html[format strings]. For example:

[source,java]
----
@Command(descriptionHeading = "%nDescription (%1$tb %1$te, %1$tY)%n%n")
class MainClass {}
----
The `descriptionHeading` attribute is a format string with some date/time conversion format specifiers and some line separators. Picocli will format this string with any arguments that are passed to the `Help::descriptionHeading(Object...)` method. For example:
[source,java]
----
Help help = new Help(new MainClass());
Calendar c = new GregorianCalendar(2017, MAY, 23);
String formatted = help.descriptionHeading(c);

assert "\nDescription (May 23, 2017)\n\n".equals(formatted);
----

== Advanced Usage Help Customization
=== Custom Layout
=== Table and Columns
=== Option Renderer
=== Parameter Renderer
=== Param Label Renderer

== Subcommands
=== Registering Subcommands
=== Usage Help for Subcommands

== Subclassing to Reuse Options and Command Attributes
Picocli will walk the class hierarchy to check for annotations, so you can declare common @Options and @Command attributes on a superclass and override these fields or attributes on a subclass.

The below example shows how common options like `help` and `version` can be declared as fields in a superclass so they are available in all subclasses. Similarly, annotating the superclass with default `@Command` attributes means subclasses won't need to set these attributes.

[source,java]
----
@Command(synopsisHeading      = "%nUsage:%n%n",      descriptionHeading = "%nDescription:%n%n",
         parameterListHeading = "%nParameters:%n%n", optionListHeading  = "%nOptions:%n%n",
         commandListHeading   = "%nCommands:%n%n",   showDefaultValues  = false)
public abstract class AbstractCommand {

    @Option(names = { "-h", "-?", "--help" }, help = true,
            description = "give this help list")
    protected boolean helpRequested;

    @Option(names = { "-V", "--version" }, help = true,
            description = "print program version")
    protected boolean versionRequested;
}
----

All commands that extend `AbstractCommand` support the `--help` and `--version` options, and generate a usage help message in the same spacious style. For example:

[source,java]
----
@Command(name        = "zip",
         header      = "Compresses the specified FILE(s).",
         description = "The default action is to add or replace zipfile entries from list, " +
                       "which can include the special name - to compress standard input.",
         footer      = "Copyright (c) 1990-2008 Info-ZIP - Type 'zip "-L"' for software license.")
public class ZipCommand extends AbstractCommand {
    @Option(names = { "-o", "--output" }, description = "output file to write to")
    private File output;

    @Parameter(paramLabel = "FILE", description = "FILEs to compress")
    private File[] files;
}
----

== Putting it all Together
Imagine an application that takes some input files and compresses them to an output file.
----
Compress -o outputFile file1 file2 file3
----
The program takes one option (`-o`, the output file) and one or more input files.
One way to accomplish this with picocli looks like this:

[source, java]
----
import picocli.CommandLine.*;
import java.io.File;

@Command(name = "Compress", header = "Compresses the specified input files to an output file")
public class Compress {
    @Parameters(arity = "1..*", description = "one or more files to compress")
    File[] inputFiles;

    @Option(names = {"-o", "--outfile"}, description = "optional output file name. If omitted directory name is used.")
    File outputFile;

    @Option(names = {"-h", "--help"}, help = true, description = "display this help message")
    boolean helpRequested;

    public static void main(String... args) {
        try {
            Compress compress = CommandLine.parse(new Compress(), args);
            if (compress.helpRequested) {
                CommandLine.usage(new Compress(), System.err);
                return;
            }
            doCompress();
        } catch (ParseException ex) {
            System.err.println(ex.getMessage());
            CommandLine.usage(new Compress(), System.err);
        }
    }

    private void doCompress() { ... } // business logic of the application
}
----

== Download

NOTE: Here is the source. Copy and paste it into a file called `CommandLine.java`, add it to your project, and enjoy!

[source,java]
----
include::../src/main/java/picocli/CommandLine.java[]
----

= picocli - a mighty tiny Command Line Interface
Remko Popma <rpopma@apache.org>
v0.3.0, 2017-03-25
:toc: left
:numbered:
:toclevels: 2
:toc-title: Features

A Java command line parsing framework in a single file, so you can include it _in source form_
and let users run your application without an external dependency.
Produces clean and easily tailored usage help messages.

How it works: annotate your class and picocli initializes it from the command line arguments,
converting the input to strongly typed values in the fields of your class.

== Example

[source,java]
----
import picocli.CommandLine.Option;
import picocli.CommandLine.Parameters;
import java.io.File;

public class Example {
    @Option(names = { "-v", "--verbose" }, description = "Be verbose.")
    private boolean verbose = false;

    @Option(names = { "-h", "--help" }, help = true,
            description = "Displays this help message and quits.")
    private boolean helpRequested = false;

    @Parameters(arity = "1..*", paramLabel = "FILE", description = "File(s) to process.")
    private File[] inputFiles;
    ...
}
----

Then invoke `CommandLine.parse` with the command line parameters and an object you want to initialize.

[source,java]
----
String[] args = { "-v", "inputFile1", "inputFile2" };
Example app = CommandLine.parse(new Example(), args);
assert !app.helpRequested;
assert  app.verbose;
assert  app.inputFiles != null && app.inputFiles.length == 2;
----

== Options and Parameters
Command line arguments can be separated into _options_ (sometimes called _flags_ or _switches_), and _parameters_ (sometimes called _positional parameters_ or _operands_).
Options have a name, parameters are the values that follow the options.

[source]
----
<command> -cvf=file1.txt --out result.txt abc def 123 45.6
            |      |        |       |      |   |   |   |
            |      |        |       |      +---+---+---+--- positional parameters
            |      |        |       |
            |      |        |       +--- option-parameter for "--out"
            |      |        |
            |      |        +--- option
            |      |
            |      +--- option-parameter for "-f"
            |
            +--- clustered options "-c", "-v", and "-f"
----
Picocli has separate annotations for options and positional parameters because they work slightly differently.

.Best Practices
[TIP]
The https://www.gnu.org/prep/standards/html_node/Command_002dLine-Interfaces.html#Command_002dLine-Interfaces[GNU recommendations] for command line interfaces and http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap12.html#tag_12_02[POSIX Utility Guidelines] may be useful. Generally, many applications use options for optional values and parameters for mandatory values.
However, picocli lets you make options required if you want to, see <<Required Options>>.

=== Options
An option must have one or more `names`. Option names usually have a prefix to distinguish them from parameters. Different operating systems and applications use https://en.wikipedia.org/wiki/Command-line_interface#Command-line_option[different prefixing] styles. Picocli lets you use any option name you want.

TIP: You may be interested in this http://catb.org/~esr/writings/taoup/html/ch10s05.html#id2948149[list of common option names]. Following these conventions may make your application more intuitive to use.

The below example shows options with one or more names, options that take an option parameter, and "help" options.
[source,java]
----
class Tar {
    @Option(names = { "-c", "--create" }, description = "create a new archive")
    boolean create;

    @Option(names = "-x", description = "extract files from an archive")
    boolean extract;

    @Option(names = { "-f", "--file" }, paramLabel = "ARCHIVE",
            description = "use archive file or device ARCHIVE")
    File archive;

    @Parameters(paramLabel = "FILE", description = "one ore more files to archive")
    File[] files;
}
----
Picocli matches the option names to set the field values.
[source,java]
----
String[] args = { "-cf", "result.tar", "file1.txt", "file2.txt" };
Tar tar = CommandLine.parse(new Tar(), args);
assert  tar.create;
assert !tar.extract;
assert  tar.archive.equals(new File("result.tar"));
assert  Arrays.equals(tar.files, new File[] {new File("file1.txt"), new File("file2.txt")});
----

Picocli supports http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap12.html#tag_12_02[POSIX clustered short options]:
One or more options without option-arguments, followed by at most one option that takes an option-argument, should be accepted when grouped behind one '-' delimiter.

For example, given this annotated class:
[source,java]
----
class ClusteredShortOptions {
    @Option(names = "-a") boolean a;
    @Option(names = "-b") boolean b;
    @Option(names = "-c") boolean c;
    @Option(names = "-f") String  f;
}
----
The following command line arguments are all equivalent and parsing them will give the same result:

[source,java]
----
<command> -abcfInputFile.txt
<command> -a -b -c -fInputFile.txt
<command> -a -b -c -f InputFile.txt
<command> -a -b -c -f=InputFile.txt
<command> -abc -f=InputFile.txt
<command> -ab -cf=InputFile.txt
...
----

=== Positional Parameters
Positional parameters (also called operands) are the command line arguments following the options.

Use the (zero-based) `index` attribute to specify exactly which parameters to capture. Omitting the `index` attribute means the field is initialized with all positional parameters (so the field should be a multi-value type like an array or a collection).

The `index` attribute accepts "range" values, so an annotation like `@Parameters(index="2..4")` captures arguments at index 2, 3 and 4. Range values can be open-ended. For example, `@Parameters(index="3..*")` captures all arguments from index 3 and up.

The advantage of capturing individual parameters in separate fields is that you can enforce strong typing. For example:

[source,java]
----
class PositionalParameters {
    @Parameters(hidden = true)  // "hidden": don't show this parameter in usage help message
    List<String> allParameters; // no "index" attribute: captures _all_ arguments (as Strings)

    @Parameters(index = "0",    // index=0: the first positional parameter
                description = "Host name or IP address to connect to")
    InetAddress host;

    @Parameters(index = "1",    // index=1: the second positional parameter
                description = "Port number to connect to")
    int port;

    @Parameters(index = "2..*", description = "the files to process")
    File[] files;
}
----

Picocli initializes fields with the values at the specified index in the arguments array.
[source,java]
----
String[] args = { "localhost", "12345", "file1.txt", "file2.txt" };
PositionalParameters params = CommandLine.parse(new PositionalParameters(), args);
assert params.host.getHostName().equals("localhost");
assert params.port == 12345;
assert Arrays.equals(params.files, new File[] {new File("file1.txt"), new File("file2.txt")});
assert params.allParameters.equals(Arrays.asList("localhost", "12345", "file1.txt", "file2.txt"));
----

See <<Type Conversion>> for which types are supported out of the box and how to add custom types.

=== Double dash (`--`)
When one of the command line arguments is two dashes without any characters attached (`--`), picocli interprets all following arguments as positional parameters, even arguments that match an option name.

[source,java]
----
class DoubleDash {
    @Parameters
    List<String> params;

    @Option(names = "--files")
    List<String> files;

    @Option(names = { "-v", "--verbose" })
    boolean verbose;
}
----

The `--` clarifies which of the arguments are positional parameters:
[source,java]
----
String[] args = { "-v", "--", "--files", "file1", "file2" };
DoubleDash doubleDash = CommandLine.parse(new DoubleDash(), args);

assert doubleDash.verbose;
assert doubleDash.files == null;
assert doubleDash.params != null && doubleDash.params.length == 3;
assert doubleDash.params.equals(Arrays.asList("--files", "file1", "file2"));
----

=== Option-Parameter Separators
==== Default Separators
Options may take an _option parameter_ (also called _option-argument_).
For POSIX-style short options (like `-f` or `-c`), the option parameter may be attached to the option,
or it may be separated by a space or the _separator string_ (`=` by default).
That is, all of the below are equivalent:
[source,java]
----
<command> -foutput.txt
<command> -f output.txt
<command> -f=output.txt
----

Long option names (like `--file`) must be separated from their option parameter by a space or the
_separator string_ (`=` by default). That is, the first two below examples are valid but the last example is invalid:
[source,java]
----
// valid
<command> --file output.txt
<command> --file=output.txt

// invalid (picocli will not recognize the --file option)
<command> --fileoutput.txt
----

==== Custom Separators
The separator string can be customized programmatically or declaratively.

Use the `separator` attribute of the `@Command` annotation to declaratively set a separator string:
[source,java]
----
@Command(separator = ":")  // declaratively set a separator
class OptionArg {
    @Option(names = { "-f", "--file" }) String file;
}
----
[source,java]
----
OptionArg optionArg = CommandLine.parse(new OptionArg(), "-f:output.txt");
assert optionArg.file.equals("output.txt");
----

Alternatively, the separator string can be changed programmatically with the `CommandLine.setSeparator(String separator)` method.
For example:
[source,java]
----
OptionArg optionArg     = new OptionArg();
CommandLine commandLine = new CommandLine(optionArg);

commandLine.setSeparator(":"); // programmatically set a separator
commandLine.parse("-f:output.txt");
assert optionArg.file.equals("output.txt");
----

== Type Conversion
When command line options and parameters are mapped to the annotated fields,
the text value is converted to the type of the annotated field.

=== Built-in Type Converters
Out of the box, picocli can convert command line argument strings to any Java primitive type or their wrapper,
File, BigDecimal, BigInteger, InetAddress, URL, URI, Charset, UUID, regex Pattern, String, StringBuilder, CharSequence,
`java.sql.Time` (for values in any of the `"HH:mm"`, `"HH:mm:ss"`, `"HH:mm:ss.SSS"`, or `"HH:mm:ss,SSS"` formats), and
`java.util.Date` (for values in `"yyyy-MM-dd"` format).

=== Custom Type Converters
Register a custom converter to handle data types other than the above built-in ones.

Custom converters need to implement the `picocli.CommandLine.ITypeConverter` interface:

[source,java]
----
public interface ITypeConverter<K> {
    /**
     * Converts the specified command line argument value to some domain object.
     * @param value the command line argument String value
     * @return the resulting domain object
     * @throws Exception an exception detailing what went wrong during the conversion
     */
    K convert(String value) throws Exception;
}
----

Custom type converters can be registered with the `CommandLine.registerConverter(Class<K> cls, ITypeConverter<K> converter)`
method.

NOTE: Picocli works with Java 5 and higher, so it does not have default converters for Java 8 types like `Path` or
`Duration`. Lambdas make it easy to register custom converters for these types:

[source,java]
----
commandLine.registerConverter(java.nio.file.Path.class, s -> java.nio.file.Paths.get(s));
commandLine.registerConverter(java.time.Duration.class, s -> java.time.Duration.parse(s));
----

After registering custom converters, call the `parse(String...)` method on the `CommandLine` instance where the converters are registered. The static `parse` method cannot be used. For example:

[source,java]
----
class App {
    @Parameters Path path;
    @Option(names = "-d") Duration duration;
}
----

[source,java]
----
App app = new App();
CommandLine commandLine = new CommandLine(app);
commandLine.registerConverter(Path.class,     s -> Paths.get(s));
commandLine.registerConverter(Duration.class, s -> Duration.parse(s));

commandLine.parse("-d", "PT15M", "file1.txt");
assert app.path.equals(Paths.get("file1.txt"));
assert app.duration.equals(Duration.parse("PT15M"));
----

=== Arrays and Collections

IMPORTANT: With array fields picocli uses reflection to discover the array element type, but with collections, Java type erasure means picocli cannot find out the generic type of the collection. For non-String collections, use the `type` attribute to explicitly tell picocli what type to convert the command line arguments to.

Multiple parameters can be captured together in a single array or `Collection` field. When using a collection, use the `type` attribute to specify the collection element type. For example:

[source,java]
----
class Convert {
    @Option(type = java.util.regex.Pattern.class, // List elements are Pattern objects
            names = "-patterns",
            description = "the regular expressions to use for the conversion");
    List<Pattern> patterns;

    @Parameters(type = File.class, // convert arguments to File before adding to the List
                description = "files to convert")
    List<File> files;
}
----

[source,java]
----
String[] args = { "-patterns", "a*b", "[a-e][i-u]", "--", "file1.txt", "file2.txt" };
Convert convert = CommandLine.parse(new Convert(), args);

// convert.patterns now has two Pattern objects
// convert.files now has two File objects
----

NOTE: If a collection is returned from a type converter, picocli will add the values to the field, not the collection itself.

=== Numeric Arguments
Numeric values are interpreted as decimal numbers by default. If you want picocli to be more flexible, you can
register a custom type converter that delegates to the https://docs.oracle.com/javase/8/docs/api/java/lang/Integer.html#decode-java.lang.String-[decode] method to convert strings to numbers.

NOTE: The `decode` method looks at the prefix to determine the radix, so numbers
starting with `0x`, `0X` or `#` are interpreted as hexadecimal numbers, numbers starting with `0` are interpreted
as octal numbers, and otherwise the number is interpreted as a decimal number.

Java 8-style lambdas:
[source,java]
----
commandLine.registerConverter(Byte.class,    s -> Byte::decode);
commandLine.registerConverter(Byte.TYPE,     s -> Byte::decode);
commandLine.registerConverter(Short.class,   s -> Short::decode);
commandLine.registerConverter(Short.TYPE,    s -> Short::decode);
commandLine.registerConverter(Integer.class, s -> Integer::decode);
commandLine.registerConverter(Integer.TYPE,  s -> Integer::decode);
commandLine.registerConverter(Long.class,    s -> Long::decode);
commandLine.registerConverter(Long.TYPE,     s -> Long::decode);
----

In Java 5 this becomes a bit more verbose:
[source,java]
----
ITypeConverter<Integer> intConverter = new ITypeConverter<Integer>() {
    public Integer convert(String s) {
        return Integer.decode(s);
    }
};
commandLine.registerConverter(Integer.class, intConverter);
commandLine.registerConverter(Integer.TYPE,  intConverter);
...
----

== Arity
Arity is the number of parameters that will be consumed by an option.
Most of the time picocli will consume the right number of parameters automatically and you don't need to worry about this.

When an option or parameters field has a type that can hold multiple values (an array or a collection),
the `arity` attribute lets you control exactly how many parameters are captured by this field.

=== Default Arity
The default arity value of a field annotated with `@Option` or `@Parameters` depends on the field's type.

* Boolean fields: arity is zero (no parameter is consumed - the field is set to `true` when the option name is recognized).
* Single-valued types like `int`, `String`, `File`: arity is one (consume one parameter). Omitting the option parameter results in a ParameterException: "Missing required parameter for field '<field-name>'".
* Multi-valued types like arrays or collections: consume from zero up to all available parameters.

=== Boolean Options with Explicit Parameters
It is possible to explicitly specify "true" or "false" as a parameter for a boolean option by defining an explicit <<Arity: Minimum and Maximum Number of Parameters,`arity`>> attribute. A boolean option with `arity = "0..1"` accepts zero to one parameters, `arity = "1"` means the option _must_ have one parameter. For example:

[source, java]
----
class BooleanOptionWithParameters {
    @Option(names = "-x", arity = "1", description = "1 mandatory parameter")
    boolean x;

    @Option(names = "-y", arity = "0..1", description = "min 0 and max 1 parameter")
    boolean y;
}
----

The following ways to invoke the program will be accepted (values are not case sensitive):
----
<command> -x true
<command> -x FALSE
<command> -x TRUE -y
<command> -x True -y False
----

But trying to specify the `-x` option without a parameter, or with a value other than "true" or "false" (case insensitive) will result in a `ParameterException`.

=== Arrays and Collections
Option fields of type array or `List` (or any class extending `Collection`) will be able to hold multiple values.
By default, picocli will capture arguments into these fields until it encounters a command line argument that is
an option name or a registered command name.

The `arity` attribute can be used to specify the exact number of required parameters, or a range with a minimum and a maximum number of parameters. The maximum can be a fixed number, or can be `"*"` to denote "any number" of parameters. For example:
[source, java]
----
class MyProgram {
    @Parameters(arity = "3", descriptions = "exactly three Files")
    File[] files;

    @Option(names = "-f", arity = "2..4", description = "two to four floating point numbers")
    double[] doubles;

    @Option(names = "-s", arity = "1..*", description = "at least one string")
    String[] strings;
}
----
A `MissingParameterException` is thrown when fewer than the miminum number of required parameters is specified as command line arguments. Options with an exact number or an exact range will consume up to the maximum number of parameters.

Once the minimum number of parameters is consumed, picocli will check for each subsequent command line argument whether it is another parameter, or a new option. For example:

----
<command> -s A B C -f 1.0 2.0 3.0
----
The above command line arguments will be parsed as three parameters for the `-s` option, followed by three parameters for the `-f` option.

=== Ambiguous Input
Positional parameters do not have an option name, so it is not always easy to decide where they start. The below example command line arguments will be parsed as six parameters for the `-s` option, not as three strings and three files:
----
<command> -s A B C file1 file2 file3
----

Users can disambiguate the input by specifying a double dash (`--`) after the option parameters.
The argument `--` is interpreted as a delimiter indicating the end of options. Any following arguments are treated as positional parameters. For example, the following command line arguments will be parsed as three strings and three files:
----
<command> -s A B C -- file1 file2 file3
----

=== Option-Parameter Separators and Arity

IMPORTANT: A separator clarifies that a parameter belongs to an option, but does not prevent subsequent parameters from also being assigned to the same option. For example:

[source,java]
----
@Option(names = "-opt", arity = "2") List<String> values;
@Parameters                          List<String> remainder;
----
Because arity is 2, both parameters in the below example are assigned to the `-opt` option:
----
<command> -opt=val1 val2
----

== Required Options
=== Options
Options can be marked `required` to make it mandatory for the user to specify them on the command line. When a required option is not specified, a `MissingParameterException` is thrown from the `parse` method. For example:
[source, java]
----
class MandatoryOption {
    @Option(names = "-n", required = true, description = "mandatory number")
    int number;

    @Parameters
    File[] files;
}
----
The following command line arguments would result in an exception complaining that `number` is missing:
----
// invalid: missing option -n
<command> file1 file2 file3
----
The following command line arguments would be accepted:
----
// valid: required option -n has a value
<command> -n 123 file1 file2 file3
----

=== Parameters
Use the `arity` attribute to make `@Parameters` mandatory:
[source, java]
----
class BothOptionAndParametersMandatory {
    @Parameters(arity = "1..*", descriptions = "at least one File")
    File[] files;

    @Option(names = "-n", required = true, description = "mandatory number")
    int number;
}
----
The following command line arguments would result in an exception complaining that `files` are missing:
----
// invalid: missing file parameters
<command> -n 123
----
The following command line arguments would be accepted:
----
// valid: both required fields have a value
<command> -n 123 file1
----

== Help Options
Options with the attribute `help = true` are special: if one of the command line arguments is a "help" option, picocli will stop parsing the remaining arguments and will not check for required options.

[source,java]
----
@Option(names = {"-h", "--help"}, help = true, description = "display this help message")
boolean helpRequested;
----
This is suitable for options that should trigger the usage help message or application version information being shown on the console.

It is the responsibility of the application to check the field and show the usage help message:
[source,java]
----
Compress app = CommandLine.parse(new App(), args);
if (app.helpRequested) {
   CommandLine.usage(new App(), System.err);
   return;
}
----

== Usage Help
=== Example
A default picocli usage help message looks like this:
----
Usage: cat [-AbeEnstTuv] [--help] [--version] [FILE...]
Concatenate FILE(s), or standard input, to standard output.
      FILE                    Files whose contents to display
  -A, --show-all              equivalent to -vET
  -b, --number-nonblank       number nonempty output lines, overrides -n
  -e                          equivalent to -vET
  -E, --show-ends             display $ at end of each line
  -n, --number                number all output lines
  -s, --squeeze-blank         suppress repeated empty output lines
  -t                          equivalent to -vT
  -T, --show-tabs             display TAB characters as ^I
  -u                          (ignored)
  -v, --show-nonprinting      use ^ and M- notation, except for LDF and TAB
      --help                  display this help and exit
      --version               output version information and exit
Copyright(c) 2017
----

The usage help message is generated from annotation attributes, like below:
[source,java]
----
@Command(name = "cat", footer = "Copyright(c) 2017",
         description = "Concatenate FILE(s), or standard input, to standard output.")
class Cat {

  @Parameters(paramLabel = "FILE", description = "Files whose contents to display")
  List<File> files;

  @Option(names = "--help", help = true, description = "display this help and exit")
  boolean help;

  @Option(names = "-t",                 description = "equivalent to -vT")  boolean t;
  @Option(names = "-e",                 description = "equivalent to -vET") boolean e;
  @Option(names = {"-A", "--show-all"}, description = "equivalent to -vET") boolean all;

  // ...
}
----

=== Command Name
In the above example, the program name is taken from the `name` attribute of the `Command` annotation:
[source,java]
----
@Command(name = "cat")
----
Without a `name` attribute, picocli will show a generic `<main class>` in the synopsis:
----
Usage: <main class> [-AbeEnstTuv] [--help] [--version] [FILE...]
----
=== Parameter Labels
Non-boolean options require a value. The usage help should explain this, and picocli shows the option parameter
in the synopsis and in the option list. By default, the field name is shown in `<` and `>` fish brackets.
Use the `paramLabel` attribute to display a different name. For example:
----
Usage: <main class> [-f=FILE] [-n=<number>] NUM <host>
      NUM                     number param
      host                    the host parameter
  -f= FILE                    a file
  -n= <number>                a number option
----
Some annotated fields in the below example class have a `paramLabel` attribute and others don't:
[source,java]
----
@Command(showDefaultValues = false)
class ParamLabels {
    @Option(names = "-f",    paramLabel = "FILE", description = "a file")      File f;
    @Option(names = "-n",    description = "a number option")                  int number;
    @Parameters(index = "0", paramLabel = "NUM", description = "number param") int n;
    @Parameters(index = "1", description = "the host parameter")               InetAddress host;
}
----
NOTE: For demonstration purposes the above example mixes the all-uppercase (e.g., `NUM`) style label and the fish bracket (e.g., `<number>`) style labels. For real applications, mixing these label styles should be avoided. An application should consistently use only one style.

=== Hidden Options and Parameters
Options and Parameters with the `hidden` attribute set to `true` will not be shown in the usage help message.
This is useful for example when a parameter at some index is captured into multiple fields:
by default each of these fields would be shown in the usage message, which would be confusing for users.

For example, the `all` field below is annotated as `hidden = true`:
[source,java]
----
@Command(showDefaultValues = false)
class App {
    @Parameters(index = "0",    description = "destination host")  InetAddress host;
    @Parameters(index = "1",    description = "destination port")  int port;
    @Parameters(index = "2..*", description = "files to transfer") String[] files;

    @Parameters(hidden = true) String[] all;
}
----
The above will generate the following usage help message, where the `all` field is not shown:
----
Usage: <main class> <host> <port> [<files>...]
      host                    destination host
      port                    destination port
      files                   files to transfer
----

== Customizing Usage Help
=== Example
The below example demonstrates what a customized usage message can look like.
Note how section headings with line separators can create a more spacious usage message,
and also that options are listed in declaration order (instead of in alphabetic order).
----
Usage:

Record changes to the repository.

git-commit [-ap] [--fixup=<commit>] [--squash=<commit>] [-c=<commit>]
           [-C=<commit>] [-F=<file>] [-m[=<msg>...]] [<files>...]

Description:

Stores the current contents of the index in a new commit along with a log
message from the user describing the changes.

Parameters:
      <files>                 the files to commit

Options:
  -a, --all                   Tell the command to automatically stage files
                                that have been modified and deleted, but new
                                files you have not told Git about are not
                                affected.
  -p, --patch                 Use the interactive patch selection interface to
                                chose which changes to commit
  -C, --reuse-message=<commit>
                              Take an existing commit object, and reuse the log
                                message and the authorship information
                                (including the timestamp) when creating the
                                commit.
  -c, --reedit-message=<commit>
                              Like -C, but with -c the editor is invoked, so
                                that the user canfurther edit the commit
                                message.
      --fixup=<commit>        Construct a commit message for use with rebase
                                --autosquash.
      --squash=<commit>        Construct a commit message for use with rebase
                                --autosquash. The commitmessage subject line is
                                taken from the specified commit with a prefix
                                of "squash! ". Can be used with additional
                                commit message options (-m/-c/-C/-F).
  -F, --file=<file>           Take the commit message from the given file. Use
                                - to read the message from the standard input.
  -m, --message[=<msg>...]     Use the given <msg> as the commit message. If
                                multiple -m options are given, their values are
                                concatenated as separate paragraphs.
----

=== Section Headings
The above spacious layout is mainly due to the section headings:
[code,java]
----
@CommandLine.Command(name = "git-commit",
        sortOptions = false,
        headerHeading = "Usage:%n%n",
        synopsisHeading = "%n",
        descriptionHeading = "%nDescription:%n%n",
        parameterListHeading = "%nParameters:%n",
        optionListHeading = "%nOptions:%n",
        header = "Record changes to the repository.",
        description = "Stores the current contents of the index in a new commit " +
                "along with a log message from the user describing the changes.")
class GitCommit { ... }
----

=== Unsorted Option List
By default the options list displays options in alphabetical order. Use the `sortOptions = false` attribute to display options in the order they are declared in your class.

=== Show Default Values
Use the `showDefaultValues = true` attribute to append the default value of the options and positional parameters to the description column.

=== Abbreviated Synopsis
=== Custom Synopsis
=== Command Header and Description
=== Footer
=== Option-Parameter Separators

=== Reordering Sections
To reorder sections of the usage message, you need to use the `CommandLine.Help` class directly. The `CommandLine::usage` method implementation looks like this:

[source,java]
----
Map<String, Object> subcommandMap = new HashMap<String, Object>();
subcommandMap.put("add", new AddCommand());
...
Help help = new Help(new MainClass()).addAllCommands(subcommandMap);
StringBuilder sb = new StringBuilder()
        .append(help.headerHeading())
        .append(help.header())
        .append(help.synopsisHeading())      //e.g. Usage:
        .append(help.synopsis())             //e.g. <main> [OPTIONS] [ARGUMENTS]
        .append(help.descriptionHeading())   //e.g. %nDescription:%n%n
        .append(help.description())          //e.g. "application description"
        .append(help.parameterListHeading()) //e.g. %nPositional parameters:%n%n
        .append(help.parameterList())        //e.g. [FILE...] the files to convert
        .append(help.optionListHeading())    //e.g. %nOptions:%n%n
        .append(help.optionList())           //e.g. -h, --help   displays this help
        .append(help.commandListHeading())   //e.g. %nCommands:%n%n
        .append(help.commandList())          //e.g.    add       adds a to b
        .append(help.footerHeading())
        .append(help.footer());
----
In your application, instead of calling `CommandLine.usage(new MainClass(), System.err)`, you can alter the above code to, for example, list subcommands first, then global options and finally the parameters.

=== Formatted Headings
By using the `Help` class directly as explained in the previous section,
the `xxxHeading()` methods can be passed arguments.
These arguments can be referenced by the format specifiers in the heading https://docs.oracle.com/javase/8/docs/api/java/util/Formatter.html[format strings]. For example:

[source,java]
----
@Command(descriptionHeading = "%nDescription (%1$tb %1$te, %1$tY)%n%n")
class MainClass {}
----
The `descriptionHeading` attribute is a format string with some date/time conversion format specifiers and some line separators. Picocli will format this string with any arguments that are passed to the `Help::descriptionHeading(Object...)` method. For example:
[source,java]
----
Help help = new Help(new MainClass());
Calendar c = new GregorianCalendar(2017, MAY, 23);
String formatted = help.descriptionHeading(c);

assert "\nDescription (May 23, 2017)\n\n".equals(formatted);
----

== Advanced Usage Help Customization
=== Custom Layout
=== Table and Columns
=== Option Renderer
=== Parameter Renderer
=== Param Label Renderer

== Subcommands
=== Registering Subcommands
=== Usage Help for Subcommands

== Subclassing to Reuse Options and Command Attributes
Picocli will walk the class hierarchy to check for annotations, so you can declare common @Options and @Command attributes on a superclass and override these fields or attributes on a subclass.

The below example shows how common options like `help` and `version` can be declared as fields in a superclass so they are available in all subclasses. Similarly, annotating the superclass with default `@Command` attributes means subclasses won't need to set these attributes.

[source,java]
----
@Command(synopsisHeading      = "%nUsage:%n%n",      descriptionHeading = "%nDescription:%n%n",
         parameterListHeading = "%nParameters:%n%n", optionListHeading  = "%nOptions:%n%n",
         commandListHeading   = "%nCommands:%n%n",   showDefaultValues  = false)
public abstract class AbstractCommand {

    @Option(names = { "-h", "-?", "--help" }, help = true,
            description = "give this help list")
    protected boolean helpRequested;

    @Option(names = { "-V", "--version" }, help = true,
            description = "print program version")
    protected boolean versionRequested;
}
----

All commands that extend `AbstractCommand` support the `--help` and `--version` options, and generate a usage help message in the same spacious style. For example:

[source,java]
----
@Command(name        = "zip",
         header      = "Compresses the specified FILE(s).",
         description = "The default action is to add or replace zipfile entries from list, " +
                       "which can include the special name - to compress standard input.",
         footer      = "Copyright (c) 1990-2008 Info-ZIP - Type 'zip "-L"' for software license.")
public class ZipCommand extends AbstractCommand {
    @Option(names = { "-o", "--output" }, description = "output file to write to")
    private File output;

    @Parameter(paramLabel = "FILE", description = "FILEs to compress")
    private File[] files;
}
----

== Putting it all Together
Imagine an application that takes some input files and compresses them to an output file.
----
Compress -o outputFile file1 file2 file3
----
The program takes one option (`-o`, the output file) and one or more input files.
One way to accomplish this with picocli looks like this:

[source, java]
----
import picocli.CommandLine.*;
import java.io.File;

@Command(name = "Compress", header = "Compresses the specified input files to an output file")
public class Compress {
    @Parameters(arity = "1..*", description = "one or more files to compress")
    File[] inputFiles;

    @Option(names = {"-o", "--outfile"}, description = "optional output file name. If omitted directory name is used.")
    File outputFile;

    @Option(names = {"-h", "--help"}, help = true, description = "display this help message")
    boolean helpRequested;

    public static void main(String... args) {
        try {
            Compress compress = CommandLine.parse(new Compress(), args);
            if (compress.helpRequested) {
                CommandLine.usage(new Compress(), System.err);
                return;
            }
            doCompress();
        } catch (ParseException ex) {
            System.err.println(ex.getMessage());
            CommandLine.usage(new Compress(), System.err);
        }
    }

    private void doCompress() { ... } // business logic of the application
}
----

== Download

NOTE: Here is the source. Copy and paste it into a file called `CommandLine.java`, add it to your project, and enjoy!

[source,java]
----
include::../src/main/java/picocli/CommandLine.java[]
----


Update README.adoc

Update README.adoc

=== Example: kustomize
:icons: font

This is an example demonstrating how skaffold can work with kustomize with the `skaffold deploy` command.

ifndef::env-github[]
==== Example files
link:{github-repo-tree}/examples/kustomize[see on Github icon:github[]]

[source,yaml, indent=3, title=skaffold.yaml]
----
include::skaffold.yaml[]
----

[source,yaml, indent=3, title=kustomization.yaml]
----
include::kustomization.yaml[]
----

[source,patch, indent=3, title=patch.yaml]
----
include::patch.yaml[]
----

[source,patch, indent=3, title=deployment.yaml]
----
include::deployment.yaml[]
----

endif::[]

=== Example: passing arguments to kustomize
:icons: font

This is an example demonstrating how additional arguments can be passed to the `kustomize build` command.

ifndef::env-github[]

[source,yaml, indent=3, title=skaffold-kustomize-args.yaml]
----
include::skaffold-kustomize-args.yaml[]
----

endif::[]

=== Example: kustomize
:icons: font

This is an example demonstrating how skaffold can work with kustomize with the `skaffold deploy` command.

ifndef::env-github[]
==== Example files
link:{github-repo-tree}/examples/kustomize[see on Github icon:github[]]

[source,yaml, indent=3, title=skaffold.yaml]
----
include::skaffold.yaml[]
----

[source,yaml, indent=3, title=kustomization.yaml]
----
include::kustomization.yaml[]
----

[source,patch, indent=3, title=patch.yaml]
----
include::patch.yaml[]
----

[source,patch, indent=3, title=deployment.yaml]
----
include::deployment.yaml[]
----

endif::[]

=== Example: passing arguments to kustomize
:icons: font

This is an example demonstrating how additional arguments can be passed to kustomize

ifndef::env-github[]

[source,yaml, indent=3, title=skaffold-kustomize-args.yaml]
----
include::skaffold-kustomize-args.yaml[]
----

endif::[]