Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[DO NOT MERGE] Release 0.50 CI Test #4077

Open
wants to merge 15 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion MODULE.bazel
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
module(
name = "rules_go",
version = "0.49.0",
version = "0.50.1",
compatibility_level = 0,
repo_name = "io_bazel_rules_go",
)
Expand Down
3 changes: 2 additions & 1 deletion docs/go/extras/extras.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ This rule has moved. See [gazelle rule] in the Gazelle repository.

<pre>
gomock(<a href="#gomock-name">name</a>, <a href="#gomock-out">out</a>, <a href="#gomock-library">library</a>, <a href="#gomock-source_importpath">source_importpath</a>, <a href="#gomock-source">source</a>, <a href="#gomock-interfaces">interfaces</a>, <a href="#gomock-package">package</a>, <a href="#gomock-self_package">self_package</a>, <a href="#gomock-aux_files">aux_files</a>,
<a href="#gomock-mockgen_tool">mockgen_tool</a>, <a href="#gomock-imports">imports</a>, <a href="#gomock-copyright_file">copyright_file</a>, <a href="#gomock-mock_names">mock_names</a>, <a href="#gomock-kwargs">kwargs</a>)
<a href="#gomock-mockgen_tool">mockgen_tool</a>, <a href="#gomock-mockgen_args">mockgen_args</a>, <a href="#gomock-imports">imports</a>, <a href="#gomock-copyright_file">copyright_file</a>, <a href="#gomock-mock_names">mock_names</a>, <a href="#gomock-kwargs">kwargs</a>)
</pre>

Calls [mockgen](https://github.com/golang/mock) to generates a Go file containing mocks from the given library.
Expand All @@ -57,6 +57,7 @@ If `source` is given, the mocks are generated in source mode; otherwise in refle
| <a id="gomock-self_package"></a>self_package | the full package import path for the generated code. The purpose of this flag is to prevent import cycles in the generated code by trying to include its own package. See [mockgen's -self_package](https://github.com/golang/mock#flags) for more information. | <code>""</code> |
| <a id="gomock-aux_files"></a>aux_files | a map from source files to their package path. This only needed when <code>source</code> is provided. See [mockgen's -aux_files](https://github.com/golang/mock#flags) for more information. | <code>{}</code> |
| <a id="gomock-mockgen_tool"></a>mockgen_tool | the mockgen tool to run. | <code>Label("//extras/gomock:mockgen")</code> |
| <a id="gomock-mockgen_args"></a>mockgen_args | additional arguments to pass to the mockgen tool. | <code>[]</code> |
| <a id="gomock-imports"></a>imports | dictionary of name-path pairs of explicit imports to use. See [mockgen's -imports](https://github.com/golang/mock#flags) for more information. | <code>{}</code> |
| <a id="gomock-copyright_file"></a>copyright_file | optional file containing copyright to prepend to the generated contents. See [mockgen's -copyright_file](https://github.com/golang/mock#flags) for more information. | <code>None</code> |
| <a id="gomock-mock_names"></a>mock_names | dictionary of interface name to mock name pairs to change the output names of the mock objects. Mock names default to 'Mock' prepended to the name of the interface. See [mockgen's -mock_names](https://github.com/golang/mock#flags) for more information. | <code>{}</code> |
Expand Down
16 changes: 15 additions & 1 deletion extras/gomock.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -160,14 +160,18 @@ _gomock_source = rule(
cfg = "exec",
mandatory = False,
),
"mockgen_args": attr.string_list(
doc = "Additional arguments to pass to the mockgen tool",
mandatory = False,
),
"_go_context_data": attr.label(
default = "//:go_context_data",
),
},
toolchains = [GO_TOOLCHAIN],
)

def gomock(name, out, library = None, source_importpath = "", source = None, interfaces = [], package = "", self_package = "", aux_files = {}, mockgen_tool = _MOCKGEN_TOOL, imports = {}, copyright_file = None, mock_names = {}, **kwargs):
def gomock(name, out, library = None, source_importpath = "", source = None, interfaces = [], package = "", self_package = "", aux_files = {}, mockgen_tool = _MOCKGEN_TOOL, mockgen_args = [], imports = {}, copyright_file = None, mock_names = {}, **kwargs):
"""Calls [mockgen](https://github.com/golang/mock) to generates a Go file containing mocks from the given library.

If `source` is given, the mocks are generated in source mode; otherwise in reflective mode.
Expand All @@ -183,6 +187,7 @@ def gomock(name, out, library = None, source_importpath = "", source = None, int
self_package: the full package import path for the generated code. The purpose of this flag is to prevent import cycles in the generated code by trying to include its own package. See [mockgen's -self_package](https://github.com/golang/mock#flags) for more information.
aux_files: a map from source files to their package path. This only needed when `source` is provided. See [mockgen's -aux_files](https://github.com/golang/mock#flags) for more information.
mockgen_tool: the mockgen tool to run.
mockgen_args: additional arguments to pass to the mockgen tool.
imports: dictionary of name-path pairs of explicit imports to use. See [mockgen's -imports](https://github.com/golang/mock#flags) for more information.
copyright_file: optional file containing copyright to prepend to the generated contents. See [mockgen's -copyright_file](https://github.com/golang/mock#flags) for more information.
mock_names: dictionary of interface name to mock name pairs to change the output names of the mock objects. Mock names default to 'Mock' prepended to the name of the interface. See [mockgen's -mock_names](https://github.com/golang/mock#flags) for more information.
Expand All @@ -199,6 +204,7 @@ def gomock(name, out, library = None, source_importpath = "", source = None, int
self_package = self_package,
aux_files = aux_files,
mockgen_tool = mockgen_tool,
mockgen_args = mockgen_args,
imports = imports,
copyright_file = copyright_file,
mock_names = mock_names,
Expand All @@ -213,6 +219,7 @@ def gomock(name, out, library = None, source_importpath = "", source = None, int
package = package,
self_package = self_package,
mockgen_tool = mockgen_tool,
mockgen_args = mockgen_args,
imports = imports,
copyright_file = copyright_file,
mock_names = mock_names,
Expand Down Expand Up @@ -375,6 +382,11 @@ _gomock_prog_exec = rule(
cfg = "exec",
mandatory = False,
),
"mockgen_args": attr.string_list(
doc = "Additional arguments to pass to the mockgen tool",
mandatory = False,
default = [],
),
"_go_context_data": attr.label(
default = "//:go_context_data",
),
Expand All @@ -398,5 +410,7 @@ def _handle_shared_args(ctx, args):
if len(ctx.attr.mock_names) > 0:
mock_names = ",".join(["{0}={1}".format(name, pkg) for name, pkg in ctx.attr.mock_names.items()])
args += ["-mock_names", mock_names]
if ctx.attr.mockgen_args:
args += ctx.attr.mockgen_args

return args, needed_files
2 changes: 1 addition & 1 deletion go/def.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ TOOLS_NOGO = [str(Label(l)) for l in _TOOLS_NOGO]

# Current version or next version to be tagged. Gazelle and other tools may
# check this to determine compatibility.
RULES_GO_VERSION = "0.49.0"
RULES_GO_VERSION = "0.50.1"

go_context = _go_context
gomock = _gomock
Expand Down
9 changes: 2 additions & 7 deletions go/nogo.rst
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,9 @@
.. footer:: The ``nogo`` logo was derived from the Go gopher, which was designed by Renee French. (http://reneefrench.blogspot.com/) The design is licensed under the Creative Commons 3.0 Attributions license. Read this article for more details: http://blog.golang.org/gopher


**WARNING**: This functionality is experimental, so its API might change.
Please do not rely on it for production use, but feel free to use it and file
issues.

``nogo`` is a tool that analyzes the source code of Go programs. It runs
alongside the Go compiler in the Bazel Go rules and rejects programs that
contain disallowed coding patterns. In addition, ``nogo`` may report
compiler-like errors.
in an action after the Go compiler in the Bazel Go rules and rejects sources that
contain disallowed coding patterns from the configured analyzers.

``nogo`` is a powerful tool for preventing bugs and code anti-patterns early
in the development process. It may be used to run the same analyses as `vet`_,
Expand Down
14 changes: 10 additions & 4 deletions go/private/actions/archive.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,10 @@ load(
"as_tuple",
"split_srcs",
)
load(
"//go/private:context.bzl",
"get_nogo",
)
load(
"//go/private:mode.bzl",
"LINKMODE_C_ARCHIVE",
Expand Down Expand Up @@ -61,14 +65,16 @@ def emit_archive(go, source = None, _recompile_suffix = "", recompile_internal_d
# store export information for compiling dependent packages separately
out_export = go.declare_file(go, name = source.library.name, ext = pre_ext + ".x")
out_cgo_export_h = None # set if cgo used in c-shared or c-archive mode
out_facts = None
out_nogo_log = None
out_nogo_validation = None
nogo = go.get_nogo(go)

nogo = get_nogo(go)
if nogo:
out_facts = go.declare_file(go, name = source.library.name, ext = pre_ext + ".facts")
out_nogo_log = go.declare_file(go, name = source.library.name, ext = pre_ext + ".nogo.log")
out_nogo_validation = go.declare_file(go, name = source.library.name, ext = pre_ext + ".nogo")
else:
out_facts = None
out_nogo_log = None
out_nogo_validation = None

direct = [get_archive(dep) for dep in source.deps]
runfiles = source.runfiles
Expand Down
11 changes: 8 additions & 3 deletions go/private/actions/compilepkg.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -207,12 +207,13 @@ def emit_compilepkg(
_run_nogo(
go,
sources = sources,
cgo_go_srcs = cgo_go_srcs_for_nogo,
importpath = importpath,
importmap = importmap,
archives = archives + ([cover_archive] if cover_archive else []),
recompile_internal_deps = recompile_internal_deps,
cover_mode = cover_mode,
cgo_go_srcs = cgo_go_srcs_for_nogo,
testfilter = testfilter,
out_facts = out_facts,
out_log = out_nogo_log,
out_validation = out_nogo_validation,
Expand All @@ -223,12 +224,13 @@ def _run_nogo(
go,
*,
sources,
cgo_go_srcs,
importpath,
importmap,
archives,
recompile_internal_deps,
cover_mode,
cgo_go_srcs,
testfilter,
out_facts,
out_log,
out_validation,
Expand All @@ -244,7 +246,7 @@ def _run_nogo(
args.add_all(sources, before_each = "-src")
if cgo_go_srcs:
inputs.append(cgo_go_srcs)
args.add_all([cgo_go_srcs], before_each = "-src")
args.add_all([cgo_go_srcs], before_each = "-ignore_src")
if cover_mode:
args.add("-cover_mode", cover_mode)
if recompile_internal_deps:
Expand All @@ -256,7 +258,10 @@ def _run_nogo(
args.add("-importpath", go.label.name)
if importmap:
args.add("-p", importmap)

args.add("-package_list", go.package_list)
if testfilter:
args.add("-testfilter", testfilter)

args.add_all(archives, before_each = "-facts", map_each = _facts)
args.add("-out_facts", out_facts)
Expand Down
13 changes: 10 additions & 3 deletions go/private/context.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -435,9 +435,9 @@ def _matches_scopes(label, scopes):
return True
return False

def _get_nogo(go):
def get_nogo(go):
"""Returns the nogo file for this target, if enabled and in scope."""
label = go._ctx.label
label = go.label
if _matches_scopes(label, NOGO_INCLUDES) and not _matches_scopes(label, NOGO_EXCLUDES):
return go.nogo
else:
Expand Down Expand Up @@ -503,6 +503,14 @@ def go_context(ctx, attr = None):
#
# See https://go.dev/doc/toolchain for more info.
"GOTOOLCHAIN": "local",

# NOTE(#4049): Since Go 1.23.0, os.Readlink (and consequently
# filepath.EvalSymlinks) stopped treating Windows mount points and
# reparse points (junctions) as symbolic links. Bazel uses junctions
# when constructing exec roots, and we use filepath.EvalSymlinks in
# GoStdlib, so this broke us. Setting GODEBUG=winsymlink=0 restores
# the old behavior.
"GODEBUG": "winsymlink=0",
}

# Path mapping can't map the values of environment variables, so we pass GOROOT to the action
Expand Down Expand Up @@ -615,7 +623,6 @@ def go_context(ctx, attr = None):
library_to_source = _library_to_source,
declare_file = _declare_file,
declare_directory = _declare_directory,
get_nogo = _get_nogo,

# Private
# TODO: All uses of this should be removed
Expand Down
10 changes: 10 additions & 0 deletions go/private/platforms.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ BAZEL_GOOS_CONSTRAINTS = {
"freebsd": "@platforms//os:freebsd",
"ios": "@platforms//os:ios",
"linux": "@platforms//os:linux",
"qnx": "@platforms//os:qnx",
"windows": "@platforms//os:windows",
}

Expand Down Expand Up @@ -77,10 +78,19 @@ GOOS_GOARCH = (
("openbsd", "amd64"),
("openbsd", "arm"),
("openbsd", "arm64"),
("osx", "386"),
("osx", "amd64"),
("osx", "arm"),
("osx", "arm64"),
("qnx", "386"),
("qnx", "amd64"),
("qnx", "arm"),
("qnx", "arm64"),
("plan9", "386"),
("plan9", "amd64"),
("plan9", "arm"),
("solaris", "amd64"),
("wasip1", "wasm"),
("windows", "386"),
("windows", "amd64"),
("windows", "arm"),
Expand Down
3 changes: 1 addition & 2 deletions go/private/rules/nogo.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ load(
"EXPORT_PATH",
"GoArchive",
"GoLibrary",
"get_archive",
)
load(
"//go/private/rules:transition.bzl",
Expand All @@ -47,7 +46,7 @@ def _nogo_impl(ctx):
if ctx.attr.debug:
nogo_args.add("-debug")
nogo_inputs = []
analyzer_archives = [get_archive(dep) for dep in ctx.attr.deps]
analyzer_archives = [dep[GoArchive] for dep in ctx.attr.deps]
analyzer_importpaths = [archive.data.importpath for archive in analyzer_archives]
nogo_args.add_all(analyzer_importpaths, before_each = "-analyzer_importpath")
if ctx.file.config:
Expand Down
9 changes: 7 additions & 2 deletions go/private/rules/test.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -60,10 +60,14 @@ def _go_test_impl(ctx):

go = go_context(ctx)

validation_outputs = []

# Compile the library to test with internal white box tests
internal_library = go.new_library(go, testfilter = "exclude")
internal_source = go.library_to_source(go, ctx.attr, internal_library, ctx.coverage_instrumented())
internal_archive = go.archive(go, internal_source)
if internal_archive.data._validation_output:
validation_outputs.append(internal_archive.data._validation_output)
go_srcs = split_srcs(internal_source.srcs).go

# Compile the library with the external black box tests
Expand All @@ -82,6 +86,8 @@ def _go_test_impl(ctx):
), external_library, ctx.coverage_instrumented())
external_source, internal_archive = _recompile_external_deps(go, external_source, internal_archive, [t.label for t in ctx.attr.embed])
external_archive = go.archive(go, external_source, is_external_pkg = True)
if external_archive.data._validation_output:
validation_outputs.append(external_archive.data._validation_output)

# now generate the main function
repo_relative_rundir = ctx.attr.rundir or ctx.label.package or "."
Expand Down Expand Up @@ -165,7 +171,6 @@ def _go_test_impl(ctx):
version_file = ctx.version_file,
info_file = ctx.info_file,
)
validation_output = test_archive.data._validation_output

env = {}
for k, v in ctx.attr.env.items():
Expand All @@ -187,7 +192,7 @@ def _go_test_impl(ctx):
),
OutputGroupInfo(
compilation_outputs = [internal_archive.data.file],
_validation = [validation_output] if validation_output else [],
_validation = validation_outputs,
),
coverage_common.instrumented_files_info(
ctx,
Expand Down
1 change: 1 addition & 0 deletions go/tools/builders/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ filegroup(
"ar.go",
"asm.go",
"builder.go",
"cc.go",
"cgo2.go",
"compilepkg.go",
"constants.go",
Expand Down
2 changes: 2 additions & 0 deletions go/tools/builders/builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,8 @@ func main() {
action = stdlib
case "stdliblist":
action = stdliblist
case "cc":
action = cc
default:
log.Fatalf("unknown action: %s", verb)
}
Expand Down
47 changes: 47 additions & 0 deletions go/tools/builders/cc.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package main

import (
"errors"
"os"
"os/exec"
"path/filepath"
"runtime"
"strings"
"syscall"
)

func cc(args []string) error {
cc := os.Getenv("GO_CC")
if cc == "" {
errors.New("GO_CC environment variable not set")
}
ccroot := os.Getenv("GO_CC_ROOT")
if ccroot == "" {
errors.New("GO_CC_ROOT environment variable not set")
}
normalized := []string{cc}
normalized = append(normalized, args...)
transformArgs(normalized, cgoAbsEnvFlags, func(s string) string {
if strings.HasPrefix(s, cgoAbsPlaceholder) {
trimmed := strings.TrimPrefix(s, cgoAbsPlaceholder)
abspath := filepath.Join(ccroot, trimmed)
if _, err := os.Stat(abspath); err == nil {
// Only return the abspath if it exists, otherwise it
// means that either it won't have any effect or the original
// value was not a relpath (e.g. a path with a XCODE placehold from
// macos cc_wrapper)
return abspath
}
return trimmed
}
return s
})
if runtime.GOOS == "windows" {
cmd := exec.Command(normalized[0], normalized[1:]...)
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
return cmd.Run()
} else {
return syscall.Exec(normalized[0], normalized, os.Environ())
}
}
Loading