Skip to content

Commit

Permalink
Add go_bazel_test for nogo
Browse files Browse the repository at this point in the history
Requires some changes to the `go_bazel_test` setup.
  • Loading branch information
fmeum committed Dec 13, 2023
1 parent 7459413 commit 87d36c7
Show file tree
Hide file tree
Showing 6 changed files with 214 additions and 2 deletions.
2 changes: 2 additions & 0 deletions .bazelci/presubmit.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ tasks:
- "//..."
test_targets:
- "//..."
# Bzlmod tests require Bazel 6+
- "-//tests/core/nogo/bzlmod/..."
ubuntu2004:
# enable some unflipped incompatible flags on this platform to ensure we don't regress.
shell_commands:
Expand Down
3 changes: 3 additions & 0 deletions BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,10 @@ filegroup(
testonly = True,
srcs = [
"BUILD.bazel",
"MODULE.bazel",
"WORKSPACE",
"go.mod",
"go.sum",
"//extras:all_files",
"//go:all_files",
"//proto:all_files",
Expand Down
64 changes: 62 additions & 2 deletions go/tools/bazel_testing/bazel_testing.go
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,11 @@ type Args struct {
// of the default generated WORKSPACE file.
WorkspaceSuffix string

// ModuleFileSuffix is a string that should be appended to the end of a
// default generated MODULE.bazel file. If this is empty, no such file is
// generated.
ModuleFileSuffix string

// SetUp is a function that is executed inside the context of the testing
// workspace. It is executed once and only once before the beginning of
// all tests. If SetUp returns a non-nil error, execution is halted and
Expand Down Expand Up @@ -384,8 +389,9 @@ func setupWorkspace(args Args, files []string) (dir string, cleanup func() error

// If there's no WORKSPACE file, create one.
workspacePath := filepath.Join(mainDir, "WORKSPACE")
if _, err := os.Stat(workspacePath); os.IsNotExist(err) {
w, err := os.Create(workspacePath)
if _, err = os.Stat(workspacePath); os.IsNotExist(err) {
var w *os.File
w, err = os.Create(workspacePath)
if err != nil {
return "", cleanup, err
}
Expand Down Expand Up @@ -416,6 +422,46 @@ func setupWorkspace(args Args, files []string) (dir string, cleanup func() error
}
}

// If a MODULE.bazel file is requested, create one.
if args.ModuleFileSuffix != "" {
moduleBazelPath := filepath.Join(mainDir, "MODULE.bazel")
if _, err = os.Stat(moduleBazelPath); err == nil {
return "", cleanup, fmt.Errorf("ModuleFileSuffix set but MODULE.bazel exists")
}
var w *os.File
w, err = os.Create(moduleBazelPath)
if err != nil {
return "", cleanup, err
}
defer func() {
if cerr := w.Close(); err == nil && cerr != nil {
err = cerr
}
}()
rulesGoAbsPath := filepath.Join(execDir, "io_bazel_rules_go")
rulesGoPath, err := filepath.Rel(mainDir, rulesGoAbsPath)
if err != nil {
return "", cleanup, fmt.Errorf("could not find relative path from %q to %q for io_bazel_rules_go", mainDir, rulesGoAbsPath)
}
rulesGoPath = filepath.ToSlash(rulesGoPath)
info := moduleFileTemplateInfo{
RulesGoPath: rulesGoPath,
Suffix: args.ModuleFileSuffix,
}
if err := defaultModuleBazelTpl.Execute(w, info); err != nil {
return "", cleanup, err
}

// Enable Bzlmod.
bazelrcPath := filepath.Join(mainDir, ".bazelrc")
if _, err = os.Stat(bazelrcPath); os.IsNotExist(err) {
err = os.WriteFile(bazelrcPath, []byte("common --enable_bzlmod"), 0666)
if err != nil {
return "", cleanup, err
}
}
}

return mainDir, cleanup, nil
}

Expand Down Expand Up @@ -511,6 +557,20 @@ go_register_toolchains({{if .Nogo}}nogo = "{{.Nogo}}"{{end}})
{{.Suffix}}
`))

type moduleFileTemplateInfo struct {
RulesGoPath string
Suffix string
}

var defaultModuleBazelTpl = template.Must(template.New("").Parse(`
bazel_dep(name = "rules_go", version = "", repo_name = "io_bazel_rules_go")
local_path_override(
module_name = "rules_go",
path = "{{.RulesGoPath}}",
)
{{.Suffix}}
`))

func copyOrLink(dstPath, srcPath string) error {
if err := os.MkdirAll(filepath.Dir(dstPath), 0777); err != nil {
return err
Expand Down
6 changes: 6 additions & 0 deletions tests/core/nogo/bzlmod/BUILD.bazel
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
load("@io_bazel_rules_go//go/tools/bazel_testing:def.bzl", "go_bazel_test")

go_bazel_test(
name = "includes_exclude_test",
srcs = ["includes_excludes_test.go"],
)
15 changes: 15 additions & 0 deletions tests/core/nogo/bzlmod/README.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
Nogo Bzlmod configuration
==================

.. _nogo: /go/nogo.rst
.. _Bzlmod: /docs/go/core/bzlmod.md

Tests that verify nogo_ works when configured from ``MODULE.bazel``.

.. contents::

includes_excludes_test
-----------

Verifies that `go_library`_ targets can be built in default configurations with
nogo with includes and excludes being honored.
126 changes: 126 additions & 0 deletions tests/core/nogo/bzlmod/includes_excludes_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
// Copyright 2019 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 includes_excludes_test

import (
"strings"
"testing"

"github.com/bazelbuild/rules_go/go/tools/bazel_testing"
)

func TestMain(m *testing.M) {
bazel_testing.TestMain(m, bazel_testing.Args{
Nogo: "@io_bazel_rules_go//:tools_nogo",
Main: `
-- BUILD.bazel --
load("@io_bazel_rules_go//go:def.bzl", "go_library", "nogo", "TOOLS_NOGO")
nogo(
name = "my_nogo",
visibility = ["//visibility:public"],
deps = TOOLS_NOGO,
)
go_library(
name = "lib",
srcs = ["lib.go"],
importpath = "example.com/lib",
)
-- lib.go --
package lib
func shadowed() string {
foo := "original"
if foo == "original" {
foo := "shadow"
return foo
}
return foo
}
-- go/BUILD.bazel --
load("@io_bazel_rules_go//go:def.bzl", "go_library")
go_library(
name = "lib",
srcs = ["lib.go"],
importpath = "example.com/go/lib",
)
-- go/lib.go --
package lib
func shadowed() string {
foo := "original"
if foo == "original" {
foo := "shadow"
return foo
}
return foo
}
-- go/third_party/BUILD.bazel --
load("@io_bazel_rules_go//go:def.bzl", "go_library")
go_library(
name = "lib",
srcs = ["lib.go"],
importpath = "example.com/go/third_party/lib",
)
-- go/third_party/lib.go --
package lib
func shadowed() string {
foo := "original"
if foo == "original" {
foo := "shadow"
return foo
}
return foo
}
`,
ModuleFileSuffix: `
go_sdk = use_extension("@io_bazel_rules_go//go:extensions.bzl", "go_sdk")
go_sdk.nogo(
nogo = "//:my_nogo",
includes = ["//go:__subpackages__"],
excludes = ["//go/third_party:__subpackages__"],
)
`,
})
}

func TestNotIncluded(t *testing.T) {
if err := bazel_testing.RunBazel("build", "//:lib"); err != nil {
t.Fatal(err)
}
}

func TestIncluded(t *testing.T) {
if err := bazel_testing.RunBazel("build", "//go:lib"); err == nil {
t.Fatal("Expected build to fail")
} else if !strings.Contains(err.Error(), "go/lib.go:6:3: declaration of \"foo\" shadows declaration at line 4 (shadow)") {
t.Fatalf("Expected error to contain \"go/lib.go:6:3: declaration of \"foo\" shadows declaration at line 4 (shadow)\", got %s", err)
}
}

func TestExcluded(t *testing.T) {
if err := bazel_testing.RunBazel("build", "//go/third_party:lib"); err != nil {
t.Fatal(err)
}
}

0 comments on commit 87d36c7

Please sign in to comment.