• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

pantsbuild / pants / 19015773527

02 Nov 2025 05:33PM UTC coverage: 17.872% (-62.4%) from 80.3%
19015773527

Pull #22816

github

web-flow
Merge a12d75757 into 6c024e162
Pull Request #22816: Update Pants internal Python to 3.14

4 of 5 new or added lines in 3 files covered. (80.0%)

28452 existing lines in 683 files now uncovered.

9831 of 55007 relevant lines covered (17.87%)

0.18 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

0.0
/src/python/pants/backend/go/go_sources/load_go_binary.py
1
# Copyright 2021 Pants project contributors (see CONTRIBUTORS.md).
2
# Licensed under the Apache License, Version 2.0 (see LICENSE).
3

UNCOV
4
from __future__ import annotations
×
5

UNCOV
6
import re
×
UNCOV
7
from collections.abc import Iterable
×
UNCOV
8
from dataclasses import dataclass
×
9

UNCOV
10
from pants.backend.go.util_rules.build_opts import GoBuildOptions
×
UNCOV
11
from pants.backend.go.util_rules.build_pkg import BuildGoPackageRequest, required_built_go_package
×
UNCOV
12
from pants.backend.go.util_rules.goroot import GoRoot
×
UNCOV
13
from pants.backend.go.util_rules.import_analysis import (
×
14
    GoStdLibPackagesRequest,
15
    analyze_go_stdlib_packages,
16
)
UNCOV
17
from pants.backend.go.util_rules.link import LinkGoBinaryRequest, link_go_binary
×
UNCOV
18
from pants.engine.engine_aware import EngineAwareParameter
×
UNCOV
19
from pants.engine.fs import CreateDigest, Digest, FileContent
×
UNCOV
20
from pants.engine.internals.native_engine import EMPTY_DIGEST
×
UNCOV
21
from pants.engine.intrinsics import create_digest
×
UNCOV
22
from pants.engine.rules import collect_rules, concurrently, implicitly, rule
×
UNCOV
23
from pants.util.resources import read_resource
×
24

25

UNCOV
26
@dataclass(frozen=True)
×
UNCOV
27
class LoadedGoBinary:
×
UNCOV
28
    digest: Digest
×
29

30

UNCOV
31
@dataclass(frozen=True)
×
UNCOV
32
class LoadedGoBinaryRequest(EngineAwareParameter):
×
UNCOV
33
    dir_name: str
×
UNCOV
34
    file_names: tuple[str, ...]
×
UNCOV
35
    output_name: str
×
36

UNCOV
37
    def debug_hint(self) -> str:
×
38
        return self.output_name
×
39

40

UNCOV
41
@dataclass(frozen=True)
×
UNCOV
42
class NaiveBuildGoPackageRequestForStdlibPackageRequest:
×
UNCOV
43
    import_path: str
×
44

45

46
# This rule is necessary because the rules in this file are used to build internal binaries including the
47
# package analyzer.
UNCOV
48
@rule
×
UNCOV
49
async def naive_build_go_package_request_for_stdlib(
×
50
    request: NaiveBuildGoPackageRequestForStdlibPackageRequest,
51
    goroot: GoRoot,
52
) -> BuildGoPackageRequest:
53
    stdlib_packages = await analyze_go_stdlib_packages(
×
54
        GoStdLibPackagesRequest(with_race_detector=False, cgo_enabled=False)
55
    )
56

57
    pkg_info = stdlib_packages[request.import_path]
×
58

59
    dep_build_requests = await concurrently(
×
60
        naive_build_go_package_request_for_stdlib(
61
            NaiveBuildGoPackageRequestForStdlibPackageRequest(
62
                import_path=dep_import_path,
63
            ),
64
            goroot,
65
        )
66
        for dep_import_path in pkg_info.imports
67
        if dep_import_path not in ("C", "unsafe", "builtin")
68
    )
69

70
    return BuildGoPackageRequest(
×
71
        import_path=request.import_path,
72
        pkg_name=pkg_info.name,
73
        dir_path=pkg_info.pkg_source_path,
74
        digest=EMPTY_DIGEST,
75
        go_files=pkg_info.go_files,
76
        s_files=pkg_info.s_files,
77
        prebuilt_object_files=pkg_info.syso_files,
78
        direct_dependencies=tuple(dep_build_requests),
79
        minimum_go_version=goroot.version,
80
        build_opts=GoBuildOptions(cgo_enabled=False),
81
        is_stdlib=True,
82
    )
83

84

UNCOV
85
def setup_files(dir_name: str, file_names: tuple[str, ...]) -> tuple[FileContent, ...]:
×
86
    def get_file(file_name: str) -> bytes:
×
87
        content = read_resource(f"pants.backend.go.go_sources.{dir_name}", file_name)
×
88
        if not content:
×
89
            raise AssertionError(f"Unable to find resource for `{file_name}`.")
×
90
        return content
×
91

92
    return tuple(FileContent(f, get_file(f)) for f in file_names)
×
93

94

UNCOV
95
_IMPORTS_REGEX = re.compile(r"^import\s+\((.*?)\)", re.MULTILINE | re.DOTALL)
×
96

97

UNCOV
98
def _extract_imports(files: Iterable[FileContent]) -> set[str]:
×
99
    """Extract Go imports naively from given content."""
100
    imports: set[str] = set()
×
101
    for f in files:
×
102
        m = _IMPORTS_REGEX.search(f.content.decode())
×
103
        if m:
×
104
            f_imports = [x.strip('"') for x in m.group(1).split()]
×
105
            imports.update(f_imports)
×
106
    return imports
×
107

108

109
# TODO(13879): Maybe see if can consolidate compilation of wrapper binaries to common rules with Scala/Java?
UNCOV
110
@rule
×
UNCOV
111
async def setup_go_binary(request: LoadedGoBinaryRequest, goroot: GoRoot) -> LoadedGoBinary:
×
112
    file_contents = setup_files(request.dir_name, request.file_names)
×
113
    imports = _extract_imports(file_contents)
×
114
    imports.add("runtime")  # implicit linker dependency for all Go binaries
×
115

116
    build_opts = GoBuildOptions(cgo_enabled=False)
×
117

118
    source_digest = await create_digest(CreateDigest(file_contents))
×
119

120
    dep_build_requests = await concurrently(
×
121
        naive_build_go_package_request_for_stdlib(
122
            NaiveBuildGoPackageRequestForStdlibPackageRequest(dep_import_path), goroot
123
        )
124
        for dep_import_path in sorted(imports)
125
    )
126

127
    built_pkg = await required_built_go_package(
×
128
        **implicitly(
129
            BuildGoPackageRequest(
130
                import_path="main",
131
                pkg_name="main",
132
                dir_path=".",
133
                build_opts=build_opts,
134
                digest=source_digest,
135
                go_files=tuple(fc.path for fc in file_contents),
136
                s_files=(),
137
                direct_dependencies=dep_build_requests,
138
                minimum_go_version=goroot.version,
139
            ),
140
        ),
141
    )
142

143
    main_pkg_a_file_path = built_pkg.import_paths_to_pkg_a_files["main"]
×
144

145
    binary = await link_go_binary(
×
146
        LinkGoBinaryRequest(
147
            input_digest=built_pkg.digest,
148
            archives=(main_pkg_a_file_path,),
149
            build_opts=build_opts,
150
            import_paths_to_pkg_a_files=built_pkg.import_paths_to_pkg_a_files,
151
            output_filename=request.output_name,
152
            description=f"Link internal Go binary `{request.output_name}`",
153
        ),
154
        **implicitly(),
155
    )
156
    return LoadedGoBinary(binary.digest)
×
157

158

UNCOV
159
def rules():
×
UNCOV
160
    return collect_rules()
×
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc