Skip to content

Commit aed891b

Browse files
authored
fix: fix coder template pull on Windows (#9327)
* fix: fix coder template pull on Windows Signed-off-by: Spike Curtis <spike@coder.com> * appease linter Signed-off-by: Spike Curtis <spike@coder.com> * improvements from code review Signed-off-by: Spike Curtis <spike@coder.com> --------- Signed-off-by: Spike Curtis <spike@coder.com>
1 parent e7a231e commit aed891b

File tree

2 files changed

+165
-112
lines changed

2 files changed

+165
-112
lines changed

cli/templatepull.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ func (r *RootCmd) templatePull() *clibase.Cmd {
8383
}
8484

8585
if dest == "" {
86-
dest = templateName + "/"
86+
dest = templateName
8787
}
8888

8989
err = os.MkdirAll(dest, 0o750)

cli/templatepull_test.go

+164-111
Original file line numberDiff line numberDiff line change
@@ -40,165 +40,218 @@ func dirSum(t *testing.T, dir string) string {
4040
return hex.EncodeToString(sum.Sum(nil))
4141
}
4242

43-
func TestTemplatePull(t *testing.T) {
43+
func TestTemplatePull_NoName(t *testing.T) {
4444
t.Parallel()
4545

46-
t.Run("NoName", func(t *testing.T) {
47-
t.Parallel()
46+
inv, _ := clitest.New(t, "templates", "pull")
47+
err := inv.Run()
48+
require.Error(t, err)
49+
}
4850

49-
inv, _ := clitest.New(t, "templates", "pull")
50-
err := inv.Run()
51-
require.Error(t, err)
52-
})
51+
// Stdout tests that 'templates pull' pulls down the latest template
52+
// and writes it to stdout.
53+
func TestTemplatePull_Stdout(t *testing.T) {
54+
t.Parallel()
5355

54-
// Stdout tests that 'templates pull' pulls down the latest template
55-
// and writes it to stdout.
56-
t.Run("Stdout", func(t *testing.T) {
57-
t.Parallel()
56+
client := coderdtest.New(t, &coderdtest.Options{IncludeProvisionerDaemon: true})
57+
user := coderdtest.CreateFirstUser(t, client)
5858

59-
client := coderdtest.New(t, &coderdtest.Options{IncludeProvisionerDaemon: true})
60-
user := coderdtest.CreateFirstUser(t, client)
59+
// Create an initial template bundle.
60+
source1 := genTemplateVersionSource()
61+
// Create an updated template bundle. This will be used to ensure
62+
// that templates are correctly returned in order from latest to oldest.
63+
source2 := genTemplateVersionSource()
6164

62-
// Create an initial template bundle.
63-
source1 := genTemplateVersionSource()
64-
// Create an updated template bundle. This will be used to ensure
65-
// that templates are correctly returned in order from latest to oldest.
66-
source2 := genTemplateVersionSource()
65+
expected, err := echo.Tar(source2)
66+
require.NoError(t, err)
6767

68-
expected, err := echo.Tar(source2)
69-
require.NoError(t, err)
68+
version1 := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, source1)
69+
_ = coderdtest.AwaitTemplateVersionJob(t, client, version1.ID)
7070

71-
version1 := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, source1)
72-
_ = coderdtest.AwaitTemplateVersionJob(t, client, version1.ID)
71+
template := coderdtest.CreateTemplate(t, client, user.OrganizationID, version1.ID)
7372

74-
template := coderdtest.CreateTemplate(t, client, user.OrganizationID, version1.ID)
73+
// Update the template version so that we can assert that templates
74+
// are being sorted correctly.
75+
_ = coderdtest.UpdateTemplateVersion(t, client, user.OrganizationID, source2, template.ID)
7576

76-
// Update the template version so that we can assert that templates
77-
// are being sorted correctly.
78-
_ = coderdtest.UpdateTemplateVersion(t, client, user.OrganizationID, source2, template.ID)
77+
inv, root := clitest.New(t, "templates", "pull", "--tar", template.Name)
78+
clitest.SetupConfig(t, client, root)
7979

80-
inv, root := clitest.New(t, "templates", "pull", "--tar", template.Name)
81-
clitest.SetupConfig(t, client, root)
80+
var buf bytes.Buffer
81+
inv.Stdout = &buf
8282

83-
var buf bytes.Buffer
84-
inv.Stdout = &buf
83+
err = inv.Run()
84+
require.NoError(t, err)
8585

86-
err = inv.Run()
87-
require.NoError(t, err)
86+
require.True(t, bytes.Equal(expected, buf.Bytes()), "tar files differ")
87+
}
8888

89-
require.True(t, bytes.Equal(expected, buf.Bytes()), "tar files differ")
90-
})
89+
// ToDir tests that 'templates pull' pulls down the latest template
90+
// and writes it to the correct directory.
91+
func TestTemplatePull_ToDir(t *testing.T) {
92+
t.Parallel()
9193

92-
// ToDir tests that 'templates pull' pulls down the latest template
93-
// and writes it to the correct directory.
94-
t.Run("ToDir", func(t *testing.T) {
95-
t.Parallel()
94+
client := coderdtest.New(t, &coderdtest.Options{IncludeProvisionerDaemon: true})
95+
user := coderdtest.CreateFirstUser(t, client)
9696

97-
client := coderdtest.New(t, &coderdtest.Options{IncludeProvisionerDaemon: true})
98-
user := coderdtest.CreateFirstUser(t, client)
97+
// Create an initial template bundle.
98+
source1 := genTemplateVersionSource()
99+
// Create an updated template bundle. This will be used to ensure
100+
// that templates are correctly returned in order from latest to oldest.
101+
source2 := genTemplateVersionSource()
99102

100-
// Create an initial template bundle.
101-
source1 := genTemplateVersionSource()
102-
// Create an updated template bundle. This will be used to ensure
103-
// that templates are correctly returned in order from latest to oldest.
104-
source2 := genTemplateVersionSource()
103+
expected, err := echo.Tar(source2)
104+
require.NoError(t, err)
105105

106-
expected, err := echo.Tar(source2)
107-
require.NoError(t, err)
106+
version1 := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, source1)
107+
_ = coderdtest.AwaitTemplateVersionJob(t, client, version1.ID)
108108

109-
version1 := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, source1)
110-
_ = coderdtest.AwaitTemplateVersionJob(t, client, version1.ID)
109+
template := coderdtest.CreateTemplate(t, client, user.OrganizationID, version1.ID)
111110

112-
template := coderdtest.CreateTemplate(t, client, user.OrganizationID, version1.ID)
111+
// Update the template version so that we can assert that templates
112+
// are being sorted correctly.
113+
_ = coderdtest.UpdateTemplateVersion(t, client, user.OrganizationID, source2, template.ID)
113114

114-
// Update the template version so that we can assert that templates
115-
// are being sorted correctly.
116-
_ = coderdtest.UpdateTemplateVersion(t, client, user.OrganizationID, source2, template.ID)
115+
dir := t.TempDir()
117116

118-
dir := t.TempDir()
117+
expectedDest := filepath.Join(dir, "expected")
118+
actualDest := filepath.Join(dir, "actual")
119+
ctx := context.Background()
119120

120-
expectedDest := filepath.Join(dir, "expected")
121-
actualDest := filepath.Join(dir, "actual")
122-
ctx := context.Background()
121+
err = extract.Tar(ctx, bytes.NewReader(expected), expectedDest, nil)
122+
require.NoError(t, err)
123123

124-
err = extract.Tar(ctx, bytes.NewReader(expected), expectedDest, nil)
125-
require.NoError(t, err)
124+
inv, root := clitest.New(t, "templates", "pull", template.Name, actualDest)
125+
clitest.SetupConfig(t, client, root)
126126

127-
inv, root := clitest.New(t, "templates", "pull", template.Name, actualDest)
128-
clitest.SetupConfig(t, client, root)
127+
ptytest.New(t).Attach(inv)
129128

130-
ptytest.New(t).Attach(inv)
129+
require.NoError(t, inv.Run())
131130

132-
require.NoError(t, inv.Run())
131+
require.Equal(t,
132+
dirSum(t, expectedDest),
133+
dirSum(t, actualDest),
134+
)
135+
}
133136

134-
require.Equal(t,
135-
dirSum(t, expectedDest),
136-
dirSum(t, actualDest),
137-
)
138-
})
137+
// ToDir tests that 'templates pull' pulls down the latest template
138+
// and writes it to a directory with the name of the template if the path is not implicitly supplied.
139+
// nolint: paralleltest
140+
func TestTemplatePull_ToImplicit(t *testing.T) {
141+
client := coderdtest.New(t, &coderdtest.Options{IncludeProvisionerDaemon: true})
142+
user := coderdtest.CreateFirstUser(t, client)
139143

140-
// FolderConflict tests that 'templates pull' fails when a folder with has
141-
// existing
142-
t.Run("FolderConflict", func(t *testing.T) {
143-
t.Parallel()
144+
// Create an initial template bundle.
145+
source1 := genTemplateVersionSource()
146+
// Create an updated template bundle. This will be used to ensure
147+
// that templates are correctly returned in order from latest to oldest.
148+
source2 := genTemplateVersionSource()
144149

145-
client := coderdtest.New(t, &coderdtest.Options{IncludeProvisionerDaemon: true})
146-
user := coderdtest.CreateFirstUser(t, client)
150+
expected, err := echo.Tar(source2)
151+
require.NoError(t, err)
147152

148-
// Create an initial template bundle.
149-
source1 := genTemplateVersionSource()
150-
// Create an updated template bundle. This will be used to ensure
151-
// that templates are correctly returned in order from latest to oldest.
152-
source2 := genTemplateVersionSource()
153+
version1 := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, source1)
154+
_ = coderdtest.AwaitTemplateVersionJob(t, client, version1.ID)
153155

154-
expected, err := echo.Tar(source2)
155-
require.NoError(t, err)
156+
template := coderdtest.CreateTemplate(t, client, user.OrganizationID, version1.ID)
156157

157-
version1 := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, source1)
158-
_ = coderdtest.AwaitTemplateVersionJob(t, client, version1.ID)
158+
// Update the template version so that we can assert that templates
159+
// are being sorted correctly.
160+
_ = coderdtest.UpdateTemplateVersion(t, client, user.OrganizationID, source2, template.ID)
159161

160-
template := coderdtest.CreateTemplate(t, client, user.OrganizationID, version1.ID)
162+
// create a tempdir and change the working directory to it for the duration of the test (cannot run in parallel)
163+
dir := t.TempDir()
164+
wd, err := os.Getwd()
165+
require.NoError(t, err)
166+
err = os.Chdir(dir)
167+
require.NoError(t, err)
168+
defer func() {
169+
err := os.Chdir(wd)
170+
require.NoError(t, err, "if this fails, it can break other subsequent tests due to wrong working directory")
171+
}()
161172

162-
// Update the template version so that we can assert that templates
163-
// are being sorted correctly.
164-
_ = coderdtest.UpdateTemplateVersion(t, client, user.OrganizationID, source2, template.ID)
173+
expectedDest := filepath.Join(dir, "expected")
174+
actualDest := filepath.Join(dir, template.Name)
165175

166-
dir := t.TempDir()
176+
ctx := context.Background()
167177

168-
expectedDest := filepath.Join(dir, "expected")
169-
conflictDest := filepath.Join(dir, "conflict")
178+
err = extract.Tar(ctx, bytes.NewReader(expected), expectedDest, nil)
179+
require.NoError(t, err)
170180

171-
err = os.MkdirAll(conflictDest, 0o700)
172-
require.NoError(t, err)
181+
inv, root := clitest.New(t, "templates", "pull", template.Name)
182+
clitest.SetupConfig(t, client, root)
173183

174-
err = os.WriteFile(
175-
filepath.Join(conflictDest, "conflict-file"),
176-
[]byte("conflict"), 0o600,
177-
)
178-
require.NoError(t, err)
184+
ptytest.New(t).Attach(inv)
179185

180-
ctx := context.Background()
186+
require.NoError(t, inv.Run())
181187

182-
err = extract.Tar(ctx, bytes.NewReader(expected), expectedDest, nil)
183-
require.NoError(t, err)
188+
require.Equal(t,
189+
dirSum(t, expectedDest),
190+
dirSum(t, actualDest),
191+
)
192+
}
193+
194+
// FolderConflict tests that 'templates pull' fails when a folder with has
195+
// existing
196+
func TestTemplatePull_FolderConflict(t *testing.T) {
197+
t.Parallel()
184198

185-
inv, root := clitest.New(t, "templates", "pull", template.Name, conflictDest)
186-
clitest.SetupConfig(t, client, root)
199+
client := coderdtest.New(t, &coderdtest.Options{IncludeProvisionerDaemon: true})
200+
user := coderdtest.CreateFirstUser(t, client)
187201

188-
pty := ptytest.New(t).Attach(inv)
202+
// Create an initial template bundle.
203+
source1 := genTemplateVersionSource()
204+
// Create an updated template bundle. This will be used to ensure
205+
// that templates are correctly returned in order from latest to oldest.
206+
source2 := genTemplateVersionSource()
189207

190-
waiter := clitest.StartWithWaiter(t, inv)
208+
expected, err := echo.Tar(source2)
209+
require.NoError(t, err)
191210

192-
pty.ExpectMatch("not empty")
193-
pty.WriteLine("no")
211+
version1 := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, source1)
212+
_ = coderdtest.AwaitTemplateVersionJob(t, client, version1.ID)
194213

195-
waiter.RequireError()
214+
template := coderdtest.CreateTemplate(t, client, user.OrganizationID, version1.ID)
196215

197-
ents, err := os.ReadDir(conflictDest)
198-
require.NoError(t, err)
216+
// Update the template version so that we can assert that templates
217+
// are being sorted correctly.
218+
_ = coderdtest.UpdateTemplateVersion(t, client, user.OrganizationID, source2, template.ID)
219+
220+
dir := t.TempDir()
221+
222+
expectedDest := filepath.Join(dir, "expected")
223+
conflictDest := filepath.Join(dir, "conflict")
224+
225+
err = os.MkdirAll(conflictDest, 0o700)
226+
require.NoError(t, err)
227+
228+
err = os.WriteFile(
229+
filepath.Join(conflictDest, "conflict-file"),
230+
[]byte("conflict"), 0o600,
231+
)
232+
require.NoError(t, err)
233+
234+
ctx := context.Background()
235+
236+
err = extract.Tar(ctx, bytes.NewReader(expected), expectedDest, nil)
237+
require.NoError(t, err)
238+
239+
inv, root := clitest.New(t, "templates", "pull", template.Name, conflictDest)
240+
clitest.SetupConfig(t, client, root)
241+
242+
pty := ptytest.New(t).Attach(inv)
243+
244+
waiter := clitest.StartWithWaiter(t, inv)
245+
246+
pty.ExpectMatch("not empty")
247+
pty.WriteLine("no")
248+
249+
waiter.RequireError()
250+
251+
ents, err := os.ReadDir(conflictDest)
252+
require.NoError(t, err)
199253

200-
require.Len(t, ents, 1, "conflict folder should have single conflict file")
201-
})
254+
require.Len(t, ents, 1, "conflict folder should have single conflict file")
202255
}
203256

204257
// genTemplateVersionSource returns a unique bundle that can be used to create

0 commit comments

Comments
 (0)