Skip to content

Commit e09dd4f

Browse files
committed
version: Add a version command
And adjust 'runc --version' to print exactly the same content. The: $ COMMAND --version interface is a popular one for this information and makes a lot of sense for single-action commands. For example, printf(1) [1] is only ever going to do one meaningful thing, so --version, --help, and other command-like actions work well as options. Umbrella commands with multiple sub-commands, on the other hand, have a more consistent interface if '... and exit' actions get their own sub-commands. That allows you to declare an interface like: $ COMMAND [global-options] SUB-COMMAND [sub-command-specific-options] [sub-command-specific-arguments] without having to say "except if you use a sub-command-like global option, in which case SUB-COMMAND is not allowed". With this commit, we add support for 'version' while keeping --version, because while 'version' makes more sense for umbrella commands, a user may not know if runc is an umbrella command when they ask for the version. Existing umbrella commands are not particularly consistent: * git(1) supports both --version and 'version', --help and 'help'. * btrfs(8) supports both --version and 'version', --help and 'help'. * ip(1) supports -V / -Version and 'help'. * npm supports 'version' and 'help'. * pip supports '--version', --help and 'help'. Setting .Version to the empty string takes advantage of the {{if .Version}} conditional [2] to avoid --help showing: VERSION: 0.0.0 because we are no longer setting .Version. I floated a few options [4], and Mike Brown (the only one with a preference) was in favor of dropping the VERSION section [5] (which turned out to not need a AppHelpTemplate adjustment ;). The help tests ensure that attempting to remove "VERSION" from the help output does not change the output (i.e. that the output didn't contain "VERSION" to begin with). That protects us from subsequent urfave/cli changes breaking the empty-string .Version approach. [1]: http://www.man7.org/linux/man-pages/man1/printf.1.html [2]: https://github.com/urfave/cli/blob/v1.18.1/README.md#customization-1 [3]: opencontainers#940 (comment) [4]: opencontainers#940 (comment) [5]: opencontainers#940 (comment) Signed-off-by: W. Trevor King <[email protected]>
1 parent 99c683a commit e09dd4f

File tree

4 files changed

+59
-20
lines changed

4 files changed

+59
-20
lines changed

main.go

Lines changed: 4 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -3,21 +3,11 @@ package main
33
import (
44
"fmt"
55
"os"
6-
"strings"
76

87
"github.com/Sirupsen/logrus"
9-
"github.com/opencontainers/runtime-spec/specs-go"
108
"github.com/urfave/cli"
119
)
1210

13-
// version will be populated by the Makefile, read from
14-
// VERSION file of the source code.
15-
var version = ""
16-
17-
// gitCommit will be the hash that the binary was built from
18-
// and will be populated by the Makefile
19-
var gitCommit = ""
20-
2111
const (
2212
specConfig = "config.json"
2313
usage = `Open Container Initiative runtime
@@ -49,16 +39,11 @@ func main() {
4939
app := cli.NewApp()
5040
app.Name = "runc"
5141
app.Usage = usage
42+
app.Version = ""
5243

53-
var v []string
54-
if version != "" {
55-
v = append(v, version)
56-
}
57-
if gitCommit != "" {
58-
v = append(v, fmt.Sprintf("commit: %s", gitCommit))
44+
cli.VersionPrinter = func(context *cli.Context) {
45+
printVersion(context)
5946
}
60-
v = append(v, fmt.Sprintf("spec: %s", specs.Version))
61-
app.Version = strings.Join(v, "\n")
6247
app.Flags = []cli.Flag{
6348
cli.BoolFlag{
6449
Name: "debug",
@@ -107,6 +92,7 @@ func main() {
10792
startCommand,
10893
stateCommand,
10994
updateCommand,
95+
versionCommand,
11096
}
11197
app.Before = func(context *cli.Context) error {
11298
if context.GlobalBool("debug") {

tests/integration/help.bats

100644100755
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,13 @@ load helpers
77
[ "$status" -eq 0 ]
88
[[ ${lines[0]} =~ NAME:+ ]]
99
[[ ${lines[1]} =~ runc\ '-'\ Open\ Container\ Initiative\ runtime+ ]]
10+
[ "${output}" = "${output/VERSION/}" ]
1011

1112
runc --help
1213
[ "$status" -eq 0 ]
1314
[[ ${lines[0]} =~ NAME:+ ]]
1415
[[ ${lines[1]} =~ runc\ '-'\ Open\ Container\ Initiative\ runtime+ ]]
16+
[ "${output}" = "${output/VERSION/}" ]
1517
}
1618

1719
@test "runc command -h" {

tests/integration/version.bats

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,18 @@
22

33
load helpers
44

5-
@test "runc version" {
5+
@test "runc --version" {
66
runc -v
77
[ "$status" -eq 0 ]
8-
[[ ${lines[0]} =~ runc\ version\ [0-9]+\.[0-9]+\.[0-9]+ ]]
8+
[[ ${lines[0]} =~ runC\ [0-9]+\.[0-9]+\.[0-9]+ ]]
9+
[[ ${lines[1]} =~ commit:+ ]]
10+
[[ ${lines[2]} =~ spec:\ [0-9]+\.[0-9]+\.[0-9]+ ]]
11+
}
12+
13+
@test "runc version" {
14+
runc version
15+
[ "$status" -eq 0 ]
16+
[[ ${lines[0]} =~ runC\ [0-9]+\.[0-9]+\.[0-9]+ ]]
917
[[ ${lines[1]} =~ commit:+ ]]
1018
[[ ${lines[2]} =~ spec:\ [0-9]+\.[0-9]+\.[0-9]+ ]]
1119
}

version.go

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
package main
2+
3+
import (
4+
"fmt"
5+
"os"
6+
7+
"github.com/opencontainers/runtime-spec/specs-go"
8+
"github.com/urfave/cli"
9+
)
10+
11+
// version will be populated by the Makefile, read from
12+
// VERSION file of the source code.
13+
var version = ""
14+
15+
// gitCommit will be the hash that the binary was built from
16+
// and will be populated by the Makefile
17+
var gitCommit = ""
18+
19+
var versionCommand = cli.Command{
20+
Name: "version",
21+
Usage: "output the runtime version",
22+
Description: `The version command outputs the runtime version.`,
23+
Action: printVersion,
24+
}
25+
26+
func printVersion(context *cli.Context) (err error) {
27+
if version == "" {
28+
_, err = os.Stdout.WriteString("runC unknown\n")
29+
} else {
30+
_, err = os.Stdout.WriteString(fmt.Sprintf("runC %s\n", version))
31+
}
32+
if err != nil {
33+
return err
34+
}
35+
if gitCommit != "" {
36+
_, err = os.Stdout.WriteString(fmt.Sprintf("commit: %s\n", gitCommit))
37+
if err != nil {
38+
return err
39+
}
40+
}
41+
_, err = os.Stdout.WriteString(fmt.Sprintf("spec: %s\n", specs.Version))
42+
return err
43+
}

0 commit comments

Comments
 (0)