Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 11e586d

Browse files
mafredrikylecarbs
authored andcommitted
feat: Unify cli behavior for templates create and update (#1385)
Fixes #565
1 parent fee541d commit 11e586d

File tree

4 files changed

+143
-44
lines changed

4 files changed

+143
-44
lines changed

cli/templatecreate.go

+25-16
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,8 @@ func templateCreate() *cobra.Command {
2727
)
2828
cmd := &cobra.Command{
2929
Use: "create [name]",
30-
Short: "Create a template from the current directory",
30+
Short: "Create a template from the current directory or as specified by flag",
31+
Args: cobra.MaximumNArgs(1),
3132
RunE: func(cmd *cobra.Command, args []string) error {
3233
client, err := createClient(cmd)
3334
if err != nil {
@@ -51,19 +52,10 @@ func templateCreate() *cobra.Command {
5152
return xerrors.Errorf("A template already exists named %q!", templateName)
5253
}
5354

54-
// Confirm upload of the users current directory.
55-
// Truncate if in the home directory, because a shorter path looks nicer.
56-
displayDirectory := directory
57-
userHomeDir, err := os.UserHomeDir()
58-
if err != nil {
59-
return xerrors.Errorf("get home dir: %w", err)
60-
}
61-
if strings.HasPrefix(displayDirectory, userHomeDir) {
62-
displayDirectory = strings.TrimPrefix(displayDirectory, userHomeDir)
63-
displayDirectory = "~" + displayDirectory
64-
}
55+
// Confirm upload of the directory.
56+
prettyDir := prettyDirectoryPath(directory)
6557
_, err = cliui.Prompt(cmd, cliui.PromptOptions{
66-
Text: fmt.Sprintf("Create and upload %q?", displayDirectory),
58+
Text: fmt.Sprintf("Create and upload %q?", prettyDir),
6759
IsConfirm: true,
6860
Default: "yes",
6961
})
@@ -73,7 +65,7 @@ func templateCreate() *cobra.Command {
7365

7466
spin := spinner.New(spinner.CharSets[5], 100*time.Millisecond)
7567
spin.Writer = cmd.OutOrStdout()
76-
spin.Suffix = cliui.Styles.Keyword.Render(" Uploading current directory...")
68+
spin.Suffix = cliui.Styles.Keyword.Render(" Uploading directory...")
7769
spin.Start()
7870
defer spin.Stop()
7971
archive, err := provisionersdk.Tar(directory, provisionersdk.TemplateArchiveLimit)
@@ -123,9 +115,9 @@ func templateCreate() *cobra.Command {
123115
}
124116
currentDirectory, _ := os.Getwd()
125117
cmd.Flags().StringVarP(&directory, "directory", "d", currentDirectory, "Specify the directory to create from")
126-
cmd.Flags().StringVarP(&provisioner, "provisioner", "p", "terraform", "Customize the provisioner backend")
118+
cmd.Flags().StringVarP(&provisioner, "test.provisioner", "", "terraform", "Customize the provisioner backend")
127119
// This is for testing!
128-
err := cmd.Flags().MarkHidden("provisioner")
120+
err := cmd.Flags().MarkHidden("test.provisioner")
129121
if err != nil {
130122
panic(err)
131123
}
@@ -228,3 +220,20 @@ func createValidTemplateVersion(cmd *cobra.Command, client *codersdk.Client, org
228220

229221
return &version, parameters, nil
230222
}
223+
224+
// prettyDirectoryPath returns a prettified path when inside the users
225+
// home directory. Falls back to dir if the users home directory cannot
226+
// discerned. This function calls filepath.Clean on the result.
227+
func prettyDirectoryPath(dir string) string {
228+
dir = filepath.Clean(dir)
229+
homeDir, err := os.UserHomeDir()
230+
if err != nil {
231+
return dir
232+
}
233+
pretty := dir
234+
if strings.HasPrefix(pretty, homeDir) {
235+
pretty = strings.TrimPrefix(pretty, homeDir)
236+
pretty = "~" + pretty
237+
}
238+
return pretty
239+
}

cli/templatecreate_test.go

+16-14
Original file line numberDiff line numberDiff line change
@@ -22,28 +22,30 @@ func TestTemplateCreate(t *testing.T) {
2222
Parse: echo.ParseComplete,
2323
Provision: echo.ProvisionComplete,
2424
})
25-
cmd, root := clitest.New(t, "templates", "create", "my-template", "--directory", source, "--provisioner", string(database.ProvisionerTypeEcho))
25+
cmd, root := clitest.New(t, "templates", "create", "my-template", "--directory", source, "--test.provisioner", string(database.ProvisionerTypeEcho))
2626
clitest.SetupConfig(t, client, root)
2727
_ = coderdtest.NewProvisionerDaemon(t, client)
28-
doneChan := make(chan struct{})
2928
pty := ptytest.New(t)
3029
cmd.SetIn(pty.Input())
3130
cmd.SetOut(pty.Output())
31+
32+
execDone := make(chan error)
3233
go func() {
33-
defer close(doneChan)
34-
err := cmd.Execute()
35-
require.NoError(t, err)
34+
execDone <- cmd.Execute()
3635
}()
37-
matches := []string{
38-
"Create and upload", "yes",
39-
"Confirm create?", "yes",
36+
37+
matches := []struct {
38+
match string
39+
write string
40+
}{
41+
{match: "Create and upload", write: "yes"},
42+
{match: "Confirm create?", write: "yes"},
4043
}
41-
for i := 0; i < len(matches); i += 2 {
42-
match := matches[i]
43-
value := matches[i+1]
44-
pty.ExpectMatch(match)
45-
pty.WriteLine(value)
44+
for _, m := range matches {
45+
pty.ExpectMatch(m.match)
46+
pty.WriteLine(m.write)
4647
}
47-
<-doneChan
48+
49+
require.NoError(t, <-execDone)
4850
})
4951
}

cli/templateupdate.go

+38-14
Original file line numberDiff line numberDiff line change
@@ -3,22 +3,28 @@ package cli
33
import (
44
"fmt"
55
"os"
6-
"path/filepath"
76
"time"
87

8+
"github.com/briandowns/spinner"
99
"github.com/spf13/cobra"
1010
"golang.org/x/xerrors"
1111

12+
"github.com/coder/coder/cli/cliui"
1213
"github.com/coder/coder/coderd/database"
1314
"github.com/coder/coder/codersdk"
1415
"github.com/coder/coder/provisionersdk"
1516
)
1617

1718
func templateUpdate() *cobra.Command {
18-
return &cobra.Command{
19-
Use: "update <template> [directory]",
20-
Args: cobra.MinimumNArgs(1),
21-
Short: "Update the source-code of a template from a directory.",
19+
var (
20+
directory string
21+
provisioner string
22+
)
23+
24+
cmd := &cobra.Command{
25+
Use: "update <template>",
26+
Args: cobra.ExactArgs(1),
27+
Short: "Update the source-code of a template from the current directory or as specified by flag",
2228
RunE: func(cmd *cobra.Command, args []string) error {
2329
client, err := createClient(cmd)
2430
if err != nil {
@@ -33,16 +39,22 @@ func templateUpdate() *cobra.Command {
3339
return err
3440
}
3541

36-
directory, err := os.Getwd()
42+
// Confirm upload of the directory.
43+
prettyDir := prettyDirectoryPath(directory)
44+
_, err = cliui.Prompt(cmd, cliui.PromptOptions{
45+
Text: fmt.Sprintf("Upload %q?", prettyDir),
46+
IsConfirm: true,
47+
Default: "yes",
48+
})
3749
if err != nil {
3850
return err
3951
}
40-
if len(args) >= 2 {
41-
directory, err = filepath.Abs(args[1])
42-
if err != nil {
43-
return err
44-
}
45-
}
52+
53+
spin := spinner.New(spinner.CharSets[5], 100*time.Millisecond)
54+
spin.Writer = cmd.OutOrStdout()
55+
spin.Suffix = cliui.Styles.Keyword.Render(" Uploading directory...")
56+
spin.Start()
57+
defer spin.Stop()
4658
content, err := provisionersdk.Tar(directory, provisionersdk.TemplateArchiveLimit)
4759
if err != nil {
4860
return err
@@ -51,13 +63,14 @@ func templateUpdate() *cobra.Command {
5163
if err != nil {
5264
return err
5365
}
66+
spin.Stop()
5467

5568
before := time.Now()
5669
templateVersion, err := client.CreateTemplateVersion(cmd.Context(), organization.ID, codersdk.CreateTemplateVersionRequest{
5770
TemplateID: template.ID,
5871
StorageMethod: database.ProvisionerStorageMethodFile,
5972
StorageSource: resp.Hash,
60-
Provisioner: database.ProvisionerTypeTerraform,
73+
Provisioner: database.ProvisionerType(provisioner),
6174
})
6275
if err != nil {
6376
return err
@@ -71,7 +84,7 @@ func templateUpdate() *cobra.Command {
7184
if !ok {
7285
break
7386
}
74-
_, _ = fmt.Printf("terraform (%s): %s\n", log.Level, log.Output)
87+
_, _ = fmt.Printf("%s (%s): %s\n", provisioner, log.Level, log.Output)
7588
}
7689
templateVersion, err = client.TemplateVersion(cmd.Context(), templateVersion.ID)
7790
if err != nil {
@@ -92,4 +105,15 @@ func templateUpdate() *cobra.Command {
92105
return nil
93106
},
94107
}
108+
109+
currentDirectory, _ := os.Getwd()
110+
cmd.Flags().StringVarP(&directory, "directory", "d", currentDirectory, "Specify the directory to create from")
111+
cmd.Flags().StringVarP(&provisioner, "test.provisioner", "", "terraform", "Customize the provisioner backend")
112+
// This is for testing!
113+
err := cmd.Flags().MarkHidden("test.provisioner")
114+
if err != nil {
115+
panic(err)
116+
}
117+
118+
return cmd
95119
}

cli/templateupdate_test.go

+64
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
package cli_test
2+
3+
import (
4+
"context"
5+
"testing"
6+
7+
"github.com/stretchr/testify/assert"
8+
"github.com/stretchr/testify/require"
9+
10+
"github.com/coder/coder/cli/clitest"
11+
"github.com/coder/coder/coderd/coderdtest"
12+
"github.com/coder/coder/coderd/database"
13+
"github.com/coder/coder/codersdk"
14+
"github.com/coder/coder/provisioner/echo"
15+
"github.com/coder/coder/pty/ptytest"
16+
)
17+
18+
func TestTemplateUpdate(t *testing.T) {
19+
t.Parallel()
20+
21+
client := coderdtest.New(t, nil)
22+
user := coderdtest.CreateFirstUser(t, client)
23+
_ = coderdtest.NewProvisionerDaemon(t, client)
24+
version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, nil)
25+
_ = coderdtest.AwaitTemplateVersionJob(t, client, version.ID)
26+
template := coderdtest.CreateTemplate(t, client, user.OrganizationID, version.ID)
27+
28+
// Test the cli command.
29+
source := clitest.CreateTemplateVersionSource(t, &echo.Responses{
30+
Parse: echo.ParseComplete,
31+
Provision: echo.ProvisionComplete,
32+
})
33+
cmd, root := clitest.New(t, "templates", "update", template.Name, "--directory", source, "--test.provisioner", string(database.ProvisionerTypeEcho))
34+
clitest.SetupConfig(t, client, root)
35+
pty := ptytest.New(t)
36+
cmd.SetIn(pty.Input())
37+
cmd.SetOut(pty.Output())
38+
39+
execDone := make(chan error)
40+
go func() {
41+
execDone <- cmd.Execute()
42+
}()
43+
44+
matches := []struct {
45+
match string
46+
write string
47+
}{
48+
{match: "Upload", write: "yes"},
49+
}
50+
for _, m := range matches {
51+
pty.ExpectMatch(m.match)
52+
pty.WriteLine(m.write)
53+
}
54+
55+
require.NoError(t, <-execDone)
56+
57+
// Assert that the template version changed.
58+
templateVersions, err := client.TemplateVersionsByTemplate(context.Background(), codersdk.TemplateVersionsByTemplateRequest{
59+
TemplateID: template.ID,
60+
})
61+
require.NoError(t, err)
62+
assert.Len(t, templateVersions, 2)
63+
assert.NotEqual(t, template.ActiveVersionID, templateVersions[1].ID)
64+
}

0 commit comments

Comments
 (0)