-
Notifications
You must be signed in to change notification settings - Fork 897
feat(cli): add --id parameter to templates init command #7116
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
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -5,6 +5,9 @@ import ( | |
"fmt" | ||
"os" | ||
"path/filepath" | ||
"sort" | ||
|
||
"golang.org/x/xerrors" | ||
|
||
"github.com/coder/coder/cli/clibase" | ||
"github.com/coder/coder/cli/cliui" | ||
|
@@ -14,7 +17,8 @@ import ( | |
) | ||
|
||
func (*RootCmd) templateInit() *clibase.Cmd { | ||
return &clibase.Cmd{ | ||
var templateIDArg string | ||
cmd := &clibase.Cmd{ | ||
Use: "init [directory]", | ||
Short: "Get started with a templated template.", | ||
Middleware: clibase.RequireRangeArgs(0, 1), | ||
|
@@ -23,29 +27,40 @@ func (*RootCmd) templateInit() *clibase.Cmd { | |
if err != nil { | ||
return err | ||
} | ||
exampleNames := []string{} | ||
exampleByName := map[string]codersdk.TemplateExample{} | ||
|
||
optsToID := map[string]string{} | ||
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), | ||
) | ||
exampleNames = append(exampleNames, name) | ||
exampleByName[name] = example | ||
optsToID[name] = example.ID | ||
} | ||
|
||
_, _ = fmt.Fprintln(inv.Stdout, cliui.Styles.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")) | ||
option, err := cliui.Select(inv, cliui.SelectOptions{ | ||
Options: exampleNames, | ||
}) | ||
if err != nil { | ||
return err | ||
// If the user didn't specify any template, prompt them to select one. | ||
if templateIDArg == "" { | ||
opts := keys(optsToID) | ||
johnstcn marked this conversation as resolved.
Show resolved
Hide resolved
|
||
sort.Strings(opts) | ||
_, _ = fmt.Fprintln(inv.Stdout, cliui.Styles.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{ | ||
Options: sort.StringSlice(keys(optsToID)), | ||
johnstcn marked this conversation as resolved.
Show resolved
Hide resolved
|
||
}) | ||
if err != nil { | ||
return err | ||
} | ||
templateIDArg = optsToID[selected] | ||
} | ||
|
||
selectedTemplate, ok := templateByID(templateIDArg, exampleList) | ||
if !ok { | ||
ids := values(optsToID) | ||
sort.Strings(ids) | ||
return xerrors.Errorf("Template ID %q does not exist!\nValid options are: %q", templateIDArg, ids) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Not a biggie, but this was a bit of a brain twister for me since the name/id stored in the map seemed unintuitive. 😅 To me it would make sense to have There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Our goal is to have an example template ID that we can pass to |
||
} | ||
selectedTemplate := exampleByName[option] | ||
archive, err := examples.Archive(selectedTemplate.ID) | ||
if err != nil { | ||
return err | ||
|
@@ -81,4 +96,39 @@ func (*RootCmd) templateInit() *clibase.Cmd { | |
return nil | ||
}, | ||
} | ||
|
||
cmd.Options = clibase.OptionSet{ | ||
{ | ||
Flag: "id", | ||
Description: "Specify a given example template by ID.", | ||
Value: clibase.StringOf(&templateIDArg), | ||
johnstcn marked this conversation as resolved.
Show resolved
Hide resolved
|
||
}, | ||
} | ||
|
||
return cmd | ||
} | ||
|
||
func templateByID(templateID string, tes []codersdk.TemplateExample) (codersdk.TemplateExample, bool) { | ||
for _, te := range tes { | ||
if te.ID == templateID { | ||
return te, true | ||
} | ||
} | ||
return codersdk.TemplateExample{}, false | ||
} | ||
|
||
func keys[K comparable, V any](m map[K]V) []K { | ||
l := make([]K, 0, len(m)) | ||
for k := range m { | ||
l = append(l, k) | ||
} | ||
return l | ||
} | ||
|
||
func values[K comparable, V any](m map[K]V) []V { | ||
l := make([]V, 0, len(m)) | ||
for _, v := range m { | ||
l = append(l, v) | ||
} | ||
return l | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,10 @@ | ||
Usage: coder templates init [directory] | ||
Usage: coder templates init [flags] [directory] | ||
|
||
Get started with a templated template. | ||
|
||
[1mOptions[0m | ||
--id string | ||
Specify a given example template by ID. | ||
|
||
--- | ||
Run `coder --help` for a list of global options. |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -96,7 +96,7 @@ provision: | |
[ ! -e ~/.config/coderv2/session ] && coder login http://localhost:3000 --first-user-username admin --first-user-email [email protected] --first-user-password $(< /dev/urandom tr -dc _A-Z-a-z-0-9 | head -c12 | tee ${HOME}/.config/coderv2/password) | ||
# Create an initial template | ||
temp_template_dir=$(mktemp -d) | ||
echo code-server | coder templates init "${temp_template_dir}" | ||
coder templates init --id docker "${temp_template_dir}" | ||
DOCKER_ARCH="amd64" | ||
if [ "$(arch)" = "aarch64" ]; then | ||
DOCKER_ARCH="arm64" | ||
|
Uh oh!
There was an error while loading. Please reload this page.