-
Notifications
You must be signed in to change notification settings - Fork 6
Create a Script
When you want to create a simple command, you must create a go_console.Script
object.
In this case, can get rid of go_console.Script.Name
and go_console.Script.Runner
.
Note:
go_console.Script.Runner
will be executed when.Build()
is called. (if defined)
package main
import (
"github.com/DrSmithFr/go-console"
"github.com/DrSmithFr/go-console/input/argument"
"github.com/DrSmithFr/go-console/input/option"
)
func main() {
//
// Easy way to create a command with arguments and options
//
cmd := go_console.Script{
Description: "The app:command command.",
Arguments: []go_console.Argument{
{
Name: "name",
Value: argument.Optional | argument.List,
Description: "The name of the user.",
},
},
Options: []go_console.Option{
{
Name: "foo",
Shortcut: "f",
Value: option.None,
Description: "The foo option.",
},
},
}
cmd.Build()
}
We strongly recommend that you define a description for your command, arguments and options. This will be displayed when the user runs
./command --help
The most interesting part of the commands are the arguments and options that you can make available. These arguments and options allow you to pass dynamic information from the terminal to the command.
Arguments are the strings - separated by spaces - that come after the command name itself. They are ordered, and can be optional or required and/or list.
package main
import (
"fmt"
"github.com/DrSmithFr/go-console"
"github.com/DrSmithFr/go-console/input/argument"
"github.com/DrSmithFr/go-console/input/option"
)
func main() {
// Declare the command with a struct
cmd := go_console.Script{
Description: "This is a test command",
Arguments: []go_console.Argument{
{
Description: "The last name of the user",
Name: "name",
Value: argument.Required,
},
},
Options: []go_console.Option{
{
Description: "The last name of the user",
Name: "foo",
Shortcut: "f",
Value: option.None,
},
},
}
// Build the command before using it
cmd.Build()
//
// You now have access to a last_name argument in your command:
//
text := fmt.Sprintf("Hi %s", cmd.Input.Argument("name"))
lastName := cmd.Input.Argument("last_name")
if lastName != "" {
text = fmt.Sprintf("%s %s", text, lastName)
}
// Using the Output as an io.Writer
_, err := fmt.Fprintf(cmd.Output, "%s", text)
if err != nil {
panic(err)
}
// Using the Output Methode
cmd.Output.Print("!")
}
The command can now be used in either of the following ways:
go run command-script John
> Hi John!
go run command John Smith
> Hi John Daligault!
It is also possible to let an argument take a list of values (imagine you want to greet all your friends). Only the last argument can be a list:
package main
import (
"fmt"
"github.com/DrSmithFr/go-console/input/argument"
"github.com/DrSmithFr/go-console"
)
func main() {
cmd := go_console.
NewScript().
AddInputArgument(
argument.
New("names", argument.List | argument.Required).
SetDescription("Who do you want to greet?"),
).
Build()
//
// You can access the names argument as an array:
//
names := cmd.Input.ArgumentList("names")
for _, name := range names {
cmd.PrintText(fmt.Sprintf("Hi %s!", name))
}
}
To use this, specify as many names as you want:
go run command-script John Alex Fred
There are three argument variants you can use:
argument.Required
The argument is mandatory. The command doesn't run if the argument isn't provided;
argument.Optional
The argument is optional and therefore can be omitted. This is the default behavior of arguments;
argument.List
The argument can contain any number of values. For that reason, it must be used at the end of the argument list.
You can combine List
with Required
and Optional
like this:
cmd := go_console.
NewScript().
AddInputArgument(
argument.
New("names", argument.List | argument.Required),
).
Build()
Unlike arguments, options are not ordered (meaning you can specify them in any order) and are specified with two
dashes (e.g. --yell
). Options are always optional, and can be setup to accept a value (e.g. --dir=src
) or as a
boolean flag without a value (e.g. --yell
).
For example, add a new option to the command that can be used to specify how many times in a row the message should be printed:
package main
import (
"fmt"
"github.com/DrSmithFr/go-console/input/argument"
"github.com/DrSmithFr/go-console/input/option"
"github.com/DrSmithFr/go-console"
"strconv"
)
func main() {
cmd := go_console.
NewScript().
AddInputArgument(
argument.
New("name", argument.Required).
SetDescription("Who do you want to greet?"),
).
AddInputOption(
option.
New("iterations", option.Required).
SetDescription("How many times should the message be printed?").
SetDefault("1"),
).
Build()
//
// Next, use this in the command to print the message multiple times:
//
iterations, _ := strconv.Atoi(cmd.Input.Option("iterations"))
for i := 0; i < iterations; i++ {
cmd.PrintText(
fmt.Sprintf("Hi %s!", cmd.Input.Argument("name")),
)
}
}
Now, when you run the command, you can optionally specify a --iterations
flag:
# no --iterations provided, the default (1) is used
$ php bin/console app:greet John
Hi John!
$ php bin/console app:greet John --iterations=5
Hi John!
Hi John!
Hi John!
Hi John!
Hi John!
$ php bin/console app:greet John --iterations=5 --yell
$ php bin/console app:greet John --yell --iterations=5
$ php bin/console app:greet --yell --iterations=5 John
You can also declare a one-letter shortcut that you can call with a single dash, like -i
:
cmd := go_console.
NewScript().
AddInputOption(
option.
New("iterations", option.Required).
SetShortcut("i"),
).
Build()
Note that to comply with the docopt standard, long options can specify their values after a white
space or an = sign (e.g. --iterations 5
or --iterations=5
), but short options can only use white spaces or no
separation at all (e.g. -i 5
or -i5
).
While it is possible to separate an option from its value with a white space, using this form leads to an ambiguity should the option appear before the command name. For example,
php bin/console --iterations 5 app:greet Fabien
is ambiguous; Go-console would interpret 5 as the command name. To avoid this situation, always place options after the command name, or avoid using a space to separate the option name from its value.
There are four option variants you can use:
option.List
This option accepts multiple values (e.g.
--dir=/foo --dir=/bar
);
argument.None
Do not accept input for this option (e.g.
--yell
). This is the default behavior of options;
argument.Required
This value is required (e.g.
--iterations=5
or-i5
), the option itself is still optional;
argument.Optional
This option may or may not have a value (e.g.
--yell
or--yell=loud
).
You can combine IS_ARRAY
with REQUIRED
and OPTIONAL
like this:
cmd := go_console.
NewCli().
AddInputOption(
option.New("iterations", option.List | option.Required),
).
Build()