Skip to content

Commit 0865185

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. I prefer "runC" to "runc", to match http://runc.io/ and some naming issues [6], but Michael prefers "runc" [7]. [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]: #940 (comment) [4]: #940 (comment) [5]: #940 (comment) [6]: #24 [7]: #940 (comment) Signed-off-by: W. Trevor King <[email protected]>
1 parent 6b574d5 commit 0865185

File tree

4 files changed

+58
-20
lines changed

4 files changed

+58
-20
lines changed

main.go

Lines changed: 4 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -4,21 +4,11 @@ import (
44
"fmt"
55
"io"
66
"os"
7-
"strings"
87

98
"github.com/Sirupsen/logrus"
10-
"github.com/opencontainers/runtime-spec/specs-go"
119
"github.com/urfave/cli"
1210
)
1311

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

54-
var v []string
55-
if version != "" {
56-
v = append(v, version)
57-
}
58-
if gitCommit != "" {
59-
v = append(v, fmt.Sprintf("commit: %s", gitCommit))
45+
cli.VersionPrinter = func(context *cli.Context) {
46+
printVersion(context)
6047
}
61-
v = append(v, fmt.Sprintf("spec: %s", specs.Version))
62-
app.Version = strings.Join(v, "\n")
6348
app.Flags = []cli.Flag{
6449
cli.BoolFlag{
6550
Name: "debug",
@@ -108,6 +93,7 @@ func main() {
10893
startCommand,
10994
stateCommand,
11095
updateCommand,
96+
versionCommand,
11197
}
11298
app.Before = func(context *cli.Context) error {
11399
if context.GlobalBool("debug") {

tests/integration/help.bats

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

0 commit comments

Comments
 (0)