diff --git a/internal/ansi/ansi.go b/internal/ansi/ansi.go index 091ba1ac3..dc80bc6c8 100644 --- a/internal/ansi/ansi.go +++ b/internal/ansi/ansi.go @@ -2,11 +2,10 @@ package ansi import ( "fmt" - "io" "os" + "github.com/auth0/auth0-cli/internal/iostream" "github.com/logrusorgru/aurora" - "github.com/mattn/go-isatty" "github.com/tidwall/pretty" ) @@ -29,22 +28,23 @@ var DisableColors = false // `CLICOLOR_FORCE`. Cf. https://bixense.com/clicolors/ var EnvironmentOverrideColors = true +var color = Color() + // Bold returns bolded text if the writer supports colors func Bold(text string) string { - color := Color(os.Stdout) return color.Sprintf(color.Bold(text)) } // Color returns an aurora.Aurora instance with colors enabled or disabled // depending on whether the writer supports colors. -func Color(w io.Writer) aurora.Aurora { - return aurora.NewAurora(shouldUseColors(w)) +func Color() aurora.Aurora { + return aurora.NewAurora(shouldUseColors()) } // ColorizeJSON returns a colorized version of the input JSON, if the writer // supports colors. -func ColorizeJSON(json string, darkStyle bool, w io.Writer) string { - if !shouldUseColors(w) { +func ColorizeJSON(json string, darkStyle bool) string { + if !shouldUseColors() { return json } @@ -58,8 +58,6 @@ func ColorizeJSON(json string, darkStyle bool, w io.Writer) string { // ColorizeStatus returns a colorized number for HTTP status code func ColorizeStatus(status int) aurora.Value { - color := Color(os.Stdout) - switch { case status >= 500: return color.Red(status).Bold() @@ -72,68 +70,58 @@ func ColorizeStatus(status int) aurora.Value { // Faint returns slightly offset color text if the writer supports it func Faint(text string) string { - color := Color(os.Stdout) return color.Sprintf(color.Faint(text)) } // Italic returns italicized text if the writer supports it. func Italic(text string) string { - color := Color(os.Stdout) return color.Sprintf(color.Italic(text)) } // Red returns text colored red func Red(text string) string { - color := Color(os.Stdout) return color.Sprintf(color.Red(text)) } // BrightRed returns text colored bright red func BrightRed(text string) string { - color := Color(os.Stdout) return color.Sprintf(color.BrightRed(text)) } // Green returns text colored green func Green(text string) string { - color := Color(os.Stdout) return color.Sprintf(color.Green(text)) } // Yellow returns text colored yellow func Yellow(text string) string { - color := Color(os.Stdout) return color.Sprintf(color.Yellow(text)) } // BrightYellow returns text colored bright yellow func BrightYellow(text string) string { - color := Color(os.Stdout) return color.Sprintf(color.BrightYellow(text)) } // Blue returns text colored blue func Blue(text string) string { - color := Color(os.Stdout) return color.Sprintf(color.Blue(text)) } // Magenta returns text colored magenta func Magenta(text string) string { - color := Color(os.Stdout) return color.Sprintf(color.Magenta(text)) } // Cyan returns text colored cyan func Cyan(text string) string { - color := Color(os.Stdout) return color.Sprintf(color.BrightCyan(text)) } // Linkify returns an ANSI escape sequence with an hyperlink, if the writer // supports colors. -func Linkify(text, url string, w io.Writer) string { - if !shouldUseColors(w) { +func Linkify(text, url string) string { + if !shouldUseColors() { return text } @@ -144,16 +132,11 @@ func Linkify(text, url string, w io.Writer) string { // StrikeThrough returns struck though text if the writer supports colors func StrikeThrough(text string) string { - color := Color(os.Stdout) return color.Sprintf(color.StrikeThrough(text)) } -func IsTerminal() bool { - return isatty.IsTerminal(os.Stdout.Fd()) -} - -func shouldUseColors(w io.Writer) bool { - useColors := ForceColors || IsTerminal() +func shouldUseColors() bool { + useColors := ForceColors || iostream.IsOutputTerminal() if EnvironmentOverrideColors { force, ok := os.LookupEnv("CLICOLOR_FORCE") diff --git a/internal/ansi/spinner.go b/internal/ansi/spinner.go index 52a70703b..db851fd05 100644 --- a/internal/ansi/spinner.go +++ b/internal/ansi/spinner.go @@ -1,10 +1,10 @@ package ansi import ( - "os" "time" "github.com/auth0/auth0-cli/internal/auth0" + "github.com/auth0/auth0-cli/internal/iostream" "github.com/briandowns/spinner" ) @@ -34,11 +34,11 @@ func loading(initialMsg, doneMsg, failMsg string, fn func() error) error { go func() { defer close(done) - s := spinner.New(spinner.CharSets[11], 100*time.Millisecond, spinner.WithWriter(os.Stderr)) + s := spinner.New(spinner.CharSets[11], 100*time.Millisecond, spinner.WithWriter(iostream.Messages)) s.Prefix = initialMsg s.FinalMSG = doneMsg s.HideCursor = true - s.Writer = os.Stderr + s.Writer = iostream.Messages if err := s.Color(spinnerColor); err != nil { panic(auth0.Error(err, "failed setting spinner color")) diff --git a/internal/cli/cli.go b/internal/cli/cli.go index 222f1fd8f..a8627cb07 100644 --- a/internal/cli/cli.go +++ b/internal/cli/cli.go @@ -16,11 +16,11 @@ import ( "time" "github.com/auth0/auth0-cli/internal/analytics" - "github.com/auth0/auth0-cli/internal/ansi" "github.com/auth0/auth0-cli/internal/auth" "github.com/auth0/auth0-cli/internal/auth0" "github.com/auth0/auth0-cli/internal/buildinfo" "github.com/auth0/auth0-cli/internal/display" + "github.com/auth0/auth0-cli/internal/iostream" "github.com/google/uuid" "github.com/lestrrat-go/jwx/jwt" "github.com/spf13/cobra" @@ -516,11 +516,11 @@ func canPrompt(cmd *cobra.Command) bool { return false } - return ansi.IsTerminal() && !noInput + return iostream.IsInputTerminal() && iostream.IsOutputTerminal() && !noInput } -func shouldPrompt(cmd *cobra.Command, flag string) bool { - return canPrompt(cmd) && !cmd.Flags().Changed(flag) +func shouldPrompt(cmd *cobra.Command, flag *Flag) bool { + return canPrompt(cmd) && !flag.IsSet(cmd) } func shouldPromptWhenFlagless(cmd *cobra.Command, flag string) bool { @@ -536,7 +536,7 @@ func shouldPromptWhenFlagless(cmd *cobra.Command, flag string) bool { } func prepareInteractivity(cmd *cobra.Command) { - if canPrompt(cmd) { + if canPrompt(cmd) || !iostream.IsInputTerminal() { cmd.Flags().VisitAll(func(flag *pflag.Flag) { _ = cmd.Flags().SetAnnotation(flag.Name, cobra.BashCompOneRequiredFlag, []string{"false"}) }) diff --git a/internal/cli/completion.go b/internal/cli/completion.go index 75b3a9f3a..9259dafe2 100644 --- a/internal/cli/completion.go +++ b/internal/cli/completion.go @@ -1,8 +1,7 @@ package cli import ( - "os" - + "github.com/auth0/auth0-cli/internal/iostream" "github.com/spf13/cobra" ) @@ -57,22 +56,22 @@ PS> auth0 completion powershell > auth0.ps1 Run: func(cmd *cobra.Command, args []string) { switch args[0] { case "bash": - err := cmd.Root().GenBashCompletion(os.Stdout) + err := cmd.Root().GenBashCompletion(iostream.Output) if err != nil { cli.renderer.Errorf("An unexpected error occurred while setting up completion: %v", err.Error()) } case "zsh": - err := cmd.Root().GenZshCompletion(os.Stdout) + err := cmd.Root().GenZshCompletion(iostream.Output) if err != nil { cli.renderer.Errorf("An unexpected error occurred while setting up completion: %v", err.Error()) } case "fish": - err := cmd.Root().GenFishCompletion(os.Stdout, true) + err := cmd.Root().GenFishCompletion(iostream.Output, true) if err != nil { cli.renderer.Errorf("An unexpected error occurred while setting up completion: %v", err.Error()) } case "powershell": - err := cmd.Root().GenPowerShellCompletion(os.Stdout) + err := cmd.Root().GenPowerShellCompletion(iostream.Output) if err != nil { cli.renderer.Errorf("An unexpected error occurred while setting up completion: %v", err.Error()) } diff --git a/internal/cli/flags.go b/internal/cli/flags.go index 7cd86a668..3836e18f7 100644 --- a/internal/cli/flags.go +++ b/internal/cli/flags.go @@ -261,7 +261,7 @@ func shouldAsk(cmd *cobra.Command, f *Flag, isUpdate bool) bool { return shouldPromptWhenFlagless(cmd, f.LongForm) } - return shouldPrompt(cmd, f.LongForm) + return shouldPrompt(cmd, f) } func markFlagRequired(cmd *cobra.Command, f *Flag, isUpdate bool) error { diff --git a/internal/cli/rules.go b/internal/cli/rules.go index ec7c47a42..5a38c16b2 100644 --- a/internal/cli/rules.go +++ b/internal/cli/rules.go @@ -1,11 +1,13 @@ package cli import ( + "encoding/json" "errors" "fmt" "github.com/auth0/auth0-cli/internal/ansi" "github.com/auth0/auth0-cli/internal/auth0" + "github.com/auth0/auth0-cli/internal/iostream" "github.com/auth0/auth0-cli/internal/prompt" "github.com/spf13/cobra" "gopkg.in/auth0.v5/management" @@ -128,35 +130,42 @@ auth0 rules create --name "My Rule" auth0 rules create -n "My Rule" --template "Empty rule" auth0 rules create -n "My Rule" -t "Empty rule" --enabled=false`, RunE: func(cmd *cobra.Command, args []string) error { - if err := ruleName.Ask(cmd, &inputs.Name, nil); err != nil { - return err - } + rule := &management.Rule{} + pipedInput := iostream.PipedInput() - if err := ruleTemplate.Select(cmd, &inputs.Template, ruleTemplateOptions.labels(), nil); err != nil { - return err - } + if len(pipedInput) > 0 { + err := json.Unmarshal(pipedInput, rule) + if err != nil { + return fmt.Errorf("Invalid JSON input: %w", err) + } + } else { + if err := ruleName.Ask(cmd, &inputs.Name, nil); err != nil { + return err + } - // TODO(cyx): we can re-think this once we have - // `--stdin` based commands. For now we don't have - // those yet, so keeping this simple. - err := ruleScript.OpenEditor( - cmd, - &inputs.Script, - ruleTemplateOptions.getValue(inputs.Template), - inputs.Name+".*.js", - cli.ruleEditorHint, - ) - if err != nil { - return fmt.Errorf("Failed to capture input from the editor: %w", err) - } + if err := ruleTemplate.Select(cmd, &inputs.Template, ruleTemplateOptions.labels(), nil); err != nil { + return err + } + + err := ruleScript.OpenEditor( + cmd, + &inputs.Script, + ruleTemplateOptions.getValue(inputs.Template), + inputs.Name+".*.js", + cli.ruleEditorHint, + ) + if err != nil { + return fmt.Errorf("Failed to capture input from the editor: %w", err) + } - rule := &management.Rule{ - Name: &inputs.Name, - Script: auth0.String(inputs.Script), - Enabled: &inputs.Enabled, + rule = &management.Rule{ + Name: &inputs.Name, + Script: auth0.String(inputs.Script), + Enabled: &inputs.Enabled, + } } - err = ansi.Waiting(func() error { + err := ansi.Waiting(func() error { return cli.api.Rule.Create(rule) }) @@ -278,70 +287,79 @@ func updateRuleCmd(cli *cli) *cobra.Command { auth0 rules update --name "My Updated Rule" auth0 rules update -n "My Updated Rule" --enabled=false`, RunE: func(cmd *cobra.Command, args []string) error { - if len(args) > 0 { - inputs.ID = args[0] - } else { - err := ruleID.Pick(cmd, &inputs.ID, cli.rulePickerOptions) + rule := &management.Rule{} + pipedInput := iostream.PipedInput() + + if len(pipedInput) > 0 { + err := json.Unmarshal(pipedInput, rule) if err != nil { - return err + return fmt.Errorf("Invalid JSON input: %w", err) } - } - var rule *management.Rule - err := ansi.Waiting(func() error { - var err error - rule, err = cli.api.Rule.Read(inputs.ID) - return err - }) - if err != nil { - return fmt.Errorf("Failed to fetch rule with ID: %s %v", inputs.ID, err) - } + inputs.ID = rule.GetID() + rule.ID = nil + } else { + if len(args) > 0 { + inputs.ID = args[0] + } else { + err := ruleID.Pick(cmd, &inputs.ID, cli.rulePickerOptions) + if err != nil { + return err + } + } - if err := ruleName.AskU(cmd, &inputs.Name, rule.Name); err != nil { - return err - } + err := ansi.Waiting(func() error { + var err error + rule, err = cli.api.Rule.Read(inputs.ID) + return err + }) + if err != nil { + return fmt.Errorf("Failed to fetch rule with ID: %s %v", inputs.ID, err) + } - if !ruleEnabled.IsSet(cmd) { - inputs.Enabled = auth0.BoolValue(rule.Enabled) - } + if err := ruleName.AskU(cmd, &inputs.Name, rule.Name); err != nil { + return err + } - if err := ruleEnabled.AskBoolU(cmd, &inputs.Enabled, rule.Enabled); err != nil { - return err - } + if !ruleEnabled.IsSet(cmd) { + inputs.Enabled = auth0.BoolValue(rule.Enabled) + } - // TODO(cyx): we can re-think this once we have - // `--stdin` based commands. For now we don't have - // those yet, so keeping this simple. - err = ruleScript.OpenEditorU( - cmd, - &inputs.Script, - rule.GetScript(), - rule.GetName()+".*.js", - cli.ruleEditorHint, - ) - if err != nil { - return fmt.Errorf("Failed to capture input from the editor: %w", err) - } + if err := ruleEnabled.AskBoolU(cmd, &inputs.Enabled, rule.Enabled); err != nil { + return err + } - // Since name is optional, no need to specify what they chose. - if inputs.Name == "" { - inputs.Name = rule.GetName() - } + err = ruleScript.OpenEditorU( + cmd, + &inputs.Script, + rule.GetScript(), + rule.GetName()+".*.js", + cli.ruleEditorHint, + ) + if err != nil { + return fmt.Errorf("Failed to capture input from the editor: %w", err) + } - if inputs.Script == "" { - inputs.Script = rule.GetScript() - } + // Since name is optional, no need to specify what they chose. + if inputs.Name == "" { + inputs.Name = rule.GetName() + } - // Prepare rule payload for update. This will also be - // re-hydrated by the SDK, which we'll use below during - // display. - rule = &management.Rule{ - Name: &inputs.Name, - Script: &inputs.Script, - Enabled: &inputs.Enabled, + if inputs.Script == "" { + inputs.Script = rule.GetScript() + } + + // Prepare rule payload for update. This will also be + // re-hydrated by the SDK, which we'll use below during + // display. + rule = &management.Rule{ + Name: &inputs.Name, + Script: &inputs.Script, + Enabled: &inputs.Enabled, + } } - err = ansi.Waiting(func() error { + err := ansi.Waiting(func() error { return cli.api.Rule.Update(inputs.ID, rule) }) diff --git a/internal/cli/test.go b/internal/cli/test.go index e6dc68618..dc2c3e891 100644 --- a/internal/cli/test.go +++ b/internal/cli/test.go @@ -7,6 +7,7 @@ import ( "github.com/auth0/auth0-cli/internal/ansi" "github.com/auth0/auth0-cli/internal/auth/authutil" "github.com/auth0/auth0-cli/internal/auth0" + "github.com/auth0/auth0-cli/internal/iostream" "github.com/spf13/cobra" "gopkg.in/auth0.v5/management" ) @@ -52,7 +53,7 @@ var ( Help: "The list of scopes you want to use.", } - testDomainArg = Argument{ + testDomainArg = Flag{ Name: "Custom Domain", Help: "One of your custom domains.", } @@ -140,11 +141,9 @@ auth0 test login --connection `, return fmt.Errorf("Unable to find client %s; if you specified a client, please verify it exists, otherwise re-run the command", inputs.ClientID) } - if inputs.CustomDomain == "" { - err = testDomainArg.Pick(cmd, &inputs.CustomDomain, cli.customDomainPickerOptions) - if err != nil && err != errNoCustomDomains { - return err - } + err = testDomainArg.Pick(cmd, &inputs.CustomDomain, cli.customDomainPickerOptions) + if err != nil && err != errNoCustomDomains { + return err } if proceed := runLoginFlowPreflightChecks(cli, client); !proceed { @@ -255,7 +254,11 @@ auth0 test token --client-id --audience --scopes if err != nil { return fmt.Errorf("An unexpected error occurred while logging in to machine-to-machine client %s: %w", inputs.ClientID, err) } - cli.renderer.GetToken(client, tokenResponse) + if iostream.IsOutputTerminal() { + cli.renderer.GetToken(client, tokenResponse) + } else { + cli.renderer.Output(tokenResponse.AccessToken) + } return nil } @@ -276,7 +279,11 @@ auth0 test token --client-id --audience --scopes if err != nil { return fmt.Errorf("An unexpected error occurred when logging in to client %s: %w", inputs.ClientID, err) } - cli.renderer.GetToken(client, tokenResponse) + if iostream.IsOutputTerminal() { + cli.renderer.GetToken(client, tokenResponse) + } else { + cli.renderer.Output(tokenResponse.AccessToken) + } return nil }, } diff --git a/internal/display/apis.go b/internal/display/apis.go index a756d56a4..2a28824a7 100644 --- a/internal/display/apis.go +++ b/internal/display/apis.go @@ -2,12 +2,12 @@ package display import ( "fmt" - "os" "strconv" "strings" "github.com/auth0/auth0-cli/internal/ansi" "github.com/auth0/auth0-cli/internal/auth0" + "github.com/auth0/auth0-cli/internal/iostream" "golang.org/x/term" "gopkg.in/auth0.v5/management" ) @@ -186,7 +186,7 @@ func getScopes(scopes []*management.ResourceServerScope) (string, bool) { ellipsis := "..." separator := " " padding := 22 // the longest apiView key plus two spaces before and after in the label column - terminalWidth, _, err := term.GetSize(int(os.Stdin.Fd())) + terminalWidth, _, err := term.GetSize(int(iostream.Input.Fd())) if err != nil { terminalWidth = 80 } diff --git a/internal/display/display.go b/internal/display/display.go index a8cc52513..1db3d412d 100644 --- a/internal/display/display.go +++ b/internal/display/display.go @@ -4,12 +4,11 @@ import ( "encoding/json" "fmt" "io" - "os" "strings" "time" "github.com/auth0/auth0-cli/internal/ansi" - "github.com/auth0/auth0-cli/internal/auth0" + "github.com/auth0/auth0-cli/internal/iostream" "github.com/charmbracelet/glamour" "github.com/olekukonko/tablewriter" ) @@ -41,11 +40,15 @@ type View interface { func NewRenderer() *Renderer { return &Renderer{ - MessageWriter: os.Stderr, - ResultWriter: os.Stdout, + MessageWriter: iostream.Messages, + ResultWriter: iostream.Output, } } +func (r *Renderer) Output(message string) { + fmt.Fprint(r.ResultWriter, message) +} + func (r *Renderer) Newline() { fmt.Fprintln(r.MessageWriter) } @@ -80,7 +83,7 @@ func (r *Renderer) JSONResult(data interface{}) { r.Errorf("couldn't marshal results as JSON: %v", err) return } - fmt.Fprint(r.ResultWriter, string(b)) + r.Output(string(b)) } func (r *Renderer) Results(data []View) { @@ -273,16 +276,3 @@ func boolean(v bool) string { } return ansi.Red("✗") } - -func isOutputPiped() bool { - fi, err := os.Stdout.Stat() - if err != nil { - panic(auth0.Error(err, "failed to get the FileInfo struct of stdout")) - } - - if (fi.Mode() & os.ModeCharDevice) == 0 { - return true - } - - return false -} diff --git a/internal/display/get_token.go b/internal/display/get_token.go index faf6ed204..35fd67a24 100644 --- a/internal/display/get_token.go +++ b/internal/display/get_token.go @@ -11,12 +11,6 @@ import ( ) func (r *Renderer) GetToken(c *management.Client, t *authutil.TokenResponse) { - // pass the access token to the pipe and exit - if isOutputPiped() { - fmt.Fprint(r.ResultWriter, t.AccessToken) - return - } - fmt.Fprint(r.ResultWriter, "\n") r.Heading(fmt.Sprintf("token for %s", auth0.StringValue(c.Name))) diff --git a/internal/display/organizations.go b/internal/display/organizations.go index 9af37648a..cffbfd689 100644 --- a/internal/display/organizations.go +++ b/internal/display/organizations.go @@ -104,7 +104,7 @@ func makeOrganizationView(organization *management.Organization, w io.Writer) *o LogoURL: organization.GetBranding().GetLogoUrl(), AccentColor: accentColor, BackgroundColor: backgroundColor, - Metadata: ansi.ColorizeJSON(metadata, false, w), + Metadata: ansi.ColorizeJSON(metadata, false), raw: organization, } } diff --git a/internal/display/try_login.go b/internal/display/try_login.go index ae7668894..599b579b1 100644 --- a/internal/display/try_login.go +++ b/internal/display/try_login.go @@ -3,7 +3,6 @@ package display import ( "encoding/json" "fmt" - "os" "reflect" "github.com/auth0/auth0-cli/internal/ansi" @@ -39,6 +38,6 @@ func (r *Renderer) TryLogin(u *authutil.UserInfo, t *authutil.TokenResponse) { case OutputFormatJSON: fmt.Fprint(r.ResultWriter, jsonStr) default: - fmt.Fprintln(r.ResultWriter, ansi.ColorizeJSON(jsonStr, false, os.Stdout)) + fmt.Fprintln(r.ResultWriter, ansi.ColorizeJSON(jsonStr, false)) } } diff --git a/internal/iostream/iostream.go b/internal/iostream/iostream.go new file mode 100644 index 000000000..101dfa01a --- /dev/null +++ b/internal/iostream/iostream.go @@ -0,0 +1,45 @@ +package iostream + +import ( + "bufio" + "io" + "os" + + "github.com/auth0/auth0-cli/internal/auth0" + "github.com/mattn/go-isatty" +) + +var ( + Input = os.Stdin + Output = os.Stdout + Messages = os.Stderr +) + +func IsInputTerminal() bool { + return isatty.IsTerminal(Input.Fd()) +} + +func IsOutputTerminal() bool { + return isatty.IsTerminal(Output.Fd()) +} + +func PipedInput() []byte { + if !IsInputTerminal() { + reader := bufio.NewReader(Input) + var pipedInput []byte + + for { + input, err := reader.ReadBytes('\n') + if err == io.EOF { + break + } else if err != nil { + panic(auth0.Error(err, "unable to read from pipe")) + } + pipedInput = append(pipedInput, input...) + } + + return pipedInput + } + + return []byte{} +} diff --git a/internal/prompt/editor.go b/internal/prompt/editor.go index 438fe1a04..3673cc05e 100644 --- a/internal/prompt/editor.go +++ b/internal/prompt/editor.go @@ -7,6 +7,7 @@ import ( "os/exec" "runtime" + "github.com/auth0/auth0-cli/internal/iostream" "github.com/kballard/go-shellquote" ) @@ -57,9 +58,9 @@ func (p *editorPrompt) openFile(filename string, infoFn func()) error { } cmd := exec.Command(editorExe, args[1:]...) - cmd.Stdin = os.Stdin - cmd.Stdout = os.Stdout - cmd.Stderr = os.Stderr + cmd.Stdin = iostream.Input + cmd.Stdout = iostream.Output + cmd.Stderr = iostream.Messages if !isCLIEditor && infoFn != nil { infoFn() diff --git a/internal/prompt/prompt.go b/internal/prompt/prompt.go index 37ddfeb80..8f0255689 100644 --- a/internal/prompt/prompt.go +++ b/internal/prompt/prompt.go @@ -1,12 +1,11 @@ package prompt import ( - "os" - "github.com/AlecAivazis/survey/v2" + "github.com/auth0/auth0-cli/internal/iostream" ) -var stdErrWriter = survey.WithStdio(os.Stdin, os.Stderr, os.Stderr) +var stdErrWriter = survey.WithStdio(iostream.Input, iostream.Messages, iostream.Messages) var Icons = survey.WithIcons(func(icons *survey.IconSet) { icons.Question.Text = ""