tinka alpha

Arguments

This guide covers a Command's arguments. You will learn how to:

Overview

Arguments are the values that follow a Command's name without a flag, such as the name in act make:controller posts. A Command declares them in order, so help shows them, and Tinka checks them before Run starts: a missing required argument, or one more than the Command takes, is a usage error. A Command that declares no arguments takes none.

Declare arguments

List the arguments in Args, in order. Run reads their values from c.Args:

go
var importCommand = &cli.Command{
	Name:    "posts:import",
	Summary: "Import posts from a file",
	Args:    []cli.Arg{{Name: "file", Usage: "The file to import", Required: true}},
	Run: func(ctx context.Context, c *cli.Call) (cli.Result, error) {
		file := c.Args[0]
		…
	},
}
Output
$ act posts:import
Error: missing argument <file>.
  Fix: Run `act posts:import --help` to see usage
Namestring

Names the argument in help and errors, such as <file>.

Usagestring

Says what the argument is, for help.

Requiredbool

Makes the argument's absence a usage error.

Variadicbool

Takes every remaining value. Only the last argument can be variadic.

Promptstring

The question to ask for the argument when it's missing and a person can answer. See Ask for missing arguments.

Make arguments optional

An argument without Required may be left out. Check len(c.Args) before reading it, or use cmp.Or for a default:

go
		name := "world"
		if len(c.Args) > 0 {
			name = c.Args[0]
		}

Help shows an optional argument in brackets, such as act greet [flags] [<name>].

Accept many values

Make the last argument Variadic to take every remaining value. Combined with Required, it needs at least one:

go
var tag = &cli.Command{
	Name: "posts:tag",
	Args: []cli.Arg{{Name: "tag", Required: true}, {Name: "posts", Variadic: true}},
	Run: func(ctx context.Context, c *cli.Call) (cli.Result, error) {
		tag, posts := c.Args[0], c.Args[1:]
		…
	},
}
Terminal
act posts:tag go 12 17 31

Parse arguments as types

c.Arg[T] returns an argument as a T: a string, an int, int64, float64, bool or time.Duration, or any type that parses itself from text by implementing encoding.TextUnmarshaler, such as netip.Addr or a type of your own. A value that doesn't parse is a usage error that names the argument, and an argument that wasn't given is the zero value:

go
var ping = &cli.Command{
	Name: "ping",
	Args: []cli.Arg{{Name: "addr", Required: true}, {Name: "count"}},
	Run: func(ctx context.Context, c *cli.Call) (cli.Result, error) {
		addr, err := c.Arg[netip.Addr](0)
		if err != nil {
			return nil, err
		}
		count, err := c.Arg[int](1)
		if err != nil {
			return nil, err
		}
		count = cmp.Or(count, 4)
		…
	},
}
Output
$ act ping 1.2.3
Error: invalid <addr> "1.2.3": ParseAddr("1.2.3"): IPv4 address too short.
  Fix: Run `act ping --help` to see usage

Ask for missing arguments

Give a required argument a Prompt, and a person who leaves it out is asked for it instead of getting an error:

go
	Args: []cli.Arg{{Name: "file", Required: true, Prompt: "Which file should be imported?"}},
Output
$ act posts:import
? Which file should be imported?

The question is asked only when a person can answer: in a terminal, outside Agent mode, and without --no-interaction. Otherwise the missing argument stays a usage error, so scripts and agents never wait for input.

Pass values that start with a dash

Arguments and flags may come in any order. Everything after -- is an argument, even when it starts with a dash:

Terminal
act posts:import -- -draft-.json

See also: Flags, Prompts, Creating Commands