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  }