| /* Copyright 2017 The Bazel Authors. All rights reserved. |
| |
| Licensed under the Apache License, Version 2.0 (the "License"); |
| you may not use this file except in compliance with the License. |
| You may obtain a copy of the License at |
| |
| http://www.apache.org/licenses/LICENSE-2.0 |
| |
| Unless required by applicable law or agreed to in writing, software |
| distributed under the License is distributed on an "AS IS" BASIS, |
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| See the License for the specific language governing permissions and |
| limitations under the License. |
| */ |
| |
| package repo_test |
| |
| import ( |
| "fmt" |
| "os" |
| "path/filepath" |
| "runtime" |
| "strings" |
| "testing" |
| |
| "github.com/bazelbuild/bazel-gazelle/repo" |
| "github.com/bazelbuild/bazel-gazelle/rule" |
| "github.com/bazelbuild/bazel-gazelle/testtools" |
| ) |
| |
| func TestFindExternalRepo(t *testing.T) { |
| if runtime.GOOS == "windows" { |
| t.Skip("symlinks not supported on windows") |
| } |
| |
| dir, err := os.MkdirTemp(os.Getenv("TEST_TEMPDIR"), "TestFindExternalRepo") |
| if err != nil { |
| t.Fatal(err) |
| } |
| defer os.RemoveAll(dir) |
| dir, err = filepath.EvalSymlinks(dir) |
| if err != nil { |
| t.Fatal(err) |
| } |
| |
| name := "foo" |
| externalPath := filepath.Join(dir, "bazel", "output-base", "external", name) |
| if err := os.MkdirAll(externalPath, 0o777); err != nil { |
| t.Fatal(err) |
| } |
| |
| bazelOutPath := filepath.Join(dir, "bazel", "output-base", "execroot", "test", "bazel-out") |
| if err := os.MkdirAll(bazelOutPath, 0o777); err != nil { |
| t.Fatal(err) |
| } |
| |
| workspacePath := filepath.Join(dir, "workspace") |
| if err := os.MkdirAll(workspacePath, 0o777); err != nil { |
| t.Fatal(err) |
| } |
| if err := os.Symlink(bazelOutPath, filepath.Join(workspacePath, "bazel-out")); err != nil { |
| t.Fatal(err) |
| } |
| |
| if got, err := repo.FindExternalRepo(workspacePath, name); err != nil { |
| t.Fatal(err) |
| } else if got != externalPath { |
| t.Errorf("got %q ; want %q", got, externalPath) |
| } |
| } |
| |
| func TestListRepositories(t *testing.T) { |
| for _, tc := range []struct { |
| desc, workspace, want string |
| }{ |
| { |
| desc: "empty", |
| want: "", |
| }, { |
| desc: "go_repository", |
| workspace: ` |
| go_repository( |
| name = "custom_repo", |
| commit = "123456", |
| remote = "https://example.com/repo", |
| importpath = "example.com/repo", |
| ) |
| `, |
| want: "custom_repo example.com/repo", |
| }, |
| } { |
| t.Run(tc.desc, func(t *testing.T) { |
| workspace, err := rule.LoadData("WORKSPACE", "", []byte(tc.workspace)) |
| if err != nil { |
| t.Fatal(err) |
| } |
| repos, _, err := repo.ListRepositories(workspace) |
| if err != nil { |
| t.Fatal(err) |
| } |
| got := reposToString(repos) |
| if got != tc.want { |
| t.Errorf("got\n%s\n\nwant:\n%s", got, tc.want) |
| } |
| }) |
| } |
| } |
| |
| func TestListRepositoriesWithRepositoryDirective(t *testing.T) { |
| for _, tc := range []struct { |
| desc, workspace, want string |
| }{ |
| { |
| desc: "empty", |
| want: "", |
| }, { |
| desc: "git_repository", |
| workspace: ` |
| git_repository( |
| name = "custom_repo", |
| commit = "123456", |
| remote = "https://example.com/repo", |
| importpath = "example.com/repo", |
| ) |
| # gazelle:repository go_repository name=custom_repo importpath=example.com/repo1 |
| # gazelle:repository go_repository name=custom_repo_2 importpath=example.com/repo2 |
| `, |
| want: `custom_repo example.com/repo1 |
| custom_repo_2 example.com/repo2`, |
| }, { |
| desc: "directive_prefer_latest", |
| workspace: ` |
| # gazelle:repository go_repository name=custom_repo importpath=example.com/repo1 |
| # gazelle:repository go_repository name=custom_repo_2 importpath=example.com/repo2 |
| # gazelle:repository go_repository name=custom_repo importpath=example.com/repo3 |
| `, |
| want: `custom_repo example.com/repo3 |
| custom_repo_2 example.com/repo2`, |
| }, |
| } { |
| t.Run(tc.desc, func(t *testing.T) { |
| workspace, err := rule.LoadData("WORKSPACE", "", []byte(tc.workspace)) |
| if err != nil { |
| t.Fatal(err) |
| } |
| repos, _, err := repo.ListRepositories(workspace) |
| if err != nil { |
| t.Fatal(err) |
| } |
| got := reposToString(repos) |
| if got != tc.want { |
| t.Errorf("got\n%s\n\nwant:\n%s", got, tc.want) |
| } |
| }) |
| } |
| } |
| |
| func TestListRepositoriesWithRepositoryMacroDirective(t *testing.T) { |
| files := []testtools.FileSpec{{ |
| Path: "repos1.bzl", |
| Content: ` |
| def go_repositories(): |
| go_repository( |
| name = "go_repo", |
| commit = "123456", |
| remote = "https://example.com/go", |
| importpath = "example.com/go", |
| ) |
| |
| def foo_repositories(): |
| go_repository( |
| name = "foo_repo", |
| commit = "123456", |
| remote = "https://example.com/foo", |
| importpath = "example.com/foo", |
| ) |
| `, |
| }, { |
| Path: "repos2.bzl", |
| Content: ` |
| def bar_repositories(): |
| # gazelle:repository go_repository name=extra_repo importpath=example.com/extra |
| go_repository( |
| name = "bar_repo", |
| commit = "123456", |
| remote = "https://example.com/bar", |
| importpath = "example.com/bar", |
| ) |
| |
| def baz_repositories(): |
| # gazelle:repository go_repository name=ignored_repo importpath=example.com/ignored |
| go_repository( |
| name = "ignored_repo", |
| commit = "123456", |
| remote = "https://example.com/ignored", |
| importpath = "example.com/ignored", |
| ) |
| `, |
| }} |
| dir, cleanup := testtools.CreateFiles(t, files) |
| defer cleanup() |
| workspaceString := ` |
| # gazelle:repository_macro repos1.bzl%go_repositories |
| # gazelle:repository_macro repos1.bzl%foo_repositories |
| # gazelle:repository_macro repos2.bzl%bar_repositories |
| ` |
| workspace, err := rule.LoadData(dir+"/WORKSPACE", "", []byte(workspaceString)) |
| if err != nil { |
| t.Fatal(err) |
| } |
| repos, _, err := repo.ListRepositories(workspace) |
| if err != nil { |
| t.Fatal(err) |
| } |
| got := reposToString(repos) |
| want := `go_repo example.com/go |
| foo_repo example.com/foo |
| bar_repo example.com/bar |
| extra_repo example.com/extra` |
| if got != want { |
| t.Errorf("got\n%s\n\nwant:\n%s", got, want) |
| } |
| } |
| |
| func TestListRepositoriesWithPlusRepositoryMacroDirective(t *testing.T) { |
| files := []testtools.FileSpec{{ |
| Path: "repos1.bzl", |
| Content: ` |
| load("repos2.bzl", "bar_repositories", alias = "alias_repositories") |
| def go_repositories(): |
| |
| bar_repositories() |
| alias() |
| |
| go_repository( |
| name = "go_repo", |
| commit = "123456", |
| remote = "https://example.com/go", |
| importpath = "example.com/go", |
| ) |
| |
| `, |
| }, { |
| Path: "repos2.bzl", |
| Content: ` |
| def bar_repositories(): |
| go_repository( |
| name = "bar_repo", |
| commit = "123456", |
| remote = "https://example.com/bar", |
| importpath = "example.com/bar", |
| ) |
| |
| def alias_repositories(): |
| go_repository( |
| name = "alias_repo", |
| commit = "123456", |
| remote = "https://example.com/alias", |
| importpath = "example.com/alias", |
| ) |
| `, |
| }} |
| dir, cleanup := testtools.CreateFiles(t, files) |
| defer cleanup() |
| workspaceString := ` |
| # gazelle:repository_macro +repos1.bzl%go_repositories` |
| workspace, err := rule.LoadData(filepath.Join(dir, "WORKSPACE"), "", []byte(workspaceString)) |
| if err != nil { |
| t.Fatal(err) |
| } |
| repos, _, err := repo.ListRepositories(workspace) |
| if err != nil { |
| t.Fatal(err) |
| } |
| got := reposToString(repos) |
| want := `bar_repo example.com/bar |
| alias_repo example.com/alias |
| go_repo example.com/go` |
| if got != want { |
| t.Errorf("got\n%s\n\nwant:\n%s", got, want) |
| } |
| } |
| |
| func reposToString(repos []*rule.Rule) string { |
| buf := &strings.Builder{} |
| sep := "" |
| for _, r := range repos { |
| fmt.Fprintf(buf, "%s%s %s", sep, r.Name(), r.AttrString("importpath")) |
| sep = "\n" |
| } |
| return buf.String() |
| } |