Page Menu
Home
Musing Studio
Search
Configure Global Search
Log In
Files
F10668945
README.md
No One
Temporary
Actions
Download File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
31 KB
Subscribers
None
README.md
View Options
cli
===
[](https://travis-ci.org/urfave/cli)
[](https://ci.appveyor.com/project/urfave/cli)
[](https://godoc.org/github.com/urfave/cli)
[](https://codebeat.co/projects/github-com-urfave-cli)
[](https://goreportcard.com/report/urfave/cli)
[](http://gocover.io/github.com/urfave/cli) /
[](http://gocover.io/github.com/urfave/cli/altsrc)
**
Notice
:**
This
is
the
library
formerly
known
as
`
github
.
com
/
codegangsta
/
cli
`
--
Github
will
automatically
redirect
requests
to
this
repository
,
but
we
recommend
updating
your
references
for
clarity
.
cli
is
a
simple
,
fast
,
and
fun
package
for
building
command
line
apps
in
Go
.
The
goal
is
to
enable
developers
to
write
fast
and
distributable
command
line
applications
in
an
expressive
way
.
<!--
toc
-->
-
[
Overview
](#
overview
)
-
[
Installation
](#
installation
)
*
[
Supported
platforms
](#
supported
-
platforms
)
*
[
Using
the
`
v2
`
branch
](#
using
-
the
-
v2
-
branch
)
*
[
Pinning
to
the
`
v1
`
releases
](#
pinning
-
to
-
the
-
v1
-
releases
)
-
[
Getting
Started
](#
getting
-
started
)
-
[
Examples
](#
examples
)
*
[
Arguments
](#
arguments
)
*
[
Flags
](#
flags
)
+
[
Placeholder
Values
](#
placeholder
-
values
)
+
[
Alternate
Names
](#
alternate
-
names
)
+
[
Ordering
](#
ordering
)
+
[
Values
from
the
Environment
](#
values
-
from
-
the
-
environment
)
+
[
Values
from
alternate
input
sources
(
YAML
,
TOML
,
and
others
)](#
values
-
from
-
alternate
-
input
-
sources
-
yaml
-
toml
-
and
-
others
)
*
[
Subcommands
](#
subcommands
)
*
[
Subcommands
categories
](#
subcommands
-
categories
)
*
[
Exit
code
](#
exit
-
code
)
*
[
Bash
Completion
](#
bash
-
completion
)
+
[
Enabling
](#
enabling
)
+
[
Distribution
](#
distribution
)
+
[
Customization
](#
customization
)
*
[
Generated
Help
Text
](#
generated
-
help
-
text
)
+
[
Customization
](#
customization
-
1
)
*
[
Version
Flag
](#
version
-
flag
)
+
[
Customization
](#
customization
-
2
)
+
[
Full
API
Example
](#
full
-
api
-
example
)
-
[
Contribution
Guidelines
](#
contribution
-
guidelines
)
<!--
tocstop
-->
##
Overview
Command
line
apps
are
usually
so
tiny
that
there
is
absolutely
no
reason
why
your
code
should
*
not
*
be
self
-
documenting
.
Things
like
generating
help
text
and
parsing
command
flags
/
options
should
not
hinder
productivity
when
writing
a
command
line
app
.
**
This
is
where
cli
comes
into
play
.**
cli
makes
command
line
programming
fun
,
organized
,
and
expressive
!
##
Installation
Make
sure
you
have
a
working
Go
environment
.
Go
version
1.2
+
is
supported
.
[
See
the
install
instructions
for
Go
](
http
:
//golang.org/doc/install.html).
To
install
cli
,
simply
run
:
```
$
go
get
github
.
com
/
urfave
/
cli
```
Make
sure
your
`
PATH
`
includes
the
`
$
GOPATH
/
bin
`
directory
so
your
commands
can
be
easily
used
:
```
export
PATH
=$
PATH
:$
GOPATH
/
bin
```
###
Supported
platforms
cli
is
tested
against
multiple
versions
of
Go
on
Linux
,
and
against
the
latest
released
version
of
Go
on
OS
X
and
Windows
.
For
full
details
,
see
[
`
./.
travis
.
yml
`
](./.
travis
.
yml
)
and
[
`
./
appveyor
.
yml
`
](./
appveyor
.
yml
).
###
Using
the
`
v2
`
branch
**
Warning
**:
The
`
v2
`
branch
is
currently
unreleased
and
considered
unstable
.
There
is
currently
a
long
-
lived
branch
named
`
v2
`
that
is
intended
to
land
as
the
new
`
master
`
branch
once
development
there
has
settled
down
.
The
current
`
master
`
branch
(
mirrored
as
`
v1
`
)
is
being
manually
merged
into
`
v2
`
on
an
irregular
human
-
based
schedule
,
but
generally
if
one
wants
to
"upgrade"
to
`
v2
`
*
now
*
and
accept
the
volatility
(
read
:
"awesomeness"
)
that
comes
along
with
that
,
please
use
whatever
version
pinning
of
your
preference
,
such
as
via
`
gopkg
.
in
`
:
```
$
go
get
gopkg
.
in
/
urfave
/
cli
.
v2
```
```
go
...
import
(
"gopkg.in/urfave/cli.v2"
// imports as package "cli"
)
...
```
###
Pinning
to
the
`
v1
`
releases
Similarly
to
the
section
above
describing
use
of
the
`
v2
`
branch
,
if
one
wants
to
avoid
any
unexpected
compatibility
pains
once
`
v2
`
becomes
`
master
`
,
then
pinning
to
`
v1
`
is
an
acceptable
option
,
e
.
g
.:
```
$
go
get
gopkg
.
in
/
urfave
/
cli
.
v1
```
```
go
...
import
(
"gopkg.in/urfave/cli.v1"
// imports as package "cli"
)
...
```
This
will
pull
the
latest
tagged
`
v1
`
release
(
e
.
g
.
`
v1
.
18.1
`
at
the
time
of
writing
).
##
Getting
Started
One
of
the
philosophies
behind
cli
is
that
an
API
should
be
playful
and
full
of
discovery
.
So
a
cli
app
can
be
as
little
as
one
line
of
code
in
`
main
()
`
.
<!--
{
"args"
:
[
"--help"
],
"output"
:
"A new cli application"
}
-->
```
go
package
main
import
(
"os"
"github.com/urfave/cli"
)
func
main
()
{
cli
.
NewApp
().
Run
(
os
.
Args
)
}
```
This
app
will
run
and
show
help
text
,
but
is
not
very
useful
.
Let
'
s
give
an
action
to
execute
and
some
help
documentation
:
<!--
{
"output"
:
"boom! I say!"
}
-->
```
go
package
main
import
(
"fmt"
"os"
"github.com/urfave/cli"
)
func
main
()
{
app
:=
cli
.
NewApp
()
app
.
Name
=
"boom"
app
.
Usage
=
"make an explosive entrance"
app
.
Action
=
func
(
c
*
cli
.
Context
)
error
{
fmt
.
Println
(
"boom! I say!"
)
return
nil
}
app
.
Run
(
os
.
Args
)
}
```
Running
this
already
gives
you
a
ton
of
functionality
,
plus
support
for
things
like
subcommands
and
flags
,
which
are
covered
below
.
##
Examples
Being
a
programmer
can
be
a
lonely
job
.
Thankfully
by
the
power
of
automation
that
is
not
the
case
!
Let
'
s
create
a
greeter
app
to
fend
off
our
demons
of
loneliness
!
Start
by
creating
a
directory
named
`
greet
`
,
and
within
it
,
add
a
file
,
`
greet
.
go
`
with
the
following
code
in
it
:
<!--
{
"output"
:
"Hello friend!"
}
-->
```
go
package
main
import
(
"fmt"
"os"
"github.com/urfave/cli"
)
func
main
()
{
app
:=
cli
.
NewApp
()
app
.
Name
=
"greet"
app
.
Usage
=
"fight the loneliness!"
app
.
Action
=
func
(
c
*
cli
.
Context
)
error
{
fmt
.
Println
(
"Hello friend!"
)
return
nil
}
app
.
Run
(
os
.
Args
)
}
```
Install
our
command
to
the
`
$
GOPATH
/
bin
`
directory
:
```
$
go
install
```
Finally
run
our
new
command
:
```
$
greet
Hello
friend
!
```
cli
also
generates
neat
help
text
:
```
$
greet
help
NAME
:
greet
-
fight
the
loneliness
!
USAGE
:
greet
[
global
options
]
command
[
command
options
]
[
arguments
...]
VERSION
:
0.0
.
0
COMMANDS
:
help
,
h
Shows
a
list
of
commands
or
help
for
one
command
GLOBAL
OPTIONS
--
version
Shows
version
information
```
###
Arguments
You
can
lookup
arguments
by
calling
the
`
Args
`
function
on
`
cli
.
Context
`
,
e
.
g
.:
<!--
{
"output"
:
"Hello \""
}
-->
```
go
package
main
import
(
"fmt"
"os"
"github.com/urfave/cli"
)
func
main
()
{
app
:=
cli
.
NewApp
()
app
.
Action
=
func
(
c
*
cli
.
Context
)
error
{
fmt
.
Printf
(
"Hello %q"
,
c
.
Args
().
Get
(
0
))
return
nil
}
app
.
Run
(
os
.
Args
)
}
```
###
Flags
Setting
and
querying
flags
is
simple
.
<!--
{
"output"
:
"Hello Nefertiti"
}
-->
```
go
package
main
import
(
"fmt"
"os"
"github.com/urfave/cli"
)
func
main
()
{
app
:=
cli
.
NewApp
()
app
.
Flags
=
[]
cli
.
Flag
{
cli
.
StringFlag
{
Name
:
"lang"
,
Value
:
"english"
,
Usage
:
"language for the greeting"
,
},
}
app
.
Action
=
func
(
c
*
cli
.
Context
)
error
{
name
:=
"Nefertiti"
if
c
.
NArg
()
>
0
{
name
=
c
.
Args
().
Get
(
0
)
}
if
c
.
String
(
"lang"
)
==
"spanish"
{
fmt
.
Println
(
"Hola"
,
name
)
}
else
{
fmt
.
Println
(
"Hello"
,
name
)
}
return
nil
}
app
.
Run
(
os
.
Args
)
}
```
You
can
also
set
a
destination
variable
for
a
flag
,
to
which
the
content
will
be
scanned
.
<!--
{
"output"
:
"Hello someone"
}
-->
```
go
package
main
import
(
"os"
"fmt"
"github.com/urfave/cli"
)
func
main
()
{
var
language
string
app
:=
cli
.
NewApp
()
app
.
Flags
=
[]
cli
.
Flag
{
cli
.
StringFlag
{
Name
:
"lang"
,
Value
:
"english"
,
Usage
:
"language for the greeting"
,
Destination
:
&
language
,
},
}
app
.
Action
=
func
(
c
*
cli
.
Context
)
error
{
name
:=
"someone"
if
c
.
NArg
()
>
0
{
name
=
c
.
Args
()[
0
]
}
if
language
==
"spanish"
{
fmt
.
Println
(
"Hola"
,
name
)
}
else
{
fmt
.
Println
(
"Hello"
,
name
)
}
return
nil
}
app
.
Run
(
os
.
Args
)
}
```
See
full
list
of
flags
at
http
:
//godoc.org/github.com/urfave/cli
####
Placeholder
Values
Sometimes
it
'
s
useful
to
specify
a
flag
'
s
value
within
the
usage
string
itself
.
Such
placeholders
are
indicated
with
back
quotes
.
For
example
this
:
<!--
{
"args"
:
[
"--help"
],
"output"
:
"--config FILE, -c FILE"
}
-->
```
go
package
main
import
(
"os"
"github.com/urfave/cli"
)
func
main
()
{
app
:=
cli
.
NewApp
()
app
.
Flags
=
[]
cli
.
Flag
{
cli
.
StringFlag
{
Name
:
"config, c"
,
Usage
:
"Load configuration from `FILE`"
,
},
}
app
.
Run
(
os
.
Args
)
}
```
Will
result
in
help
output
like
:
```
--
config
FILE
,
-
c
FILE
Load
configuration
from
FILE
```
Note
that
only
the
first
placeholder
is
used
.
Subsequent
back
-
quoted
words
will
be
left
as
-
is
.
####
Alternate
Names
You
can
set
alternate
(
or
short
)
names
for
flags
by
providing
a
comma
-
delimited
list
for
the
`
Name
`
.
e
.
g
.
<!--
{
"args"
:
[
"--help"
],
"output"
:
"--lang value, -l value.*language for the greeting.*default: \"english\""
}
-->
```
go
package
main
import
(
"os"
"github.com/urfave/cli"
)
func
main
()
{
app
:=
cli
.
NewApp
()
app
.
Flags
=
[]
cli
.
Flag
{
cli
.
StringFlag
{
Name
:
"lang, l"
,
Value
:
"english"
,
Usage
:
"language for the greeting"
,
},
}
app
.
Run
(
os
.
Args
)
}
```
That
flag
can
then
be
set
with
`
--
lang
spanish
`
or
`
-
l
spanish
`
.
Note
that
giving
two
different
forms
of
the
same
flag
in
the
same
command
invocation
is
an
error
.
####
Ordering
Flags
for
the
application
and
commands
are
shown
in
the
order
they
are
defined
.
However
,
it
'
s
possible
to
sort
them
from
outside
this
library
by
using
`
FlagsByName
`
or
`
CommandsByName
`
with
`
sort
`
.
For
example
this
:
<!--
{
"args"
:
[
"--help"
],
"output"
:
"add a task to the list\n.*complete a task on the list\n.*\n\n.*\n.*Load configuration from FILE\n.*Language for the greeting.*"
}
-->
```
go
package
main
import
(
"os"
"sort"
"github.com/urfave/cli"
)
func
main
()
{
app
:=
cli
.
NewApp
()
app
.
Flags
=
[]
cli
.
Flag
{
cli
.
StringFlag
{
Name
:
"lang, l"
,
Value
:
"english"
,
Usage
:
"Language for the greeting"
,
},
cli
.
StringFlag
{
Name
:
"config, c"
,
Usage
:
"Load configuration from `FILE`"
,
},
}
app
.
Commands
=
[]
cli
.
Command
{
{
Name
:
"complete"
,
Aliases
:
[]
string
{
"c"
},
Usage
:
"complete a task on the list"
,
Action
:
func
(
c
*
cli
.
Context
)
error
{
return
nil
},
},
{
Name
:
"add"
,
Aliases
:
[]
string
{
"a"
},
Usage
:
"add a task to the list"
,
Action
:
func
(
c
*
cli
.
Context
)
error
{
return
nil
},
},
}
sort
.
Sort
(
cli
.
FlagsByName
(
app
.
Flags
))
sort
.
Sort
(
cli
.
CommandsByName
(
app
.
Commands
))
app
.
Run
(
os
.
Args
)
}
```
Will
result
in
help
output
like
:
```
--
config
FILE
,
-
c
FILE
Load
configuration
from
FILE
--
lang
value
,
-
l
value
Language
for
the
greeting
(
default
:
"english"
)
```
####
Values
from
the
Environment
You
can
also
have
the
default
value
set
from
the
environment
via
`
EnvVar
`
.
e
.
g
.
<!--
{
"args"
:
[
"--help"
],
"output"
:
"language for the greeting.*APP_LANG"
}
-->
```
go
package
main
import
(
"os"
"github.com/urfave/cli"
)
func
main
()
{
app
:=
cli
.
NewApp
()
app
.
Flags
=
[]
cli
.
Flag
{
cli
.
StringFlag
{
Name
:
"lang, l"
,
Value
:
"english"
,
Usage
:
"language for the greeting"
,
EnvVar
:
"APP_LANG"
,
},
}
app
.
Run
(
os
.
Args
)
}
```
The
`
EnvVar
`
may
also
be
given
as
a
comma
-
delimited
"cascade"
,
where
the
first
environment
variable
that
resolves
is
used
as
the
default
.
<!--
{
"args"
:
[
"--help"
],
"output"
:
"language for the greeting.*LEGACY_COMPAT_LANG.*APP_LANG.*LANG"
}
-->
```
go
package
main
import
(
"os"
"github.com/urfave/cli"
)
func
main
()
{
app
:=
cli
.
NewApp
()
app
.
Flags
=
[]
cli
.
Flag
{
cli
.
StringFlag
{
Name
:
"lang, l"
,
Value
:
"english"
,
Usage
:
"language for the greeting"
,
EnvVar
:
"LEGACY_COMPAT_LANG,APP_LANG,LANG"
,
},
}
app
.
Run
(
os
.
Args
)
}
```
####
Values
from
alternate
input
sources
(
YAML
,
TOML
,
and
others
)
There
is
a
separate
package
altsrc
that
adds
support
for
getting
flag
values
from
other
file
input
sources
.
Currently
supported
input
source
formats
:
*
YAML
*
TOML
In
order
to
get
values
for
a
flag
from
an
alternate
input
source
the
following
code
would
be
added
to
wrap
an
existing
cli
.
Flag
like
below
:
```
go
altsrc
.
NewIntFlag
(
cli
.
IntFlag
{
Name
:
"test"
})
```
Initialization
must
also
occur
for
these
flags
.
Below
is
an
example
initializing
getting
data
from
a
yaml
file
below
.
```
go
command
.
Before
=
altsrc
.
InitInputSourceWithContext
(
command
.
Flags
,
NewYamlSourceFromFlagFunc
(
"load"
))
```
The
code
above
will
use
the
"load"
string
as
a
flag
name
to
get
the
file
name
of
a
yaml
file
from
the
cli
.
Context
.
It
will
then
use
that
file
name
to
initialize
the
yaml
input
source
for
any
flags
that
are
defined
on
that
command
.
As
a
note
the
"load"
flag
used
would
also
have
to
be
defined
on
the
command
flags
in
order
for
this
code
snipped
to
work
.
Currently
only
the
aboved
specified
formats
are
supported
but
developers
can
add
support
for
other
input
sources
by
implementing
the
altsrc
.
InputSourceContext
for
their
given
sources
.
Here
is
a
more
complete
sample
of
a
command
using
YAML
support
:
<!--
{
"args"
:
[
"test-cmd"
,
"--help"
],
"output"
:
"--test value.*default: 0"
}
-->
```
go
package
notmain
import
(
"fmt"
"os"
"github.com/urfave/cli"
"github.com/urfave/cli/altsrc"
)
func
main
()
{
app
:=
cli
.
NewApp
()
flags
:=
[]
cli
.
Flag
{
altsrc
.
NewIntFlag
(
cli
.
IntFlag
{
Name
:
"test"
}),
cli
.
StringFlag
{
Name
:
"load"
},
}
app
.
Action
=
func
(
c
*
cli
.
Context
)
error
{
fmt
.
Println
(
"yaml ist rad"
)
return
nil
}
app
.
Before
=
altsrc
.
InitInputSourceWithContext
(
flags
,
altsrc
.
NewYamlSourceFromFlagFunc
(
"load"
))
app
.
Flags
=
flags
app
.
Run
(
os
.
Args
)
}
```
###
Subcommands
Subcommands
can
be
defined
for
a
more
git
-
like
command
line
app
.
<!--
{
"args"
:
[
"template"
,
"add"
],
"output"
:
"new task template: .+"
}
-->
```
go
package
main
import
(
"fmt"
"os"
"github.com/urfave/cli"
)
func
main
()
{
app
:=
cli
.
NewApp
()
app
.
Commands
=
[]
cli
.
Command
{
{
Name
:
"add"
,
Aliases
:
[]
string
{
"a"
},
Usage
:
"add a task to the list"
,
Action
:
func
(
c
*
cli
.
Context
)
error
{
fmt
.
Println
(
"added task: "
,
c
.
Args
().
First
())
return
nil
},
},
{
Name
:
"complete"
,
Aliases
:
[]
string
{
"c"
},
Usage
:
"complete a task on the list"
,
Action
:
func
(
c
*
cli
.
Context
)
error
{
fmt
.
Println
(
"completed task: "
,
c
.
Args
().
First
())
return
nil
},
},
{
Name
:
"template"
,
Aliases
:
[]
string
{
"t"
},
Usage
:
"options for task templates"
,
Subcommands
:
[]
cli
.
Command
{
{
Name
:
"add"
,
Usage
:
"add a new template"
,
Action
:
func
(
c
*
cli
.
Context
)
error
{
fmt
.
Println
(
"new task template: "
,
c
.
Args
().
First
())
return
nil
},
},
{
Name
:
"remove"
,
Usage
:
"remove an existing template"
,
Action
:
func
(
c
*
cli
.
Context
)
error
{
fmt
.
Println
(
"removed task template: "
,
c
.
Args
().
First
())
return
nil
},
},
},
},
}
app
.
Run
(
os
.
Args
)
}
```
###
Subcommands
categories
For
additional
organization
in
apps
that
have
many
subcommands
,
you
can
associate
a
category
for
each
command
to
group
them
together
in
the
help
output
.
E
.
g
.
```
go
package
main
import
(
"os"
"github.com/urfave/cli"
)
func
main
()
{
app
:=
cli
.
NewApp
()
app
.
Commands
=
[]
cli
.
Command
{
{
Name
:
"noop"
,
},
{
Name
:
"add"
,
Category
:
"template"
,
},
{
Name
:
"remove"
,
Category
:
"template"
,
},
}
app
.
Run
(
os
.
Args
)
}
```
Will
include
:
```
COMMANDS
:
noop
Template
actions
:
add
remove
```
###
Exit
code
Calling
`
App
.
Run
`
will
not
automatically
call
`
os
.
Exit
`
,
which
means
that
by
default
the
exit
code
will
"fall through"
to
being
`
0
`
.
An
explicit
exit
code
may
be
set
by
returning
a
non
-
nil
error
that
fulfills
`
cli
.
ExitCoder
`
,
*
or
*
a
`
cli
.
MultiError
`
that
includes
an
error
that
fulfills
`
cli
.
ExitCoder
`
,
e
.
g
.:
```
go
package
main
import
(
"os"
"github.com/urfave/cli"
)
func
main
()
{
app
:=
cli
.
NewApp
()
app
.
Flags
=
[]
cli
.
Flag
{
cli
.
BoolTFlag
{
Name
:
"ginger-crouton"
,
Usage
:
"is it in the soup?"
,
},
}
app
.
Action
=
func
(
ctx
*
cli
.
Context
)
error
{
if
!
ctx
.
Bool
(
"ginger-crouton"
)
{
return
cli
.
NewExitError
(
"it is not in the soup"
,
86
)
}
return
nil
}
app
.
Run
(
os
.
Args
)
}
```
###
Bash
Completion
You
can
enable
completion
commands
by
setting
the
`
EnableBashCompletion
`
flag
on
the
`
App
`
object
.
By
default
,
this
setting
will
only
auto
-
complete
to
show
an
app
'
s
subcommands
,
but
you
can
write
your
own
completion
methods
for
the
App
or
its
subcommands
.
<!--
{
"args"
:
[
"complete"
,
"--generate-bash-completion"
],
"output"
:
"laundry"
}
-->
```
go
package
main
import
(
"fmt"
"os"
"github.com/urfave/cli"
)
func
main
()
{
tasks
:=
[]
string
{
"cook"
,
"clean"
,
"laundry"
,
"eat"
,
"sleep"
,
"code"
}
app
:=
cli
.
NewApp
()
app
.
EnableBashCompletion
=
true
app
.
Commands
=
[]
cli
.
Command
{
{
Name
:
"complete"
,
Aliases
:
[]
string
{
"c"
},
Usage
:
"complete a task on the list"
,
Action
:
func
(
c
*
cli
.
Context
)
error
{
fmt
.
Println
(
"completed task: "
,
c
.
Args
().
First
())
return
nil
},
BashComplete
:
func
(
c
*
cli
.
Context
)
{
// This will complete if no args are passed
if
c
.
NArg
()
>
0
{
return
}
for
_
,
t
:=
range
tasks
{
fmt
.
Println
(
t
)
}
},
},
}
app
.
Run
(
os
.
Args
)
}
```
####
Enabling
Source
the
`
autocomplete
/
bash_autocomplete
`
file
in
your
`
.
bashrc
`
file
while
setting
the
`
PROG
`
variable
to
the
name
of
your
program
:
`
PROG
=
myprogram
source
/.../
cli
/
autocomplete
/
bash_autocomplete
`
####
Distribution
Copy
`
autocomplete
/
bash_autocomplete
`
into
`
/
etc
/
bash_completion
.
d
/
`
and
rename
it
to
the
name
of
the
program
you
wish
to
add
autocomplete
support
for
(
or
automatically
install
it
there
if
you
are
distributing
a
package
).
Don
'
t
forget
to
source
the
file
to
make
it
active
in
the
current
shell
.
```
sudo
cp
src
/
bash_autocomplete
/
etc
/
bash_completion
.
d
/<
myprogram
>
source
/
etc
/
bash_completion
.
d
/<
myprogram
>
```
Alternatively
,
you
can
just
document
that
users
should
source
the
generic
`
autocomplete
/
bash_autocomplete
`
in
their
bash
configuration
with
`
$
PROG
`
set
to
the
name
of
their
program
(
as
above
).
####
Customization
The
default
bash
completion
flag
(
`
--
generate
-
bash
-
completion
`
)
is
defined
as
`
cli
.
BashCompletionFlag
`
,
and
may
be
redefined
if
desired
,
e
.
g
.:
<!--
{
"args"
:
[
"--compgen"
],
"output"
:
"wat\nhelp\nh"
}
-->
```
go
package
main
import
(
"os"
"github.com/urfave/cli"
)
func
main
()
{
cli
.
BashCompletionFlag
=
cli
.
BoolFlag
{
Name
:
"compgen"
,
Hidden
:
true
,
}
app
:=
cli
.
NewApp
()
app
.
EnableBashCompletion
=
true
app
.
Commands
=
[]
cli
.
Command
{
{
Name
:
"wat"
,
},
}
app
.
Run
(
os
.
Args
)
}
```
###
Generated
Help
Text
The
default
help
flag
(
`
-
h
/--
help
`
)
is
defined
as
`
cli
.
HelpFlag
`
and
is
checked
by
the
cli
internals
in
order
to
print
generated
help
text
for
the
app
,
command
,
or
subcommand
,
and
break
execution
.
####
Customization
All
of
the
help
text
generation
may
be
customized
,
and
at
multiple
levels
.
The
templates
are
exposed
as
variables
`
AppHelpTemplate
`
,
`
CommandHelpTemplate
`
,
and
`
SubcommandHelpTemplate
`
which
may
be
reassigned
or
augmented
,
and
full
override
is
possible
by
assigning
a
compatible
func
to
the
`
cli
.
HelpPrinter
`
variable
,
e
.
g
.:
<!--
{
"output"
:
"Ha HA. I pwnd the help!!1"
}
-->
```
go
package
main
import
(
"fmt"
"io"
"os"
"github.com/urfave/cli"
)
func
main
()
{
// EXAMPLE: Append to an existing template
cli
.
AppHelpTemplate
=
fmt
.
Sprintf
(
`
%
s
WEBSITE
:
http
:
//awesometown.example.com
SUPPORT
:
support
@
awesometown
.
example
.
com
`
,
cli
.
AppHelpTemplate
)
// EXAMPLE: Override a template
cli
.
AppHelpTemplate
=
`
NAME
:
{{.
Name
}}
-
{{.
Usage
}}
USAGE
:
{{.
HelpName
}}
{{
if
.
VisibleFlags
}}[
global
options
]{{
end
}}{{
if
.
Commands
}}
command
[
command
options
]{{
end
}}
{{
if
.
ArgsUsage
}}{{.
ArgsUsage
}}{{
else
}}[
arguments
...]{{
end
}}
{{
if
len
.
Authors
}}
AUTHOR
:
{{
range
.
Authors
}}{{
.
}}{{
end
}}
{{
end
}}{{
if
.
Commands
}}
COMMANDS
:
{{
range
.
Commands
}}{{
if
not
.
HideHelp
}}
{{
join
.
Names
", "
}}{{
"\t"
}}{{.
Usage
}}{{
"\n"
}}{{
end
}}{{
end
}}{{
end
}}{{
if
.
VisibleFlags
}}
GLOBAL
OPTIONS
:
{{
range
.
VisibleFlags
}}{{.}}
{{
end
}}{{
end
}}{{
if
.
Copyright
}}
COPYRIGHT
:
{{.
Copyright
}}
{{
end
}}{{
if
.
Version
}}
VERSION
:
{{.
Version
}}
{{
end
}}
`
// EXAMPLE: Replace the `HelpPrinter` func
cli
.
HelpPrinter
=
func
(
w
io
.
Writer
,
templ
string
,
data
interface
{})
{
fmt
.
Println
(
"Ha HA. I pwnd the help!!1"
)
}
cli
.
NewApp
().
Run
(
os
.
Args
)
}
```
The
default
flag
may
be
customized
to
something
other
than
`
-
h
/--
help
`
by
setting
`
cli
.
HelpFlag
`
,
e
.
g
.:
<!--
{
"args"
:
[
"--halp"
],
"output"
:
"haaaaalp.*HALP"
}
-->
```
go
package
main
import
(
"os"
"github.com/urfave/cli"
)
func
main
()
{
cli
.
HelpFlag
=
cli
.
BoolFlag
{
Name
:
"halp, haaaaalp"
,
Usage
:
"HALP"
,
EnvVar
:
"SHOW_HALP,HALPPLZ"
,
}
cli
.
NewApp
().
Run
(
os
.
Args
)
}
```
###
Version
Flag
The
default
version
flag
(
`
-
v
/--
version
`
)
is
defined
as
`
cli
.
VersionFlag
`
,
which
is
checked
by
the
cli
internals
in
order
to
print
the
`
App
.
Version
`
via
`
cli
.
VersionPrinter
`
and
break
execution
.
####
Customization
The
default
flag
may
be
customized
to
something
other
than
`
-
v
/--
version
`
by
setting
`
cli
.
VersionFlag
`
,
e
.
g
.:
<!--
{
"args"
:
[
"--print-version"
],
"output"
:
"partay version 19\\.99\\.0"
}
-->
```
go
package
main
import
(
"os"
"github.com/urfave/cli"
)
func
main
()
{
cli
.
VersionFlag
=
cli
.
BoolFlag
{
Name
:
"print-version, V"
,
Usage
:
"print only the version"
,
}
app
:=
cli
.
NewApp
()
app
.
Name
=
"partay"
app
.
Version
=
"19.99.0"
app
.
Run
(
os
.
Args
)
}
```
Alternatively
,
the
version
printer
at
`
cli
.
VersionPrinter
`
may
be
overridden
,
e
.
g
.:
<!--
{
"args"
:
[
"--version"
],
"output"
:
"version=19\\.99\\.0 revision=fafafaf"
}
-->
```
go
package
main
import
(
"fmt"
"os"
"github.com/urfave/cli"
)
var
(
Revision
=
"fafafaf"
)
func
main
()
{
cli
.
VersionPrinter
=
func
(
c
*
cli
.
Context
)
{
fmt
.
Printf
(
"version=%s revision=%s\n"
,
c
.
App
.
Version
,
Revision
)
}
app
:=
cli
.
NewApp
()
app
.
Name
=
"partay"
app
.
Version
=
"19.99.0"
app
.
Run
(
os
.
Args
)
}
```
####
Full
API
Example
**
Notice
**:
This
is
a
contrived
(
functioning
)
example
meant
strictly
for
API
demonstration
purposes
.
Use
of
one
'
s
imagination
is
encouraged
.
<!--
{
"output"
:
"made it!\nPhew!"
}
-->
```
go
package
main
import
(
"errors"
"flag"
"fmt"
"io"
"io/ioutil"
"os"
"time"
"github.com/urfave/cli"
)
func
init
()
{
cli
.
AppHelpTemplate
+=
"\nCUSTOMIZED: you bet ur muffins\n"
cli
.
CommandHelpTemplate
+=
"\nYMMV\n"
cli
.
SubcommandHelpTemplate
+=
"\nor something\n"
cli
.
HelpFlag
=
cli
.
BoolFlag
{
Name
:
"halp"
}
cli
.
BashCompletionFlag
=
cli
.
BoolFlag
{
Name
:
"compgen"
,
Hidden
:
true
}
cli
.
VersionFlag
=
cli
.
BoolFlag
{
Name
:
"print-version, V"
}
cli
.
HelpPrinter
=
func
(
w
io
.
Writer
,
templ
string
,
data
interface
{})
{
fmt
.
Fprintf
(
w
,
"best of luck to you\n"
)
}
cli
.
VersionPrinter
=
func
(
c
*
cli
.
Context
)
{
fmt
.
Fprintf
(
c
.
App
.
Writer
,
"version=%s\n"
,
c
.
App
.
Version
)
}
cli
.
OsExiter
=
func
(
c
int
)
{
fmt
.
Fprintf
(
cli
.
ErrWriter
,
"refusing to exit %d\n"
,
c
)
}
cli
.
ErrWriter
=
ioutil
.
Discard
cli
.
FlagStringer
=
func
(
fl
cli
.
Flag
)
string
{
return
fmt
.
Sprintf
(
"\t\t%s"
,
fl
.
GetName
())
}
}
type
hexWriter
struct
{}
func
(
w
*
hexWriter
)
Write
(
p
[]
byte
)
(
int
,
error
)
{
for
_
,
b
:=
range
p
{
fmt
.
Printf
(
"%x"
,
b
)
}
fmt
.
Printf
(
"\n"
)
return
len
(
p
),
nil
}
type
genericType
struct
{
s
string
}
func
(
g
*
genericType
)
Set
(
value
string
)
error
{
g
.
s
=
value
return
nil
}
func
(
g
*
genericType
)
String
()
string
{
return
g
.
s
}
func
main
()
{
app
:=
cli
.
NewApp
()
app
.
Name
=
"kənˈtrīv"
app
.
Version
=
"19.99.0"
app
.
Compiled
=
time
.
Now
()
app
.
Authors
=
[]
cli
.
Author
{
cli
.
Author
{
Name
:
"Example Human"
,
Email
:
"human@example.com"
,
},
}
app
.
Copyright
=
"(c) 1999 Serious Enterprise"
app
.
HelpName
=
"contrive"
app
.
Usage
=
"demonstrate available API"
app
.
UsageText
=
"contrive - demonstrating the available API"
app
.
ArgsUsage
=
"[args and such]"
app
.
Commands
=
[]
cli
.
Command
{
cli
.
Command
{
Name
:
"doo"
,
Aliases
:
[]
string
{
"do"
},
Category
:
"motion"
,
Usage
:
"do the doo"
,
UsageText
:
"doo - does the dooing"
,
Description
:
"no really, there is a lot of dooing to be done"
,
ArgsUsage
:
"[arrgh]"
,
Flags
:
[]
cli
.
Flag
{
cli
.
BoolFlag
{
Name
:
"forever, forevvarr"
},
},
Subcommands
:
cli
.
Commands
{
cli
.
Command
{
Name
:
"wop"
,
Action
:
wopAction
,
},
},
SkipFlagParsing
:
false
,
HideHelp
:
false
,
Hidden
:
false
,
HelpName
:
"doo!"
,
BashComplete
:
func
(
c
*
cli
.
Context
)
{
fmt
.
Fprintf
(
c
.
App
.
Writer
,
"--better\n"
)
},
Before
:
func
(
c
*
cli
.
Context
)
error
{
fmt
.
Fprintf
(
c
.
App
.
Writer
,
"brace for impact\n"
)
return
nil
},
After
:
func
(
c
*
cli
.
Context
)
error
{
fmt
.
Fprintf
(
c
.
App
.
Writer
,
"did we lose anyone?\n"
)
return
nil
},
Action
:
func
(
c
*
cli
.
Context
)
error
{
c
.
Command
.
FullName
()
c
.
Command
.
HasName
(
"wop"
)
c
.
Command
.
Names
()
c
.
Command
.
VisibleFlags
()
fmt
.
Fprintf
(
c
.
App
.
Writer
,
"dodododododoodododddooooododododooo\n"
)
if
c
.
Bool
(
"forever"
)
{
c
.
Command
.
Run
(
c
)
}
return
nil
},
OnUsageError
:
func
(
c
*
cli
.
Context
,
err
error
,
isSubcommand
bool
)
error
{
fmt
.
Fprintf
(
c
.
App
.
Writer
,
"for shame\n"
)
return
err
},
},
}
app
.
Flags
=
[]
cli
.
Flag
{
cli
.
BoolFlag
{
Name
:
"fancy"
},
cli
.
BoolTFlag
{
Name
:
"fancier"
},
cli
.
DurationFlag
{
Name
:
"howlong, H"
,
Value
:
time
.
Second
*
3
},
cli
.
Float64Flag
{
Name
:
"howmuch"
},
cli
.
GenericFlag
{
Name
:
"wat"
,
Value
:
&
genericType
{}},
cli
.
Int64Flag
{
Name
:
"longdistance"
},
cli
.
Int64SliceFlag
{
Name
:
"intervals"
},
cli
.
IntFlag
{
Name
:
"distance"
},
cli
.
IntSliceFlag
{
Name
:
"times"
},
cli
.
StringFlag
{
Name
:
"dance-move, d"
},
cli
.
StringSliceFlag
{
Name
:
"names, N"
},
cli
.
UintFlag
{
Name
:
"age"
},
cli
.
Uint64Flag
{
Name
:
"bigage"
},
}
app
.
EnableBashCompletion
=
true
app
.
HideHelp
=
false
app
.
HideVersion
=
false
app
.
BashComplete
=
func
(
c
*
cli
.
Context
)
{
fmt
.
Fprintf
(
c
.
App
.
Writer
,
"lipstick\nkiss\nme\nlipstick\nringo\n"
)
}
app
.
Before
=
func
(
c
*
cli
.
Context
)
error
{
fmt
.
Fprintf
(
c
.
App
.
Writer
,
"HEEEERE GOES\n"
)
return
nil
}
app
.
After
=
func
(
c
*
cli
.
Context
)
error
{
fmt
.
Fprintf
(
c
.
App
.
Writer
,
"Phew!\n"
)
return
nil
}
app
.
CommandNotFound
=
func
(
c
*
cli
.
Context
,
command
string
)
{
fmt
.
Fprintf
(
c
.
App
.
Writer
,
"Thar be no %q here.\n"
,
command
)
}
app
.
OnUsageError
=
func
(
c
*
cli
.
Context
,
err
error
,
isSubcommand
bool
)
error
{
if
isSubcommand
{
return
err
}
fmt
.
Fprintf
(
c
.
App
.
Writer
,
"WRONG: %#v\n"
,
err
)
return
nil
}
app
.
Action
=
func
(
c
*
cli
.
Context
)
error
{
cli
.
DefaultAppComplete
(
c
)
cli
.
HandleExitCoder
(
errors
.
New
(
"not an exit coder, though"
))
cli
.
ShowAppHelp
(
c
)
cli
.
ShowCommandCompletions
(
c
,
"nope"
)
cli
.
ShowCommandHelp
(
c
,
"also-nope"
)
cli
.
ShowCompletions
(
c
)
cli
.
ShowSubcommandHelp
(
c
)
cli
.
ShowVersion
(
c
)
categories
:=
c
.
App
.
Categories
()
categories
.
AddCommand
(
"sounds"
,
cli
.
Command
{
Name
:
"bloop"
,
})
for
_
,
category
:=
range
c
.
App
.
Categories
()
{
fmt
.
Fprintf
(
c
.
App
.
Writer
,
"%s\n"
,
category
.
Name
)
fmt
.
Fprintf
(
c
.
App
.
Writer
,
"%#v\n"
,
category
.
Commands
)
fmt
.
Fprintf
(
c
.
App
.
Writer
,
"%#v\n"
,
category
.
VisibleCommands
())
}
fmt
.
Printf
(
"%#v\n"
,
c
.
App
.
Command
(
"doo"
))
if
c
.
Bool
(
"infinite"
)
{
c
.
App
.
Run
([]
string
{
"app"
,
"doo"
,
"wop"
})
}
if
c
.
Bool
(
"forevar"
)
{
c
.
App
.
RunAsSubcommand
(
c
)
}
c
.
App
.
Setup
()
fmt
.
Printf
(
"%#v\n"
,
c
.
App
.
VisibleCategories
())
fmt
.
Printf
(
"%#v\n"
,
c
.
App
.
VisibleCommands
())
fmt
.
Printf
(
"%#v\n"
,
c
.
App
.
VisibleFlags
())
fmt
.
Printf
(
"%#v\n"
,
c
.
Args
().
First
())
if
len
(
c
.
Args
())
>
0
{
fmt
.
Printf
(
"%#v\n"
,
c
.
Args
()[
1
])
}
fmt
.
Printf
(
"%#v\n"
,
c
.
Args
().
Present
())
fmt
.
Printf
(
"%#v\n"
,
c
.
Args
().
Tail
())
set
:=
flag
.
NewFlagSet
(
"contrive"
,
0
)
nc
:=
cli
.
NewContext
(
c
.
App
,
set
,
c
)
fmt
.
Printf
(
"%#v\n"
,
nc
.
Args
())
fmt
.
Printf
(
"%#v\n"
,
nc
.
Bool
(
"nope"
))
fmt
.
Printf
(
"%#v\n"
,
nc
.
BoolT
(
"nerp"
))
fmt
.
Printf
(
"%#v\n"
,
nc
.
Duration
(
"howlong"
))
fmt
.
Printf
(
"%#v\n"
,
nc
.
Float64
(
"hay"
))
fmt
.
Printf
(
"%#v\n"
,
nc
.
Generic
(
"bloop"
))
fmt
.
Printf
(
"%#v\n"
,
nc
.
Int64
(
"bonk"
))
fmt
.
Printf
(
"%#v\n"
,
nc
.
Int64Slice
(
"burnks"
))
fmt
.
Printf
(
"%#v\n"
,
nc
.
Int
(
"bips"
))
fmt
.
Printf
(
"%#v\n"
,
nc
.
IntSlice
(
"blups"
))
fmt
.
Printf
(
"%#v\n"
,
nc
.
String
(
"snurt"
))
fmt
.
Printf
(
"%#v\n"
,
nc
.
StringSlice
(
"snurkles"
))
fmt
.
Printf
(
"%#v\n"
,
nc
.
Uint
(
"flub"
))
fmt
.
Printf
(
"%#v\n"
,
nc
.
Uint64
(
"florb"
))
fmt
.
Printf
(
"%#v\n"
,
nc
.
GlobalBool
(
"global-nope"
))
fmt
.
Printf
(
"%#v\n"
,
nc
.
GlobalBoolT
(
"global-nerp"
))
fmt
.
Printf
(
"%#v\n"
,
nc
.
GlobalDuration
(
"global-howlong"
))
fmt
.
Printf
(
"%#v\n"
,
nc
.
GlobalFloat64
(
"global-hay"
))
fmt
.
Printf
(
"%#v\n"
,
nc
.
GlobalGeneric
(
"global-bloop"
))
fmt
.
Printf
(
"%#v\n"
,
nc
.
GlobalInt
(
"global-bips"
))
fmt
.
Printf
(
"%#v\n"
,
nc
.
GlobalIntSlice
(
"global-blups"
))
fmt
.
Printf
(
"%#v\n"
,
nc
.
GlobalString
(
"global-snurt"
))
fmt
.
Printf
(
"%#v\n"
,
nc
.
GlobalStringSlice
(
"global-snurkles"
))
fmt
.
Printf
(
"%#v\n"
,
nc
.
FlagNames
())
fmt
.
Printf
(
"%#v\n"
,
nc
.
GlobalFlagNames
())
fmt
.
Printf
(
"%#v\n"
,
nc
.
GlobalIsSet
(
"wat"
))
fmt
.
Printf
(
"%#v\n"
,
nc
.
GlobalSet
(
"wat"
,
"nope"
))
fmt
.
Printf
(
"%#v\n"
,
nc
.
NArg
())
fmt
.
Printf
(
"%#v\n"
,
nc
.
NumFlags
())
fmt
.
Printf
(
"%#v\n"
,
nc
.
Parent
())
nc
.
Set
(
"wat"
,
"also-nope"
)
ec
:=
cli
.
NewExitError
(
"ohwell"
,
86
)
fmt
.
Fprintf
(
c
.
App
.
Writer
,
"%d"
,
ec
.
ExitCode
())
fmt
.
Printf
(
"made it!\n"
)
return
ec
}
if
os
.
Getenv
(
"HEXY"
)
!=
""
{
app
.
Writer
=
&
hexWriter
{}
app
.
ErrWriter
=
&
hexWriter
{}
}
app
.
Metadata
=
map
[
string
]
interface
{}{
"layers"
:
"many"
,
"explicable"
:
false
,
"whatever-values"
:
19.99
,
}
app
.
Run
(
os
.
Args
)
}
func
wopAction
(
c
*
cli
.
Context
)
error
{
fmt
.
Fprintf
(
c
.
App
.
Writer
,
":wave: over here, eh\n"
)
return
nil
}
```
##
Contribution
Guidelines
Feel
free
to
put
up
a
pull
request
to
fix
a
bug
or
maybe
add
a
feature
.
I
will
give
it
a
code
review
and
make
sure
that
it
does
not
break
backwards
compatibility
.
If
I
or
any
other
collaborators
agree
that
it
is
in
line
with
the
vision
of
the
project
,
we
will
work
with
you
to
get
the
code
into
a
mergeable
state
and
merge
it
into
the
master
branch
.
If
you
have
contributed
something
significant
to
the
project
,
we
will
most
likely
add
you
as
a
collaborator
.
As
a
collaborator
you
are
given
the
ability
to
merge
others
pull
requests
.
It
is
very
important
that
new
code
does
not
break
existing
code
,
so
be
careful
about
what
code
you
do
choose
to
merge
.
If
you
feel
like
you
have
contributed
to
the
project
but
have
not
yet
been
added
as
a
collaborator
,
we
probably
forgot
to
add
you
,
please
open
an
issue
.
File Metadata
Details
Attached
Mime Type
text/x-c
Expires
Thu, May 15, 11:29 AM (22 h, 6 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
3236691
Attached To
rWCLI writeas-cli
Event Timeline
Log In to Comment