Skip to content

Commit 4b2219c

Browse files
authoredAug 23, 2024··
fix: duplicate import added when import path contains hyphens (#859) (#890)
1 parent ce14607 commit 4b2219c

File tree

8 files changed

+146
-29
lines changed

8 files changed

+146
-29
lines changed
 

‎.version

+1-1
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
0.2.766
1+
0.2.768

‎cmd/templ/imports/process.go

+3-3
Original file line numberDiff line numberDiff line change
@@ -137,16 +137,16 @@ func Process(t parser.TemplateFile) (parser.TemplateFile, error) {
137137
return t, nil
138138
}
139139

140-
func getImportDetails(imp *ast.ImportSpec) (name, path string, err error) {
140+
func getImportDetails(imp *ast.ImportSpec) (name, importPath string, err error) {
141141
if imp.Name != nil {
142142
name = imp.Name.Name
143143
}
144144
if imp.Path != nil {
145-
path, err = strconv.Unquote(imp.Path.Value)
145+
importPath, err = strconv.Unquote(imp.Path.Value)
146146
if err != nil {
147147
err = fmt.Errorf("failed to unquote package path %s: %w", imp.Path.Value, err)
148148
return
149149
}
150150
}
151-
return name, path, nil
151+
return name, importPath, nil
152152
}

‎cmd/templ/imports/process_test.go

+92
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,13 @@ package imports
22

33
import (
44
"bytes"
5+
"os"
6+
"path"
57
"path/filepath"
68
"strings"
79
"testing"
810

11+
"github.com/a-h/templ/cmd/templ/testproject"
912
"github.com/a-h/templ/parser/v2"
1013
"github.com/google/go-cmp/cmp"
1114
"golang.org/x/tools/txtar"
@@ -60,3 +63,92 @@ func clean(b []byte) string {
6063
b = bytes.TrimSuffix(b, []byte("\n"))
6164
return string(b)
6265
}
66+
67+
func TestImport(t *testing.T) {
68+
if testing.Short() {
69+
t.Skip("skipping test in short mode.")
70+
return
71+
}
72+
73+
tests := []struct {
74+
name string
75+
src string
76+
assertions func(t *testing.T, updated string)
77+
}{
78+
{
79+
name: "un-named imports are removed",
80+
src: `package main
81+
82+
import "fmt"
83+
import "github.com/a-h/templ/cmd/templ/testproject/css-classes"
84+
85+
templ Page(count int) {
86+
{ fmt.Sprintf("%d", count) }
87+
{ cssclasses.Header }
88+
}
89+
`,
90+
assertions: func(t *testing.T, updated string) {
91+
if count := strings.Count(updated, "github.com/a-h/templ/cmd/templ/testproject/css-classes"); count != 0 {
92+
t.Errorf("expected un-named import to be removed, but got %d instance of it", count)
93+
}
94+
},
95+
},
96+
{
97+
name: "named imports are retained",
98+
src: `package main
99+
100+
import "fmt"
101+
import cssclasses "github.com/a-h/templ/cmd/templ/testproject/css-classes"
102+
103+
templ Page(count int) {
104+
{ fmt.Sprintf("%d", count) }
105+
{ cssclasses.Header }
106+
}
107+
`,
108+
assertions: func(t *testing.T, updated string) {
109+
if count := strings.Count(updated, "cssclasses \"github.com/a-h/templ/cmd/templ/testproject/css-classes\""); count != 1 {
110+
t.Errorf("expected named import to be retained, got %d instances of it", count)
111+
}
112+
if count := strings.Count(updated, "github.com/a-h/templ/cmd/templ/testproject/css-classes"); count != 1 {
113+
t.Errorf("expected one import, got %d", count)
114+
}
115+
},
116+
},
117+
}
118+
119+
for _, test := range tests {
120+
// Create test project.
121+
dir, err := testproject.Create("github.com/a-h/templ/cmd/templ/testproject")
122+
if err != nil {
123+
t.Fatalf("failed to create test project: %v", err)
124+
}
125+
defer os.RemoveAll(dir)
126+
127+
// Load the templates.templ file.
128+
filePath := path.Join(dir, "templates.templ")
129+
err = os.WriteFile(filePath, []byte(test.src), 0660)
130+
if err != nil {
131+
t.Fatalf("failed to write file: %v", err)
132+
}
133+
134+
// Parse the new file.
135+
template, err := parser.Parse(filePath)
136+
if err != nil {
137+
t.Fatalf("failed to parse %v", err)
138+
}
139+
template.Filepath = filePath
140+
tf, err := Process(template)
141+
if err != nil {
142+
t.Fatalf("failed to process file: %v", err)
143+
}
144+
145+
// Write it back out after processing.
146+
buf := new(strings.Builder)
147+
if err := tf.Write(buf); err != nil {
148+
t.Fatalf("failed to write template file: %v", err)
149+
}
150+
151+
// Assert.
152+
test.assertions(t, buf.String())
153+
}
154+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
package cssclasses
2+
3+
const Header = "header"

‎cmd/templ/testproject/testproject.go

+22
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,12 @@ func Create(moduleRoot string) (dir string, err error) {
2222
return dir, fmt.Errorf("failed to read embedded dir: %w", err)
2323
}
2424
for _, file := range files {
25+
if file.IsDir() {
26+
if err = os.MkdirAll(filepath.Join(dir, file.Name()), 0777); err != nil {
27+
return dir, fmt.Errorf("failed to create dir: %w", err)
28+
}
29+
continue
30+
}
2531
src := filepath.Join("testdata", file.Name())
2632
data, err := testdata.ReadFile(src)
2733
if err != nil {
@@ -38,6 +44,22 @@ func Create(moduleRoot string) (dir string, err error) {
3844
return dir, fmt.Errorf("failed to copy file: %w", err)
3945
}
4046
}
47+
files, err = testdata.ReadDir("testdata/css-classes")
48+
if err != nil {
49+
return dir, fmt.Errorf("failed to read embedded dir: %w", err)
50+
}
51+
for _, file := range files {
52+
src := filepath.Join("testdata", "css-classes", file.Name())
53+
data, err := testdata.ReadFile(src)
54+
if err != nil {
55+
return dir, fmt.Errorf("failed to read file: %w", err)
56+
}
57+
target := filepath.Join(dir, "css-classes", file.Name())
58+
err = os.WriteFile(target, data, 0660)
59+
if err != nil {
60+
return dir, fmt.Errorf("failed to copy file: %w", err)
61+
}
62+
}
4163
return dir, nil
4264
}
4365

‎go.mod

+5-5
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,9 @@ require (
1919
go.lsp.dev/jsonrpc2 v0.10.0
2020
go.lsp.dev/uri v0.3.0
2121
go.uber.org/zap v1.27.0
22-
golang.org/x/mod v0.17.0
23-
golang.org/x/sync v0.3.0
24-
golang.org/x/tools v0.13.0
22+
golang.org/x/mod v0.20.0
23+
golang.org/x/sync v0.8.0
24+
golang.org/x/tools v0.24.0
2525
)
2626

2727
require (
@@ -33,8 +33,8 @@ require (
3333
github.com/stretchr/testify v1.8.4 // indirect
3434
go.lsp.dev/pkg v0.0.0-20210717090340-384b27a52fb2 // indirect
3535
go.uber.org/multierr v1.11.0 // indirect
36-
golang.org/x/net v0.24.0 // indirect
37-
golang.org/x/sys v0.21.0 // indirect
36+
golang.org/x/net v0.28.0 // indirect
37+
golang.org/x/sys v0.23.0 // indirect
3838
)
3939

4040
// replace github.com/a-h/parse => /Users/adrian/github.com/a-h/parse

‎go.sum

+10-10
Original file line numberDiff line numberDiff line change
@@ -58,19 +58,19 @@ go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E=
5858
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
5959
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
6060
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
61-
golang.org/x/mod v0.17.0 h1:zY54UmvipHiNd+pm+m0x9KhZ9hl1/7QNMyxXbc6ICqA=
62-
golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
61+
golang.org/x/mod v0.20.0 h1:utOm6MM3R3dnawAiJgn0y+xvuYRsm1RKM/4giyfDgV0=
62+
golang.org/x/mod v0.20.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
6363
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
6464
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
6565
golang.org/x/net v0.0.0-20210916014120-12bc252f5db8/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
6666
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
6767
golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
68-
golang.org/x/net v0.24.0 h1:1PcaxkF854Fu3+lvBIx5SYn9wRlBzzcnHZSiaFFAb0w=
69-
golang.org/x/net v0.24.0/go.mod h1:2Q7sJY5mzlzWjKtYUEXSlBWCdyaioyXzRB2RtU8KVE8=
68+
golang.org/x/net v0.28.0 h1:a9JDOJc5GMUJ0+UDqmLT86WiEy7iWyIhz8gz8E4e5hE=
69+
golang.org/x/net v0.28.0/go.mod h1:yqtgsTWOOnlGLG9GFRrK3++bGOUEkNBoHZc8MEDWPNg=
7070
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
7171
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
72-
golang.org/x/sync v0.3.0 h1:ftCYgMx6zT/asHUrPw8BLLscYtGznsLAnjq5RH9P66E=
73-
golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y=
72+
golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ=
73+
golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
7474
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
7575
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
7676
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
@@ -80,8 +80,8 @@ golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBc
8080
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
8181
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
8282
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
83-
golang.org/x/sys v0.21.0 h1:rF+pYz3DAGSQAxAu1CbC7catZg4ebC4UIeIhKxBZvws=
84-
golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
83+
golang.org/x/sys v0.23.0 h1:YfKFowiIMvtgl1UERQoTPPToxltDeZfbj4H7dVUCwmM=
84+
golang.org/x/sys v0.23.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
8585
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
8686
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
8787
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
@@ -93,8 +93,8 @@ golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
9393
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
9494
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
9595
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
96-
golang.org/x/tools v0.13.0 h1:Iey4qkscZuv0VvIt8E0neZjtPVQFSc870HQ448QgEmQ=
97-
golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58=
96+
golang.org/x/tools v0.24.0 h1:J1shsA93PJUEVaUSaay7UXAyE8aimq3GW0pjlolpa24=
97+
golang.org/x/tools v0.24.0/go.mod h1:YhNqVBIfWHdzvTLs0d8LCuMhkKUgSUKldakyV7W/WDQ=
9898
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
9999
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
100100
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=

‎gomod2nix.toml

+10-10
Original file line numberDiff line numberDiff line change
@@ -74,17 +74,17 @@ schema = 3
7474
version = "v1.27.0"
7575
hash = "sha256-8655KDrulc4Das3VRduO9MjCn8ZYD5WkULjCvruaYsU="
7676
[mod."golang.org/x/mod"]
77-
version = "v0.17.0"
78-
hash = "sha256-CLaPeF6uTFuRDv4oHwOQE6MCMvrzkUjWN3NuyywZjKU="
77+
version = "v0.20.0"
78+
hash = "sha256-nXYnY2kpbVkaZ/7Mf7FmxwGDX7N4cID3gKjGghmVRp4="
7979
[mod."golang.org/x/net"]
80-
version = "v0.24.0"
81-
hash = "sha256-w1c21ljta5wNIyel9CSIn/crPzwOCRofNKhqmfs4aEQ="
80+
version = "v0.28.0"
81+
hash = "sha256-WdH/mgsX/CB+CiYtXEwJAXHN8FgtW2YhFcWwrrHNBLo="
8282
[mod."golang.org/x/sync"]
83-
version = "v0.3.0"
84-
hash = "sha256-bCJKLvwExhYacH2ZrWlZ38lr1d6oNenNt2m1QqDCs0o="
83+
version = "v0.8.0"
84+
hash = "sha256-usvF0z7gq1vsX58p4orX+8WHlv52pdXgaueXlwj2Wss="
8585
[mod."golang.org/x/sys"]
86-
version = "v0.21.0"
87-
hash = "sha256-gapzPWuEqY36V6W2YhIDYR49sEvjJRd7bSuf9K1f4JY="
86+
version = "v0.23.0"
87+
hash = "sha256-tC6QVLu72bADgINz26FUGdmYqKgsU45bHPg7sa0ZV7w="
8888
[mod."golang.org/x/tools"]
89-
version = "v0.13.0"
90-
hash = "sha256-OCgLOwia8fNHxfdogXVApf0/qK6jE2ukegOx7lkOzfo="
89+
version = "v0.24.0"
90+
hash = "sha256-2LBEW//aW8qrHc26F6Ma7CsYJRaCALfi0xQl2KgWems="

0 commit comments

Comments
 (0)
Please sign in to comment.