Skip to content

Commit

Permalink
Fix shac check on Windows
Browse files Browse the repository at this point in the history
Share the Go modules across installation, while using separate sumdb
(via separate GOPATH) to work around race conditions.

Change-Id: Iae8ae78a2cbd2cc8aa7c4d76ba35a8d8e5812c50
Reviewed-on: https://fuchsia-review.googlesource.com/c/shac-project/shac/+/931379
Fuchsia-Auto-Submit: Oliver Newman <[email protected]>
Reviewed-by: Oliver Newman <[email protected]>
Commit-Queue: Auto-Submit <[email protected]>
Reviewed-by: Anthony Fandrianto <[email protected]>
  • Loading branch information
maruel authored and CQ Bot committed Oct 16, 2023
1 parent 4a57f93 commit adb70a5
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 18 deletions.
38 changes: 27 additions & 11 deletions checks/common.star
Original file line number Diff line number Diff line change
Expand Up @@ -14,27 +14,33 @@

def go_install(ctx, pkg, version):
"""Runs `go install`."""
env = go_env(ctx)
cache = _go_cache(ctx)

env = go_env()
# Save executables in a common directory.
env["GOBIN"] = cache + "/gobin"

# TODO(olivernewman): Implement proper cache directories for shac instead of
# creating a `.tools` directory, which requires making the root directory
# writable.
env["GOBIN"] = ctx.scm.root + "/.tools/gobin"
tool_name = pkg.split("/")[-1]

# Setting GOPATH is necessary on Windows when USERPROFILE is not set.
# Use one GOPATH per tool. Since both GOBIN and GOMODCACHE are redirected,
# in practice only sumdb is going to be unique
env["GOPATH"] = cache + "/" + tool_name

# TODO(olivernewman): Stop using a separate GOPATH for each tool, and instead
# install the tools sequentially. Multiple concurrent `go install` runs on the
# same GOPATH results in race conditions.
ctx.os.exec(
["go", "install", "%s@%s" % (pkg, version)],
allow_network = True,
env = env,
).wait()

tool_name = pkg.split("/")[-1]
return "%s/%s" % (env["GOBIN"], tool_name)
tool_exec = tool_name
if ctx.platform.os == "windows":
tool_exec += ".exe"
return "%s/%s" % (env["GOBIN"], tool_exec)

def go_env():
def go_env(ctx):
"""Returns environment variables to use when running Go tooling."""
cache = _go_cache(ctx)
return {
# Disable cgo as it's not necessary and not all development platforms have
# the necessary headers.
Expand All @@ -44,7 +50,17 @@ def go_env():
# to fail on some machines.
"-buildvcs=false",
]),
# Share the Go module cache to reduce downloads.
"GOMODCACHE": cache + "/mod",
# TODO(olivernewman): The default gopackagesdriver is broken within an
# nsjail.
"GOPACKAGESDRIVER": "off",
}

def _go_cache(ctx):
"""Returns the shared Go cache."""

# TODO(olivernewman): Implement proper cache directories for shac instead of
# creating a `.tools` directory, which requires making the root directory
# writable.
return ctx.scm.root + "/.tools"
17 changes: 10 additions & 7 deletions checks/go.star
Original file line number Diff line number Diff line change
Expand Up @@ -62,9 +62,9 @@ def _gosec(ctx, version = "v2.15.0", level = "error", exclude = [
affected_files = set(ctx.scm.affected_files())
exe = go_install(ctx, "github.com/securego/gosec/v2/cmd/gosec", version)
res = ctx.os.exec(
[exe, "-fmt=json", "-quiet", "-exclude=%s" % ",".join(exclude), "-exclude-dir=.tools", "./..."],
[exe, "-fmt=json", "-quiet", "-exclude=%s" % ",".join(exclude), "-exclude-dir=.tools", "-exclude-dir=internal/engine/testdata", "./..."],
ok_retcodes = (0, 1),
env = go_env(),
env = go_env(ctx),
).wait()
if not res.retcode:
return
Expand Down Expand Up @@ -112,7 +112,7 @@ def _ineffassign(ctx, version = "v0.0.0-20230107090616-13ace0543b28"):
exe = go_install(ctx, "github.com/gordonklaus/ineffassign", version)
res = ctx.os.exec(
[exe, "./..."],
env = go_env(),
env = go_env(ctx),
# ineffassign's README claims that it emits a retcode of 1 if it returns any
# findings, but it actually emits a retcode of 3.
# https://github.com/gordonklaus/ineffassign/blob/4cc7213b9bc8b868b2990c372f6fa057fa88b91c/ineffassign.go#L70
Expand Down Expand Up @@ -143,7 +143,7 @@ def _staticcheck(ctx, version = "v0.4.3"):
will be rolled from time to time.
"""
exe = go_install(ctx, "honnef.co/go/tools/cmd/staticcheck", version)
env = go_env()
env = go_env(ctx)
res = ctx.os.exec(
[exe, "-f=json", "./..."],
ok_retcodes = [0, 1],
Expand Down Expand Up @@ -192,7 +192,7 @@ def _shadow(ctx, version = "v0.7.0"):
"-json",
"./...",
],
env = go_env(),
env = go_env(ctx),
).wait()

# Example output:
Expand Down Expand Up @@ -241,7 +241,7 @@ def no_fork_without_lock(ctx):
"-json",
"./...",
],
env = go_env(),
env = go_env(ctx),
).wait().stdout)

# Skip the "execsupport" package since it contains the wrappers around Run()
Expand Down Expand Up @@ -285,7 +285,7 @@ def govet(
] +
["-" + a for a in analyzers] +
["./..."],
env = go_env(),
env = go_env(ctx),
).wait().stderr

# output is of the form:
Expand All @@ -299,6 +299,9 @@ def govet(
current_package_lines = []
lines = output.splitlines()
for i, line in enumerate(lines):
if line.startswith("warning: "):
# warning: GOPATH set to GOROOT () has no effect
continue
if not line.startswith("# "):
current_package_lines.append(line)
if i + 1 < len(lines):
Expand Down

0 comments on commit adb70a5

Please sign in to comment.