This repository has been archived by the owner on Sep 19, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
/
command.go
99 lines (82 loc) · 1.44 KB
/
command.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
package command
import (
"bytes"
"errors"
"fmt"
"io"
"os"
"github.com/alecthomas/kong"
)
type context struct {
Stdout io.Writer
Stderr io.Writer
}
func Run() {
new(
os.Stdout,
os.Stderr,
os.Exit,
).Run(os.Args[1:])
}
type Result struct {
ExitCode int
Stdout string
Stderr string
}
func Capture(args ...string) (result Result) {
exitCode := -1
var stdout bytes.Buffer
var stderr bytes.Buffer
exited := errors.New("exited")
defer func() {
if exitCode != -1 {
v := recover()
if v != nil && v != exited {
panic(fmt.Errorf("recovered from unexpected panic: %v", v))
}
}
result = Result{
ExitCode: exitCode,
Stdout: stdout.String(),
Stderr: stderr.String(),
}
}()
new(
&stdout,
&stderr,
func(code int) {
exitCode = code
panic(exited)
},
).Run(args)
return
}
type command struct {
parser *kong.Kong
}
func new(stdout io.Writer, stderr io.Writer, exit func(int)) *command {
parser, err := kong.New(
&rootCommand{},
kong.Name("multidockerfile"),
kong.Description("Split multi-stage Dockerfiles into multiple files."),
kong.UsageOnError(),
kong.Writers(stdout, stderr),
kong.Exit(exit),
)
if err != nil {
panic(err)
}
return &command{
parser: parser,
}
}
func (c *command) Run(args []string) {
ctx, err := c.parser.Parse(args)
c.parser.FatalIfErrorf(err)
err = ctx.Run(&context{
Stdout: ctx.Stdout,
Stderr: ctx.Stderr,
})
ctx.FatalIfErrorf(err)
ctx.Exit(0)
}