fix(cli): speed up CLI over SSH (#7885)

By caching the terminal's color profile, we avoid myriad round trips during command execution.
This commit is contained in:
Ammar Bandukwala 2023-06-07 00:22:58 -05:00 committed by GitHub
parent 1288a83e42
commit 5eaf809851
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
46 changed files with 190 additions and 172 deletions

View File

@ -179,7 +179,7 @@ type message struct {
func waitingMessage(agent codersdk.WorkspaceAgent, opts AgentOptions) (m *message) {
m = &message{
Spin: fmt.Sprintf("Waiting for connection from %s...", Styles.Field.Render(agent.Name)),
Spin: fmt.Sprintf("Waiting for connection from %s...", DefaultStyles.Field.Render(agent.Name)),
Prompt: "Don't panic, your workspace is booting up!",
}
defer func() {
@ -192,7 +192,7 @@ func waitingMessage(agent codersdk.WorkspaceAgent, opts AgentOptions) (m *messag
// We don't want to wrap the troubleshooting URL, so we'll handle word
// wrapping ourselves (vs using lipgloss).
w := wordwrap.NewWriter(Styles.Paragraph.GetWidth() - Styles.Paragraph.GetMarginLeft()*2)
w := wordwrap.NewWriter(DefaultStyles.Paragraph.GetWidth() - DefaultStyles.Paragraph.GetMarginLeft()*2)
w.Breakpoints = []rune{' ', '\n'}
_, _ = fmt.Fprint(w, m.Prompt)
@ -208,7 +208,7 @@ func waitingMessage(agent codersdk.WorkspaceAgent, opts AgentOptions) (m *messag
// We want to prefix the prompt with a caret, but we want text on the
// following lines to align with the text on the first line (i.e. added
// spacing).
ind := " " + Styles.Prompt.String()
ind := " " + DefaultStyles.Prompt.String()
iw := indent.NewWriter(1, func(w io.Writer) {
_, _ = w.Write([]byte(ind))
ind = " " // Set indentation to space after initial prompt.
@ -223,7 +223,7 @@ func waitingMessage(agent codersdk.WorkspaceAgent, opts AgentOptions) (m *messag
case codersdk.WorkspaceAgentDisconnected:
m.Prompt = "The workspace agent lost connection!"
case codersdk.WorkspaceAgentConnected:
m.Spin = fmt.Sprintf("Waiting for %s to become ready...", Styles.Field.Render(agent.Name))
m.Spin = fmt.Sprintf("Waiting for %s to become ready...", DefaultStyles.Field.Render(agent.Name))
m.Prompt = "Don't panic, your workspace agent has connected and the workspace is getting ready!"
if opts.NoWait {
m.Prompt = "Your workspace is still getting ready, it may be in an incomplete state."

View File

@ -1,27 +1,20 @@
package cliui
import (
"os"
"github.com/charmbracelet/charm/ui/common"
"github.com/charmbracelet/lipgloss"
"github.com/muesli/termenv"
"golang.org/x/xerrors"
)
var (
Canceled = xerrors.New("canceled")
var Canceled = xerrors.New("canceled")
defaultStyles = common.DefaultStyles()
)
// DefaultStyles compose visual elements of the UI.
var DefaultStyles Styles
// ValidateNotEmpty is a helper function to disallow empty inputs!
func ValidateNotEmpty(s string) error {
if s == "" {
return xerrors.New("Must be provided!")
}
return nil
}
// Styles compose visual elements of the UI!
var Styles = struct {
type Styles struct {
Bold,
Checkmark,
Code,
@ -38,23 +31,45 @@ var Styles = struct {
Logo,
Warn,
Wrap lipgloss.Style
}{
Bold: lipgloss.NewStyle().Bold(true),
Checkmark: defaultStyles.Checkmark,
Code: defaultStyles.Code,
Crossmark: defaultStyles.Error.Copy().SetString("✘"),
DateTimeStamp: defaultStyles.LabelDim,
Error: defaultStyles.Error,
Field: defaultStyles.Code.Copy().Foreground(lipgloss.AdaptiveColor{Light: "#000000", Dark: "#FFFFFF"}),
Keyword: defaultStyles.Keyword,
Paragraph: defaultStyles.Paragraph,
Placeholder: lipgloss.NewStyle().Foreground(lipgloss.AdaptiveColor{Light: "#585858", Dark: "#4d46b3"}),
Prompt: defaultStyles.Prompt.Copy().Foreground(lipgloss.AdaptiveColor{Light: "#9B9B9B", Dark: "#5C5C5C"}),
FocusedPrompt: defaultStyles.FocusedPrompt.Copy().Foreground(lipgloss.Color("#651fff")),
Fuchsia: defaultStyles.SelectedMenuItem.Copy(),
Logo: defaultStyles.Logo.Copy().SetString("Coder"),
Warn: lipgloss.NewStyle().Foreground(
lipgloss.AdaptiveColor{Light: "#04B575", Dark: "#ECFD65"},
),
Wrap: lipgloss.NewStyle().Width(80),
}
func init() {
lipgloss.SetDefaultRenderer(
lipgloss.NewRenderer(os.Stdout, termenv.WithColorCache(true)),
)
// All Styles are set after we change the DefaultRenderer so that the ColorCache
// is in effect, mitigating the severe performance issue seen here:
// https://github.com/coder/coder/issues/7884.
charmStyles := common.DefaultStyles()
DefaultStyles = Styles{
Bold: lipgloss.NewStyle().Bold(true),
Checkmark: charmStyles.Checkmark,
Code: charmStyles.Code,
Crossmark: charmStyles.Error.Copy().SetString("✘"),
DateTimeStamp: charmStyles.LabelDim,
Error: charmStyles.Error,
Field: charmStyles.Code.Copy().Foreground(lipgloss.AdaptiveColor{Light: "#000000", Dark: "#FFFFFF"}),
Keyword: charmStyles.Keyword,
Paragraph: charmStyles.Paragraph,
Placeholder: lipgloss.NewStyle().Foreground(lipgloss.AdaptiveColor{Light: "#585858", Dark: "#4d46b3"}),
Prompt: charmStyles.Prompt.Copy().Foreground(lipgloss.AdaptiveColor{Light: "#9B9B9B", Dark: "#5C5C5C"}),
FocusedPrompt: charmStyles.FocusedPrompt.Copy().Foreground(lipgloss.Color("#651fff")),
Fuchsia: charmStyles.SelectedMenuItem.Copy(),
Logo: charmStyles.Logo.Copy().SetString("Coder"),
Warn: lipgloss.NewStyle().Foreground(
lipgloss.AdaptiveColor{Light: "#04B575", Dark: "#ECFD65"},
),
Wrap: lipgloss.NewStyle().Width(80),
}
}
// ValidateNotEmpty is a helper function to disallow empty inputs!
func ValidateNotEmpty(s string) error {
if s == "" {
return xerrors.New("Must be provided!")
}
return nil
}

View File

@ -35,7 +35,7 @@ func (m cliMessage) String() string {
// Warn writes a log to the writer provided.
func Warn(wtr io.Writer, header string, lines ...string) {
_, _ = fmt.Fprint(wtr, cliMessage{
Style: Styles.Warn.Copy(),
Style: DefaultStyles.Warn.Copy(),
Prefix: "WARN: ",
Header: header,
Lines: lines,
@ -63,7 +63,7 @@ func Infof(wtr io.Writer, fmtStr string, args ...interface{}) {
// Error writes a log to the writer provided.
func Error(wtr io.Writer, header string, lines ...string) {
_, _ = fmt.Fprint(wtr, cliMessage{
Style: Styles.Error.Copy(),
Style: DefaultStyles.Error.Copy(),
Prefix: "ERROR: ",
Header: header,
Lines: lines,

View File

@ -15,7 +15,7 @@ func RichParameter(inv *clibase.Invocation, templateVersionParameter codersdk.Te
label = templateVersionParameter.DisplayName
}
_, _ = fmt.Fprintln(inv.Stdout, Styles.Bold.Render(label))
_, _ = fmt.Fprintln(inv.Stdout, DefaultStyles.Bold.Render(label))
if templateVersionParameter.DescriptionPlaintext != "" {
_, _ = fmt.Fprintln(inv.Stdout, " "+strings.TrimSpace(strings.Join(strings.Split(templateVersionParameter.DescriptionPlaintext, "\n"), "\n "))+"\n")
}
@ -40,7 +40,7 @@ func RichParameter(inv *clibase.Invocation, templateVersionParameter codersdk.Te
}
_, _ = fmt.Fprintln(inv.Stdout)
_, _ = fmt.Fprintln(inv.Stdout, " "+Styles.Prompt.String()+Styles.Field.Render(strings.Join(values, ", ")))
_, _ = fmt.Fprintln(inv.Stdout, " "+DefaultStyles.Prompt.String()+DefaultStyles.Field.Render(strings.Join(values, ", ")))
value = string(v)
}
} else if len(templateVersionParameter.Options) > 0 {
@ -54,7 +54,7 @@ func RichParameter(inv *clibase.Invocation, templateVersionParameter codersdk.Te
})
if err == nil {
_, _ = fmt.Fprintln(inv.Stdout)
_, _ = fmt.Fprintln(inv.Stdout, " "+Styles.Prompt.String()+Styles.Field.Render(richParameterOption.Name))
_, _ = fmt.Fprintln(inv.Stdout, " "+DefaultStyles.Prompt.String()+DefaultStyles.Field.Render(richParameterOption.Name))
value = richParameterOption.Value
}
} else {
@ -65,7 +65,7 @@ func RichParameter(inv *clibase.Invocation, templateVersionParameter codersdk.Te
text += ":"
value, err = Prompt(inv, PromptOptions{
Text: Styles.Bold.Render(text),
Text: DefaultStyles.Bold.Render(text),
Validate: func(value string) error {
return validateRichPrompt(value, templateVersionParameter)
},

View File

@ -55,21 +55,21 @@ func Prompt(inv *clibase.Invocation, opts PromptOptions) (string, error) {
}
}
_, _ = fmt.Fprint(inv.Stdout, Styles.FocusedPrompt.String()+opts.Text+" ")
_, _ = fmt.Fprint(inv.Stdout, DefaultStyles.FocusedPrompt.String()+opts.Text+" ")
if opts.IsConfirm {
if len(opts.Default) == 0 {
opts.Default = ConfirmYes
}
renderedYes := Styles.Placeholder.Render(ConfirmYes)
renderedNo := Styles.Placeholder.Render(ConfirmNo)
renderedYes := DefaultStyles.Placeholder.Render(ConfirmYes)
renderedNo := DefaultStyles.Placeholder.Render(ConfirmNo)
if opts.Default == ConfirmYes {
renderedYes = Styles.Bold.Render(ConfirmYes)
renderedYes = DefaultStyles.Bold.Render(ConfirmYes)
} else {
renderedNo = Styles.Bold.Render(ConfirmNo)
renderedNo = DefaultStyles.Bold.Render(ConfirmNo)
}
_, _ = fmt.Fprint(inv.Stdout, Styles.Placeholder.Render("("+renderedYes+Styles.Placeholder.Render("/"+renderedNo+Styles.Placeholder.Render(") "))))
_, _ = fmt.Fprint(inv.Stdout, DefaultStyles.Placeholder.Render("("+renderedYes+DefaultStyles.Placeholder.Render("/"+renderedNo+DefaultStyles.Placeholder.Render(") "))))
} else if opts.Default != "" {
_, _ = fmt.Fprint(inv.Stdout, Styles.Placeholder.Render("("+opts.Default+") "))
_, _ = fmt.Fprint(inv.Stdout, DefaultStyles.Placeholder.Render("("+opts.Default+") "))
}
interrupt := make(chan os.Signal, 1)
@ -126,7 +126,7 @@ func Prompt(inv *clibase.Invocation, opts PromptOptions) (string, error) {
if opts.Validate != nil {
err := opts.Validate(line)
if err != nil {
_, _ = fmt.Fprintln(inv.Stdout, defaultStyles.Error.Render(err.Error()))
_, _ = fmt.Fprintln(inv.Stdout, DefaultStyles.Error.Render(err.Error()))
return Prompt(inv, opts)
}
}

View File

@ -71,7 +71,7 @@ func ProvisionerJob(ctx context.Context, writer io.Writer, opts ProvisionerJobOp
)
printStage := func() {
_, _ = fmt.Fprintf(writer, Styles.Prompt.Render("⧗")+"%s\n", Styles.Field.Render(currentStage))
_, _ = fmt.Fprintf(writer, DefaultStyles.Prompt.Render("⧗")+"%s\n", DefaultStyles.Field.Render(currentStage))
}
updateStage := func(stage string, startedAt time.Time) {
@ -80,11 +80,11 @@ func ProvisionerJob(ctx context.Context, writer io.Writer, opts ProvisionerJobOp
if !didLogBetweenStage {
prefix = "\033[1A\r"
}
mark := Styles.Checkmark
mark := DefaultStyles.Checkmark
if job.CompletedAt != nil && job.Status != codersdk.ProvisionerJobSucceeded {
mark = Styles.Crossmark
mark = DefaultStyles.Crossmark
}
_, _ = fmt.Fprintf(writer, prefix+mark.String()+Styles.Placeholder.Render(" %s [%dms]")+"\n", currentStage, startedAt.Sub(currentStageStartedAt).Milliseconds())
_, _ = fmt.Fprintf(writer, prefix+mark.String()+DefaultStyles.Placeholder.Render(" %s [%dms]")+"\n", currentStage, startedAt.Sub(currentStageStartedAt).Milliseconds())
}
if stage == "" {
return
@ -129,7 +129,7 @@ func ProvisionerJob(ctx context.Context, writer io.Writer, opts ProvisionerJobOp
return
}
}
_, _ = fmt.Fprintf(writer, "\033[2K\r\n"+Styles.FocusedPrompt.String()+Styles.Bold.Render("Gracefully canceling...")+"\n\n")
_, _ = fmt.Fprintf(writer, "\033[2K\r\n"+DefaultStyles.FocusedPrompt.String()+DefaultStyles.Bold.Render("Gracefully canceling...")+"\n\n")
err := opts.Cancel()
if err != nil {
errChan <- xerrors.Errorf("cancel: %w", err)
@ -207,11 +207,11 @@ func ProvisionerJob(ctx context.Context, writer io.Writer, opts ProvisionerJobOp
if !opts.Verbose {
continue
}
output = Styles.Placeholder.Render(log.Output)
output = DefaultStyles.Placeholder.Render(log.Output)
case codersdk.LogLevelError:
output = defaultStyles.Error.Render(log.Output)
output = DefaultStyles.Error.Render(log.Output)
case codersdk.LogLevelWarn:
output = Styles.Warn.Render(log.Output)
output = DefaultStyles.Warn.Render(log.Output)
case codersdk.LogLevelInfo:
output = log.Output
}
@ -222,7 +222,7 @@ func ProvisionerJob(ctx context.Context, writer io.Writer, opts ProvisionerJobOp
jobMutex.Unlock()
continue
}
_, _ = fmt.Fprintf(logOutput, "%s %s\n", Styles.Placeholder.Render(" "), output)
_, _ = fmt.Fprintf(logOutput, "%s %s\n", DefaultStyles.Placeholder.Render(" "), output)
if !opts.Silent {
didLogBetweenStage = true
}

View File

@ -78,7 +78,7 @@ func WorkspaceResources(writer io.Writer, resources []codersdk.WorkspaceResource
// Display a line for the resource.
tableWriter.AppendRow(table.Row{
Styles.Bold.Render(resourceAddress),
DefaultStyles.Bold.Render(resourceAddress),
"",
"",
})
@ -106,7 +106,7 @@ func WorkspaceResources(writer io.Writer, resources []codersdk.WorkspaceResource
if totalAgents > 1 {
sshCommand += "." + agent.Name
}
sshCommand = Styles.Code.Render(sshCommand)
sshCommand = DefaultStyles.Code.Render(sshCommand)
row = append(row, sshCommand)
}
tableWriter.AppendRow(row)
@ -121,23 +121,23 @@ func renderAgentStatus(agent codersdk.WorkspaceAgent) string {
switch agent.Status {
case codersdk.WorkspaceAgentConnecting:
since := database.Now().Sub(agent.CreatedAt)
return Styles.Warn.Render("⦾ connecting") + " " +
Styles.Placeholder.Render("["+strconv.Itoa(int(since.Seconds()))+"s]")
return DefaultStyles.Warn.Render("⦾ connecting") + " " +
DefaultStyles.Placeholder.Render("["+strconv.Itoa(int(since.Seconds()))+"s]")
case codersdk.WorkspaceAgentDisconnected:
since := database.Now().Sub(*agent.DisconnectedAt)
return Styles.Error.Render("⦾ disconnected") + " " +
Styles.Placeholder.Render("["+strconv.Itoa(int(since.Seconds()))+"s]")
return DefaultStyles.Error.Render("⦾ disconnected") + " " +
DefaultStyles.Placeholder.Render("["+strconv.Itoa(int(since.Seconds()))+"s]")
case codersdk.WorkspaceAgentTimeout:
since := database.Now().Sub(agent.CreatedAt)
return fmt.Sprintf(
"%s %s",
Styles.Warn.Render("⦾ timeout"),
Styles.Placeholder.Render("["+strconv.Itoa(int(since.Seconds()))+"s]"),
DefaultStyles.Warn.Render("⦾ timeout"),
DefaultStyles.Placeholder.Render("["+strconv.Itoa(int(since.Seconds()))+"s]"),
)
case codersdk.WorkspaceAgentConnected:
return Styles.Keyword.Render("⦿ connected")
return DefaultStyles.Keyword.Render("⦿ connected")
default:
return Styles.Warn.Render("○ unknown")
return DefaultStyles.Warn.Render("○ unknown")
}
}
@ -146,11 +146,11 @@ func renderAgentVersion(agentVersion, serverVersion string) string {
agentVersion = "(unknown)"
}
if !semver.IsValid(serverVersion) || !semver.IsValid(agentVersion) {
return Styles.Placeholder.Render(agentVersion)
return DefaultStyles.Placeholder.Render(agentVersion)
}
outdated := semver.Compare(agentVersion, serverVersion) < 0
if outdated {
return Styles.Warn.Render(agentVersion + " (outdated)")
return DefaultStyles.Warn.Render(agentVersion + " (outdated)")
}
return Styles.Keyword.Render(agentVersion)
return DefaultStyles.Keyword.Render(agentVersion)
}

View File

@ -63,7 +63,7 @@ func (r *RootCmd) create() *clibase.Cmd {
var template codersdk.Template
if templateName == "" {
_, _ = fmt.Fprintln(inv.Stdout, cliui.Styles.Wrap.Render("Select a template below to preview the provisioned infrastructure:"))
_, _ = fmt.Fprintln(inv.Stdout, cliui.DefaultStyles.Wrap.Render("Select a template below to preview the provisioned infrastructure:"))
templates, err := client.TemplatesByOrganization(inv.Context(), organization.ID)
if err != nil {
@ -81,7 +81,7 @@ func (r *RootCmd) create() *clibase.Cmd {
templateName := template.Name
if template.ActiveUserCount > 0 {
templateName += cliui.Styles.Placeholder.Render(
templateName += cliui.DefaultStyles.Placeholder.Render(
fmt.Sprintf(
" (used by %s)",
formatActiveDevelopers(template.ActiveUserCount),
@ -159,7 +159,7 @@ func (r *RootCmd) create() *clibase.Cmd {
return xerrors.Errorf("watch build: %w", err)
}
_, _ = fmt.Fprintf(inv.Stdout, "\nThe %s workspace has been created at %s!\n", cliui.Styles.Keyword.Render(workspace.Name), cliui.Styles.DateTimeStamp.Render(time.Now().Format(time.Stamp)))
_, _ = fmt.Fprintf(inv.Stdout, "\nThe %s workspace has been created at %s!\n", cliui.DefaultStyles.Keyword.Render(workspace.Name), cliui.DefaultStyles.DateTimeStamp.Render(time.Now().Format(time.Stamp)))
return nil
},
}
@ -230,7 +230,7 @@ func prepWorkspaceBuild(inv *clibase.Invocation, client *codersdk.Client, args p
useParamFile := false
if args.RichParameterFile != "" {
useParamFile = true
_, _ = fmt.Fprintln(inv.Stdout, cliui.Styles.Paragraph.Render("Attempting to read the variables from the rich parameter file.")+"\r\n")
_, _ = fmt.Fprintln(inv.Stdout, cliui.DefaultStyles.Paragraph.Render("Attempting to read the variables from the rich parameter file.")+"\r\n")
parameterMapFromFile, err = createParameterMapFromFile(args.RichParameterFile)
if err != nil {
return nil, err
@ -241,7 +241,7 @@ func prepWorkspaceBuild(inv *clibase.Invocation, client *codersdk.Client, args p
PromptRichParamLoop:
for _, templateVersionParameter := range templateVersionParameters {
if !disclaimerPrinted {
_, _ = fmt.Fprintln(inv.Stdout, cliui.Styles.Paragraph.Render("This template has customizable parameters. Values can be changed after create, but may have unintended side effects (like data loss).")+"\r\n")
_, _ = fmt.Fprintln(inv.Stdout, cliui.DefaultStyles.Paragraph.Render("This template has customizable parameters. Values can be changed after create, but may have unintended side effects (like data loss).")+"\r\n")
disclaimerPrinted = true
}
@ -265,7 +265,7 @@ PromptRichParamLoop:
}
if exists {
_, _ = fmt.Fprintln(inv.Stdout, cliui.Styles.Warn.Render(fmt.Sprintf(`Parameter %q is not mutable, so can't be customized after workspace creation.`, templateVersionParameter.Name)))
_, _ = fmt.Fprintln(inv.Stdout, cliui.DefaultStyles.Warn.Render(fmt.Sprintf(`Parameter %q is not mutable, so can't be customized after workspace creation.`, templateVersionParameter.Name)))
continue
}
}

View File

@ -51,7 +51,7 @@ func (r *RootCmd) deleteWorkspace() *clibase.Cmd {
return err
}
_, _ = fmt.Fprintf(inv.Stdout, "\nThe %s workspace has been deleted at %s!\n", cliui.Styles.Keyword.Render(workspace.Name), cliui.Styles.DateTimeStamp.Render(time.Now().Format(time.Stamp)))
_, _ = fmt.Fprintf(inv.Stdout, "\nThe %s workspace has been deleted at %s!\n", cliui.DefaultStyles.Keyword.Render(workspace.Name), cliui.DefaultStyles.DateTimeStamp.Render(time.Now().Format(time.Stamp)))
return nil
},
}

View File

@ -137,7 +137,7 @@ func (r *RootCmd) dotfiles() *clibase.Cmd {
return err
}
// if the repo exists we soft fail the update operation and try to continue
_, _ = fmt.Fprintln(inv.Stdout, cliui.Styles.Error.Render("Failed to update repo, continuing..."))
_, _ = fmt.Fprintln(inv.Stdout, cliui.DefaultStyles.Error.Render("Failed to update repo, continuing..."))
}
// save git repo url so we can detect changes next time

View File

@ -90,12 +90,12 @@ func (r *RootCmd) gitssh() *clibase.Cmd {
exitErr := &exec.ExitError{}
if xerrors.As(err, &exitErr) && exitErr.ExitCode() == 255 {
_, _ = fmt.Fprintln(inv.Stderr,
"\n"+cliui.Styles.Wrap.Render("Coder authenticates with "+cliui.Styles.Field.Render("git")+
"\n"+cliui.DefaultStyles.Wrap.Render("Coder authenticates with "+cliui.DefaultStyles.Field.Render("git")+
" using the public key below. All clones with SSH are authenticated automatically 🪄.")+"\n")
_, _ = fmt.Fprintln(inv.Stderr, cliui.Styles.Code.Render(strings.TrimSpace(key.PublicKey))+"\n")
_, _ = fmt.Fprintln(inv.Stderr, cliui.DefaultStyles.Code.Render(strings.TrimSpace(key.PublicKey))+"\n")
_, _ = fmt.Fprintln(inv.Stderr, "Add to GitHub and GitLab:")
_, _ = fmt.Fprintln(inv.Stderr, cliui.Styles.Prompt.String()+"https://github.com/settings/ssh/new")
_, _ = fmt.Fprintln(inv.Stderr, cliui.Styles.Prompt.String()+"https://gitlab.com/-/profile/keys")
_, _ = fmt.Fprintln(inv.Stderr, cliui.DefaultStyles.Prompt.String()+"https://github.com/settings/ssh/new")
_, _ = fmt.Fprintln(inv.Stderr, cliui.DefaultStyles.Prompt.String()+"https://gitlab.com/-/profile/keys")
_, _ = fmt.Fprintln(inv.Stderr)
return err
}

View File

@ -127,7 +127,7 @@ var usageTemplate = template.Must(
return opt.Flag
},
"prettyHeader": func(s string) string {
return cliui.Styles.Bold.Render(s)
return cliui.DefaultStyles.Bold.Render(s)
},
"isEnterprise": func(opt clibase.Option) bool {
return opt.Annotations.IsSet("enterprise")

View File

@ -98,9 +98,9 @@ func (r *RootCmd) list() *clibase.Cmd {
return err
}
if len(res.Workspaces) == 0 {
_, _ = fmt.Fprintln(inv.Stderr, cliui.Styles.Prompt.String()+"No workspaces found! Create one:")
_, _ = fmt.Fprintln(inv.Stderr, cliui.DefaultStyles.Prompt.String()+"No workspaces found! Create one:")
_, _ = fmt.Fprintln(inv.Stderr)
_, _ = fmt.Fprintln(inv.Stderr, " "+cliui.Styles.Code.Render("coder create <name>"))
_, _ = fmt.Fprintln(inv.Stderr, " "+cliui.DefaultStyles.Code.Render("coder create <name>"))
_, _ = fmt.Fprintln(inv.Stderr)
return nil
}

View File

@ -86,7 +86,7 @@ func (r *RootCmd) login() *clibase.Cmd {
if err != nil {
// Checking versions isn't a fatal error so we print a warning
// and proceed.
_, _ = fmt.Fprintln(inv.Stderr, cliui.Styles.Warn.Render(err.Error()))
_, _ = fmt.Fprintln(inv.Stderr, cliui.DefaultStyles.Warn.Render(err.Error()))
}
hasInitialUser, err := client.HasFirstUser(inv.Context())
@ -116,7 +116,7 @@ func (r *RootCmd) login() *clibase.Cmd {
return xerrors.Errorf("get current user: %w", err)
}
username, err = cliui.Prompt(inv, cliui.PromptOptions{
Text: "What " + cliui.Styles.Field.Render("username") + " would you like?",
Text: "What " + cliui.DefaultStyles.Field.Render("username") + " would you like?",
Default: currentUser.Username,
})
if errors.Is(err, cliui.Canceled) {
@ -129,7 +129,7 @@ func (r *RootCmd) login() *clibase.Cmd {
if email == "" {
email, err = cliui.Prompt(inv, cliui.PromptOptions{
Text: "What's your " + cliui.Styles.Field.Render("email") + "?",
Text: "What's your " + cliui.DefaultStyles.Field.Render("email") + "?",
Validate: func(s string) error {
err := validator.New().Var(s, "email")
if err != nil {
@ -148,7 +148,7 @@ func (r *RootCmd) login() *clibase.Cmd {
for !matching {
password, err = cliui.Prompt(inv, cliui.PromptOptions{
Text: "Enter a " + cliui.Styles.Field.Render("password") + ":",
Text: "Enter a " + cliui.DefaultStyles.Field.Render("password") + ":",
Secret: true,
Validate: func(s string) error {
return userpassword.Validate(s)
@ -158,7 +158,7 @@ func (r *RootCmd) login() *clibase.Cmd {
return xerrors.Errorf("specify password prompt: %w", err)
}
confirm, err := cliui.Prompt(inv, cliui.PromptOptions{
Text: "Confirm " + cliui.Styles.Field.Render("password") + ":",
Text: "Confirm " + cliui.DefaultStyles.Field.Render("password") + ":",
Secret: true,
Validate: cliui.ValidateNotEmpty,
})
@ -168,7 +168,7 @@ func (r *RootCmd) login() *clibase.Cmd {
matching = confirm == password
if !matching {
_, _ = fmt.Fprintln(inv.Stdout, cliui.Styles.Error.Render("Passwords do not match"))
_, _ = fmt.Fprintln(inv.Stdout, cliui.DefaultStyles.Error.Render("Passwords do not match"))
}
}
}
@ -211,10 +211,10 @@ func (r *RootCmd) login() *clibase.Cmd {
}
_, _ = fmt.Fprintf(inv.Stdout,
cliui.Styles.Paragraph.Render(fmt.Sprintf("Welcome to Coder, %s! You're authenticated.", cliui.Styles.Keyword.Render(username)))+"\n")
cliui.DefaultStyles.Paragraph.Render(fmt.Sprintf("Welcome to Coder, %s! You're authenticated.", cliui.DefaultStyles.Keyword.Render(username)))+"\n")
_, _ = fmt.Fprintf(inv.Stdout,
cliui.Styles.Paragraph.Render("Get started by creating a template: "+cliui.Styles.Code.Render("coder templates init"))+"\n")
cliui.DefaultStyles.Paragraph.Render("Get started by creating a template: "+cliui.DefaultStyles.Code.Render("coder templates init"))+"\n")
return nil
}
@ -264,7 +264,7 @@ func (r *RootCmd) login() *clibase.Cmd {
return xerrors.Errorf("write server url: %w", err)
}
_, _ = fmt.Fprintf(inv.Stdout, Caret+"Welcome to Coder, %s! You're authenticated.\n", cliui.Styles.Keyword.Render(resp.Username))
_, _ = fmt.Fprintf(inv.Stdout, Caret+"Welcome to Coder, %s! You're authenticated.\n", cliui.DefaultStyles.Keyword.Render(resp.Username))
return nil
},
}

View File

@ -142,7 +142,7 @@ func TestLogin(t *testing.T) {
// Validate that we reprompt for matching passwords.
pty.ExpectMatch("Passwords do not match")
pty.ExpectMatch("Enter a " + cliui.Styles.Field.Render("password"))
pty.ExpectMatch("Enter a " + cliui.DefaultStyles.Field.Render("password"))
pty.WriteLine("SomeSecurePassword!")
pty.ExpectMatch("Confirm")

View File

@ -98,14 +98,14 @@ func (r *RootCmd) ping() *clibase.Cmd {
if p2p {
if !didP2p {
_, _ = fmt.Fprintln(inv.Stdout, "p2p connection established in",
cliui.Styles.DateTimeStamp.Render(time.Since(start).Round(time.Millisecond).String()),
cliui.DefaultStyles.DateTimeStamp.Render(time.Since(start).Round(time.Millisecond).String()),
)
}
didP2p = true
via = fmt.Sprintf("%s via %s",
cliui.Styles.Fuchsia.Render("p2p"),
cliui.Styles.Code.Render(pong.Endpoint),
cliui.DefaultStyles.Fuchsia.Render("p2p"),
cliui.DefaultStyles.Code.Render(pong.Endpoint),
)
} else {
derpName := "unknown"
@ -114,15 +114,15 @@ func (r *RootCmd) ping() *clibase.Cmd {
derpName = derpRegion.RegionName
}
via = fmt.Sprintf("%s via %s",
cliui.Styles.Fuchsia.Render("proxied"),
cliui.Styles.Code.Render(fmt.Sprintf("DERP(%s)", derpName)),
cliui.DefaultStyles.Fuchsia.Render("proxied"),
cliui.DefaultStyles.Code.Render(fmt.Sprintf("DERP(%s)", derpName)),
)
}
_, _ = fmt.Fprintf(inv.Stdout, "pong from %s %s in %s\n",
cliui.Styles.Keyword.Render(workspaceName),
cliui.DefaultStyles.Keyword.Render(workspaceName),
via,
cliui.Styles.DateTimeStamp.Render(dur.String()),
cliui.DefaultStyles.DateTimeStamp.Render(dur.String()),
)
if n == int(pingNum) {

View File

@ -44,13 +44,13 @@ func (r *RootCmd) publickey() *clibase.Cmd {
}
cliui.Infof(inv.Stdout,
"This is your public key for using "+cliui.Styles.Field.Render("git")+" in "+
"This is your public key for using "+cliui.DefaultStyles.Field.Render("git")+" in "+
"Coder. All clones with SSH will be authenticated automatically 🪄.\n\n",
)
cliui.Infof(inv.Stdout, cliui.Styles.Code.Render(strings.TrimSpace(key.PublicKey))+"\n\n")
cliui.Infof(inv.Stdout, cliui.DefaultStyles.Code.Render(strings.TrimSpace(key.PublicKey))+"\n\n")
cliui.Infof(inv.Stdout, "Add to GitHub and GitLab:"+"\n")
cliui.Infof(inv.Stdout, cliui.Styles.Prompt.String()+"https://github.com/settings/ssh/new"+"\n")
cliui.Infof(inv.Stdout, cliui.Styles.Prompt.String()+"https://gitlab.com/-/profile/keys"+"\n")
cliui.Infof(inv.Stdout, cliui.DefaultStyles.Prompt.String()+"https://github.com/settings/ssh/new"+"\n")
cliui.Infof(inv.Stdout, cliui.DefaultStyles.Prompt.String()+"https://gitlab.com/-/profile/keys"+"\n")
return nil
},

View File

@ -27,7 +27,7 @@ func (r *RootCmd) rename() *clibase.Cmd {
}
_, _ = fmt.Fprintf(inv.Stdout, "%s\n\n",
cliui.Styles.Wrap.Render("WARNING: A rename can result in data loss if a resource references the workspace name in the template (e.g volumes). Please backup any data before proceeding."),
cliui.DefaultStyles.Wrap.Render("WARNING: A rename can result in data loss if a resource references the workspace name in the template (e.g volumes). Please backup any data before proceeding."),
)
_, _ = fmt.Fprintf(inv.Stdout, "See: %s\n\n", "https://coder.com/docs/coder-oss/latest/templates/resource-persistence#%EF%B8%8F-persistence-pitfalls")
_, err = cliui.Prompt(inv, cliui.PromptOptions{

View File

@ -47,7 +47,7 @@ func (*RootCmd) resetPassword() *clibase.Cmd {
}
password, err := cliui.Prompt(inv, cliui.PromptOptions{
Text: "Enter new " + cliui.Styles.Field.Render("password") + ":",
Text: "Enter new " + cliui.DefaultStyles.Field.Render("password") + ":",
Secret: true,
Validate: func(s string) error {
return userpassword.Validate(s)
@ -57,7 +57,7 @@ func (*RootCmd) resetPassword() *clibase.Cmd {
return xerrors.Errorf("password prompt: %w", err)
}
confirmedPassword, err := cliui.Prompt(inv, cliui.PromptOptions{
Text: "Confirm " + cliui.Styles.Field.Render("password") + ":",
Text: "Confirm " + cliui.DefaultStyles.Field.Render("password") + ":",
Secret: true,
Validate: cliui.ValidateNotEmpty,
})
@ -81,7 +81,7 @@ func (*RootCmd) resetPassword() *clibase.Cmd {
return xerrors.Errorf("updating password: %w", err)
}
_, _ = fmt.Fprintf(inv.Stdout, "\nPassword has been reset for user %s!\n", cliui.Styles.Keyword.Render(user.Username))
_, _ = fmt.Fprintf(inv.Stdout, "\nPassword has been reset for user %s!\n", cliui.DefaultStyles.Keyword.Render(user.Username))
return nil
},
}

View File

@ -61,7 +61,7 @@ func (r *RootCmd) restart() *clibase.Cmd {
return err
}
_, _ = fmt.Fprintf(out, "\nThe %s workspace has been restarted at %s!\n", cliui.Styles.Keyword.Render(workspace.Name), cliui.Styles.DateTimeStamp.Render(time.Now().Format(time.Stamp)))
_, _ = fmt.Fprintf(out, "\nThe %s workspace has been restarted at %s!\n", cliui.DefaultStyles.Keyword.Render(workspace.Name), cliui.DefaultStyles.DateTimeStamp.Render(time.Now().Format(time.Stamp)))
return nil
},
}

View File

@ -29,6 +29,7 @@ import (
"github.com/charmbracelet/lipgloss"
"github.com/gobwas/httphead"
"github.com/mattn/go-isatty"
"github.com/mitchellh/go-wordwrap"
"github.com/coder/coder/buildinfo"
"github.com/coder/coder/cli/clibase"
@ -42,7 +43,7 @@ import (
)
var (
Caret = cliui.Styles.Prompt.String()
Caret = cliui.DefaultStyles.Prompt.String()
// Applied as annotations to workspace commands
// so they display in a separated "help" section.
@ -538,14 +539,14 @@ func (r *RootCmd) InitClient(client *codersdk.Client) clibase.MiddlewareFunc {
// Just log the error here. We never want to fail a command
// due to a pre-run.
_, _ = fmt.Fprintf(inv.Stderr,
cliui.Styles.Warn.Render("check versions error: %s"), err)
cliui.DefaultStyles.Warn.Render("check versions error: %s"), err)
_, _ = fmt.Fprintln(inv.Stderr)
}
if err = <-warningErr; err != nil {
// Same as above
_, _ = fmt.Fprintf(inv.Stderr,
cliui.Styles.Warn.Render("check entitlement warnings error: %s"), err)
cliui.DefaultStyles.Warn.Render("check entitlement warnings error: %s"), err)
_, _ = fmt.Fprintln(inv.Stderr)
}
@ -676,17 +677,20 @@ type example struct {
// formatExamples formats the examples as width wrapped bulletpoint
// descriptions with the command underneath.
func formatExamples(examples ...example) string {
wrap := cliui.Styles.Wrap.Copy()
wrap.PaddingLeft(4)
var sb strings.Builder
padStyle := cliui.DefaultStyles.Wrap.Copy().PaddingLeft(4)
for i, e := range examples {
if len(e.Description) > 0 {
_, _ = sb.WriteString(" - " + wrap.Render(e.Description + ":")[4:] + "\n\n ")
wordwrap.WrapString(e.Description, 80)
_, _ = sb.WriteString(
" - " + padStyle.Render(e.Description + ":")[4:] + "\n\n ",
)
}
// We add 1 space here because `cliui.Styles.Code` adds an extra
// space. This makes the code block align at an even 2 or 6
// spaces for symmetry.
_, _ = sb.WriteString(" " + cliui.Styles.Code.Render(fmt.Sprintf("$ %s", e.Command)))
_, _ = sb.WriteString(" " + cliui.DefaultStyles.Code.Render(fmt.Sprintf("$ %s", e.Command)))
if i < len(examples)-1 {
_, _ = sb.WriteString("\n\n")
}
@ -724,7 +728,7 @@ func (r *RootCmd) checkVersions(i *clibase.Invocation, client *codersdk.Client)
}
if !buildinfo.VersionsMatch(clientVersion, info.Version) {
warn := cliui.Styles.Warn.Copy().Align(lipgloss.Left)
warn := cliui.DefaultStyles.Warn.Copy().Align(lipgloss.Left)
_, _ = fmt.Fprintf(i.Stderr, warn.Render(fmtWarningText), clientVersion, info.Version, strings.TrimPrefix(info.CanonicalVersion(), "v"))
_, _ = fmt.Fprintln(i.Stderr)
}
@ -743,7 +747,7 @@ func (r *RootCmd) checkWarnings(i *clibase.Invocation, client *codersdk.Client)
entitlements, err := client.Entitlements(ctx)
if err == nil {
for _, w := range entitlements.Warnings {
_, _ = fmt.Fprintln(i.Stderr, cliui.Styles.Warn.Render(w))
_, _ = fmt.Fprintln(i.Stderr, cliui.DefaultStyles.Warn.Render(w))
}
}
return nil

View File

@ -361,7 +361,7 @@ func (r *RootCmd) Server(newAPI func(context.Context, *coderd.Options) (*coderd.
cliui.Warnf(
inv.Stderr,
"The access URL %s %s, this may cause unexpected problems when creating workspaces. Generate a unique *.try.coder.app URL by not specifying an access URL.\n",
cliui.Styles.Field.Render(cfg.AccessURL.String()), reason,
cliui.DefaultStyles.Field.Render(cfg.AccessURL.String()), reason,
)
}
@ -904,7 +904,7 @@ func (r *RootCmd) Server(newAPI func(context.Context, *coderd.Options) (*coderd.
select {
case <-notifyCtx.Done():
exitErr = notifyCtx.Err()
_, _ = fmt.Fprintln(inv.Stdout, cliui.Styles.Bold.Render(
_, _ = fmt.Fprintln(inv.Stdout, cliui.DefaultStyles.Bold.Render(
"Interrupt caught, gracefully exiting. Use ctrl+\\ to force quit",
))
case <-tunnelDone:
@ -1016,7 +1016,7 @@ func (r *RootCmd) Server(newAPI func(context.Context, *coderd.Options) (*coderd.
if pgRawURL {
_, _ = fmt.Fprintf(inv.Stdout, "%s\n", url)
} else {
_, _ = fmt.Fprintf(inv.Stdout, "%s\n", cliui.Styles.Code.Render(fmt.Sprintf("psql %q", url)))
_, _ = fmt.Fprintf(inv.Stdout, "%s\n", cliui.DefaultStyles.Code.Render(fmt.Sprintf("psql %q", url)))
}
return nil
},
@ -1046,7 +1046,7 @@ func (r *RootCmd) Server(newAPI func(context.Context, *coderd.Options) (*coderd.
if pgRawURL {
_, _ = fmt.Fprintf(inv.Stdout, "%s\n", url)
} else {
_, _ = fmt.Fprintf(inv.Stdout, "%s\n", cliui.Styles.Code.Render(fmt.Sprintf("psql %q", url)))
_, _ = fmt.Fprintf(inv.Stdout, "%s\n", cliui.DefaultStyles.Code.Render(fmt.Sprintf("psql %q", url)))
}
<-ctx.Done()
@ -1282,7 +1282,7 @@ func PrintLogo(inv *clibase.Invocation) {
return
}
_, _ = fmt.Fprintf(inv.Stdout, "%s - Your Self-Hosted Remote Development Platform\n", cliui.Styles.Bold.Render("Coder "+buildinfo.Version()))
_, _ = fmt.Fprintf(inv.Stdout, "%s - Your Self-Hosted Remote Development Platform\n", cliui.DefaultStyles.Bold.Render("Coder "+buildinfo.Version()))
}
func loadCertificates(tlsCertFiles, tlsKeyFiles []string) ([]tls.Certificate, error) {

View File

@ -39,7 +39,7 @@ func (r *RootCmd) start() *clibase.Cmd {
return err
}
_, _ = fmt.Fprintf(inv.Stdout, "\nThe %s workspace has been started at %s!\n", cliui.Styles.Keyword.Render(workspace.Name), cliui.Styles.DateTimeStamp.Render(time.Now().Format(time.Stamp)))
_, _ = fmt.Fprintf(inv.Stdout, "\nThe %s workspace has been started at %s!\n", cliui.DefaultStyles.Keyword.Render(workspace.Name), cliui.DefaultStyles.DateTimeStamp.Render(time.Now().Format(time.Stamp)))
return nil
},
}

View File

@ -47,7 +47,7 @@ func (r *RootCmd) stop() *clibase.Cmd {
return err
}
_, _ = fmt.Fprintf(inv.Stdout, "\nThe %s workspace has been stopped at %s!\n", cliui.Styles.Keyword.Render(workspace.Name), cliui.Styles.DateTimeStamp.Render(time.Now().Format(time.Stamp)))
_, _ = fmt.Fprintf(inv.Stdout, "\nThe %s workspace has been stopped at %s!\n", cliui.DefaultStyles.Keyword.Render(workspace.Name), cliui.DefaultStyles.DateTimeStamp.Render(time.Now().Format(time.Stamp)))
return nil
},
}

View File

@ -133,11 +133,11 @@ func (r *RootCmd) templateCreate() *clibase.Cmd {
return err
}
_, _ = fmt.Fprintln(inv.Stdout, "\n"+cliui.Styles.Wrap.Render(
"The "+cliui.Styles.Keyword.Render(templateName)+" template has been created at "+cliui.Styles.DateTimeStamp.Render(time.Now().Format(time.Stamp))+"! "+
_, _ = fmt.Fprintln(inv.Stdout, "\n"+cliui.DefaultStyles.Wrap.Render(
"The "+cliui.DefaultStyles.Keyword.Render(templateName)+" template has been created at "+cliui.DefaultStyles.DateTimeStamp.Render(time.Now().Format(time.Stamp))+"! "+
"Developers can provision a workspace with this template using:")+"\n")
_, _ = fmt.Fprintln(inv.Stdout, " "+cliui.Styles.Code.Render(fmt.Sprintf("coder create --template=%q [workspace name]", templateName)))
_, _ = fmt.Fprintln(inv.Stdout, " "+cliui.DefaultStyles.Code.Render(fmt.Sprintf("coder create --template=%q [workspace name]", templateName)))
_, _ = fmt.Fprintln(inv.Stdout)
return nil

View File

@ -77,7 +77,7 @@ func (r *RootCmd) templateDelete() *clibase.Cmd {
// Confirm deletion of the template.
_, err = cliui.Prompt(inv, cliui.PromptOptions{
Text: fmt.Sprintf("Delete these templates: %s?", cliui.Styles.Code.Render(strings.Join(templateNames, ", "))),
Text: fmt.Sprintf("Delete these templates: %s?", cliui.DefaultStyles.Code.Render(strings.Join(templateNames, ", "))),
IsConfirm: true,
Default: cliui.ConfirmNo,
})
@ -91,7 +91,7 @@ func (r *RootCmd) templateDelete() *clibase.Cmd {
return xerrors.Errorf("delete template %q: %w", template.Name, err)
}
_, _ = fmt.Fprintln(inv.Stdout, "Deleted template "+cliui.Styles.Code.Render(template.Name)+" at "+cliui.Styles.DateTimeStamp.Render(time.Now().Format(time.Stamp))+"!")
_, _ = fmt.Fprintln(inv.Stdout, "Deleted template "+cliui.DefaultStyles.Code.Render(template.Name)+" at "+cliui.DefaultStyles.DateTimeStamp.Render(time.Now().Format(time.Stamp))+"!")
}
return nil

View File

@ -37,7 +37,7 @@ func TestTemplateDelete(t *testing.T) {
execDone <- inv.Run()
}()
pty.ExpectMatch(fmt.Sprintf("Delete these templates: %s?", cliui.Styles.Code.Render(template.Name)))
pty.ExpectMatch(fmt.Sprintf("Delete these templates: %s?", cliui.DefaultStyles.Code.Render(template.Name)))
pty.WriteLine("yes")
require.NoError(t, <-execDone)
@ -95,7 +95,7 @@ func TestTemplateDelete(t *testing.T) {
execDone <- inv.Run()
}()
pty.ExpectMatch(fmt.Sprintf("Delete these templates: %s?", cliui.Styles.Code.Render(strings.Join(templateNames, ", "))))
pty.ExpectMatch(fmt.Sprintf("Delete these templates: %s?", cliui.DefaultStyles.Code.Render(strings.Join(templateNames, ", "))))
pty.WriteLine("yes")
require.NoError(t, <-execDone)

View File

@ -90,7 +90,7 @@ func (r *RootCmd) templateEdit() *clibase.Cmd {
if err != nil {
return xerrors.Errorf("update template metadata: %w", err)
}
_, _ = fmt.Fprintf(inv.Stdout, "Updated template metadata at %s!\n", cliui.Styles.DateTimeStamp.Render(time.Now().Format(time.Stamp)))
_, _ = fmt.Fprintf(inv.Stdout, "Updated template metadata at %s!\n", cliui.DefaultStyles.DateTimeStamp.Render(time.Now().Format(time.Stamp)))
return nil
},
}

View File

@ -42,15 +42,15 @@ func (*RootCmd) templateInit() *clibase.Cmd {
for _, example := range exampleList {
name := fmt.Sprintf(
"%s\n%s\n%s\n",
cliui.Styles.Bold.Render(example.Name),
cliui.Styles.Wrap.Copy().PaddingLeft(6).Render(example.Description),
cliui.Styles.Keyword.Copy().PaddingLeft(6).Render(example.URL),
cliui.DefaultStyles.Bold.Render(example.Name),
cliui.DefaultStyles.Wrap.Copy().PaddingLeft(6).Render(example.Description),
cliui.DefaultStyles.Keyword.Copy().PaddingLeft(6).Render(example.URL),
)
optsToID[name] = example.ID
}
opts := maps.Keys(optsToID)
sort.Strings(opts)
_, _ = fmt.Fprintln(inv.Stdout, cliui.Styles.Wrap.Render(
_, _ = fmt.Fprintln(inv.Stdout, cliui.DefaultStyles.Wrap.Render(
"A template defines infrastructure as code to be provisioned "+
"for individual developer workspaces. Select an example to be copied to the active directory:\n"))
selected, err := cliui.Select(inv, cliui.SelectOptions{
@ -94,7 +94,7 @@ func (*RootCmd) templateInit() *clibase.Cmd {
} else {
relPath = "./" + relPath
}
_, _ = fmt.Fprintf(inv.Stdout, "Extracting %s to %s...\n", cliui.Styles.Field.Render(selectedTemplate.ID), relPath)
_, _ = fmt.Fprintf(inv.Stdout, "Extracting %s to %s...\n", cliui.DefaultStyles.Field.Render(selectedTemplate.ID), relPath)
err = os.MkdirAll(directory, 0o700)
if err != nil {
return err
@ -104,8 +104,8 @@ func (*RootCmd) templateInit() *clibase.Cmd {
return err
}
_, _ = fmt.Fprintln(inv.Stdout, "Create your template by running:")
_, _ = fmt.Fprintln(inv.Stdout, cliui.Styles.Paragraph.Render(cliui.Styles.Code.Render("cd "+relPath+" && coder templates create"))+"\n")
_, _ = fmt.Fprintln(inv.Stdout, cliui.Styles.Wrap.Render("Examples provide a starting point and are expected to be edited! 🎨"))
_, _ = fmt.Fprintln(inv.Stdout, cliui.DefaultStyles.Paragraph.Render(cliui.DefaultStyles.Code.Render("cd "+relPath+" && coder templates create"))+"\n")
_, _ = fmt.Fprintln(inv.Stdout, cliui.DefaultStyles.Wrap.Render("Examples provide a starting point and are expected to be edited! 🎨"))
return nil
},
}

View File

@ -73,7 +73,7 @@ func (pf *templateUploadFlags) upload(inv *clibase.Invocation, client *codersdk.
spin := spinner.New(spinner.CharSets[5], 100*time.Millisecond)
spin.Writer = inv.Stdout
spin.Suffix = cliui.Styles.Keyword.Render(" Uploading directory...")
spin.Suffix = cliui.DefaultStyles.Keyword.Render(" Uploading directory...")
spin.Start()
defer spin.Stop()
@ -182,7 +182,7 @@ func (r *RootCmd) templatePush() *clibase.Cmd {
}
}
_, _ = fmt.Fprintf(inv.Stdout, "Updated version at %s!\n", cliui.Styles.DateTimeStamp.Render(time.Now().Format(time.Stamp)))
_, _ = fmt.Fprintf(inv.Stdout, "Updated version at %s!\n", cliui.DefaultStyles.DateTimeStamp.Render(time.Now().Format(time.Stamp)))
return nil
},
}

View File

@ -76,7 +76,7 @@ func templatesToRows(templates ...codersdk.Template) []templateTableRow {
OrganizationID: template.OrganizationID,
Provisioner: template.Provisioner,
ActiveVersionID: template.ActiveVersionID,
UsedBy: cliui.Styles.Fuchsia.Render(formatActiveDevelopers(template.ActiveUserCount)),
UsedBy: cliui.DefaultStyles.Fuchsia.Render(formatActiveDevelopers(template.ActiveUserCount)),
DefaultTTL: (time.Duration(template.DefaultTTLMillis) * time.Millisecond),
}
}

View File

@ -101,7 +101,7 @@ func templateVersionsToRows(activeVersionID uuid.UUID, templateVersions ...coder
for i, templateVersion := range templateVersions {
activeStatus := ""
if templateVersion.ID == activeVersionID {
activeStatus = cliui.Styles.Code.Render(cliui.Styles.Keyword.Render("Active"))
activeStatus = cliui.DefaultStyles.Code.Render(cliui.DefaultStyles.Keyword.Render("Active"))
}
rows[i] = templateVersionRow{

View File

@ -71,16 +71,16 @@ func (r *RootCmd) userCreate() *clibase.Cmd {
}
_, _ = fmt.Fprintln(inv.Stderr, `A new user has been created!
Share the instructions below to get them started.
`+cliui.Styles.Placeholder.Render("—————————————————————————————————————————————————")+`
`+cliui.DefaultStyles.Placeholder.Render("—————————————————————————————————————————————————")+`
Download the Coder command line for your operating system:
https://github.com/coder/coder/releases
Run `+cliui.Styles.Code.Render("coder login "+client.URL.String())+` to authenticate.
Run `+cliui.DefaultStyles.Code.Render("coder login "+client.URL.String())+` to authenticate.
Your email is: `+cliui.Styles.Field.Render(email)+`
Your password is: `+cliui.Styles.Field.Render(password)+`
Your email is: `+cliui.DefaultStyles.Field.Render(email)+`
Your password is: `+cliui.DefaultStyles.Field.Render(password)+`
Create a workspace `+cliui.Styles.Code.Render("coder create")+`!`)
Create a workspace `+cliui.DefaultStyles.Code.Render("coder create")+`!`)
return nil
},
}

View File

@ -89,7 +89,7 @@ func (r *RootCmd) createUserStatusCommand(sdkStatus codersdk.UserStatus) *clibas
return xerrors.Errorf("%s user: %w", verb, err)
}
_, _ = fmt.Fprintf(inv.Stdout, "\nUser %s has been %s!\n", cliui.Styles.Keyword.Render(user.Username), pastVerb)
_, _ = fmt.Fprintf(inv.Stdout, "\nUser %s has been %s!\n", cliui.DefaultStyles.Keyword.Render(user.Username), pastVerb)
return nil
},
}

View File

@ -35,9 +35,9 @@ func (vi versionInfo) String() string {
_, _ = str.WriteString("\r\n" + vi.ExternalURL + "\r\n\r\n")
if vi.Slim {
_, _ = str.WriteString(fmt.Sprintf("Slim build of Coder, does not support the %s subcommand.", cliui.Styles.Code.Render("server")))
_, _ = str.WriteString(fmt.Sprintf("Slim build of Coder, does not support the %s subcommand.", cliui.DefaultStyles.Code.Render("server")))
} else {
_, _ = str.WriteString(fmt.Sprintf("Full build of Coder, supports the %s subcommand.", cliui.Styles.Code.Render("server")))
_, _ = str.WriteString(fmt.Sprintf("Full build of Coder, supports the %s subcommand.", cliui.DefaultStyles.Code.Render("server")))
}
return str.String()
}

View File

@ -29,7 +29,7 @@ func main() {
Use: "prompt",
Handler: func(inv *clibase.Invocation) error {
_, err := cliui.Prompt(inv, cliui.PromptOptions{
Text: "What is our " + cliui.Styles.Field.Render("company name") + "?",
Text: "What is our " + cliui.DefaultStyles.Field.Render("company name") + "?",
Default: "acme-corp",
Validate: func(s string) error {
if !strings.EqualFold(s, "coder") {

View File

@ -114,8 +114,8 @@ func readOrGenerateConfig(customTunnelHost string) (Config, error) {
if cfg.Version == 0 {
_, _ = fmt.Println()
_, _ = fmt.Println(cliui.Styles.Error.Render("You're running a deprecated tunnel version!"))
_, _ = fmt.Println(cliui.Styles.Error.Render("Upgrading you to the new version now. You will need to rebuild running workspaces."))
_, _ = fmt.Println(cliui.DefaultStyles.Error.Render("You're running a deprecated tunnel version!"))
_, _ = fmt.Println(cliui.DefaultStyles.Error.Render("Upgrading you to the new version now. You will need to rebuild running workspaces."))
_, _ = fmt.Println()
cfg, err := GenerateConfig(customTunnelHost)
@ -172,8 +172,8 @@ func GenerateConfig(customTunnelHost string) (Config, error) {
spin.Stop()
_, _ = fmt.Printf("Using tunnel in %s with latency %s.\n",
cliui.Styles.Keyword.Render(locationName),
cliui.Styles.Code.Render(node.AvgLatency.String()),
cliui.DefaultStyles.Keyword.Render(locationName),
cliui.DefaultStyles.Code.Render(node.AvgLatency.String()),
)
return Config{

View File

@ -37,7 +37,7 @@ func (r *RootCmd) groupCreate() *clibase.Cmd {
return xerrors.Errorf("create group: %w", err)
}
_, _ = fmt.Fprintf(inv.Stdout, "Successfully created group %s!\n", cliui.Styles.Keyword.Render(group.Name))
_, _ = fmt.Fprintf(inv.Stdout, "Successfully created group %s!\n", cliui.DefaultStyles.Keyword.Render(group.Name))
return nil
},
}

View File

@ -46,6 +46,6 @@ func TestCreateGroup(t *testing.T) {
err := inv.Run()
require.NoError(t, err)
pty.ExpectMatch(fmt.Sprintf("Successfully created group %s!", cliui.Styles.Keyword.Render(groupName)))
pty.ExpectMatch(fmt.Sprintf("Successfully created group %s!", cliui.DefaultStyles.Keyword.Render(groupName)))
})
}

View File

@ -41,7 +41,7 @@ func (r *RootCmd) groupDelete() *clibase.Cmd {
return xerrors.Errorf("delete group: %w", err)
}
_, _ = fmt.Fprintf(inv.Stdout, "Successfully deleted group %s!\n", cliui.Styles.Keyword.Render(group.Name))
_, _ = fmt.Fprintf(inv.Stdout, "Successfully deleted group %s!\n", cliui.DefaultStyles.Keyword.Render(group.Name))
return nil
},
}

View File

@ -49,7 +49,7 @@ func TestGroupDelete(t *testing.T) {
err = inv.Run()
require.NoError(t, err)
pty.ExpectMatch(fmt.Sprintf("Successfully deleted group %s", cliui.Styles.Keyword.Render(group.Name)))
pty.ExpectMatch(fmt.Sprintf("Successfully deleted group %s", cliui.DefaultStyles.Keyword.Render(group.Name)))
})
t.Run("NoArg", func(t *testing.T) {

View File

@ -72,7 +72,7 @@ func (r *RootCmd) groupEdit() *clibase.Cmd {
return xerrors.Errorf("patch group: %w", err)
}
_, _ = fmt.Fprintf(inv.Stdout, "Successfully patched group %s!\n", cliui.Styles.Keyword.Render(group.Name))
_, _ = fmt.Fprintf(inv.Stdout, "Successfully patched group %s!\n", cliui.DefaultStyles.Keyword.Render(group.Name))
return nil
},
}

View File

@ -68,7 +68,7 @@ func TestGroupEdit(t *testing.T) {
err = inv.Run()
require.NoError(t, err)
pty.ExpectMatch(fmt.Sprintf("Successfully patched group %s", cliui.Styles.Keyword.Render(expectedName)))
pty.ExpectMatch(fmt.Sprintf("Successfully patched group %s", cliui.DefaultStyles.Keyword.Render(expectedName)))
})
t.Run("InvalidUserInput", func(t *testing.T) {

View File

@ -125,7 +125,7 @@ func (r *RootCmd) provisionerDaemonStart() *clibase.Cmd {
select {
case <-notifyCtx.Done():
exitErr = notifyCtx.Err()
_, _ = fmt.Fprintln(inv.Stdout, cliui.Styles.Bold.Render(
_, _ = fmt.Fprintln(inv.Stdout, cliui.DefaultStyles.Bold.Render(
"Interrupt caught, gracefully exiting. Use ctrl+\\ to force quit",
))
case exitErr = <-errCh:

View File

@ -185,7 +185,7 @@ func (*RootCmd) proxyServer() *clibase.Cmd {
cliui.Warnf(
inv.Stderr,
"The access URL %s %s, this may cause unexpected problems when creating workspaces. Generate a unique *.try.coder.app URL by not specifying an access URL.\n",
cliui.Styles.Field.Render(cfg.AccessURL.String()), reason,
cliui.DefaultStyles.Field.Render(cfg.AccessURL.String()), reason,
)
}
@ -297,7 +297,7 @@ func (*RootCmd) proxyServer() *clibase.Cmd {
case exitErr = <-errCh:
case <-notifyCtx.Done():
exitErr = notifyCtx.Err()
_, _ = fmt.Fprintln(inv.Stdout, cliui.Styles.Bold.Render(
_, _ = fmt.Fprintln(inv.Stdout, cliui.DefaultStyles.Bold.Render(
"Interrupt caught, gracefully exiting. Use ctrl+\\ to force quit",
))
}

View File

@ -8,6 +8,5 @@ import (
func main() {
var rootCmd entcli.RootCmd
rootCmd.RunMain(rootCmd.EnterpriseSubcommands())
}