github.com/please-build/puku@v1.7.3-0.20240516143641-f7d7f4941f57/graph/graph_test.go (about)

     1  package graph
     2  
     3  import (
     4  	"bytes"
     5  	"testing"
     6  
     7  	"github.com/please-build/buildtools/build"
     8  	"github.com/please-build/buildtools/labels"
     9  	"github.com/stretchr/testify/assert"
    10  	"github.com/stretchr/testify/require"
    11  
    12  	"github.com/please-build/puku/config"
    13  	"github.com/please-build/puku/edit"
    14  )
    15  
    16  func TestLoadBuildFile(t *testing.T) {
    17  	g := New([]string{"BUILD_FILE", "BUILD_FILE.plz"})
    18  
    19  	f, err := g.LoadFile("test_project")
    20  	require.NoError(t, err)
    21  
    22  	libs := f.Rules("go_library")
    23  	require.Len(t, libs, 1)
    24  
    25  	f, err = g.LoadFile("test_project/foo")
    26  	require.NoError(t, err)
    27  
    28  	libs = f.Rules("go_library")
    29  	require.Len(t, libs, 1)
    30  
    31  	f, err = g.LoadFile("test_project/foo/bar")
    32  	require.NoError(t, err)
    33  	assert.Equal(t, "test_project/foo/bar/BUILD_FILE", f.Path)
    34  }
    35  
    36  func TestEnsureVisibility(t *testing.T) {
    37  	g := New(nil).WithExperimentalDirs("exp", "experimental")
    38  
    39  	foo, err := build.ParseBuild("foo/BUILD", []byte(`
    40  go_library(
    41  	name = "foo",
    42  	srcs = ["main.go"],
    43  )
    44  `))
    45  	require.NoError(t, err)
    46  
    47  	bar, err := build.ParseBuild("bar/BUILD", []byte(`
    48  go_library(
    49  	name = "bar",
    50  	srcs = ["bar.go"],
    51  	deps = ["//foo"],
    52  )
    53  `))
    54  	require.NoError(t, err)
    55  
    56  	experimental, err := build.ParseBuild("experimental/BUILD", []byte(`
    57  go_library(
    58  	name = "experimental",
    59  	srcs = ["experimental.go"],
    60  	deps = ["//foo"],
    61  )
    62  `))
    63  	require.NoError(t, err)
    64  
    65  	g.files["foo"] = foo
    66  	g.files["bar"] = bar
    67  	g.files["experimental"] = experimental
    68  
    69  	g.EnsureVisibility("//bar", "//foo")
    70  	g.EnsureVisibility("//bar", "///github.com//foo")          // skipped - target in subrepo
    71  	g.EnsureVisibility("//bar", ":foo")                        // skipped - local dep
    72  	g.EnsureVisibility("//bar:bar_test", "//bar")              // skipped - also local
    73  	g.EnsureVisibility("//experimental:experimental", "//foo") // skipped - experimental
    74  	require.Len(t, g.deps, 1)
    75  	require.Equal(t, g.deps[0], &Dependency{
    76  		From: labels.Parse("//bar"),
    77  		To:   labels.Parse("//foo"),
    78  	})
    79  
    80  	bs := new(bytes.Buffer)
    81  	err = g.FormatFilesWithWriter(bs, "text")
    82  	require.NoError(t, err)
    83  
    84  	fooT := edit.FindTargetByName(g.files["foo"], "foo")
    85  	assert.ElementsMatch(t, []string{"//bar:all"}, fooT.AttrStrings("visibility"))
    86  
    87  	require.Contains(t, bs.String(), `visibility = ["//bar:all"]`)
    88  }
    89  
    90  func TestDefaultVisibility(t *testing.T) {
    91  	conf := &config.Config{
    92  		LibKinds: map[string]*config.KindConfig{
    93  			"my_go_library": {
    94  				DefaultVisibility: []string{"//bar/..."},
    95  			},
    96  		},
    97  	}
    98  
    99  	foo, err := build.ParseBuild("foo/BUILD", []byte(`
   100  my_go_library(
   101  	name = "foo",
   102  	srcs = ["main.go"],
   103  )
   104  `))
   105  	require.NoError(t, err)
   106  
   107  	bar, err := build.ParseBuild("bar/BUILD", []byte(`
   108  package(default_visibility = ["//baz/..."])
   109  
   110  go_library(
   111  	name = "bar",
   112  	srcs = ["bar.go"],
   113  	deps = ["//foo"],
   114  )
   115  `))
   116  	require.NoError(t, err)
   117  
   118  	baz, err := build.ParseBuild("baz/BUILD", []byte(`
   119  package(default_visibility = ["//fizz/..."])
   120  
   121  go_library(
   122  	name = "baz",
   123  	srcs = ["baz.go"],
   124  	deps = ["//foo"],
   125  	visibility = ["//foo/..."],
   126  )
   127  `))
   128  	require.NoError(t, err)
   129  
   130  	fizz, err := build.ParseBuild("baz/BUILD", []byte(`
   131  go_library(
   132  	name = "fizz",
   133  	srcs = ["fizz.go"],
   134  	deps = ["//baz"],
   135  )
   136  `))
   137  	require.NoError(t, err)
   138  
   139  	g := New(nil)
   140  	g.files["foo"] = foo
   141  	g.files["bar"] = bar
   142  	g.files["baz"] = baz
   143  	g.files["fizz"] = fizz
   144  
   145  	g.EnsureVisibility("//bar", "//foo")  // Handled by kinds default visibility
   146  	g.EnsureVisibility("//baz", "//bar")  // Handled by package default visibility
   147  	g.EnsureVisibility("//fizz", "//baz") // Needs update as package visibility is overridden by visibility arg
   148  
   149  	for _, dep := range g.deps {
   150  		require.NoError(t, g.ensureVisibility(conf, dep))
   151  	}
   152  
   153  	assert.Empty(t, edit.FindTargetByName(foo, "foo").AttrStrings("visibility"))
   154  	assert.Empty(t, edit.FindTargetByName(bar, "bar").AttrStrings("visibility"))
   155  	assert.Empty(t, edit.FindTargetByName(fizz, "fizz").AttrStrings("visibility"))
   156  
   157  	// This was overridden even though we set the package visibility because the rule set visibility explicitly
   158  	assert.ElementsMatch(t,
   159  		[]string{"//foo/...", "//fizz:all"},
   160  		edit.FindTargetByName(baz, "baz").AttrStrings("visibility"),
   161  	)
   162  }
   163  
   164  func TestCheckVisibility(t *testing.T) {
   165  	label := labels.Parse("//foo/bar:baz")
   166  	t.Run("matches exactly", func(t *testing.T) {
   167  		assert.True(t, checkVisibility(label, []string{"//foo/bar:baz"}))
   168  	})
   169  	t.Run("matches all psudo-label", func(t *testing.T) {
   170  		assert.True(t, checkVisibility(label, []string{"//foo/bar:all"}))
   171  	})
   172  	t.Run("matches PUBLIC", func(t *testing.T) {
   173  		assert.True(t, checkVisibility(label, []string{"PUBLIC"}))
   174  	})
   175  	t.Run("matches package wildcard", func(t *testing.T) {
   176  		assert.True(t, checkVisibility(label, []string{"//foo/..."}))
   177  	})
   178  
   179  	t.Run("doesnt match a different package wildcard", func(t *testing.T) {
   180  		assert.False(t, checkVisibility(label, []string{"//bar/..."}))
   181  	})
   182  	t.Run("doesnt match a different package", func(t *testing.T) {
   183  		assert.False(t, checkVisibility(label, []string{"//bar:all"}))
   184  	})
   185  }
   186  
   187  func TestGetDefaultVisibilityFromFile(t *testing.T) {
   188  	file, err := build.ParseBuild("test", []byte("package(default_visibility = [\"PUBLIC\"])"))
   189  	require.NoError(t, err)
   190  
   191  	assert.Equal(t, []string{"PUBLIC"}, getDefaultVisibility(file))
   192  }