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 }