Repository: pantsbuild/pants

Issue:
go: linking step requires PATH to find `gcc`
While trying to use the Go plugin to build helm via [this branch](https://github.com/toolchainlabs/helm/tree/setup_pants), the Go linker needed to find `gcc` on the PATH in order to use it to link the binary but failed with an error because `PATH` was not passed into the `Process` even though the `--subprocess-environment-env-vars` options included `PATH`.

```
stderr:
/usr/local/Cellar/go/1.17.2/libexec/pkg/tool/darwin_amd64/link: running gcc failed: exec: "gcc": executable file not found in $PATH
```



Discussion:

Resolving patch:
diff --git a/src/python/pants/backend/go/subsystems/golang.py b/src/python/pants/backend/go/subsystems/golang.py
--- a/src/python/pants/backend/go/subsystems/golang.py
+++ b/src/python/pants/backend/go/subsystems/golang.py
@@ -58,6 +58,18 @@ def register_options(cls, register):
                 "Do not include the patch version."
             ),
         )
+        register(
+            "--subprocess-env-vars",
+            type=list,
+            member_type=str,
+            default=["LANG", "LC_CTYPE", "LC_ALL", "PATH"],
+            advanced=True,
+            help=(
+                "Environment variables to set when invoking the `go` tool. "
+                "Entries are either strings in the form `ENV_VAR=value` to set an explicit value; "
+                "or just `ENV_VAR` to copy the value from Pants's own environment."
+            ),
+        )
 
     def go_search_paths(self, env: Environment) -> tuple[str, ...]:
         def iter_path_entries():
@@ -75,6 +87,10 @@ def iter_path_entries():
     def expected_version(self) -> str:
         return cast(str, self.options.expected_version)
 
+    @property
+    def env_vars_to_pass_to_subprocesses(self) -> tuple[str, ...]:
+        return tuple(sorted(set(self.options.subprocess_env_vars)))
+
 
 @dataclass(frozen=True)
 class GoRoot:
diff --git a/src/python/pants/backend/go/util_rules/sdk.py b/src/python/pants/backend/go/util_rules/sdk.py
--- a/src/python/pants/backend/go/util_rules/sdk.py
+++ b/src/python/pants/backend/go/util_rules/sdk.py
@@ -8,9 +8,10 @@
 from typing import Iterable, Mapping
 
 from pants.backend.go.subsystems import golang
-from pants.backend.go.subsystems.golang import GoRoot
+from pants.backend.go.subsystems.golang import GolangSubsystem, GoRoot
+from pants.engine.environment import Environment, EnvironmentRequest
 from pants.engine.fs import EMPTY_DIGEST, CreateDigest, Digest, FileContent, MergeDigests
-from pants.engine.internals.selectors import Get
+from pants.engine.internals.selectors import Get, MultiGet
 from pants.engine.process import BashBinary, Process
 from pants.engine.rules import collect_rules, rule
 from pants.util.frozendict import FrozenDict
@@ -89,14 +90,21 @@ async def go_sdk_invoke_setup(goroot: GoRoot) -> GoSdkRunSetup:
 
 @rule
 async def setup_go_sdk_process(
-    request: GoSdkProcess, go_sdk_run: GoSdkRunSetup, bash: BashBinary
+    request: GoSdkProcess,
+    go_sdk_run: GoSdkRunSetup,
+    bash: BashBinary,
+    golang_subsystem: GolangSubsystem,
 ) -> Process:
-    input_digest = await Get(Digest, MergeDigests([go_sdk_run.digest, request.input_digest]))
+    input_digest, env_vars = await MultiGet(
+        Get(Digest, MergeDigests([go_sdk_run.digest, request.input_digest])),
+        Get(Environment, EnvironmentRequest(golang_subsystem.env_vars_to_pass_to_subprocesses)),
+    )
     return Process(
         argv=[bash.path, go_sdk_run.script.path, *request.command],
         env={
-            GoSdkRunSetup.CHDIR_ENV: request.working_dir or "",
+            **env_vars,
             **request.env,
+            GoSdkRunSetup.CHDIR_ENV: request.working_dir or "",
         },
         input_digest=input_digest,
         description=request.description,


Test patch: