1
15
16 package repo_test
17
18 import (
19 "fmt"
20 "os"
21 "path/filepath"
22 "runtime"
23 "strings"
24 "testing"
25
26 "github.com/bazelbuild/bazel-gazelle/repo"
27 "github.com/bazelbuild/bazel-gazelle/rule"
28 "github.com/bazelbuild/bazel-gazelle/testtools"
29 )
30
31 func TestFindExternalRepo(t *testing.T) {
32 if runtime.GOOS == "windows" {
33 t.Skip("symlinks not supported on windows")
34 }
35
36 dir, err := os.MkdirTemp(os.Getenv("TEST_TEMPDIR"), "TestFindExternalRepo")
37 if err != nil {
38 t.Fatal(err)
39 }
40 defer os.RemoveAll(dir)
41 dir, err = filepath.EvalSymlinks(dir)
42 if err != nil {
43 t.Fatal(err)
44 }
45
46 name := "foo"
47 externalPath := filepath.Join(dir, "bazel", "output-base", "external", name)
48 if err := os.MkdirAll(externalPath, 0o777); err != nil {
49 t.Fatal(err)
50 }
51
52 bazelOutPath := filepath.Join(dir, "bazel", "output-base", "execroot", "test", "bazel-out")
53 if err := os.MkdirAll(bazelOutPath, 0o777); err != nil {
54 t.Fatal(err)
55 }
56
57 workspacePath := filepath.Join(dir, "workspace")
58 if err := os.MkdirAll(workspacePath, 0o777); err != nil {
59 t.Fatal(err)
60 }
61 if err := os.Symlink(bazelOutPath, filepath.Join(workspacePath, "bazel-out")); err != nil {
62 t.Fatal(err)
63 }
64
65 if got, err := repo.FindExternalRepo(workspacePath, name); err != nil {
66 t.Fatal(err)
67 } else if got != externalPath {
68 t.Errorf("got %q ; want %q", got, externalPath)
69 }
70 }
71
72 func TestListRepositories(t *testing.T) {
73 for _, tc := range []struct {
74 desc, workspace, want string
75 }{
76 {
77 desc: "empty",
78 want: "",
79 }, {
80 desc: "go_repository",
81 workspace: `
82 go_repository(
83 name = "custom_repo",
84 commit = "123456",
85 remote = "https://example.com/repo",
86 importpath = "example.com/repo",
87 )
88 `,
89 want: "custom_repo example.com/repo",
90 },
91 } {
92 t.Run(tc.desc, func(t *testing.T) {
93 workspace, err := rule.LoadData("WORKSPACE", "", []byte(tc.workspace))
94 if err != nil {
95 t.Fatal(err)
96 }
97 repos, _, err := repo.ListRepositories(workspace)
98 if err != nil {
99 t.Fatal(err)
100 }
101 got := reposToString(repos)
102 if got != tc.want {
103 t.Errorf("got\n%s\n\nwant:\n%s", got, tc.want)
104 }
105 })
106 }
107 }
108
109 func TestListRepositoriesWithRepositoryDirective(t *testing.T) {
110 for _, tc := range []struct {
111 desc, workspace, want string
112 }{
113 {
114 desc: "empty",
115 want: "",
116 }, {
117 desc: "git_repository",
118 workspace: `
119 git_repository(
120 name = "custom_repo",
121 commit = "123456",
122 remote = "https://example.com/repo",
123 importpath = "example.com/repo",
124 )
125 # gazelle:repository go_repository name=custom_repo importpath=example.com/repo1
126 # gazelle:repository go_repository name=custom_repo_2 importpath=example.com/repo2
127 `,
128 want: `custom_repo example.com/repo1
129 custom_repo_2 example.com/repo2`,
130 }, {
131 desc: "directive_prefer_latest",
132 workspace: `
133 # gazelle:repository go_repository name=custom_repo importpath=example.com/repo1
134 # gazelle:repository go_repository name=custom_repo_2 importpath=example.com/repo2
135 # gazelle:repository go_repository name=custom_repo importpath=example.com/repo3
136 `,
137 want: `custom_repo example.com/repo3
138 custom_repo_2 example.com/repo2`,
139 },
140 } {
141 t.Run(tc.desc, func(t *testing.T) {
142 workspace, err := rule.LoadData("WORKSPACE", "", []byte(tc.workspace))
143 if err != nil {
144 t.Fatal(err)
145 }
146 repos, _, err := repo.ListRepositories(workspace)
147 if err != nil {
148 t.Fatal(err)
149 }
150 got := reposToString(repos)
151 if got != tc.want {
152 t.Errorf("got\n%s\n\nwant:\n%s", got, tc.want)
153 }
154 })
155 }
156 }
157
158 func TestListRepositoriesWithRepositoryMacroDirective(t *testing.T) {
159 files := []testtools.FileSpec{{
160 Path: "repos1.bzl",
161 Content: `
162 def go_repositories():
163 go_repository(
164 name = "go_repo",
165 commit = "123456",
166 remote = "https://example.com/go",
167 importpath = "example.com/go",
168 )
169
170 def foo_repositories():
171 go_repository(
172 name = "foo_repo",
173 commit = "123456",
174 remote = "https://example.com/foo",
175 importpath = "example.com/foo",
176 )
177 `,
178 }, {
179 Path: "repos2.bzl",
180 Content: `
181 def bar_repositories():
182 # gazelle:repository go_repository name=extra_repo importpath=example.com/extra
183 go_repository(
184 name = "bar_repo",
185 commit = "123456",
186 remote = "https://example.com/bar",
187 importpath = "example.com/bar",
188 )
189
190 def baz_repositories():
191 # gazelle:repository go_repository name=ignored_repo importpath=example.com/ignored
192 go_repository(
193 name = "ignored_repo",
194 commit = "123456",
195 remote = "https://example.com/ignored",
196 importpath = "example.com/ignored",
197 )
198 `,
199 }}
200 dir, cleanup := testtools.CreateFiles(t, files)
201 defer cleanup()
202 workspaceString := `
203 # gazelle:repository_macro repos1.bzl%go_repositories
204 # gazelle:repository_macro repos1.bzl%foo_repositories
205 # gazelle:repository_macro repos2.bzl%bar_repositories
206 `
207 workspace, err := rule.LoadData(dir+"/WORKSPACE", "", []byte(workspaceString))
208 if err != nil {
209 t.Fatal(err)
210 }
211 repos, _, err := repo.ListRepositories(workspace)
212 if err != nil {
213 t.Fatal(err)
214 }
215 got := reposToString(repos)
216 want := `go_repo example.com/go
217 foo_repo example.com/foo
218 bar_repo example.com/bar
219 extra_repo example.com/extra`
220 if got != want {
221 t.Errorf("got\n%s\n\nwant:\n%s", got, want)
222 }
223 }
224
225 func TestListRepositoriesWithPlusRepositoryMacroDirective(t *testing.T) {
226 files := []testtools.FileSpec{{
227 Path: "repos1.bzl",
228 Content: `
229 load("repos2.bzl", "bar_repositories", alias = "alias_repositories")
230 def go_repositories():
231
232 bar_repositories()
233 alias()
234
235 go_repository(
236 name = "go_repo",
237 commit = "123456",
238 remote = "https://example.com/go",
239 importpath = "example.com/go",
240 )
241
242 `,
243 }, {
244 Path: "repos2.bzl",
245 Content: `
246 def bar_repositories():
247 go_repository(
248 name = "bar_repo",
249 commit = "123456",
250 remote = "https://example.com/bar",
251 importpath = "example.com/bar",
252 )
253
254 def alias_repositories():
255 go_repository(
256 name = "alias_repo",
257 commit = "123456",
258 remote = "https://example.com/alias",
259 importpath = "example.com/alias",
260 )
261 `,
262 }}
263 dir, cleanup := testtools.CreateFiles(t, files)
264 defer cleanup()
265 workspaceString := `
266 # gazelle:repository_macro +repos1.bzl%go_repositories`
267 workspace, err := rule.LoadData(filepath.Join(dir, "WORKSPACE"), "", []byte(workspaceString))
268 if err != nil {
269 t.Fatal(err)
270 }
271 repos, _, err := repo.ListRepositories(workspace)
272 if err != nil {
273 t.Fatal(err)
274 }
275 got := reposToString(repos)
276 want := `bar_repo example.com/bar
277 alias_repo example.com/alias
278 go_repo example.com/go`
279 if got != want {
280 t.Errorf("got\n%s\n\nwant:\n%s", got, want)
281 }
282 }
283
284 func reposToString(repos []*rule.Rule) string {
285 buf := &strings.Builder{}
286 sep := ""
287 for _, r := range repos {
288 fmt.Fprintf(buf, "%s%s %s", sep, r.Name(), r.AttrString("importpath"))
289 sep = "\n"
290 }
291 return buf.String()
292 }
293
View as plain text