11package main
22
33import (
4- "errors"
5- "fmt"
6- "io"
74 "os"
8- "reflect"
9- "regexp"
10- "strings"
11- "time"
12-
13- "github.com/urfave/cli"
145
156 "github.com/smallstep/certificates/ca"
16- "github.com/smallstep/cli-utils/command"
177 "github.com/smallstep/cli-utils/step"
18- "github.com/smallstep/cli-utils/ui"
19- "github.com/smallstep/cli-utils/usage"
20- "go.step.sm/crypto/jose"
21- "go.step.sm/crypto/pemutil"
22-
23- "github.com/smallstep/cli/command/version"
24- "github.com/smallstep/cli/internal/plugin"
25- "github.com/smallstep/cli/utils"
26-
27- // Enabled cas interfaces.
28- _ "github.com/smallstep/certificates/cas/cloudcas"
29- _ "github.com/smallstep/certificates/cas/softcas"
30- _ "github.com/smallstep/certificates/cas/stepcas"
318
32- // Enabled commands
33- _ "github.com/smallstep/cli/command/api"
34- _ "github.com/smallstep/cli/command/base64"
35- _ "github.com/smallstep/cli/command/beta"
36- _ "github.com/smallstep/cli/command/ca"
37- _ "github.com/smallstep/cli/command/certificate"
38- _ "github.com/smallstep/cli/command/completion"
39- _ "github.com/smallstep/cli/command/context"
40- _ "github.com/smallstep/cli/command/crl"
41- _ "github.com/smallstep/cli/command/crypto"
42- _ "github.com/smallstep/cli/command/fileserver"
43- _ "github.com/smallstep/cli/command/oauth"
44- _ "github.com/smallstep/cli/command/path"
45- _ "github.com/smallstep/cli/command/ssh"
9+ "github.com/smallstep/cli/internal/cmd"
4610)
4711
4812// Version is set by an LDFLAG at build time representing the git tag or commit
@@ -53,143 +17,15 @@ var Version = "N/A"
5317// the time of build
5418var BuildTime = "N/A"
5519
20+ // AppName is the name of the binary. Defaults to "step" if not set.
21+ var AppName = ""
22+
5623func init () {
5724 step .Set ("Smallstep CLI" , Version , BuildTime )
5825 ca .UserAgent = step .Version ()
26+ cmd .SetName (AppName )
5927}
6028
6129func main () {
62- // initialize step environment.
63- if err := step .Init (); err != nil {
64- fmt .Fprintln (os .Stderr , err .Error ())
65- os .Exit (1 )
66- }
67-
68- defer panicHandler ()
69-
70- // create new instance of app
71- app := newApp (os .Stdout , os .Stderr )
72-
73- if err := app .Run (os .Args ); err != nil {
74- var messenger interface {
75- Message () string
76- }
77- if errors .As (err , & messenger ) {
78- if os .Getenv ("STEPDEBUG" ) == "1" {
79- fmt .Fprintf (os .Stderr , "%+v\n \n %s" , err , messenger .Message ())
80- } else {
81- fmt .Fprintln (os .Stderr , messenger .Message ())
82- fmt .Fprintln (os .Stderr , "Re-run with STEPDEBUG=1 for more info." )
83- }
84- } else {
85- if os .Getenv ("STEPDEBUG" ) == "1" {
86- fmt .Fprintf (os .Stderr , "%+v\n " , err )
87- } else {
88- fmt .Fprintln (os .Stderr , err )
89- }
90- }
91- //nolint:gocritic // ignore exitAfterDefer error because the defer is required for recovery.
92- os .Exit (1 )
93- }
94- }
95-
96- func newApp (stdout , stderr io.Writer ) * cli.App {
97- // Define default file writers and prompters for go.step.sm/crypto
98- pemutil .WriteFile = utils .WriteFile
99- pemutil .PromptPassword = func (msg string ) ([]byte , error ) {
100- return ui .PromptPassword (msg )
101- }
102- jose .PromptPassword = func (msg string ) ([]byte , error ) {
103- return ui .PromptPassword (msg )
104- }
105-
106- // Override global framework components
107- cli .VersionPrinter = func (c * cli.Context ) {
108- version .Command (c )
109- }
110- cli .AppHelpTemplate = usage .AppHelpTemplate
111- cli .SubcommandHelpTemplate = usage .SubcommandHelpTemplate
112- cli .CommandHelpTemplate = usage .CommandHelpTemplate
113- cli .HelpPrinter = usage .HelpPrinter
114- cli .FlagNamePrefixer = usage .FlagNamePrefixer
115- cli .FlagStringer = stringifyFlag
116-
117- // Configure cli app
118- app := cli .NewApp ()
119- app .Name = "step"
120- app .HelpName = "step"
121- app .Usage = "plumbing for distributed systems"
122- app .Version = step .Version ()
123- app .Commands = command .Retrieve ()
124- app .Flags = append (app .Flags , cli .HelpFlag )
125- app .EnableBashCompletion = true
126- app .Copyright = fmt .Sprintf ("(c) 2018-%d Smallstep Labs, Inc." , time .Now ().Year ())
127-
128- // Flag of custom configuration flag
129- app .Flags = append (app .Flags , cli.StringFlag {
130- Name : "config" ,
131- Usage : "path to the config file to use for CLI flags" ,
132- })
133-
134- // Action runs on `step` or `step <command>` if the command is not enabled.
135- app .Action = func (ctx * cli.Context ) error {
136- args := ctx .Args ()
137- if name := args .First (); name != "" {
138- if file , err := plugin .LookPath (name ); err == nil {
139- return plugin .Run (ctx , file )
140- }
141- if u := plugin .GetURL (name ); u != "" {
142- //nolint:staticcheck // this is a top level error - capitalization is ok
143- return fmt .Errorf ("The plugin %q was not found on this system.\n Download it from %s" , name , u )
144- }
145- return cli .ShowCommandHelp (ctx , name )
146- }
147- return cli .ShowAppHelp (ctx )
148- }
149-
150- // All non-successful output should be written to stderr
151- app .Writer = stdout
152- app .ErrWriter = stderr
153-
154- return app
155- }
156-
157- func panicHandler () {
158- if r := recover (); r != nil {
159- if os .Getenv ("STEPDEBUG" ) == "1" {
160- fmt .Fprintf (os .Stderr , "%s\n " , step .Version ())
161- fmt .Fprintf (os .Stderr , "Release Date: %s\n \n " , step .ReleaseDate ())
162- panic (r )
163- }
164-
165- fmt .Fprintln (os .Stderr , "Something unexpected happened." )
166- fmt .Fprintln (os .Stderr , "If you want to help us debug the problem, please run:" )
167- fmt .Fprintf (os .Stderr , "STEPDEBUG=1 %s\n " , strings .Join (os .Args , " " ))
168- fmt .
Fprintln (
os .
Stderr ,
"and send the output to [email protected] " )
169- os .Exit (2 )
170- }
171- }
172-
173- func flagValue (f cli.Flag ) reflect.Value {
174- fv := reflect .ValueOf (f )
175- for fv .Kind () == reflect .Ptr {
176- fv = reflect .Indirect (fv )
177- }
178- return fv
179- }
180-
181- var placeholderString = regexp .MustCompile (`<.*?>` )
182-
183- func stringifyFlag (f cli.Flag ) string {
184- fv := flagValue (f )
185- usg := fv .FieldByName ("Usage" ).String ()
186- placeholder := placeholderString .FindString (usg )
187- if placeholder == "" {
188- switch f .(type ) {
189- case cli.BoolFlag , cli.BoolTFlag :
190- default :
191- placeholder = "<value>"
192- }
193- }
194- return cli .FlagNamePrefixer (fv .FieldByName ("Name" ).String (), placeholder ) + "\t " + usg
30+ os .Exit (cmd .Run ())
19531}
0 commit comments