Skip to content

Commit 17ba4c8

Browse files
authored
fix: Allow template names to be re-used after deletion (#2454)
Fixes #2152
1 parent 289b989 commit 17ba4c8

5 files changed

+60
-7
lines changed

cli/templatecreate_test.go

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package cli_test
22

33
import (
4+
"io"
45
"os"
56
"testing"
67

@@ -197,6 +198,53 @@ func TestTemplateCreate(t *testing.T) {
197198
require.EqualError(t, <-execDone, "Parameter value absent in parameter file for \"region\"!")
198199
removeTmpDirUntilSuccess(t, tempDir)
199200
})
201+
202+
t.Run("Recreate template with same name (create, delete, create)", func(t *testing.T) {
203+
t.Parallel()
204+
client := coderdtest.New(t, &coderdtest.Options{IncludeProvisionerD: true})
205+
coderdtest.CreateFirstUser(t, client)
206+
207+
create := func() error {
208+
source := clitest.CreateTemplateVersionSource(t, &echo.Responses{
209+
Parse: echo.ParseComplete,
210+
Provision: provisionCompleteWithAgent,
211+
})
212+
args := []string{
213+
"templates",
214+
"create",
215+
"my-template",
216+
"--yes",
217+
"--directory", source,
218+
"--test.provisioner", string(database.ProvisionerTypeEcho),
219+
}
220+
cmd, root := clitest.New(t, args...)
221+
clitest.SetupConfig(t, client, root)
222+
cmd.SetOut(io.Discard)
223+
cmd.SetErr(io.Discard)
224+
225+
return cmd.Execute()
226+
}
227+
del := func() error {
228+
args := []string{
229+
"templates",
230+
"delete",
231+
"my-template",
232+
}
233+
cmd, root := clitest.New(t, args...)
234+
clitest.SetupConfig(t, client, root)
235+
cmd.SetOut(io.Discard)
236+
cmd.SetErr(io.Discard)
237+
238+
return cmd.Execute()
239+
}
240+
241+
err := create()
242+
require.NoError(t, err, "Template must be created without error")
243+
err = del()
244+
require.NoError(t, err, "Template must be deleted without error")
245+
err = create()
246+
require.NoError(t, err, "Template must be recreated without error")
247+
})
200248
}
201249

202250
func createTestParseResponse() []*proto.Parse_Response {

cli/templatedelete.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ func templateDelete() *cobra.Command {
7676
return xerrors.Errorf("delete template %q: %w", template.Name, err)
7777
}
7878

79-
_, _ = fmt.Fprintln(cmd.ErrOrStderr(), "Deleted template "+cliui.Styles.Code.Render(template.Name)+"!")
79+
_, _ = fmt.Fprintln(cmd.OutOrStdout(), "Deleted template "+cliui.Styles.Code.Render(template.Name)+"!")
8080
}
8181

8282
return nil

coderd/database/dump.sql

Lines changed: 1 addition & 6 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
DROP INDEX templates_organization_id_name_idx;
2+
CREATE UNIQUE INDEX templates_organization_id_name_idx ON templates USING btree (organization_id, name) WHERE deleted = false;
3+
CREATE UNIQUE INDEX idx_templates_name_lower ON templates USING btree (lower(name));
4+
5+
ALTER TABLE ONLY templates ADD CONSTRAINT templates_organization_id_name_key UNIQUE (organization_id, name);
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
DROP INDEX idx_templates_name_lower;
2+
DROP INDEX templates_organization_id_name_idx;
3+
CREATE UNIQUE INDEX templates_organization_id_name_idx ON templates (organization_id, lower(name)) WHERE deleted = false;
4+
5+
ALTER TABLE ONLY templates DROP CONSTRAINT templates_organization_id_name_key;

0 commit comments

Comments
 (0)