mirror of
https://github.com/coder/coder.git
synced 2025-07-12 00:14:10 +00:00
chore: use workspace name as arg in coder workspaces create
(#1007)
This commit is contained in:
@ -26,13 +26,14 @@ func templateCreate() *cobra.Command {
|
||||
provisioner string
|
||||
)
|
||||
cmd := &cobra.Command{
|
||||
Use: "create <directory> [name]",
|
||||
Use: "create [name]",
|
||||
Short: "Create a template from the current directory",
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
client, err := createClient(cmd)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
organization, err := currentOrganization(cmd, client)
|
||||
if err != nil {
|
||||
return err
|
||||
@ -44,6 +45,7 @@ func templateCreate() *cobra.Command {
|
||||
} else {
|
||||
templateName = args[0]
|
||||
}
|
||||
|
||||
_, err = client.TemplateByName(cmd.Context(), organization.ID, templateName)
|
||||
if err == nil {
|
||||
return xerrors.Errorf("A template already exists named %q!", templateName)
|
||||
@ -113,7 +115,7 @@ func templateCreate() *cobra.Command {
|
||||
"The "+cliui.Styles.Keyword.Render(templateName)+" template has been created! "+
|
||||
"Developers can provision a workspace with this template using:")+"\n")
|
||||
|
||||
_, _ = fmt.Fprintln(cmd.OutOrStdout(), " "+cliui.Styles.Code.Render("coder workspaces create "+templateName))
|
||||
_, _ = fmt.Fprintln(cmd.OutOrStdout(), " "+cliui.Styles.Code.Render(fmt.Sprintf("coder workspaces create --template=%q [workspace name]", templateName)))
|
||||
_, _ = fmt.Fprintln(cmd.OutOrStdout())
|
||||
|
||||
return nil
|
||||
@ -214,9 +216,15 @@ func createValidTemplateVersion(cmd *cobra.Command, client *codersdk.Client, org
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
return &version, parameters, cliui.WorkspaceResources(cmd.OutOrStdout(), resources, cliui.WorkspaceResourcesOptions{
|
||||
|
||||
err = cliui.WorkspaceResources(cmd.OutOrStdout(), resources, cliui.WorkspaceResourcesOptions{
|
||||
HideAgentState: true,
|
||||
HideAccess: true,
|
||||
Title: "Template Preview",
|
||||
})
|
||||
if err != nil {
|
||||
return nil, nil, xerrors.Errorf("preview template resources: %w", err)
|
||||
}
|
||||
|
||||
return &version, parameters, nil
|
||||
}
|
||||
|
@ -2,10 +2,10 @@ package cli
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"sort"
|
||||
"time"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
"golang.org/x/exp/slices"
|
||||
"golang.org/x/xerrors"
|
||||
|
||||
"github.com/coder/coder/cli/cliflag"
|
||||
@ -17,67 +17,24 @@ import (
|
||||
func workspaceCreate() *cobra.Command {
|
||||
var (
|
||||
workspaceName string
|
||||
templateName string
|
||||
)
|
||||
cmd := &cobra.Command{
|
||||
Use: "create [template]",
|
||||
Use: "create [name]",
|
||||
Short: "Create a workspace from a template",
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
client, err := createClient(cmd)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
organization, err := currentOrganization(cmd, client)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
templateName := ""
|
||||
if len(args) >= 1 {
|
||||
templateName = args[0]
|
||||
}
|
||||
|
||||
var template codersdk.Template
|
||||
if templateName == "" {
|
||||
_, _ = fmt.Fprintln(cmd.OutOrStdout(), cliui.Styles.Wrap.Render("Select a template below to preview the provisioned infrastructure:"))
|
||||
|
||||
templateNames := []string{}
|
||||
templateByName := map[string]codersdk.Template{}
|
||||
templates, err := client.TemplatesByOrganization(cmd.Context(), organization.ID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, template := range templates {
|
||||
templateName := template.Name
|
||||
if template.WorkspaceOwnerCount > 0 {
|
||||
developerText := "developer"
|
||||
if template.WorkspaceOwnerCount != 1 {
|
||||
developerText = "developers"
|
||||
}
|
||||
templateName += cliui.Styles.Placeholder.Render(fmt.Sprintf(" (used by %d %s)", template.WorkspaceOwnerCount, developerText))
|
||||
}
|
||||
templateNames = append(templateNames, templateName)
|
||||
templateByName[templateName] = template
|
||||
}
|
||||
sort.Slice(templateNames, func(i, j int) bool {
|
||||
return templateByName[templateNames[i]].WorkspaceOwnerCount > templateByName[templateNames[j]].WorkspaceOwnerCount
|
||||
})
|
||||
// Move the cursor up a single line for nicer display!
|
||||
option, err := cliui.Select(cmd, cliui.SelectOptions{
|
||||
Options: templateNames,
|
||||
HideSearch: true,
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
template = templateByName[option]
|
||||
} else {
|
||||
template, err = client.TemplateByName(cmd.Context(), organization.ID, templateName)
|
||||
if err != nil {
|
||||
return xerrors.Errorf("get template by name: %w", err)
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
workspaceName = args[0]
|
||||
}
|
||||
|
||||
if workspaceName == "" {
|
||||
@ -101,6 +58,55 @@ func workspaceCreate() *cobra.Command {
|
||||
return xerrors.Errorf("A workspace already exists named %q!", workspaceName)
|
||||
}
|
||||
|
||||
var template codersdk.Template
|
||||
if templateName == "" {
|
||||
_, _ = fmt.Fprintln(cmd.OutOrStdout(), cliui.Styles.Wrap.Render("Select a template below to preview the provisioned infrastructure:"))
|
||||
|
||||
templates, err := client.TemplatesByOrganization(cmd.Context(), organization.ID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
slices.SortFunc(templates, func(a, b codersdk.Template) bool {
|
||||
return a.WorkspaceOwnerCount > b.WorkspaceOwnerCount
|
||||
})
|
||||
|
||||
templateNames := make([]string, 0, len(templates))
|
||||
templateByName := make(map[string]codersdk.Template, len(templates))
|
||||
|
||||
for _, template := range templates {
|
||||
templateName := template.Name
|
||||
|
||||
if template.WorkspaceOwnerCount > 0 {
|
||||
developerText := "developer"
|
||||
if template.WorkspaceOwnerCount != 1 {
|
||||
developerText = "developers"
|
||||
}
|
||||
|
||||
templateName += cliui.Styles.Placeholder.Render(fmt.Sprintf(" (used by %d %s)", template.WorkspaceOwnerCount, developerText))
|
||||
}
|
||||
|
||||
templateNames = append(templateNames, templateName)
|
||||
templateByName[templateName] = template
|
||||
}
|
||||
|
||||
// Move the cursor up a single line for nicer display!
|
||||
option, err := cliui.Select(cmd, cliui.SelectOptions{
|
||||
Options: templateNames,
|
||||
HideSearch: true,
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
template = templateByName[option]
|
||||
} else {
|
||||
template, err = client.TemplateByName(cmd.Context(), organization.ID, templateName)
|
||||
if err != nil {
|
||||
return xerrors.Errorf("get template by name: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
templateVersion, err := client.TemplateVersion(cmd.Context(), template.ActiveVersionID)
|
||||
if err != nil {
|
||||
return err
|
||||
@ -164,10 +170,12 @@ func workspaceCreate() *cobra.Command {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = cliui.WorkspaceBuild(cmd.Context(), cmd.OutOrStdout(), client, workspace.LatestBuild.ID, before)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
resources, err = client.WorkspaceResourcesByBuild(cmd.Context(), workspace.LatestBuild.ID)
|
||||
if err != nil {
|
||||
return err
|
||||
@ -179,11 +187,12 @@ func workspaceCreate() *cobra.Command {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
_, _ = fmt.Fprintf(cmd.OutOrStdout(), "The %s workspace has been created!\n", cliui.Styles.Keyword.Render(workspace.Name))
|
||||
return nil
|
||||
},
|
||||
}
|
||||
cliflag.StringVarP(cmd.Flags(), &workspaceName, "name", "n", "CODER_WORKSPACE_NAME", "", "Specify a workspace name.")
|
||||
|
||||
cliflag.StringVarP(cmd.Flags(), &templateName, "template", "t", "CODER_TEMPLATE_NAME", "", "Specify a template name.")
|
||||
return cmd
|
||||
}
|
||||
|
@ -22,7 +22,7 @@ func TestWorkspaceCreate(t *testing.T) {
|
||||
version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, nil)
|
||||
coderdtest.AwaitTemplateVersionJob(t, client, version.ID)
|
||||
template := coderdtest.CreateTemplate(t, client, user.OrganizationID, version.ID)
|
||||
cmd, root := clitest.New(t, "workspaces", "create", template.Name, "--name", "my-workspace")
|
||||
cmd, root := clitest.New(t, "workspaces", "create", "my-workspace", "--template", template.Name)
|
||||
clitest.SetupConfig(t, client, root)
|
||||
doneChan := make(chan struct{})
|
||||
pty := ptytest.New(t)
|
||||
@ -52,7 +52,7 @@ func TestWorkspaceCreate(t *testing.T) {
|
||||
version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, nil)
|
||||
coderdtest.AwaitTemplateVersionJob(t, client, version.ID)
|
||||
_ = coderdtest.CreateTemplate(t, client, user.OrganizationID, version.ID)
|
||||
cmd, root := clitest.New(t, "workspaces", "create", "--name", "my-workspace")
|
||||
cmd, root := clitest.New(t, "workspaces", "create", "my-workspace")
|
||||
clitest.SetupConfig(t, client, root)
|
||||
doneChan := make(chan struct{})
|
||||
pty := ptytest.New(t)
|
||||
@ -82,7 +82,7 @@ func TestWorkspaceCreate(t *testing.T) {
|
||||
version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, nil)
|
||||
coderdtest.AwaitTemplateVersionJob(t, client, version.ID)
|
||||
_ = coderdtest.CreateTemplate(t, client, user.OrganizationID, version.ID)
|
||||
cmd, root := clitest.New(t, "workspaces", "create", "--name", "")
|
||||
cmd, root := clitest.New(t, "workspaces", "create", "")
|
||||
clitest.SetupConfig(t, client, root)
|
||||
doneChan := make(chan struct{})
|
||||
pty := ptytest.New(t)
|
||||
@ -134,7 +134,7 @@ func TestWorkspaceCreate(t *testing.T) {
|
||||
})
|
||||
coderdtest.AwaitTemplateVersionJob(t, client, version.ID)
|
||||
_ = coderdtest.CreateTemplate(t, client, user.OrganizationID, version.ID)
|
||||
cmd, root := clitest.New(t, "workspaces", "create", "--name", "")
|
||||
cmd, root := clitest.New(t, "workspaces", "create", "")
|
||||
clitest.SetupConfig(t, client, root)
|
||||
doneChan := make(chan struct{})
|
||||
pty := ptytest.New(t)
|
||||
|
3
go.mod
3
go.mod
@ -92,7 +92,8 @@ require (
|
||||
go.uber.org/atomic v1.9.0
|
||||
go.uber.org/goleak v1.1.12
|
||||
golang.org/x/crypto v0.0.0-20220315160706-3147a52a75dd
|
||||
golang.org/x/mod v0.5.1
|
||||
golang.org/x/exp v0.0.0-20220414153411-bcd21879b8fd
|
||||
golang.org/x/mod v0.6.0-dev.0.20211013180041-c96bc1413d57
|
||||
golang.org/x/oauth2 v0.0.0-20220309155454-6242fa91716a
|
||||
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c
|
||||
golang.org/x/sys v0.0.0-20220328115105-d36c6a25d886
|
||||
|
6
go.sum
6
go.sum
@ -1787,6 +1787,8 @@ golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EH
|
||||
golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU=
|
||||
golang.org/x/exp v0.0.0-20200901203048-c4f52b2c50aa/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU=
|
||||
golang.org/x/exp v0.0.0-20200908183739-ae8ad444f925/go.mod h1:1phAWC201xIgDyaFpmDeZkgf70Q4Pd/CNqfRtVPtxNw=
|
||||
golang.org/x/exp v0.0.0-20220414153411-bcd21879b8fd h1:zVFyTKZN/Q7mNRWSs1GOYnHM9NiFSJ54YVRsD0rNWT4=
|
||||
golang.org/x/exp v0.0.0-20220414153411-bcd21879b8fd/go.mod h1:lgLbSvA5ygNOMpwM/9anMpWVlVJ7Z+cHWq/eFuinpGE=
|
||||
golang.org/x/image v0.0.0-20180708004352-c73c2afc3b81/go.mod h1:ux5Hcp/YLpHSI86hEcLt0YII63i6oz57MZXIpbrjZUs=
|
||||
golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
|
||||
golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
|
||||
@ -1821,8 +1823,8 @@ golang.org/x/mod v0.3.1-0.20200828183125-ce943fd02449/go.mod h1:s0Qsj1ACt9ePp/hM
|
||||
golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.5.1 h1:OJxoQ/rynoF0dcCdI7cLPktw/hR2cueqYfjm43oqK38=
|
||||
golang.org/x/mod v0.5.1/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro=
|
||||
golang.org/x/mod v0.6.0-dev.0.20211013180041-c96bc1413d57 h1:LQmS1nU0twXLA96Kt7U9qtHJEbBk3z6Q0V4UXjZkpr4=
|
||||
golang.org/x/mod v0.6.0-dev.0.20211013180041-c96bc1413d57/go.mod h1:3p9vT2HGsQu2K1YbXdKPJLVgG5VJdoTa1poYQBtP1AY=
|
||||
golang.org/x/net v0.0.0-20170114055629-f2499483f923/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180218175443-cbe0f9307d01/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180530234432-1e491301e022/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
|
Reference in New Issue
Block a user