port entirely to ColorScheme
This commit is contained in:
parent
5e89036d49
commit
a2aa154794
36 changed files with 289 additions and 298 deletions
|
|
@ -22,6 +22,7 @@ import (
|
|||
"github.com/cli/cli/pkg/cmdutil"
|
||||
"github.com/cli/cli/update"
|
||||
"github.com/cli/cli/utils"
|
||||
"github.com/mattn/go-colorable"
|
||||
"github.com/mgutz/ansi"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
|
@ -120,12 +121,14 @@ func main() {
|
|||
}
|
||||
}
|
||||
|
||||
cs := cmdFactory.IOStreams.ColorScheme()
|
||||
|
||||
authCheckEnabled := os.Getenv("GITHUB_TOKEN") == "" &&
|
||||
os.Getenv("GITHUB_ENTERPRISE_TOKEN") == "" &&
|
||||
cmd != nil && cmdutil.IsAuthCheckEnabled(cmd)
|
||||
if authCheckEnabled {
|
||||
if !cmdutil.CheckAuth(cfg) {
|
||||
fmt.Fprintln(stderr, utils.Bold("Welcome to GitHub CLI!"))
|
||||
fmt.Fprintln(stderr, cs.Bold("Welcome to GitHub CLI!"))
|
||||
fmt.Fprintln(stderr)
|
||||
fmt.Fprintln(stderr, "To authenticate, please run `gh auth login`.")
|
||||
fmt.Fprintln(stderr, "You can also set the GITHUB_TOKEN environment variable, if preferred.")
|
||||
|
|
@ -247,5 +250,5 @@ func basicClient(currentVersion string) (*api.Client, error) {
|
|||
func apiVerboseLog() api.ClientOption {
|
||||
logTraffic := strings.Contains(os.Getenv("DEBUG"), "api")
|
||||
colorize := utils.IsTerminal(os.Stderr)
|
||||
return api.VerboseLog(utils.NewColorable(os.Stderr), logTraffic, colorize)
|
||||
return api.VerboseLog(colorable.NewColorable(os.Stderr), logTraffic, colorize)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,8 +12,7 @@ import (
|
|||
"github.com/cli/cli/auth"
|
||||
"github.com/cli/cli/internal/config"
|
||||
"github.com/cli/cli/pkg/browser"
|
||||
"github.com/cli/cli/utils"
|
||||
"github.com/mattn/go-colorable"
|
||||
"github.com/cli/cli/pkg/iostreams"
|
||||
)
|
||||
|
||||
var (
|
||||
|
|
@ -23,12 +22,13 @@ var (
|
|||
oauthClientSecret = "34ddeff2b558a23d38fba8a6de74f086ede1cc0b"
|
||||
)
|
||||
|
||||
func AuthFlowWithConfig(cfg config.Config, hostname, notice string, additionalScopes []string) (string, error) {
|
||||
func AuthFlowWithConfig(cfg config.Config, io *iostreams.IOStreams, hostname, notice string, additionalScopes []string) (string, error) {
|
||||
// TODO this probably shouldn't live in this package. It should probably be in a new package that
|
||||
// depends on both iostreams and config.
|
||||
stderr := colorable.NewColorableStderr()
|
||||
stderr := io.ErrOut
|
||||
cs := io.ColorScheme()
|
||||
|
||||
token, userLogin, err := authFlow(hostname, stderr, notice, additionalScopes)
|
||||
token, userLogin, err := authFlow(hostname, stderr, cs, notice, additionalScopes)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
|
@ -48,13 +48,13 @@ func AuthFlowWithConfig(cfg config.Config, hostname, notice string, additionalSc
|
|||
}
|
||||
|
||||
fmt.Fprintf(stderr, "%s Authentication complete. %s to continue...\n",
|
||||
utils.GreenCheck(), utils.Bold("Press Enter"))
|
||||
cs.SuccessIcon(), cs.Bold("Press Enter"))
|
||||
_ = waitForEnter(os.Stdin)
|
||||
|
||||
return token, nil
|
||||
}
|
||||
|
||||
func authFlow(oauthHost string, w io.Writer, notice string, additionalScopes []string) (string, string, error) {
|
||||
func authFlow(oauthHost string, w io.Writer, cs *iostreams.ColorScheme, notice string, additionalScopes []string) (string, string, error) {
|
||||
var verboseStream io.Writer
|
||||
if strings.Contains(os.Getenv("DEBUG"), "oauth") {
|
||||
verboseStream = w
|
||||
|
|
@ -75,9 +75,9 @@ func authFlow(oauthHost string, w io.Writer, notice string, additionalScopes []s
|
|||
HTTPClient: http.DefaultClient,
|
||||
OpenInBrowser: func(url, code string) error {
|
||||
if code != "" {
|
||||
fmt.Fprintf(w, "%s First copy your one-time code: %s\n", utils.Yellow("!"), utils.Bold(code))
|
||||
fmt.Fprintf(w, "%s First copy your one-time code: %s\n", cs.Yellow("!"), cs.Bold(code))
|
||||
}
|
||||
fmt.Fprintf(w, "- %s to open %s in your browser... ", utils.Bold("Press Enter"), oauthHost)
|
||||
fmt.Fprintf(w, "- %s to open %s in your browser... ", cs.Bold("Press Enter"), oauthHost)
|
||||
_ = waitForEnter(os.Stdin)
|
||||
|
||||
browseCmd, err := browser.Command(url)
|
||||
|
|
@ -86,7 +86,7 @@ func authFlow(oauthHost string, w io.Writer, notice string, additionalScopes []s
|
|||
}
|
||||
err = browseCmd.Run()
|
||||
if err != nil {
|
||||
fmt.Fprintf(w, "%s Failed opening a web browser at %s\n", utils.Red("!"), url)
|
||||
fmt.Fprintf(w, "%s Failed opening a web browser at %s\n", cs.Red("!"), url)
|
||||
fmt.Fprintf(w, " %s\n", err)
|
||||
fmt.Fprint(w, " Please try entering the URL in your browser manually\n")
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,7 +6,6 @@ import (
|
|||
"github.com/cli/cli/internal/config"
|
||||
"github.com/cli/cli/pkg/cmdutil"
|
||||
"github.com/cli/cli/pkg/iostreams"
|
||||
"github.com/cli/cli/utils"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
|
|
@ -63,7 +62,7 @@ func deleteRun(opts *DeleteOptions) error {
|
|||
}
|
||||
|
||||
if opts.IO.IsStdoutTTY() {
|
||||
redCheck := utils.Red("✓")
|
||||
redCheck := opts.IO.ColorScheme().Red("✓")
|
||||
fmt.Fprintf(opts.IO.ErrOut, "%s Deleted alias %s; was %s\n", redCheck, opts.Name, expansion)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -8,7 +8,6 @@ import (
|
|||
"github.com/cli/cli/internal/config"
|
||||
"github.com/cli/cli/pkg/cmdutil"
|
||||
"github.com/cli/cli/pkg/iostreams"
|
||||
"github.com/cli/cli/utils"
|
||||
"github.com/google/shlex"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
|
@ -84,6 +83,7 @@ func NewCmdSet(f *cmdutil.Factory, runF func(*SetOptions) error) *cobra.Command
|
|||
}
|
||||
|
||||
func setRun(opts *SetOptions) error {
|
||||
cs := opts.IO.ColorScheme()
|
||||
cfg, err := opts.Config()
|
||||
if err != nil {
|
||||
return err
|
||||
|
|
@ -96,7 +96,7 @@ func setRun(opts *SetOptions) error {
|
|||
|
||||
isTerminal := opts.IO.IsStdoutTTY()
|
||||
if isTerminal {
|
||||
fmt.Fprintf(opts.IO.ErrOut, "- Adding alias for %s: %s\n", utils.Bold(opts.Name), utils.Bold(opts.Expansion))
|
||||
fmt.Fprintf(opts.IO.ErrOut, "- Adding alias for %s: %s\n", cs.Bold(opts.Name), cs.Bold(opts.Expansion))
|
||||
}
|
||||
|
||||
expansion := opts.Expansion
|
||||
|
|
@ -114,13 +114,13 @@ func setRun(opts *SetOptions) error {
|
|||
return fmt.Errorf("could not create alias: %s does not correspond to a gh command", expansion)
|
||||
}
|
||||
|
||||
successMsg := fmt.Sprintf("%s Added alias.", utils.Green("✓"))
|
||||
successMsg := fmt.Sprintf("%s Added alias.", cs.SuccessIcon())
|
||||
if oldExpansion, ok := aliasCfg.Get(opts.Name); ok {
|
||||
successMsg = fmt.Sprintf("%s Changed alias %s from %s to %s",
|
||||
utils.Green("✓"),
|
||||
utils.Bold(opts.Name),
|
||||
utils.Bold(oldExpansion),
|
||||
utils.Bold(expansion),
|
||||
cs.SuccessIcon(),
|
||||
cs.Bold(opts.Name),
|
||||
cs.Bold(oldExpansion),
|
||||
cs.Bold(expansion),
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -16,7 +16,6 @@ import (
|
|||
"github.com/cli/cli/pkg/cmdutil"
|
||||
"github.com/cli/cli/pkg/iostreams"
|
||||
"github.com/cli/cli/pkg/prompt"
|
||||
"github.com/cli/cli/utils"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
|
|
@ -228,7 +227,7 @@ func loginRun(opts *LoginOptions) error {
|
|||
}
|
||||
|
||||
if authMode == 0 {
|
||||
_, err := authflow.AuthFlowWithConfig(cfg, hostname, "", opts.Scopes)
|
||||
_, err := authflow.AuthFlowWithConfig(cfg, opts.IO, hostname, "", opts.Scopes)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to authenticate via web browser: %w", err)
|
||||
}
|
||||
|
|
@ -258,6 +257,8 @@ func loginRun(opts *LoginOptions) error {
|
|||
}
|
||||
}
|
||||
|
||||
cs := opts.IO.ColorScheme()
|
||||
|
||||
gitProtocol := "https"
|
||||
if opts.Interactive {
|
||||
err = prompt.SurveyAskOne(&survey.Select{
|
||||
|
|
@ -279,7 +280,7 @@ func loginRun(opts *LoginOptions) error {
|
|||
return err
|
||||
}
|
||||
|
||||
fmt.Fprintf(opts.IO.ErrOut, "%s Configured git protocol\n", utils.GreenCheck())
|
||||
fmt.Fprintf(opts.IO.ErrOut, "%s Configured git protocol\n", cs.SuccessIcon())
|
||||
}
|
||||
|
||||
apiClient, err := client.ClientFromCfg(hostname, cfg)
|
||||
|
|
@ -302,7 +303,7 @@ func loginRun(opts *LoginOptions) error {
|
|||
return err
|
||||
}
|
||||
|
||||
fmt.Fprintf(opts.IO.ErrOut, "%s Logged in as %s\n", utils.GreenCheck(), utils.Bold(username))
|
||||
fmt.Fprintf(opts.IO.ErrOut, "%s Logged in as %s\n", cs.SuccessIcon(), cs.Bold(username))
|
||||
|
||||
return nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,7 +12,6 @@ import (
|
|||
"github.com/cli/cli/pkg/cmdutil"
|
||||
"github.com/cli/cli/pkg/iostreams"
|
||||
"github.com/cli/cli/pkg/prompt"
|
||||
"github.com/cli/cli/utils"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
|
|
@ -151,8 +150,9 @@ func logoutRun(opts *LogoutOptions) error {
|
|||
isTTY := opts.IO.IsStdinTTY() && opts.IO.IsStdoutTTY()
|
||||
|
||||
if isTTY {
|
||||
cs := opts.IO.ColorScheme()
|
||||
fmt.Fprintf(opts.IO.ErrOut, "%s Logged out of %s%s\n",
|
||||
utils.GreenCheck(), utils.Bold(hostname), usernameStr)
|
||||
cs.SuccessIcon(), cs.Bold(hostname), usernameStr)
|
||||
}
|
||||
|
||||
return nil
|
||||
|
|
|
|||
|
|
@ -20,15 +20,15 @@ type RefreshOptions struct {
|
|||
|
||||
Hostname string
|
||||
Scopes []string
|
||||
AuthFlow func(config.Config, string, []string) error
|
||||
AuthFlow func(config.Config, *iostreams.IOStreams, string, []string) error
|
||||
}
|
||||
|
||||
func NewCmdRefresh(f *cmdutil.Factory, runF func(*RefreshOptions) error) *cobra.Command {
|
||||
opts := &RefreshOptions{
|
||||
IO: f.IOStreams,
|
||||
Config: f.Config,
|
||||
AuthFlow: func(cfg config.Config, hostname string, scopes []string) error {
|
||||
_, err := authflow.AuthFlowWithConfig(cfg, hostname, "", scopes)
|
||||
AuthFlow: func(cfg config.Config, io *iostreams.IOStreams, hostname string, scopes []string) error {
|
||||
_, err := authflow.AuthFlowWithConfig(cfg, io, hostname, "", scopes)
|
||||
return err
|
||||
},
|
||||
}
|
||||
|
|
@ -118,5 +118,5 @@ func refreshRun(opts *RefreshOptions) error {
|
|||
return err
|
||||
}
|
||||
|
||||
return opts.AuthFlow(cfg, hostname, opts.Scopes)
|
||||
return opts.AuthFlow(cfg, opts.IO, hostname, opts.Scopes)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -213,7 +213,7 @@ func Test_refreshRun(t *testing.T) {
|
|||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
aa := authArgs{}
|
||||
tt.opts.AuthFlow = func(_ config.Config, hostname string, scopes []string) error {
|
||||
tt.opts.AuthFlow = func(_ config.Config, _ *iostreams.IOStreams, hostname string, scopes []string) error {
|
||||
aa.hostname = hostname
|
||||
aa.scopes = scopes
|
||||
return nil
|
||||
|
|
|
|||
|
|
@ -10,7 +10,6 @@ import (
|
|||
"github.com/cli/cli/internal/config"
|
||||
"github.com/cli/cli/pkg/cmdutil"
|
||||
"github.com/cli/cli/pkg/iostreams"
|
||||
"github.com/cli/cli/utils"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
|
|
@ -64,12 +63,14 @@ func statusRun(opts *StatusOptions) error {
|
|||
|
||||
stderr := opts.IO.ErrOut
|
||||
|
||||
cs := opts.IO.ColorScheme()
|
||||
|
||||
statusInfo := map[string][]string{}
|
||||
|
||||
hostnames, err := cfg.Hosts()
|
||||
if len(hostnames) == 0 || err != nil {
|
||||
fmt.Fprintf(stderr,
|
||||
"You are not logged into any GitHub hosts. Run %s to authenticate.\n", utils.Bold("gh auth login"))
|
||||
"You are not logged into any GitHub hosts. Run %s to authenticate.\n", cs.Bold("gh auth login"))
|
||||
return cmdutil.SilentError
|
||||
}
|
||||
|
||||
|
|
@ -98,39 +99,39 @@ func statusRun(opts *StatusOptions) error {
|
|||
if err != nil {
|
||||
var missingScopes *api.MissingScopesError
|
||||
if errors.As(err, &missingScopes) {
|
||||
addMsg("%s %s: the token in %s is %s", utils.Red("X"), hostname, tokenSource, err)
|
||||
addMsg("%s %s: the token in %s is %s", cs.Red("X"), hostname, tokenSource, err)
|
||||
if tokenIsWriteable {
|
||||
addMsg("- To request missing scopes, run: %s %s\n",
|
||||
utils.Bold("gh auth refresh -h"),
|
||||
utils.Bold(hostname))
|
||||
cs.Bold("gh auth refresh -h"),
|
||||
cs.Bold(hostname))
|
||||
}
|
||||
} else {
|
||||
addMsg("%s %s: authentication failed", utils.Red("X"), hostname)
|
||||
addMsg("- The %s token in %s is no longer valid.", utils.Bold(hostname), tokenSource)
|
||||
addMsg("%s %s: authentication failed", cs.Red("X"), hostname)
|
||||
addMsg("- The %s token in %s is no longer valid.", cs.Bold(hostname), tokenSource)
|
||||
if tokenIsWriteable {
|
||||
addMsg("- To re-authenticate, run: %s %s",
|
||||
utils.Bold("gh auth login -h"), utils.Bold(hostname))
|
||||
cs.Bold("gh auth login -h"), cs.Bold(hostname))
|
||||
addMsg("- To forget about this host, run: %s %s",
|
||||
utils.Bold("gh auth logout -h"), utils.Bold(hostname))
|
||||
cs.Bold("gh auth logout -h"), cs.Bold(hostname))
|
||||
}
|
||||
}
|
||||
failed = true
|
||||
} else {
|
||||
username, err := api.CurrentLoginName(apiClient, hostname)
|
||||
if err != nil {
|
||||
addMsg("%s %s: api call failed: %s", utils.Red("X"), hostname, err)
|
||||
addMsg("%s %s: api call failed: %s", cs.Red("X"), hostname, err)
|
||||
}
|
||||
addMsg("%s Logged in to %s as %s (%s)", utils.GreenCheck(), hostname, utils.Bold(username), tokenSource)
|
||||
addMsg("%s Logged in to %s as %s (%s)", cs.SuccessIcon(), hostname, cs.Bold(username), tokenSource)
|
||||
proto, _ := cfg.Get(hostname, "git_protocol")
|
||||
if proto != "" {
|
||||
addMsg("%s Git operations for %s configured to use %s protocol.",
|
||||
utils.GreenCheck(), hostname, utils.Bold(proto))
|
||||
cs.SuccessIcon(), hostname, cs.Bold(proto))
|
||||
}
|
||||
tokenDisplay := "*******************"
|
||||
if opts.ShowToken {
|
||||
tokenDisplay = token
|
||||
}
|
||||
addMsg("%s Token: %s", utils.GreenCheck(), tokenDisplay)
|
||||
addMsg("%s Token: %s", cs.SuccessIcon(), tokenDisplay)
|
||||
}
|
||||
addMsg("")
|
||||
|
||||
|
|
@ -143,7 +144,7 @@ func statusRun(opts *StatusOptions) error {
|
|||
if !ok {
|
||||
continue
|
||||
}
|
||||
fmt.Fprintf(stderr, "%s\n", utils.Bold(hostname))
|
||||
fmt.Fprintf(stderr, "%s\n", cs.Bold(hostname))
|
||||
for _, line := range lines {
|
||||
fmt.Fprintf(stderr, " %s\n", line)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,7 +19,6 @@ import (
|
|||
"github.com/cli/cli/pkg/cmd/gist/shared"
|
||||
"github.com/cli/cli/pkg/cmdutil"
|
||||
"github.com/cli/cli/pkg/iostreams"
|
||||
"github.com/cli/cli/utils"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
|
|
@ -116,8 +115,10 @@ func createRun(opts *CreateOptions) error {
|
|||
completionMessage = fmt.Sprintf("Created gist %s", gistName)
|
||||
}
|
||||
|
||||
cs := opts.IO.ColorScheme()
|
||||
|
||||
errOut := opts.IO.ErrOut
|
||||
fmt.Fprintf(errOut, "%s %s\n", utils.Gray("-"), processMessage)
|
||||
fmt.Fprintf(errOut, "%s %s\n", cs.Gray("-"), processMessage)
|
||||
|
||||
httpClient, err := opts.HttpClient()
|
||||
if err != nil {
|
||||
|
|
@ -132,10 +133,10 @@ func createRun(opts *CreateOptions) error {
|
|||
return fmt.Errorf("This command requires the 'gist' OAuth scope.\nPlease re-authenticate by doing `gh config set -h github.com oauth_token ''` and running the command again.")
|
||||
}
|
||||
}
|
||||
return fmt.Errorf("%s Failed to create gist: %w", utils.Red("X"), err)
|
||||
return fmt.Errorf("%s Failed to create gist: %w", cs.Red("X"), err)
|
||||
}
|
||||
|
||||
fmt.Fprintf(errOut, "%s %s\n", utils.Green("✓"), completionMessage)
|
||||
fmt.Fprintf(errOut, "%s %s\n", cs.Green("✓"), completionMessage)
|
||||
|
||||
fmt.Fprintln(opts.IO.Out, gist.HTMLURL)
|
||||
|
||||
|
|
|
|||
|
|
@ -10,7 +10,6 @@ import (
|
|||
"github.com/cli/cli/pkg/cmd/issue/shared"
|
||||
"github.com/cli/cli/pkg/cmdutil"
|
||||
"github.com/cli/cli/pkg/iostreams"
|
||||
"github.com/cli/cli/utils"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
|
|
@ -53,6 +52,8 @@ func NewCmdClose(f *cmdutil.Factory, runF func(*CloseOptions) error) *cobra.Comm
|
|||
}
|
||||
|
||||
func closeRun(opts *CloseOptions) error {
|
||||
cs := opts.IO.ColorScheme()
|
||||
|
||||
httpClient, err := opts.HttpClient()
|
||||
if err != nil {
|
||||
return err
|
||||
|
|
@ -65,7 +66,7 @@ func closeRun(opts *CloseOptions) error {
|
|||
}
|
||||
|
||||
if issue.Closed {
|
||||
fmt.Fprintf(opts.IO.ErrOut, "%s Issue #%d (%s) is already closed\n", utils.Yellow("!"), issue.Number, issue.Title)
|
||||
fmt.Fprintf(opts.IO.ErrOut, "%s Issue #%d (%s) is already closed\n", cs.Yellow("!"), issue.Number, issue.Title)
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
@ -74,7 +75,7 @@ func closeRun(opts *CloseOptions) error {
|
|||
return err
|
||||
}
|
||||
|
||||
fmt.Fprintf(opts.IO.ErrOut, "%s Closed issue #%d (%s)\n", utils.Red("✔"), issue.Number, issue.Title)
|
||||
fmt.Fprintf(opts.IO.ErrOut, "%s Closed issue #%d (%s)\n", cs.Red("✔"), issue.Number, issue.Title)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,7 +10,6 @@ import (
|
|||
"github.com/cli/cli/pkg/cmd/issue/shared"
|
||||
"github.com/cli/cli/pkg/cmdutil"
|
||||
"github.com/cli/cli/pkg/iostreams"
|
||||
"github.com/cli/cli/utils"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
|
|
@ -53,6 +52,8 @@ func NewCmdReopen(f *cmdutil.Factory, runF func(*ReopenOptions) error) *cobra.Co
|
|||
}
|
||||
|
||||
func reopenRun(opts *ReopenOptions) error {
|
||||
cs := opts.IO.ColorScheme()
|
||||
|
||||
httpClient, err := opts.HttpClient()
|
||||
if err != nil {
|
||||
return err
|
||||
|
|
@ -65,7 +66,7 @@ func reopenRun(opts *ReopenOptions) error {
|
|||
}
|
||||
|
||||
if !issue.Closed {
|
||||
fmt.Fprintf(opts.IO.ErrOut, "%s Issue #%d (%s) is already open\n", utils.Yellow("!"), issue.Number, issue.Title)
|
||||
fmt.Fprintf(opts.IO.ErrOut, "%s Issue #%d (%s) is already open\n", cs.Yellow("!"), issue.Number, issue.Title)
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
@ -74,7 +75,7 @@ func reopenRun(opts *ReopenOptions) error {
|
|||
return err
|
||||
}
|
||||
|
||||
fmt.Fprintf(opts.IO.ErrOut, "%s Reopened issue #%d (%s)\n", utils.Green("✔"), issue.Number, issue.Title)
|
||||
fmt.Fprintf(opts.IO.ErrOut, "%s Reopened issue #%d (%s)\n", cs.SuccessIcon(), issue.Number, issue.Title)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ import (
|
|||
)
|
||||
|
||||
func PrintIssues(io *iostreams.IOStreams, prefix string, totalCount int, issues []api.Issue) {
|
||||
cs := io.ColorScheme()
|
||||
table := utils.NewTablePrinter(io)
|
||||
for _, issue := range issues {
|
||||
issueNum := strconv.Itoa(issue.Number)
|
||||
|
|
@ -27,14 +28,14 @@ func PrintIssues(io *iostreams.IOStreams, prefix string, totalCount int, issues
|
|||
}
|
||||
now := time.Now()
|
||||
ago := now.Sub(issue.UpdatedAt)
|
||||
table.AddField(issueNum, nil, prShared.ColorFuncForState(issue.State))
|
||||
table.AddField(issueNum, nil, cs.ColorFromString(prShared.ColorForState(issue.State)))
|
||||
if !table.IsTTY() {
|
||||
table.AddField(issue.State, nil, nil)
|
||||
}
|
||||
table.AddField(text.ReplaceExcessiveWhitespace(issue.Title), nil, nil)
|
||||
table.AddField(labels, nil, utils.Gray)
|
||||
table.AddField(labels, nil, cs.Gray)
|
||||
if table.IsTTY() {
|
||||
table.AddField(utils.FuzzyAgo(ago), nil, utils.Gray)
|
||||
table.AddField(utils.FuzzyAgo(ago), nil, cs.Gray)
|
||||
} else {
|
||||
table.AddField(issue.UpdatedAt.String(), nil, nil)
|
||||
}
|
||||
|
|
@ -43,7 +44,7 @@ func PrintIssues(io *iostreams.IOStreams, prefix string, totalCount int, issues
|
|||
_ = table.Render()
|
||||
remaining := totalCount - len(issues)
|
||||
if remaining > 0 {
|
||||
fmt.Fprintf(io.Out, utils.Gray("%sAnd %d more\n"), prefix, remaining)
|
||||
fmt.Fprintf(io.Out, cs.Gray("%sAnd %d more\n"), prefix, remaining)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -75,33 +75,34 @@ func statusRun(opts *StatusOptions) error {
|
|||
defer opts.IO.StopPager()
|
||||
|
||||
out := opts.IO.Out
|
||||
cs := opts.IO.ColorScheme()
|
||||
|
||||
fmt.Fprintln(out, "")
|
||||
fmt.Fprintf(out, "Relevant issues in %s\n", ghrepo.FullName(baseRepo))
|
||||
fmt.Fprintln(out, "")
|
||||
|
||||
prShared.PrintHeader(out, "Issues assigned to you")
|
||||
prShared.PrintHeader(cs, out, "Issues assigned to you")
|
||||
if issuePayload.Assigned.TotalCount > 0 {
|
||||
issueShared.PrintIssues(opts.IO, " ", issuePayload.Assigned.TotalCount, issuePayload.Assigned.Issues)
|
||||
} else {
|
||||
message := " There are no issues assigned to you"
|
||||
prShared.PrintMessage(out, message)
|
||||
prShared.PrintMessage(cs, out, message)
|
||||
}
|
||||
fmt.Fprintln(out)
|
||||
|
||||
prShared.PrintHeader(out, "Issues mentioning you")
|
||||
prShared.PrintHeader(cs, out, "Issues mentioning you")
|
||||
if issuePayload.Mentioned.TotalCount > 0 {
|
||||
issueShared.PrintIssues(opts.IO, " ", issuePayload.Mentioned.TotalCount, issuePayload.Mentioned.Issues)
|
||||
} else {
|
||||
prShared.PrintMessage(out, " There are no issues mentioning you")
|
||||
prShared.PrintMessage(cs, out, " There are no issues mentioning you")
|
||||
}
|
||||
fmt.Fprintln(out)
|
||||
|
||||
prShared.PrintHeader(out, "Issues opened by you")
|
||||
prShared.PrintHeader(cs, out, "Issues opened by you")
|
||||
if issuePayload.Authored.TotalCount > 0 {
|
||||
issueShared.PrintIssues(opts.IO, " ", issuePayload.Authored.TotalCount, issuePayload.Authored.Issues)
|
||||
} else {
|
||||
prShared.PrintMessage(out, " There are no issues opened by you")
|
||||
prShared.PrintMessage(cs, out, " There are no issues opened by you")
|
||||
}
|
||||
fmt.Fprintln(out)
|
||||
|
||||
|
|
|
|||
|
|
@ -129,11 +129,12 @@ func printHumanIssuePreview(io *iostreams.IOStreams, issue *api.Issue) error {
|
|||
out := io.Out
|
||||
now := time.Now()
|
||||
ago := now.Sub(issue.CreatedAt)
|
||||
cs := io.ColorScheme()
|
||||
|
||||
// Header (Title and State)
|
||||
fmt.Fprintln(out, utils.Bold(issue.Title))
|
||||
fmt.Fprint(out, issueStateTitleWithColor(issue.State))
|
||||
fmt.Fprintln(out, utils.Gray(fmt.Sprintf(
|
||||
fmt.Fprintln(out, cs.Bold(issue.Title))
|
||||
fmt.Fprint(out, issueStateTitleWithColor(cs, issue.State))
|
||||
fmt.Fprintln(out, cs.Gray(fmt.Sprintf(
|
||||
" • %s opened %s • %s",
|
||||
issue.Author.Login,
|
||||
utils.FuzzyAgo(ago),
|
||||
|
|
@ -143,19 +144,19 @@ func printHumanIssuePreview(io *iostreams.IOStreams, issue *api.Issue) error {
|
|||
// Metadata
|
||||
fmt.Fprintln(out)
|
||||
if assignees := issueAssigneeList(*issue); assignees != "" {
|
||||
fmt.Fprint(out, utils.Bold("Assignees: "))
|
||||
fmt.Fprint(out, cs.Bold("Assignees: "))
|
||||
fmt.Fprintln(out, assignees)
|
||||
}
|
||||
if labels := shared.IssueLabelList(*issue); labels != "" {
|
||||
fmt.Fprint(out, utils.Bold("Labels: "))
|
||||
fmt.Fprint(out, cs.Bold("Labels: "))
|
||||
fmt.Fprintln(out, labels)
|
||||
}
|
||||
if projects := issueProjectList(*issue); projects != "" {
|
||||
fmt.Fprint(out, utils.Bold("Projects: "))
|
||||
fmt.Fprint(out, cs.Bold("Projects: "))
|
||||
fmt.Fprintln(out, projects)
|
||||
}
|
||||
if issue.Milestone.Title != "" {
|
||||
fmt.Fprint(out, utils.Bold("Milestone: "))
|
||||
fmt.Fprint(out, cs.Bold("Milestone: "))
|
||||
fmt.Fprintln(out, issue.Milestone.Title)
|
||||
}
|
||||
|
||||
|
|
@ -172,12 +173,12 @@ func printHumanIssuePreview(io *iostreams.IOStreams, issue *api.Issue) error {
|
|||
fmt.Fprintln(out)
|
||||
|
||||
// Footer
|
||||
fmt.Fprintf(out, utils.Gray("View this issue on GitHub: %s\n"), issue.URL)
|
||||
fmt.Fprintf(out, cs.Gray("View this issue on GitHub: %s\n"), issue.URL)
|
||||
return nil
|
||||
}
|
||||
|
||||
func issueStateTitleWithColor(state string) string {
|
||||
colorFunc := prShared.ColorFuncForState(state)
|
||||
func issueStateTitleWithColor(cs *iostreams.ColorScheme, state string) string {
|
||||
colorFunc := cs.ColorFromString(prShared.ColorForState(state))
|
||||
return colorFunc(strings.Title(strings.ToLower(state)))
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -97,13 +97,15 @@ func checksRun(opts *ChecksOptions) error {
|
|||
markColor func(string) string
|
||||
}
|
||||
|
||||
cs := opts.IO.ColorScheme()
|
||||
|
||||
outputs := []output{}
|
||||
|
||||
for _, c := range pr.Commits.Nodes[0].Commit.StatusCheckRollup.Contexts.Nodes {
|
||||
mark := "✓"
|
||||
bucket := "pass"
|
||||
state := c.State
|
||||
markColor := utils.Green
|
||||
markColor := cs.Green
|
||||
if state == "" {
|
||||
if c.Status == "COMPLETED" {
|
||||
state = c.Conclusion
|
||||
|
|
@ -116,12 +118,12 @@ func checksRun(opts *ChecksOptions) error {
|
|||
passing++
|
||||
case "ERROR", "FAILURE", "CANCELLED", "TIMED_OUT", "ACTION_REQUIRED":
|
||||
mark = "X"
|
||||
markColor = utils.Red
|
||||
markColor = cs.Red
|
||||
failing++
|
||||
bucket = "fail"
|
||||
case "EXPECTED", "REQUESTED", "QUEUED", "PENDING", "IN_PROGRESS", "STALE":
|
||||
mark = "-"
|
||||
markColor = utils.Yellow
|
||||
markColor = cs.Yellow
|
||||
pending++
|
||||
bucket = "pending"
|
||||
default:
|
||||
|
|
@ -206,7 +208,7 @@ func checksRun(opts *ChecksOptions) error {
|
|||
"%d failing, %d successful, and %d pending checks",
|
||||
failing, passing, pending)
|
||||
|
||||
summary = fmt.Sprintf("%s\n%s", utils.Bold(summary), tallies)
|
||||
summary = fmt.Sprintf("%s\n%s", cs.Bold(summary), tallies)
|
||||
}
|
||||
|
||||
if opts.IO.IsStdoutTTY() {
|
||||
|
|
|
|||
|
|
@ -11,7 +11,6 @@ import (
|
|||
"github.com/cli/cli/pkg/cmd/pr/shared"
|
||||
"github.com/cli/cli/pkg/cmdutil"
|
||||
"github.com/cli/cli/pkg/iostreams"
|
||||
"github.com/cli/cli/utils"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
|
|
@ -61,6 +60,8 @@ func NewCmdClose(f *cmdutil.Factory, runF func(*CloseOptions) error) *cobra.Comm
|
|||
}
|
||||
|
||||
func closeRun(opts *CloseOptions) error {
|
||||
cs := opts.IO.ColorScheme()
|
||||
|
||||
httpClient, err := opts.HttpClient()
|
||||
if err != nil {
|
||||
return err
|
||||
|
|
@ -73,10 +74,10 @@ func closeRun(opts *CloseOptions) error {
|
|||
}
|
||||
|
||||
if pr.State == "MERGED" {
|
||||
fmt.Fprintf(opts.IO.ErrOut, "%s Pull request #%d (%s) can't be closed because it was already merged", utils.Red("!"), pr.Number, pr.Title)
|
||||
fmt.Fprintf(opts.IO.ErrOut, "%s Pull request #%d (%s) can't be closed because it was already merged", cs.Red("!"), pr.Number, pr.Title)
|
||||
return cmdutil.SilentError
|
||||
} else if pr.Closed {
|
||||
fmt.Fprintf(opts.IO.ErrOut, "%s Pull request #%d (%s) is already closed\n", utils.Yellow("!"), pr.Number, pr.Title)
|
||||
fmt.Fprintf(opts.IO.ErrOut, "%s Pull request #%d (%s) is already closed\n", cs.Yellow("!"), pr.Number, pr.Title)
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
@ -85,7 +86,7 @@ func closeRun(opts *CloseOptions) error {
|
|||
return fmt.Errorf("API call failed: %w", err)
|
||||
}
|
||||
|
||||
fmt.Fprintf(opts.IO.ErrOut, "%s Closed pull request #%d (%s)\n", utils.Red("✔"), pr.Number, pr.Title)
|
||||
fmt.Fprintf(opts.IO.ErrOut, "%s Closed pull request #%d (%s)\n", cs.Red("✔"), pr.Number, pr.Title)
|
||||
|
||||
crossRepoPR := pr.HeadRepositoryOwner.Login != baseRepo.RepoOwner()
|
||||
|
||||
|
|
@ -114,24 +115,24 @@ func closeRun(opts *CloseOptions) error {
|
|||
if localBranchExists {
|
||||
err = git.DeleteLocalBranch(pr.HeadRefName)
|
||||
if err != nil {
|
||||
err = fmt.Errorf("failed to delete local branch %s: %w", utils.Cyan(pr.HeadRefName), err)
|
||||
err = fmt.Errorf("failed to delete local branch %s: %w", cs.Cyan(pr.HeadRefName), err)
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if branchToSwitchTo != "" {
|
||||
branchSwitchString = fmt.Sprintf(" and switched to branch %s", utils.Cyan(branchToSwitchTo))
|
||||
branchSwitchString = fmt.Sprintf(" and switched to branch %s", cs.Cyan(branchToSwitchTo))
|
||||
}
|
||||
}
|
||||
|
||||
if !crossRepoPR {
|
||||
err = api.BranchDeleteRemote(apiClient, baseRepo, pr.HeadRefName)
|
||||
if err != nil {
|
||||
err = fmt.Errorf("failed to delete remote branch %s: %w", utils.Cyan(pr.HeadRefName), err)
|
||||
err = fmt.Errorf("failed to delete remote branch %s: %w", cs.Cyan(pr.HeadRefName), err)
|
||||
return err
|
||||
}
|
||||
}
|
||||
fmt.Fprintf(opts.IO.ErrOut, "%s Deleted branch %s%s\n", utils.Red("✔"), utils.Cyan(pr.HeadRefName), branchSwitchString)
|
||||
fmt.Fprintf(opts.IO.ErrOut, "%s Deleted branch %s%s\n", cs.Red("✔"), cs.Cyan(pr.HeadRefName), branchSwitchString)
|
||||
}
|
||||
|
||||
return nil
|
||||
|
|
|
|||
|
|
@ -127,6 +127,8 @@ func NewCmdCreate(f *cmdutil.Factory, runF func(*CreateOptions) error) *cobra.Co
|
|||
}
|
||||
|
||||
func createRun(opts *CreateOptions) error {
|
||||
cs := opts.IO.ColorScheme()
|
||||
|
||||
httpClient, err := opts.HttpClient()
|
||||
if err != nil {
|
||||
return err
|
||||
|
|
@ -323,11 +325,11 @@ func createRun(opts *CreateOptions) error {
|
|||
|
||||
if isTerminal {
|
||||
fmt.Fprintf(opts.IO.ErrOut, message,
|
||||
utils.Cyan(headBranchLabel),
|
||||
utils.Cyan(baseBranch),
|
||||
cs.Cyan(headBranchLabel),
|
||||
cs.Cyan(baseBranch),
|
||||
ghrepo.FullName(baseRepo))
|
||||
if (title == "" || body == "") && defaultsErr != nil {
|
||||
fmt.Fprintf(opts.IO.ErrOut, "%s warning: could not compute title or body defaults: %s\n", utils.Yellow("!"), defaultsErr)
|
||||
fmt.Fprintf(opts.IO.ErrOut, "%s warning: could not compute title or body defaults: %s\n", cs.Yellow("!"), defaultsErr)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -145,15 +145,16 @@ func listRun(opts *ListOptions) error {
|
|||
fmt.Fprintf(opts.IO.Out, "\n%s\n\n", title)
|
||||
}
|
||||
|
||||
cs := opts.IO.ColorScheme()
|
||||
table := utils.NewTablePrinter(opts.IO)
|
||||
for _, pr := range listResult.PullRequests {
|
||||
prNum := strconv.Itoa(pr.Number)
|
||||
if table.IsTTY() {
|
||||
prNum = "#" + prNum
|
||||
}
|
||||
table.AddField(prNum, nil, shared.ColorFuncForPR(pr))
|
||||
table.AddField(prNum, nil, cs.ColorFromString(shared.ColorForPR(pr)))
|
||||
table.AddField(text.ReplaceExcessiveWhitespace(pr.Title), nil, nil)
|
||||
table.AddField(pr.HeadLabel(), nil, utils.Cyan)
|
||||
table.AddField(pr.HeadLabel(), nil, cs.Cyan)
|
||||
if !table.IsTTY() {
|
||||
table.AddField(prStateWithDraft(&pr), nil, nil)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,7 +16,6 @@ import (
|
|||
"github.com/cli/cli/pkg/cmdutil"
|
||||
"github.com/cli/cli/pkg/iostreams"
|
||||
"github.com/cli/cli/pkg/prompt"
|
||||
"github.com/cli/cli/utils"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
|
|
@ -111,6 +110,8 @@ func NewCmdMerge(f *cmdutil.Factory, runF func(*MergeOptions) error) *cobra.Comm
|
|||
}
|
||||
|
||||
func mergeRun(opts *MergeOptions) error {
|
||||
cs := opts.IO.ColorScheme()
|
||||
|
||||
httpClient, err := opts.HttpClient()
|
||||
if err != nil {
|
||||
return err
|
||||
|
|
@ -123,13 +124,13 @@ func mergeRun(opts *MergeOptions) error {
|
|||
}
|
||||
|
||||
if pr.Mergeable == "CONFLICTING" {
|
||||
err := fmt.Errorf("%s Pull request #%d (%s) has conflicts and isn't mergeable ", utils.Red("!"), pr.Number, pr.Title)
|
||||
err := fmt.Errorf("%s Pull request #%d (%s) has conflicts and isn't mergeable ", cs.Red("!"), pr.Number, pr.Title)
|
||||
return err
|
||||
} else if pr.Mergeable == "UNKNOWN" {
|
||||
err := fmt.Errorf("%s Pull request #%d (%s) can't be merged right now; try again in a few seconds", utils.Red("!"), pr.Number, pr.Title)
|
||||
err := fmt.Errorf("%s Pull request #%d (%s) can't be merged right now; try again in a few seconds", cs.Red("!"), pr.Number, pr.Title)
|
||||
return err
|
||||
} else if pr.State == "MERGED" {
|
||||
err := fmt.Errorf("%s Pull request #%d (%s) was already merged", utils.Red("!"), pr.Number, pr.Title)
|
||||
err := fmt.Errorf("%s Pull request #%d (%s) was already merged", cs.Red("!"), pr.Number, pr.Title)
|
||||
return err
|
||||
}
|
||||
|
||||
|
|
@ -170,7 +171,7 @@ func mergeRun(opts *MergeOptions) error {
|
|||
isTerminal := opts.IO.IsStdoutTTY()
|
||||
|
||||
if isTerminal {
|
||||
fmt.Fprintf(opts.IO.ErrOut, "%s %s pull request #%d (%s)\n", utils.Magenta("✔"), action, pr.Number, pr.Title)
|
||||
fmt.Fprintf(opts.IO.ErrOut, "%s %s pull request #%d (%s)\n", cs.Magenta("✔"), action, pr.Number, pr.Title)
|
||||
}
|
||||
|
||||
if deleteBranch {
|
||||
|
|
@ -198,13 +199,13 @@ func mergeRun(opts *MergeOptions) error {
|
|||
if localBranchExists {
|
||||
err = git.DeleteLocalBranch(pr.HeadRefName)
|
||||
if err != nil {
|
||||
err = fmt.Errorf("failed to delete local branch %s: %w", utils.Cyan(pr.HeadRefName), err)
|
||||
err = fmt.Errorf("failed to delete local branch %s: %w", cs.Cyan(pr.HeadRefName), err)
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if branchToSwitchTo != "" {
|
||||
branchSwitchString = fmt.Sprintf(" and switched to branch %s", utils.Cyan(branchToSwitchTo))
|
||||
branchSwitchString = fmt.Sprintf(" and switched to branch %s", cs.Cyan(branchToSwitchTo))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -213,13 +214,13 @@ func mergeRun(opts *MergeOptions) error {
|
|||
var httpErr api.HTTPError
|
||||
// The ref might have already been deleted by GitHub
|
||||
if err != nil && (!errors.As(err, &httpErr) || httpErr.StatusCode != 422) {
|
||||
err = fmt.Errorf("failed to delete remote branch %s: %w", utils.Cyan(pr.HeadRefName), err)
|
||||
err = fmt.Errorf("failed to delete remote branch %s: %w", cs.Cyan(pr.HeadRefName), err)
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if isTerminal {
|
||||
fmt.Fprintf(opts.IO.ErrOut, "%s Deleted branch %s%s\n", utils.Red("✔"), utils.Cyan(pr.HeadRefName), branchSwitchString)
|
||||
fmt.Fprintf(opts.IO.ErrOut, "%s Deleted branch %s%s\n", cs.Red("✔"), cs.Cyan(pr.HeadRefName), branchSwitchString)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -12,7 +12,6 @@ import (
|
|||
"github.com/cli/cli/pkg/cmd/pr/shared"
|
||||
"github.com/cli/cli/pkg/cmdutil"
|
||||
"github.com/cli/cli/pkg/iostreams"
|
||||
"github.com/cli/cli/utils"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
|
|
@ -63,6 +62,8 @@ func NewCmdReady(f *cmdutil.Factory, runF func(*ReadyOptions) error) *cobra.Comm
|
|||
}
|
||||
|
||||
func readyRun(opts *ReadyOptions) error {
|
||||
cs := opts.IO.ColorScheme()
|
||||
|
||||
httpClient, err := opts.HttpClient()
|
||||
if err != nil {
|
||||
return err
|
||||
|
|
@ -75,10 +76,10 @@ func readyRun(opts *ReadyOptions) error {
|
|||
}
|
||||
|
||||
if pr.Closed {
|
||||
fmt.Fprintf(opts.IO.ErrOut, "%s Pull request #%d is closed. Only draft pull requests can be marked as \"ready for review\"", utils.Red("!"), pr.Number)
|
||||
fmt.Fprintf(opts.IO.ErrOut, "%s Pull request #%d is closed. Only draft pull requests can be marked as \"ready for review\"", cs.Red("!"), pr.Number)
|
||||
return cmdutil.SilentError
|
||||
} else if !pr.IsDraft {
|
||||
fmt.Fprintf(opts.IO.ErrOut, "%s Pull request #%d is already \"ready for review\"\n", utils.Yellow("!"), pr.Number)
|
||||
fmt.Fprintf(opts.IO.ErrOut, "%s Pull request #%d is already \"ready for review\"\n", cs.Yellow("!"), pr.Number)
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
@ -87,7 +88,7 @@ func readyRun(opts *ReadyOptions) error {
|
|||
return fmt.Errorf("API call failed: %w", err)
|
||||
}
|
||||
|
||||
fmt.Fprintf(opts.IO.ErrOut, "%s Pull request #%d is marked as \"ready for review\"\n", utils.Green("✔"), pr.Number)
|
||||
fmt.Fprintf(opts.IO.ErrOut, "%s Pull request #%d is marked as \"ready for review\"\n", cs.Green("✔"), pr.Number)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,7 +10,6 @@ import (
|
|||
"github.com/cli/cli/pkg/cmd/pr/shared"
|
||||
"github.com/cli/cli/pkg/cmdutil"
|
||||
"github.com/cli/cli/pkg/iostreams"
|
||||
"github.com/cli/cli/utils"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
|
|
@ -53,6 +52,8 @@ func NewCmdReopen(f *cmdutil.Factory, runF func(*ReopenOptions) error) *cobra.Co
|
|||
}
|
||||
|
||||
func reopenRun(opts *ReopenOptions) error {
|
||||
cs := opts.IO.ColorScheme()
|
||||
|
||||
httpClient, err := opts.HttpClient()
|
||||
if err != nil {
|
||||
return err
|
||||
|
|
@ -65,12 +66,12 @@ func reopenRun(opts *ReopenOptions) error {
|
|||
}
|
||||
|
||||
if pr.State == "MERGED" {
|
||||
fmt.Fprintf(opts.IO.ErrOut, "%s Pull request #%d (%s) can't be reopened because it was already merged", utils.Red("!"), pr.Number, pr.Title)
|
||||
fmt.Fprintf(opts.IO.ErrOut, "%s Pull request #%d (%s) can't be reopened because it was already merged", cs.Red("!"), pr.Number, pr.Title)
|
||||
return cmdutil.SilentError
|
||||
}
|
||||
|
||||
if !pr.Closed {
|
||||
fmt.Fprintf(opts.IO.ErrOut, "%s Pull request #%d (%s) is already open\n", utils.Yellow("!"), pr.Number, pr.Title)
|
||||
fmt.Fprintf(opts.IO.ErrOut, "%s Pull request #%d (%s) is already open\n", cs.Yellow("!"), pr.Number, pr.Title)
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
@ -79,7 +80,7 @@ func reopenRun(opts *ReopenOptions) error {
|
|||
return fmt.Errorf("API call failed: %w", err)
|
||||
}
|
||||
|
||||
fmt.Fprintf(opts.IO.ErrOut, "%s Reopened pull request #%d (%s)\n", utils.Green("✔"), pr.Number, pr.Title)
|
||||
fmt.Fprintf(opts.IO.ErrOut, "%s Reopened pull request #%d (%s)\n", cs.Green("✔"), pr.Number, pr.Title)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,7 +17,6 @@ import (
|
|||
"github.com/cli/cli/pkg/markdown"
|
||||
"github.com/cli/cli/pkg/prompt"
|
||||
"github.com/cli/cli/pkg/surveyext"
|
||||
"github.com/cli/cli/utils"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
|
|
@ -172,13 +171,15 @@ func reviewRun(opts *ReviewOptions) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
cs := opts.IO.ColorScheme()
|
||||
|
||||
switch reviewData.State {
|
||||
case api.ReviewComment:
|
||||
fmt.Fprintf(opts.IO.ErrOut, "%s Reviewed pull request #%d\n", utils.Gray("-"), pr.Number)
|
||||
fmt.Fprintf(opts.IO.ErrOut, "%s Reviewed pull request #%d\n", cs.Gray("-"), pr.Number)
|
||||
case api.ReviewApprove:
|
||||
fmt.Fprintf(opts.IO.ErrOut, "%s Approved pull request #%d\n", utils.Green("✓"), pr.Number)
|
||||
fmt.Fprintf(opts.IO.ErrOut, "%s Approved pull request #%d\n", cs.SuccessIcon(), pr.Number)
|
||||
case api.ReviewRequestChanges:
|
||||
fmt.Fprintf(opts.IO.ErrOut, "%s Requested changes to pull request #%d\n", utils.Red("+"), pr.Number)
|
||||
fmt.Fprintf(opts.IO.ErrOut, "%s Requested changes to pull request #%d\n", cs.Red("+"), pr.Number)
|
||||
}
|
||||
|
||||
return nil
|
||||
|
|
|
|||
|
|
@ -6,44 +6,46 @@ import (
|
|||
"strings"
|
||||
|
||||
"github.com/cli/cli/api"
|
||||
"github.com/cli/cli/pkg/iostreams"
|
||||
"github.com/cli/cli/utils"
|
||||
)
|
||||
|
||||
func StateTitleWithColor(pr api.PullRequest) string {
|
||||
prStateColorFunc := ColorFuncForPR(pr)
|
||||
func StateTitleWithColor(cs *iostreams.ColorScheme, pr api.PullRequest) string {
|
||||
prStateColorFunc := cs.ColorFromString(ColorForPR(pr))
|
||||
|
||||
if pr.State == "OPEN" && pr.IsDraft {
|
||||
return prStateColorFunc(strings.Title(strings.ToLower("Draft")))
|
||||
}
|
||||
return prStateColorFunc(strings.Title(strings.ToLower(pr.State)))
|
||||
}
|
||||
|
||||
func ColorFuncForPR(pr api.PullRequest) func(string) string {
|
||||
func ColorForPR(pr api.PullRequest) string {
|
||||
if pr.State == "OPEN" && pr.IsDraft {
|
||||
return utils.Gray
|
||||
return "gray"
|
||||
}
|
||||
return ColorFuncForState(pr.State)
|
||||
return ColorForState(pr.State)
|
||||
}
|
||||
|
||||
// ColorFuncForState returns a color function for a PR/Issue state
|
||||
func ColorFuncForState(state string) func(string) string {
|
||||
// ColorForState returns a color constant for a PR/Issue state
|
||||
func ColorForState(state string) string {
|
||||
switch state {
|
||||
case "OPEN":
|
||||
return utils.Green
|
||||
return "green"
|
||||
case "CLOSED":
|
||||
return utils.Red
|
||||
return "red"
|
||||
case "MERGED":
|
||||
return utils.Magenta
|
||||
return "magenta"
|
||||
default:
|
||||
return nil
|
||||
return ""
|
||||
}
|
||||
}
|
||||
|
||||
func PrintHeader(w io.Writer, s string) {
|
||||
fmt.Fprintln(w, utils.Bold(s))
|
||||
func PrintHeader(cs *iostreams.ColorScheme, w io.Writer, s string) {
|
||||
fmt.Fprintln(w, cs.Bold(s))
|
||||
}
|
||||
|
||||
func PrintMessage(w io.Writer, s string) {
|
||||
fmt.Fprintln(w, utils.Gray(s))
|
||||
func PrintMessage(cs *iostreams.ColorScheme, w io.Writer, s string) {
|
||||
fmt.Fprintln(w, cs.Gray(s))
|
||||
}
|
||||
|
||||
func ListHeader(repoName string, itemName string, matchCount int, totalMatchCount int, hasFilters bool) string {
|
||||
|
|
|
|||
|
|
@ -18,7 +18,6 @@ import (
|
|||
"github.com/cli/cli/pkg/cmdutil"
|
||||
"github.com/cli/cli/pkg/iostreams"
|
||||
"github.com/cli/cli/pkg/text"
|
||||
"github.com/cli/cli/utils"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
|
|
@ -104,38 +103,39 @@ func statusRun(opts *StatusOptions) error {
|
|||
defer opts.IO.StopPager()
|
||||
|
||||
out := opts.IO.Out
|
||||
cs := opts.IO.ColorScheme()
|
||||
|
||||
fmt.Fprintln(out, "")
|
||||
fmt.Fprintf(out, "Relevant pull requests in %s\n", ghrepo.FullName(baseRepo))
|
||||
fmt.Fprintln(out, "")
|
||||
|
||||
shared.PrintHeader(out, "Current branch")
|
||||
shared.PrintHeader(cs, out, "Current branch")
|
||||
currentPR := prPayload.CurrentPR
|
||||
if currentPR != nil && currentPR.State != "OPEN" && prPayload.DefaultBranch == currentBranch {
|
||||
currentPR = nil
|
||||
}
|
||||
if currentPR != nil {
|
||||
printPrs(out, 1, *currentPR)
|
||||
printPrs(cs, out, 1, *currentPR)
|
||||
} else if currentPRHeadRef == "" {
|
||||
shared.PrintMessage(out, " There is no current branch")
|
||||
shared.PrintMessage(cs, out, " There is no current branch")
|
||||
} else {
|
||||
shared.PrintMessage(out, fmt.Sprintf(" There is no pull request associated with %s", utils.Cyan("["+currentPRHeadRef+"]")))
|
||||
shared.PrintMessage(cs, out, fmt.Sprintf(" There is no pull request associated with %s", cs.Cyan("["+currentPRHeadRef+"]")))
|
||||
}
|
||||
fmt.Fprintln(out)
|
||||
|
||||
shared.PrintHeader(out, "Created by you")
|
||||
shared.PrintHeader(cs, out, "Created by you")
|
||||
if prPayload.ViewerCreated.TotalCount > 0 {
|
||||
printPrs(out, prPayload.ViewerCreated.TotalCount, prPayload.ViewerCreated.PullRequests...)
|
||||
printPrs(cs, out, prPayload.ViewerCreated.TotalCount, prPayload.ViewerCreated.PullRequests...)
|
||||
} else {
|
||||
shared.PrintMessage(out, " You have no open pull requests")
|
||||
shared.PrintMessage(cs, out, " You have no open pull requests")
|
||||
}
|
||||
fmt.Fprintln(out)
|
||||
|
||||
shared.PrintHeader(out, "Requesting a code review from you")
|
||||
shared.PrintHeader(cs, out, "Requesting a code review from you")
|
||||
if prPayload.ReviewRequested.TotalCount > 0 {
|
||||
printPrs(out, prPayload.ReviewRequested.TotalCount, prPayload.ReviewRequested.PullRequests...)
|
||||
printPrs(cs, out, prPayload.ReviewRequested.TotalCount, prPayload.ReviewRequested.PullRequests...)
|
||||
} else {
|
||||
shared.PrintMessage(out, " You have no pull requests to review")
|
||||
shared.PrintMessage(cs, out, " You have no pull requests to review")
|
||||
}
|
||||
fmt.Fprintln(out)
|
||||
|
||||
|
|
@ -179,20 +179,20 @@ func prSelectorForCurrentBranch(baseRepo ghrepo.Interface, prHeadRef string, rem
|
|||
return
|
||||
}
|
||||
|
||||
func printPrs(w io.Writer, totalCount int, prs ...api.PullRequest) {
|
||||
func printPrs(cs *iostreams.ColorScheme, w io.Writer, totalCount int, prs ...api.PullRequest) {
|
||||
for _, pr := range prs {
|
||||
prNumber := fmt.Sprintf("#%d", pr.Number)
|
||||
|
||||
prStateColorFunc := utils.Green
|
||||
prStateColorFunc := cs.Green
|
||||
if pr.IsDraft {
|
||||
prStateColorFunc = utils.Gray
|
||||
prStateColorFunc = cs.Gray
|
||||
} else if pr.State == "MERGED" {
|
||||
prStateColorFunc = utils.Magenta
|
||||
prStateColorFunc = cs.Magenta
|
||||
} else if pr.State == "CLOSED" {
|
||||
prStateColorFunc = utils.Red
|
||||
prStateColorFunc = cs.Red
|
||||
}
|
||||
|
||||
fmt.Fprintf(w, " %s %s %s", prStateColorFunc(prNumber), text.Truncate(50, text.ReplaceExcessiveWhitespace(pr.Title)), utils.Cyan("["+pr.HeadLabel()+"]"))
|
||||
fmt.Fprintf(w, " %s %s %s", prStateColorFunc(prNumber), text.Truncate(50, text.ReplaceExcessiveWhitespace(pr.Title)), cs.Cyan("["+pr.HeadLabel()+"]"))
|
||||
|
||||
checks := pr.ChecksStatus()
|
||||
reviews := pr.ReviewStatus()
|
||||
|
|
@ -208,14 +208,14 @@ func printPrs(w io.Writer, totalCount int, prs ...api.PullRequest) {
|
|||
var summary string
|
||||
if checks.Failing > 0 {
|
||||
if checks.Failing == checks.Total {
|
||||
summary = utils.Red("× All checks failing")
|
||||
summary = cs.Red("× All checks failing")
|
||||
} else {
|
||||
summary = utils.Red(fmt.Sprintf("× %d/%d checks failing", checks.Failing, checks.Total))
|
||||
summary = cs.Red(fmt.Sprintf("× %d/%d checks failing", checks.Failing, checks.Total))
|
||||
}
|
||||
} else if checks.Pending > 0 {
|
||||
summary = utils.Yellow("- Checks pending")
|
||||
summary = cs.Yellow("- Checks pending")
|
||||
} else if checks.Passing == checks.Total {
|
||||
summary = utils.Green("✓ Checks passing")
|
||||
summary = cs.Green("✓ Checks passing")
|
||||
}
|
||||
fmt.Fprint(w, summary)
|
||||
}
|
||||
|
|
@ -226,20 +226,20 @@ func printPrs(w io.Writer, totalCount int, prs ...api.PullRequest) {
|
|||
}
|
||||
|
||||
if reviews.ChangesRequested {
|
||||
fmt.Fprint(w, utils.Red("+ Changes requested"))
|
||||
fmt.Fprint(w, cs.Red("+ Changes requested"))
|
||||
} else if reviews.ReviewRequired {
|
||||
fmt.Fprint(w, utils.Yellow("- Review required"))
|
||||
fmt.Fprint(w, cs.Yellow("- Review required"))
|
||||
} else if reviews.Approved {
|
||||
fmt.Fprint(w, utils.Green("✓ Approved"))
|
||||
fmt.Fprint(w, cs.Green("✓ Approved"))
|
||||
}
|
||||
} else {
|
||||
fmt.Fprintf(w, " - %s", shared.StateTitleWithColor(pr))
|
||||
fmt.Fprintf(w, " - %s", shared.StateTitleWithColor(cs, pr))
|
||||
}
|
||||
|
||||
fmt.Fprint(w, "\n")
|
||||
}
|
||||
remaining := totalCount - len(prs)
|
||||
if remaining > 0 {
|
||||
fmt.Fprintf(w, utils.Gray(" And %d more\n"), remaining)
|
||||
fmt.Fprintf(w, cs.Gray(" And %d more\n"), remaining)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -111,11 +111,13 @@ func viewRun(opts *ViewOptions) error {
|
|||
if connectedToTerminal {
|
||||
return printHumanPrPreview(opts.IO, pr)
|
||||
}
|
||||
return printRawPrPreview(opts.IO.Out, pr)
|
||||
|
||||
cs := opts.IO.ColorScheme()
|
||||
return printRawPrPreview(opts.IO.Out, cs, pr)
|
||||
}
|
||||
|
||||
func printRawPrPreview(out io.Writer, pr *api.PullRequest) error {
|
||||
reviewers := prReviewerList(*pr)
|
||||
func printRawPrPreview(out io.Writer, cs *iostreams.ColorScheme, pr *api.PullRequest) error {
|
||||
reviewers := prReviewerList(*pr, cs)
|
||||
assignees := prAssigneeList(*pr)
|
||||
labels := prLabelList(*pr)
|
||||
projects := prProjectList(*pr)
|
||||
|
|
@ -140,10 +142,12 @@ func printRawPrPreview(out io.Writer, pr *api.PullRequest) error {
|
|||
func printHumanPrPreview(io *iostreams.IOStreams, pr *api.PullRequest) error {
|
||||
out := io.Out
|
||||
|
||||
cs := io.ColorScheme()
|
||||
|
||||
// Header (Title and State)
|
||||
fmt.Fprintln(out, utils.Bold(pr.Title))
|
||||
fmt.Fprintf(out, "%s", shared.StateTitleWithColor(*pr))
|
||||
fmt.Fprintln(out, utils.Gray(fmt.Sprintf(
|
||||
fmt.Fprintln(out, cs.Bold(pr.Title))
|
||||
fmt.Fprintf(out, "%s", shared.StateTitleWithColor(cs, *pr))
|
||||
fmt.Fprintln(out, cs.Gray(fmt.Sprintf(
|
||||
" • %s wants to merge %s into %s from %s",
|
||||
pr.Author.Login,
|
||||
utils.Pluralize(pr.Commits.TotalCount, "commit"),
|
||||
|
|
@ -153,24 +157,24 @@ func printHumanPrPreview(io *iostreams.IOStreams, pr *api.PullRequest) error {
|
|||
fmt.Fprintln(out)
|
||||
|
||||
// Metadata
|
||||
if reviewers := prReviewerList(*pr); reviewers != "" {
|
||||
fmt.Fprint(out, utils.Bold("Reviewers: "))
|
||||
if reviewers := prReviewerList(*pr, cs); reviewers != "" {
|
||||
fmt.Fprint(out, cs.Bold("Reviewers: "))
|
||||
fmt.Fprintln(out, reviewers)
|
||||
}
|
||||
if assignees := prAssigneeList(*pr); assignees != "" {
|
||||
fmt.Fprint(out, utils.Bold("Assignees: "))
|
||||
fmt.Fprint(out, cs.Bold("Assignees: "))
|
||||
fmt.Fprintln(out, assignees)
|
||||
}
|
||||
if labels := prLabelList(*pr); labels != "" {
|
||||
fmt.Fprint(out, utils.Bold("Labels: "))
|
||||
fmt.Fprint(out, cs.Bold("Labels: "))
|
||||
fmt.Fprintln(out, labels)
|
||||
}
|
||||
if projects := prProjectList(*pr); projects != "" {
|
||||
fmt.Fprint(out, utils.Bold("Projects: "))
|
||||
fmt.Fprint(out, cs.Bold("Projects: "))
|
||||
fmt.Fprintln(out, projects)
|
||||
}
|
||||
if pr.Milestone.Title != "" {
|
||||
fmt.Fprint(out, utils.Bold("Milestone: "))
|
||||
fmt.Fprint(out, cs.Bold("Milestone: "))
|
||||
fmt.Fprintln(out, pr.Milestone.Title)
|
||||
}
|
||||
|
||||
|
|
@ -187,7 +191,7 @@ func printHumanPrPreview(io *iostreams.IOStreams, pr *api.PullRequest) error {
|
|||
fmt.Fprintln(out)
|
||||
|
||||
// Footer
|
||||
fmt.Fprintf(out, utils.Gray("View this pull request on GitHub: %s\n"), pr.URL)
|
||||
fmt.Fprintf(out, cs.Gray("View this pull request on GitHub: %s\n"), pr.URL)
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
@ -205,43 +209,39 @@ type reviewerState struct {
|
|||
State string
|
||||
}
|
||||
|
||||
// colorFuncForReviewerState returns a color function for a reviewer state
|
||||
func colorFuncForReviewerState(state string) func(string) string {
|
||||
switch state {
|
||||
case requestedReviewState:
|
||||
return utils.Yellow
|
||||
case approvedReviewState:
|
||||
return utils.Green
|
||||
case changesRequestedReviewState:
|
||||
return utils.Red
|
||||
case commentedReviewState:
|
||||
return func(str string) string { return str } // Do nothing
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// formattedReviewerState formats a reviewerState with state color
|
||||
func formattedReviewerState(reviewer *reviewerState) string {
|
||||
func formattedReviewerState(cs *iostreams.ColorScheme, reviewer *reviewerState) string {
|
||||
state := reviewer.State
|
||||
if state == dismissedReviewState {
|
||||
// Show "DISMISSED" review as "COMMENTED", since "dimissed" only makes
|
||||
// sense when displayed in an events timeline but not in the final tally.
|
||||
state = commentedReviewState
|
||||
}
|
||||
stateColorFunc := colorFuncForReviewerState(state)
|
||||
return fmt.Sprintf("%s (%s)", reviewer.Name, stateColorFunc(strings.ReplaceAll(strings.Title(strings.ToLower(state)), "_", " ")))
|
||||
|
||||
var colorFunc func(string) string
|
||||
switch state {
|
||||
case requestedReviewState:
|
||||
colorFunc = cs.Yellow
|
||||
case approvedReviewState:
|
||||
colorFunc = cs.Green
|
||||
case changesRequestedReviewState:
|
||||
colorFunc = cs.Red
|
||||
default:
|
||||
colorFunc = func(str string) string { return str } // Do nothing
|
||||
}
|
||||
|
||||
return fmt.Sprintf("%s (%s)", reviewer.Name, colorFunc(strings.ReplaceAll(strings.Title(strings.ToLower(state)), "_", " ")))
|
||||
}
|
||||
|
||||
// prReviewerList generates a reviewer list with their last state
|
||||
func prReviewerList(pr api.PullRequest) string {
|
||||
func prReviewerList(pr api.PullRequest, cs *iostreams.ColorScheme) string {
|
||||
reviewerStates := parseReviewers(pr)
|
||||
reviewers := make([]string, 0, len(reviewerStates))
|
||||
|
||||
sortReviewerStates(reviewerStates)
|
||||
|
||||
for _, reviewer := range reviewerStates {
|
||||
reviewers = append(reviewers, formattedReviewerState(reviewer))
|
||||
reviewers = append(reviewers, formattedReviewerState(cs, reviewer))
|
||||
}
|
||||
|
||||
reviewerList := strings.Join(reviewers, ", ")
|
||||
|
|
|
|||
|
|
@ -18,7 +18,6 @@ import (
|
|||
"github.com/cli/cli/pkg/cmdutil"
|
||||
"github.com/cli/cli/pkg/iostreams"
|
||||
"github.com/cli/cli/pkg/prompt"
|
||||
"github.com/cli/cli/utils"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
|
|
@ -246,11 +245,11 @@ func createRun(opts *CreateOptions) error {
|
|||
|
||||
stderr := opts.IO.ErrOut
|
||||
stdout := opts.IO.Out
|
||||
greenCheck := utils.Green("✓")
|
||||
cs := opts.IO.ColorScheme()
|
||||
isTTY := opts.IO.IsStdoutTTY()
|
||||
|
||||
if isTTY {
|
||||
fmt.Fprintf(stderr, "%s Created repository %s on GitHub\n", greenCheck, ghrepo.FullName(repo))
|
||||
fmt.Fprintf(stderr, "%s Created repository %s on GitHub\n", cs.SuccessIcon(), ghrepo.FullName(repo))
|
||||
} else {
|
||||
fmt.Fprintln(stdout, repo.URL)
|
||||
}
|
||||
|
|
@ -272,7 +271,7 @@ func createRun(opts *CreateOptions) error {
|
|||
return err
|
||||
}
|
||||
if isTTY {
|
||||
fmt.Fprintf(stderr, "%s Added remote %s\n", greenCheck, remoteURL)
|
||||
fmt.Fprintf(stderr, "%s Added remote %s\n", cs.SuccessIcon(), remoteURL)
|
||||
}
|
||||
} else if opts.IO.CanPrompt() {
|
||||
doSetup := createLocalDirectory
|
||||
|
|
@ -300,7 +299,7 @@ func createRun(opts *CreateOptions) error {
|
|||
return err
|
||||
}
|
||||
|
||||
fmt.Fprintf(stderr, "%s Initialized repository in './%s/'\n", utils.GreenCheck(), path)
|
||||
fmt.Fprintf(stderr, "%s Initialized repository in './%s/'\n", cs.SuccessIcon(), path)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -154,6 +154,7 @@ func creditsRun(opts *CreditsOptions) error {
|
|||
static := opts.Static || isWindows
|
||||
|
||||
out := opts.IO.Out
|
||||
cs := opts.IO.ColorScheme()
|
||||
|
||||
if isTTY && static {
|
||||
fmt.Fprintln(out, "THANK YOU CONTRIBUTORS!!! <3")
|
||||
|
|
@ -167,7 +168,7 @@ func creditsRun(opts *CreditsOptions) error {
|
|||
}
|
||||
|
||||
if isTTY && !static {
|
||||
logins = append(logins, getColor(x)(c.Login))
|
||||
logins = append(logins, cs.ColorFromString(getColor(x))(c.Login))
|
||||
} else {
|
||||
fmt.Fprintf(out, "%s\n", c.Login)
|
||||
}
|
||||
|
|
@ -183,14 +184,13 @@ func creditsRun(opts *CreditsOptions) error {
|
|||
|
||||
thankLines := strings.Split(thankYou, "\n")
|
||||
for x, tl := range thankLines {
|
||||
lines = append(lines, getColor(x)(tl))
|
||||
lines = append(lines, cs.ColorFromString(getColor(x))(tl))
|
||||
}
|
||||
lines = append(lines, "")
|
||||
lines = append(lines, logins...)
|
||||
lines = append(lines, "( <3 press ctrl-c to quit <3 )")
|
||||
|
||||
termWidth, termHeight, err := utils.TerminalSize(out)
|
||||
//termWidth, termHeight, err := terminal.GetSize(int(outFile.Fd()))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
@ -277,14 +277,14 @@ func twinkle(starLine string) string {
|
|||
return starLine
|
||||
}
|
||||
|
||||
func getColor(x int) func(string) string {
|
||||
rainbow := []func(string) string{
|
||||
utils.Magenta,
|
||||
utils.Red,
|
||||
utils.Yellow,
|
||||
utils.Green,
|
||||
utils.Cyan,
|
||||
utils.Blue,
|
||||
func getColor(x int) string {
|
||||
rainbow := []string{
|
||||
"magenta",
|
||||
"red",
|
||||
"yellow",
|
||||
"green",
|
||||
"cyan",
|
||||
"blue",
|
||||
}
|
||||
|
||||
ix := x % len(rainbow)
|
||||
|
|
|
|||
|
|
@ -125,14 +125,15 @@ func forkRun(opts *ForkOptions) error {
|
|||
|
||||
connectedToTerminal := opts.IO.IsStdoutTTY() && opts.IO.IsStderrTTY() && opts.IO.IsStdinTTY()
|
||||
|
||||
cs := opts.IO.ColorScheme()
|
||||
stderr := opts.IO.ErrOut
|
||||
s := utils.Spinner(stderr)
|
||||
stopSpinner := func() {}
|
||||
|
||||
if connectedToTerminal {
|
||||
loading := utils.Gray("Forking ") + utils.Bold(utils.Gray(ghrepo.FullName(repoToFork))) + utils.Gray("...")
|
||||
loading := cs.Gray("Forking ") + cs.Bold(cs.Gray(ghrepo.FullName(repoToFork))) + cs.Gray("...")
|
||||
s.Suffix = " " + loading
|
||||
s.FinalMSG = utils.Gray(fmt.Sprintf("- %s\n", loading))
|
||||
s.FinalMSG = cs.Gray(fmt.Sprintf("- %s\n", loading))
|
||||
utils.StartSpinner(s)
|
||||
stopSpinner = func() {
|
||||
utils.StopSpinner(s)
|
||||
|
|
@ -163,8 +164,8 @@ func forkRun(opts *ForkOptions) error {
|
|||
if createdAgo > time.Minute {
|
||||
if connectedToTerminal {
|
||||
fmt.Fprintf(stderr, "%s %s %s\n",
|
||||
utils.Yellow("!"),
|
||||
utils.Bold(ghrepo.FullName(forkedRepo)),
|
||||
cs.Yellow("!"),
|
||||
cs.Bold(ghrepo.FullName(forkedRepo)),
|
||||
"already exists")
|
||||
} else {
|
||||
fmt.Fprintf(stderr, "%s already exists", ghrepo.FullName(forkedRepo))
|
||||
|
|
@ -172,7 +173,7 @@ func forkRun(opts *ForkOptions) error {
|
|||
}
|
||||
} else {
|
||||
if connectedToTerminal {
|
||||
fmt.Fprintf(stderr, "%s Created fork %s\n", utils.GreenCheck(), utils.Bold(ghrepo.FullName(forkedRepo)))
|
||||
fmt.Fprintf(stderr, "%s Created fork %s\n", cs.SuccessIcon(), cs.Bold(ghrepo.FullName(forkedRepo)))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -196,7 +197,7 @@ func forkRun(opts *ForkOptions) error {
|
|||
}
|
||||
if remote, err := remotes.FindByRepo(forkedRepo.RepoOwner(), forkedRepo.RepoName()); err == nil {
|
||||
if connectedToTerminal {
|
||||
fmt.Fprintf(stderr, "%s Using existing remote %s\n", utils.GreenCheck(), utils.Bold(remote.Name))
|
||||
fmt.Fprintf(stderr, "%s Using existing remote %s\n", cs.SuccessIcon(), cs.Bold(remote.Name))
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
|
@ -223,7 +224,7 @@ func forkRun(opts *ForkOptions) error {
|
|||
return err
|
||||
}
|
||||
if connectedToTerminal {
|
||||
fmt.Fprintf(stderr, "%s Renamed %s remote to %s\n", utils.GreenCheck(), utils.Bold(remoteName), utils.Bold(renameTarget))
|
||||
fmt.Fprintf(stderr, "%s Renamed %s remote to %s\n", cs.SuccessIcon(), cs.Bold(remoteName), cs.Bold(renameTarget))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -235,7 +236,7 @@ func forkRun(opts *ForkOptions) error {
|
|||
}
|
||||
|
||||
if connectedToTerminal {
|
||||
fmt.Fprintf(stderr, "%s Added remote %s\n", utils.GreenCheck(), utils.Bold(remoteName))
|
||||
fmt.Fprintf(stderr, "%s Added remote %s\n", cs.SuccessIcon(), cs.Bold(remoteName))
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
|
@ -260,7 +261,7 @@ func forkRun(opts *ForkOptions) error {
|
|||
}
|
||||
|
||||
if connectedToTerminal {
|
||||
fmt.Fprintf(stderr, "%s Cloned fork\n", utils.GreenCheck())
|
||||
fmt.Fprintf(stderr, "%s Cloned fork\n", cs.SuccessIcon())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -122,6 +122,7 @@ func NewCmdGarden(f *cmdutil.Factory, runF func(*GardenOptions) error) *cobra.Co
|
|||
}
|
||||
|
||||
func gardenRun(opts *GardenOptions) error {
|
||||
cs := opts.IO.ColorScheme()
|
||||
out := opts.IO.Out
|
||||
|
||||
if runtime.GOOS == "windows" {
|
||||
|
|
@ -201,7 +202,7 @@ func gardenRun(opts *GardenOptions) error {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
player := &Player{0, 0, utils.Bold("@"), geo, 0}
|
||||
player := &Player{0, 0, cs.Bold("@"), geo, 0}
|
||||
|
||||
garden := plantGarden(commits, geo)
|
||||
if len(garden) < geo.Height {
|
||||
|
|
@ -213,7 +214,7 @@ func gardenRun(opts *GardenOptions) error {
|
|||
geo.Width = 0
|
||||
}
|
||||
clear(opts.IO)
|
||||
drawGarden(out, garden, player)
|
||||
drawGarden(cs, out, garden, player)
|
||||
|
||||
// thanks stackoverflow https://stackoverflow.com/a/17278776
|
||||
_ = exec.Command("stty", sttyFileArg, "/dev/tty", "cbreak", "min", "1").Run()
|
||||
|
|
@ -224,7 +225,7 @@ func gardenRun(opts *GardenOptions) error {
|
|||
fmt.Fprint(out, "\033[?25h")
|
||||
_ = exec.Command("stty", sttyFileArg, "/dev/tty", strings.TrimSpace(string(oldTTYSettings))).Run()
|
||||
fmt.Fprintln(out)
|
||||
fmt.Fprintln(out, utils.Bold("You turn and walk away from the wildflower garden..."))
|
||||
fmt.Fprintln(out, cs.Bold("You turn and walk away from the wildflower garden..."))
|
||||
}
|
||||
|
||||
c := make(chan os.Signal)
|
||||
|
|
@ -312,7 +313,7 @@ func gardenRun(opts *GardenOptions) error {
|
|||
fmt.Fprintln(out)
|
||||
fmt.Fprintln(out)
|
||||
|
||||
fmt.Fprint(out, utils.Bold(sl))
|
||||
fmt.Fprint(out, cs.Bold(sl))
|
||||
}
|
||||
|
||||
walkAway()
|
||||
|
|
@ -423,7 +424,7 @@ func plantGarden(commits []*Commit, geo *Geometry) [][]*Cell {
|
|||
return garden
|
||||
}
|
||||
|
||||
func drawGarden(out io.Writer, garden [][]*Cell, player *Player) {
|
||||
func drawGarden(cs *iostreams.ColorScheme, out io.Writer, garden [][]*Cell, player *Player) {
|
||||
fmt.Fprint(out, "\033[?25l") // hide cursor. it needs to be restored at command exit.
|
||||
sl := ""
|
||||
for y, gardenRow := range garden {
|
||||
|
|
@ -432,7 +433,7 @@ func drawGarden(out io.Writer, garden [][]*Cell, player *Player) {
|
|||
underPlayer := (player.X == x && player.Y == y)
|
||||
if underPlayer {
|
||||
sl = gardenCell.StatusLine
|
||||
char = utils.Bold(player.Char)
|
||||
char = cs.Bold(player.Char)
|
||||
|
||||
if strings.Contains(gardenCell.StatusLine, "stream") {
|
||||
player.ShoeMoistureContent = 5
|
||||
|
|
@ -447,7 +448,7 @@ func drawGarden(out io.Writer, garden [][]*Cell, player *Player) {
|
|||
}
|
||||
|
||||
fmt.Println()
|
||||
fmt.Fprintln(out, utils.Bold(sl))
|
||||
fmt.Fprintln(out, cs.Bold(sl))
|
||||
}
|
||||
|
||||
func statusLine(garden [][]*Cell, player *Player) string {
|
||||
|
|
|
|||
|
|
@ -151,9 +151,11 @@ func viewRun(opts *ViewOptions) error {
|
|||
return err
|
||||
}
|
||||
|
||||
cs := opts.IO.ColorScheme()
|
||||
|
||||
var readmeContent string
|
||||
if readme == nil {
|
||||
readmeContent = utils.Gray("This repository does not have a README")
|
||||
readmeContent = cs.Gray("This repository does not have a README")
|
||||
} else if isMarkdownFile(readme.Filename) {
|
||||
var err error
|
||||
style := markdown.GetStyle(opts.IO.TerminalTheme())
|
||||
|
|
@ -168,7 +170,7 @@ func viewRun(opts *ViewOptions) error {
|
|||
|
||||
description := repo.Description
|
||||
if description == "" {
|
||||
description = utils.Gray("No description provided")
|
||||
description = cs.Gray("No description provided")
|
||||
}
|
||||
|
||||
repoData := struct {
|
||||
|
|
@ -177,10 +179,10 @@ func viewRun(opts *ViewOptions) error {
|
|||
Readme string
|
||||
View string
|
||||
}{
|
||||
FullName: utils.Bold(fullName),
|
||||
FullName: cs.Bold(fullName),
|
||||
Description: description,
|
||||
Readme: readmeContent,
|
||||
View: utils.Gray(fmt.Sprintf("View this repository on GitHub: %s", openURL)),
|
||||
View: cs.Gray(fmt.Sprintf("View this repository on GitHub: %s", openURL)),
|
||||
}
|
||||
|
||||
err = tmpl.Execute(stdout, repoData)
|
||||
|
|
|
|||
|
|
@ -6,8 +6,8 @@ import (
|
|||
"strings"
|
||||
|
||||
"github.com/cli/cli/pkg/cmdutil"
|
||||
"github.com/cli/cli/pkg/iostreams"
|
||||
"github.com/cli/cli/pkg/text"
|
||||
"github.com/cli/cli/utils"
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/spf13/pflag"
|
||||
)
|
||||
|
|
@ -80,7 +80,7 @@ func isRootCmd(command *cobra.Command) bool {
|
|||
return command != nil && !command.HasParent()
|
||||
}
|
||||
|
||||
func rootHelpFunc(command *cobra.Command, args []string) {
|
||||
func rootHelpFunc(cs *iostreams.ColorScheme, command *cobra.Command, args []string) {
|
||||
if isRootCmd(command.Parent()) && len(args) >= 2 && args[1] != "--help" && args[1] != "-h" {
|
||||
nestedSuggestFunc(command, args[1])
|
||||
hasFailed = true
|
||||
|
|
@ -158,7 +158,7 @@ Read the manual at https://cli.github.com/manual`})
|
|||
for _, e := range helpEntries {
|
||||
if e.Title != "" {
|
||||
// If there is a title, add indentation to each line in the body
|
||||
fmt.Fprintln(out, utils.Bold(e.Title))
|
||||
fmt.Fprintln(out, cs.Bold(e.Title))
|
||||
fmt.Fprintln(out, text.Indent(strings.Trim(e.Body, "\r\n"), " "))
|
||||
} else {
|
||||
// If there is no title print the body as is
|
||||
|
|
|
|||
|
|
@ -50,8 +50,14 @@ func NewCmdRoot(f *cmdutil.Factory, version, buildDate string) *cobra.Command {
|
|||
cmd.SetOut(f.IOStreams.Out)
|
||||
cmd.SetErr(f.IOStreams.ErrOut)
|
||||
|
||||
cs := f.IOStreams.ColorScheme()
|
||||
|
||||
helpHelper := func(command *cobra.Command, args []string) {
|
||||
rootHelpFunc(cs, command, args)
|
||||
}
|
||||
|
||||
cmd.PersistentFlags().Bool("help", false, "Show help for command")
|
||||
cmd.SetHelpFunc(rootHelpFunc)
|
||||
cmd.SetHelpFunc(helpHelper)
|
||||
cmd.SetUsageFunc(rootUsageFunc)
|
||||
cmd.SetFlagErrorFunc(rootFlagErrrorFunc)
|
||||
|
||||
|
|
|
|||
|
|
@ -121,3 +121,32 @@ func (c *ColorScheme) SuccessIcon() string {
|
|||
func (c *ColorScheme) WarningIcon() string {
|
||||
return c.Yellow("!")
|
||||
}
|
||||
|
||||
func (c *ColorScheme) ColorFromString(s string) func(string) string {
|
||||
s = strings.ToLower(s)
|
||||
var fn func(string) string
|
||||
switch s {
|
||||
case "bold":
|
||||
fn = c.Bold
|
||||
case "red":
|
||||
fn = c.Red
|
||||
case "yellow":
|
||||
fn = c.Yellow
|
||||
case "green":
|
||||
fn = c.Green
|
||||
case "gray":
|
||||
fn = c.Gray
|
||||
case "magenta":
|
||||
fn = c.Magenta
|
||||
case "cyan":
|
||||
fn = c.Cyan
|
||||
case "blue":
|
||||
fn = c.Blue
|
||||
default:
|
||||
fn = func(s string) string {
|
||||
return s
|
||||
}
|
||||
}
|
||||
|
||||
return fn
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,57 +0,0 @@
|
|||
package utils
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
|
||||
"github.com/cli/cli/pkg/iostreams"
|
||||
"github.com/mattn/go-colorable"
|
||||
"github.com/mgutz/ansi"
|
||||
)
|
||||
|
||||
var (
|
||||
// Outputs ANSI color if stdout is a tty
|
||||
Magenta = makeColorFunc("magenta")
|
||||
Cyan = makeColorFunc("cyan")
|
||||
Red = makeColorFunc("red")
|
||||
Yellow = makeColorFunc("yellow")
|
||||
Blue = makeColorFunc("blue")
|
||||
Green = makeColorFunc("green")
|
||||
Gray = makeColorFunc("black+h")
|
||||
Bold = makeColorFunc("default+b")
|
||||
)
|
||||
|
||||
// NewColorable returns an output stream that handles ANSI color sequences on Windows
|
||||
func NewColorable(w io.Writer) io.Writer {
|
||||
if f, isFile := w.(*os.File); isFile {
|
||||
return colorable.NewColorable(f)
|
||||
}
|
||||
return w
|
||||
}
|
||||
|
||||
func makeColorFunc(color string) func(string) string {
|
||||
cf := ansi.ColorFunc(color)
|
||||
return func(arg string) string {
|
||||
if isColorEnabled() {
|
||||
if color == "black+h" && iostreams.Is256ColorSupported() {
|
||||
return fmt.Sprintf("\x1b[%d;5;%dm%s\x1b[m", 38, 242, arg)
|
||||
}
|
||||
return cf(arg)
|
||||
}
|
||||
return arg
|
||||
}
|
||||
}
|
||||
|
||||
func isColorEnabled() bool {
|
||||
if iostreams.EnvColorForced() {
|
||||
return true
|
||||
}
|
||||
|
||||
if iostreams.EnvColorDisabled() {
|
||||
return false
|
||||
}
|
||||
|
||||
// TODO ignores cmd.OutOrStdout
|
||||
return IsTerminal(os.Stdout)
|
||||
}
|
||||
|
|
@ -97,15 +97,3 @@ func DisplayURL(urlStr string) string {
|
|||
}
|
||||
return u.Hostname() + u.Path
|
||||
}
|
||||
|
||||
func GreenCheck() string {
|
||||
return Green("✓")
|
||||
}
|
||||
|
||||
func YellowDash() string {
|
||||
return Yellow("-")
|
||||
}
|
||||
|
||||
func RedX() string {
|
||||
return Red("X")
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue