Skip to content

feat(cli): colorize help page #9589

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Sep 8, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions cli/cliui/cliui.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,11 @@ var (
Blue = color.Color("#5000ff")
)

// Color returns a color for the given string.
func Color(s string) termenv.Color {
return color.Color(s)
}

func isTerm() bool {
return color != termenv.Ascii
}
Expand Down
36 changes: 24 additions & 12 deletions cli/help.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,10 @@ import (
"golang.org/x/crypto/ssh/terminal"
"golang.org/x/xerrors"

"github.com/coder/coder/v2/buildinfo"
"github.com/coder/coder/v2/cli/clibase"
"github.com/coder/coder/v2/cli/cliui"
"github.com/coder/pretty"
)

//go:embed help.tpl
Expand Down Expand Up @@ -47,12 +49,28 @@ func wrapTTY(s string) string {
var usageTemplate = template.Must(
template.New("usage").Funcs(
template.FuncMap{
"version": func() string {
return buildinfo.Version()
},
"wrapTTY": func(s string) string {
return wrapTTY(s)
},
"trimNewline": func(s string) string {
return strings.TrimSuffix(s, "\n")
},
"keyword": func(s string) string {
return pretty.Sprint(
pretty.FgColor(cliui.Color("#0173ff")),
s,
)
},
"prettyHeader": func(s string) string {
return pretty.Sprint(
pretty.FgColor(
cliui.Color("#ffb500"),
), strings.ToUpper(s), ":",
)
},
"typeHelper": func(opt *clibase.Option) string {
switch v := opt.Value.(type) {
case *clibase.Enum:
Expand All @@ -71,13 +89,15 @@ var usageTemplate = template.Must(

body = wordwrap.WrapString(body, uint(twidth-len(spacing)))

sc := bufio.NewScanner(strings.NewReader(body))

var sb strings.Builder
for _, line := range strings.Split(body, "\n") {
for sc.Scan() {
// Remove existing indent, if any.
line = strings.TrimSpace(line)
// line = strings.TrimSpace(line)
// Use spaces so we can easily calculate wrapping.
_, _ = sb.WriteString(spacing)
_, _ = sb.WriteString(line)
_, _ = sb.Write(sc.Bytes())
_, _ = sb.WriteString("\n")
}
return sb.String()
Expand Down Expand Up @@ -126,9 +146,7 @@ var usageTemplate = template.Must(
"flagName": func(opt clibase.Option) string {
return opt.Flag
},
"prettyHeader": func(s string) string {
return cliui.Bold(s)
},

"isEnterprise": func(opt clibase.Option) bool {
return opt.Annotations.IsSet("enterprise")
},
Expand Down Expand Up @@ -160,12 +178,6 @@ var usageTemplate = template.Must(
}
return sb.String()
},
"formatLong": func(long string) string {
// We intentionally don't wrap here because it would misformat
// examples, where the new line would start without the prior
// line's indentation.
return strings.TrimSpace(long)
},
"formatGroupDescription": func(s string) string {
s = strings.ReplaceAll(s, "\n", "")
s = s + "\n"
Expand Down
24 changes: 13 additions & 11 deletions cli/help.tpl
Original file line number Diff line number Diff line change
@@ -1,20 +1,22 @@
{{- /* Heavily inspired by the Go toolchain formatting. */ -}}
Usage: {{.FullUsage}}
{{- /* Heavily inspired by the Go toolchain and fd */ -}}
coder {{version}}

{{prettyHeader "Usage"}}
{{indent .FullUsage 2}}


{{ with .Short }}
{{- wrapTTY . }}
{{- indent . 2 | wrapTTY }}
{{"\n"}}
{{- end}}

{{ with .Aliases }}
{{ "\n" }}
{{ "Aliases:"}} {{ joinStrings .}}
{{ "\n" }}
{{" Aliases: "}} {{- joinStrings .}}
{{- end }}

{{- with .Long}}
{{- formatLong . }}
{{"\n"}}
{{- indent . 2}}
{{ "\n" }}
{{- end }}
{{ with visibleChildren . }}
Expand All @@ -34,11 +36,11 @@ Usage: {{.FullUsage}}
{{- else }}
{{- end }}
{{- range $index, $option := $group.Options }}
{{- if not (eq $option.FlagShorthand "") }}{{- print "\n -" $option.FlagShorthand ", " -}}
{{- if not (eq $option.FlagShorthand "") }}{{- print "\n "}} {{ keyword "-"}}{{keyword $option.FlagShorthand }}{{", "}}
{{- else }}{{- print "\n " -}}
{{- end }}
{{- with flagName $option }}--{{ . }}{{ end }} {{- with typeHelper $option }} {{ . }}{{ end }}
{{- with envName $option }}, ${{ . }}{{ end }}
{{- with flagName $option }}{{keyword "--"}}{{ keyword . }}{{ end }} {{- with typeHelper $option }} {{ . }}{{ end }}
{{- with envName $option }}, {{ print "$" . | keyword }}{{ end }}
{{- with $option.Default }} (default: {{ . }}){{ end }}
{{- with $option.Description }}
{{- $desc := $option.Description }}
Expand All @@ -47,7 +49,7 @@ Usage: {{.FullUsage}}
{{- end -}}
{{- end }}
{{- end }}
---
———
{{- if .Parent }}
Run `coder --help` for a list of global options.
{{- else }}
Expand Down
52 changes: 28 additions & 24 deletions cli/testdata/coder_--help.golden
Original file line number Diff line number Diff line change
@@ -1,15 +1,19 @@
Usage: coder [global-flags] <subcommand>

Coder v0.0.0-devel — A tool for provisioning self-hosted development environments with Terraform.
- Start a Coder server:

$ coder server

- Get started by creating a template from an example:

$ coder templates init

Subcommands
coder v0.0.0-devel

USAGE:
coder [global-flags] <subcommand>

Coder v0.0.0-devel — A tool for provisioning self-hosted development
environments with Terraform.
- Start a Coder server:

$ coder server

- Get started by creating a template from an example:

$ coder templates init

SUBCOMMANDS:
config-ssh Add an SSH Host entry for your workspaces "ssh
coder.workspace"
create Create a workspace
Expand Down Expand Up @@ -45,43 +49,43 @@ Coder v0.0.0-devel — A tool for provisioning self-hosted development environme
users Manage users
version Show coder version

Global Options
GLOBAL OPTIONS:
Global options are applied to all commands. They can be set using environment
variables or flags.

--debug-options bool
--debug-options bool
Print all options, how they're set, then exit.

--disable-direct-connections bool, $CODER_DISABLE_DIRECT_CONNECTIONS
--disable-direct-connections bool, $CODER_DISABLE_DIRECT_CONNECTIONS
Disable direct (P2P) connections to workspaces.

--global-config string, $CODER_CONFIG_DIR (default: ~/.config/coderv2)
--global-config string, $CODER_CONFIG_DIR (default: ~/.config/coderv2)
Path to the global `coder` config directory.

--header string-array, $CODER_HEADER
--header string-array, $CODER_HEADER
Additional HTTP headers added to all requests. Provide as key=value.
Can be specified multiple times.

--header-command string, $CODER_HEADER_COMMAND
--header-command string, $CODER_HEADER_COMMAND
An external command that outputs additional HTTP headers added to all
requests. The command must output each header as `key=value` on its
own line.

--no-feature-warning bool, $CODER_NO_FEATURE_WARNING
--no-feature-warning bool, $CODER_NO_FEATURE_WARNING
Suppress warnings about unlicensed features.

--no-version-warning bool, $CODER_NO_VERSION_WARNING
--no-version-warning bool, $CODER_NO_VERSION_WARNING
Suppress warning when client and server versions do not match.

--token string, $CODER_SESSION_TOKEN
--token string, $CODER_SESSION_TOKEN
Specify an authentication token. For security reasons setting
CODER_SESSION_TOKEN is preferred.

--url url, $CODER_URL
--url url, $CODER_URL
URL to a deployment.

-v, --verbose bool, $CODER_VERBOSE
-v, --verbose bool, $CODER_VERBOSE
Enable verbose output.

---
———
Report bugs and request features at https://github.com/coder/coder/issues/new
33 changes: 18 additions & 15 deletions cli/testdata/coder_agent_--help.golden
Original file line number Diff line number Diff line change
@@ -1,41 +1,44 @@
Usage: coder agent [flags]
coder v0.0.0-devel

Starts the Coder workspace agent.
USAGE:
coder agent [flags]

Options
--log-human string, $CODER_AGENT_LOGGING_HUMAN (default: /dev/stderr)
Starts the Coder workspace agent.

OPTIONS:
--log-human string, $CODER_AGENT_LOGGING_HUMAN (default: /dev/stderr)
Output human-readable logs to a given file.

--log-json string, $CODER_AGENT_LOGGING_JSON
--log-json string, $CODER_AGENT_LOGGING_JSON
Output JSON logs to a given file.

--log-stackdriver string, $CODER_AGENT_LOGGING_STACKDRIVER
--log-stackdriver string, $CODER_AGENT_LOGGING_STACKDRIVER
Output Stackdriver compatible logs to a given file.

--auth string, $CODER_AGENT_AUTH (default: token)
--auth string, $CODER_AGENT_AUTH (default: token)
Specify the authentication type to use for the agent.

--debug-address string, $CODER_AGENT_DEBUG_ADDRESS (default: 127.0.0.1:2113)
--debug-address string, $CODER_AGENT_DEBUG_ADDRESS (default: 127.0.0.1:2113)
The bind address to serve a debug HTTP server.

--log-dir string, $CODER_AGENT_LOG_DIR (default: /tmp)
--log-dir string, $CODER_AGENT_LOG_DIR (default: /tmp)
Specify the location for the agent log files.

--no-reap bool
--no-reap bool
Do not start a process reaper.

--pprof-address string, $CODER_AGENT_PPROF_ADDRESS (default: 127.0.0.1:6060)
--pprof-address string, $CODER_AGENT_PPROF_ADDRESS (default: 127.0.0.1:6060)
The address to serve pprof.

--prometheus-address string, $CODER_AGENT_PROMETHEUS_ADDRESS (default: 127.0.0.1:2112)
--prometheus-address string, $CODER_AGENT_PROMETHEUS_ADDRESS (default: 127.0.0.1:2112)
The bind address to serve Prometheus metrics.

--ssh-max-timeout duration, $CODER_AGENT_SSH_MAX_TIMEOUT (default: 72h)
--ssh-max-timeout duration, $CODER_AGENT_SSH_MAX_TIMEOUT (default: 72h)
Specify the max timeout for a SSH connection, it is advisable to set
it to a minimum of 60s, but no more than 72h.

--tailnet-listen-port int, $CODER_AGENT_TAILNET_LISTEN_PORT (default: 0)
--tailnet-listen-port int, $CODER_AGENT_TAILNET_LISTEN_PORT (default: 0)
Specify a static port for Tailscale to use for listening.

---
———
Run `coder --help` for a list of global options.
44 changes: 24 additions & 20 deletions cli/testdata/coder_config-ssh_--help.golden
Original file line number Diff line number Diff line change
@@ -1,51 +1,55 @@
Usage: coder config-ssh [flags]
coder v0.0.0-devel

Add an SSH Host entry for your workspaces "ssh coder.workspace"
USAGE:
coder config-ssh [flags]

- You can use -o (or --ssh-option) so set SSH options to be used for all your
workspaces:
Add an SSH Host entry for your workspaces "ssh coder.workspace"

$ coder config-ssh -o ForwardAgent=yes
- You can use -o (or --ssh-option) so set SSH options to be used for all
your
workspaces:

$ coder config-ssh -o ForwardAgent=yes

- You can use --dry-run (or -n) to see the changes that would be made:

$ coder config-ssh --dry-run

- You can use --dry-run (or -n) to see the changes that would be made:

$ coder config-ssh --dry-run

Options
--coder-binary-path string, $CODER_SSH_CONFIG_BINARY_PATH
OPTIONS:
--coder-binary-path string, $CODER_SSH_CONFIG_BINARY_PATH
Optionally specify the absolute path to the coder binary used in
ProxyCommand. By default, the binary invoking this command ('config
ssh') is used.

-n, --dry-run bool, $CODER_SSH_DRY_RUN
-n, --dry-run bool, $CODER_SSH_DRY_RUN
Perform a trial run with no changes made, showing a diff at the end.

--force-unix-filepaths bool, $CODER_CONFIGSSH_UNIX_FILEPATHS
--force-unix-filepaths bool, $CODER_CONFIGSSH_UNIX_FILEPATHS
By default, 'config-ssh' uses the os path separator when writing the
ssh config. This might be an issue in Windows machine that use a
unix-like shell. This flag forces the use of unix file paths (the
forward slash '/').

--ssh-config-file string, $CODER_SSH_CONFIG_FILE (default: ~/.ssh/config)
--ssh-config-file string, $CODER_SSH_CONFIG_FILE (default: ~/.ssh/config)
Specifies the path to an SSH config.

--ssh-host-prefix string, $CODER_CONFIGSSH_SSH_HOST_PREFIX
--ssh-host-prefix string, $CODER_CONFIGSSH_SSH_HOST_PREFIX
Override the default host prefix.

-o, --ssh-option string-array, $CODER_SSH_CONFIG_OPTS
-o, --ssh-option string-array, $CODER_SSH_CONFIG_OPTS
Specifies additional SSH options to embed in each host stanza.

--use-previous-options bool, $CODER_SSH_USE_PREVIOUS_OPTIONS
--use-previous-options bool, $CODER_SSH_USE_PREVIOUS_OPTIONS
Specifies whether or not to keep options from previous run of
config-ssh.

--wait yes|no|auto, $CODER_CONFIGSSH_WAIT (default: auto)
--wait yes|no|auto, $CODER_CONFIGSSH_WAIT (default: auto)
Specifies whether or not to wait for the startup script to finish
executing. Auto means that the agent startup script behavior
configured in the workspace template is used.

-y, --yes bool
-y, --yes bool
Bypass prompts.

---
———
Run `coder --help` for a list of global options.
Loading