github.com/bazelbuild/bazel-gazelle@v0.36.1-0.20240520142334-61b277ba6fed/repo/repo_test.go (about) 1 /* Copyright 2017 The Bazel Authors. All rights reserved. 2 3 Licensed under the Apache License, Version 2.0 (the "License"); 4 you may not use this file except in compliance with the License. 5 You may obtain a copy of the License at 6 7 http://www.apache.org/licenses/LICENSE-2.0 8 9 Unless required by applicable law or agreed to in writing, software 10 distributed under the License is distributed on an "AS IS" BASIS, 11 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 See the License for the specific language governing permissions and 13 limitations under the License. 14 */ 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 }