mirror of https://github.com/coder/coder.git
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:
parent
1288a83e42
commit
5eaf809851
|
@ -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."
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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)
|
||||
},
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
},
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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")
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
18
cli/login.go
18
cli/login.go
|
@ -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
|
||||
},
|
||||
}
|
||||
|
|
|
@ -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")
|
||||
|
|
14
cli/ping.go
14
cli/ping.go
|
@ -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) {
|
||||
|
|
|
@ -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
|
||||
},
|
||||
|
|
|
@ -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{
|
||||
|
|
|
@ -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
|
||||
},
|
||||
}
|
||||
|
|
|
@ -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
|
||||
},
|
||||
}
|
||||
|
|
22
cli/root.go
22
cli/root.go
|
@ -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
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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
|
||||
},
|
||||
}
|
||||
|
|
|
@ -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
|
||||
},
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
},
|
||||
}
|
||||
|
|
|
@ -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
|
||||
},
|
||||
}
|
||||
|
|
|
@ -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
|
||||
},
|
||||
}
|
||||
|
|
|
@ -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),
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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{
|
||||
|
|
|
@ -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
|
||||
},
|
||||
}
|
||||
|
|
|
@ -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
|
||||
},
|
||||
}
|
||||
|
|
|
@ -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()
|
||||
}
|
||||
|
|
|
@ -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") {
|
||||
|
|
|
@ -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{
|
||||
|
|
|
@ -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
|
||||
},
|
||||
}
|
||||
|
|
|
@ -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)))
|
||||
})
|
||||
}
|
||||
|
|
|
@ -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
|
||||
},
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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
|
||||
},
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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",
|
||||
))
|
||||
}
|
||||
|
|
|
@ -8,6 +8,5 @@ import (
|
|||
|
||||
func main() {
|
||||
var rootCmd entcli.RootCmd
|
||||
|
||||
rootCmd.RunMain(rootCmd.EnterpriseSubcommands())
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue