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

pantsbuild / pants / 20632486505

01 Jan 2026 04:21AM UTC coverage: 43.231% (-37.1%) from 80.281%
20632486505

Pull #22962

github

web-flow
Merge 08d5c63b0 into f52ab6675
Pull Request #22962: Bump the gha-deps group across 1 directory with 6 updates

26122 of 60424 relevant lines covered (43.23%)

0.86 hits per line

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

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

4
from __future__ import annotations
2✔
5

6
import os
2✔
7
from collections.abc import Iterable, Sequence
2✔
8

9
from pants.core.environments.target_types import EnvironmentField
2✔
10
from pants.core.goals.package import OutputPathField
2✔
11
from pants.core.goals.run import RestartableField
2✔
12
from pants.core.goals.test import TestExtraEnvVarsField, TestTimeoutField
2✔
13
from pants.engine.addresses import Address
2✔
14
from pants.engine.target import (
2✔
15
    COMMON_TARGET_FIELDS,
16
    AsyncFieldMixin,
17
    BoolField,
18
    Dependencies,
19
    InvalidFieldException,
20
    InvalidTargetException,
21
    MultipleSourcesField,
22
    StringField,
23
    StringSequenceField,
24
    Target,
25
    TargetGenerator,
26
    TriBoolField,
27
    ValidNumbers,
28
    generate_multiple_sources_field_help_message,
29
)
30
from pants.util.strutil import help_text
2✔
31

32
# -----------------------------------------------------------------------------------------------
33
# Build option fields
34
# -----------------------------------------------------------------------------------------------
35

36

37
class GoCgoEnabledField(TriBoolField):
2✔
38
    """Enables Cgo support."""
39

40
    alias = "cgo_enabled"
2✔
41
    help = help_text(
2✔
42
        """
43
        Enable Cgo support, which allows Go and C code to interact. This option must be enabled for any
44
        packages making use of Cgo to actually be compiled with Cgo support.
45

46
        This field can be specified on several different target types, including `go_binary` and `go_mod` target
47
        types. If this field is specified on a `go_binary` target, then that instance takes precedence over other
48
        configuration when building the applicable executable. The applicable `go_mod` target will be checked next
49
        as a fallback. Finally, if neither target specifies this field, then the value will be taken from
50
        the value of the `[golang].cgo_enabled` option. (Note: That option will be deprecated in a future Pants
51
        version.)
52

53
        See https://go.dev/blog/cgo and https://pkg.go.dev/cmd/cgo for additional information about Cgo.
54
        """
55
    )
56

57

58
class GoRaceDetectorEnabledField(TriBoolField):
2✔
59
    """Enables the Go data race detector."""
60

61
    alias = "race"
2✔
62
    help = help_text(
2✔
63
        """
64
        Enable compiling the binary with the Go data race detector.
65

66
        See https://go.dev/doc/articles/race_detector for additional information about the Go data race detector.
67
        """
68
    )
69

70

71
class GoTestRaceDetectorEnabledField(GoRaceDetectorEnabledField):
2✔
72
    alias = "test_race"
2✔
73
    help = help_text(
2✔
74
        """
75
        Enable compiling this package's test binary with the Go data race detector.
76

77
        See https://go.dev/doc/articles/race_detector for additional information about the Go data race detector.
78
        """
79
    )
80

81

82
class GoMemorySanitizerEnabledField(TriBoolField):
2✔
83
    """Enables the C/C++ memory sanitizer."""
84

85
    alias = "msan"
2✔
86
    help = help_text(
2✔
87
        """
88
        Enable interoperation between Go code and the C/C++ "memory sanitizer."
89

90
        See https://github.com/google/sanitizers/wiki/MemorySanitizer for additional information about
91
        the C/C++ memory sanitizer.
92
        """
93
    )
94

95

96
class GoTestMemorySanitizerEnabledField(GoRaceDetectorEnabledField):
2✔
97
    alias = "test_msan"
2✔
98
    help = help_text(
2✔
99
        """
100
        Enable interoperation between Go code and the C/C++ "memory sanitizer" when building this package's
101
        test binary.
102

103
        See https://github.com/google/sanitizers/wiki/MemorySanitizer for additional information about
104
        the C/C++ memory sanitizer.
105
        """
106
    )
107

108

109
class GoAddressSanitizerEnabledField(TriBoolField):
2✔
110
    """Enables the C/C++ address sanitizer."""
111

112
    alias = "asan"
2✔
113
    help = help_text(
2✔
114
        """
115
        Enable interoperation between Go code and the C/C++ "address sanitizer."
116

117
        See https://github.com/google/sanitizers/wiki/AddressSanitizer for additional information about
118
        the C/C++ address sanitizer.
119
        """
120
    )
121

122

123
class GoTestAddressSanitizerEnabledField(GoRaceDetectorEnabledField):
2✔
124
    alias = "test_asan"
2✔
125
    help = help_text(
2✔
126
        """
127
        Enable interoperation between Go code and the C/C++ "address sanitizer" when building this package's
128
        test binary.
129

130
        See https://github.com/google/sanitizers/wiki/AddressSanitizer for additional information about
131
        the C/C++ address sanitizer.
132
        """
133
    )
134

135

136
class GoAssemblerFlagsField(StringSequenceField):
2✔
137
    alias = "assembler_flags"
2✔
138
    help = help_text(
2✔
139
        """
140
        Extra flags to pass to the Go assembler (i.e., `go tool asm`) when assembling Go-format assembly code.
141

142
        Note: These flags will not be added to gcc/clang-format assembly that is assembled in packages using Cgo.
143

144
        This field can be specified on several different target types:
145

146
        - On `go_mod` targets, the assembler flags are used when building any package involving the module
147
        including both first-party (i.e., `go_package` targets) and third-party dependencies.
148

149
        - On `go_binary` targets, the assembler flags are used when building any packages comprising that binary
150
        including third-party dependencies. These assembler flags will be added after any assembler flags
151
        added by any `assembler_flags` field set on the applicable `go_mod` target.
152

153
        - On `go_package` targets, the assembler flags are used only for building that specific package and not
154
        for any other package. These assembler flags will be added after any assembler flags added by any
155
        `assembler_flags` field set on the applicable `go_mod` target or applicable `go_binary` target.
156

157
        Run `go doc cmd/asm` to see the flags supported by `go tool asm`.
158
        """
159
    )
160

161

162
class GoCompilerFlagsField(StringSequenceField):
2✔
163
    alias = "compiler_flags"
2✔
164
    help = help_text(
2✔
165
        """
166
        Extra flags to pass to the Go compiler (i.e., `go tool compile`) when compiling Go code.
167

168
        This field can be specified on several different target types:
169

170
        - On `go_mod` targets, the compiler flags are used when compiling any package involving the module
171
        including both first-party (i.e., `go_package` targets) and third-party dependencies.
172

173
        - On `go_binary` targets, the compiler flags are used when compiling any packages comprising that binary
174
        including third-party dependencies. These compiler flags will be added after any compiler flags
175
        added by any `compiler_flags` field set on the applicable `go_mod` target.
176

177
        - On `go_package` targets, the compiler flags are used only for compiling that specific package and not
178
        for any other package. These compiler flags will be added after any compiler flags added by any
179
        `compiler_flags` field set on the applicable `go_mod` target or applicable `go_binary` target.
180

181
        Run `go doc cmd/compile` to see the flags supported by `go tool compile`.
182
        """
183
    )
184

185

186
class GoLinkerFlagsField(StringSequenceField):
2✔
187
    alias = "linker_flags"
2✔
188
    help = help_text(
2✔
189
        """
190
        Extra flags to pass to the Go linker (i.e., `go tool link`) when linking Go binaries.
191

192
        This field can be specified on several different target types:
193

194
        - On `go_mod` targets, the linker flags are used when linking any binary involving the module
195
        including both `go_binary` targets and test binaries for `go_package` targets within the module.
196

197
        - On `go_binary` targets, the linker flags are used when linking that binary. These linker flags
198
        will be added after any linker flags added by any `linker_flags` field set on the applicable
199
        `go_mod` target.
200

201
        Run `go doc cmd/link` to see the flags supported by `go tool link`.
202
        """
203
    )
204

205

206
# -----------------------------------------------------------------------------------------------
207
# `go_third_party_package` target
208
# -----------------------------------------------------------------------------------------------
209

210

211
class GoImportPathField(StringField):
2✔
212
    alias = "import_path"
2✔
213
    help = help_text(
2✔
214
        """
215
        Import path in Go code to import this package.
216

217
        This field should not be overridden; use the value from target generation.
218
        """
219
    )
220
    required = True
2✔
221
    value: str
2✔
222

223

224
class GoThirdPartyPackageDependenciesField(Dependencies):
2✔
225
    pass
2✔
226

227

228
class GoThirdPartyPackageTarget(Target):
2✔
229
    alias = "go_third_party_package"
2✔
230
    core_fields = (*COMMON_TARGET_FIELDS, GoThirdPartyPackageDependenciesField, GoImportPathField)
2✔
231
    help = help_text(
2✔
232
        """
233
        A package from a third-party Go module.
234

235
        You should not explicitly create this target in BUILD files. Instead, add a `go_mod`
236
        target where you have your `go.mod` file, which will generate
237
        `go_third_party_package` targets for you.
238

239
        Make sure that your `go.mod` and `go.sum` files include this package's module.
240
        """
241
    )
242

243
    def validate(self) -> None:
2✔
244
        if not self.address.is_generated_target:
×
245
            raise InvalidTargetException(
×
246
                f"The `{self.alias}` target type should not be manually created in BUILD "
247
                f"files, but it was created for {self.address}.\n\n"
248
                "Instead, add a `go_mod` target where you have your `go.mod` file, which will "
249
                f"generate `{self.alias}` targets for you based on the `require` directives in "
250
                f"your `go.mod`."
251
            )
252

253

254
# -----------------------------------------------------------------------------------------------
255
# `go_mod` target generator
256
# -----------------------------------------------------------------------------------------------
257

258

259
class GoModSourcesField(MultipleSourcesField):
2✔
260
    alias = "_sources"
2✔
261
    default = ("go.mod", "go.sum")
2✔
262
    expected_num_files = range(1, 3)  # i.e. 1 or 2.
2✔
263

264
    @property
2✔
265
    def go_mod_path(self) -> str:
2✔
266
        return os.path.join(self.address.spec_path, "go.mod")
×
267

268
    @property
2✔
269
    def go_sum_path(self) -> str:
2✔
270
        return os.path.join(self.address.spec_path, "go.sum")
×
271

272
    def validate_resolved_files(self, files: Sequence[str]) -> None:
2✔
273
        super().validate_resolved_files(files)
×
274
        if self.go_mod_path not in files:
×
275
            raise InvalidFieldException(
×
276
                f"The {repr(self.alias)} field in target {self.address} must include "
277
                f"{self.go_mod_path}, but only had: {list(files)}\n\n"
278
                f"Make sure that you're declaring the `{GoModTarget.alias}` target in the same "
279
                "directory as your `go.mod` file."
280
            )
281
        invalid_files = set(files) - {self.go_mod_path, self.go_sum_path}
×
282
        if invalid_files:
×
283
            raise InvalidFieldException(
×
284
                f"The {repr(self.alias)} field in target {self.address} must only include "
285
                f"`{self.go_mod_path}` and optionally {self.go_sum_path}, but had: "
286
                f"{sorted(invalid_files)}\n\n"
287
                f"Make sure that you're declaring the `{GoModTarget.alias}` target in the same "
288
                f"directory as your `go.mod` file and that you don't override the `{self.alias}` "
289
                "field."
290
            )
291

292

293
# TODO: This field probably shouldn't be registered.
294
class GoModDependenciesField(Dependencies):
2✔
295
    alias = "_dependencies"
2✔
296

297

298
class GoModTarget(TargetGenerator):
2✔
299
    alias = "go_mod"
2✔
300
    help = help_text(
2✔
301
        """
302
        A first-party Go module (corresponding to a `go.mod` file).
303

304
        Generates `go_third_party_package` targets based on the `require` directives in your
305
        `go.mod`.
306

307
        If you have third-party packages, make sure you have an up-to-date `go.sum`. Run
308
        `go mod tidy` directly to update your `go.mod` and `go.sum`.
309
        """
310
    )
311
    generated_target_cls = GoThirdPartyPackageTarget
2✔
312
    core_fields = (
2✔
313
        *COMMON_TARGET_FIELDS,
314
        GoModDependenciesField,
315
        GoModSourcesField,
316
        GoCgoEnabledField,
317
        GoRaceDetectorEnabledField,
318
        GoMemorySanitizerEnabledField,
319
        GoAddressSanitizerEnabledField,
320
        GoAssemblerFlagsField,
321
        GoCompilerFlagsField,
322
        GoLinkerFlagsField,
323
    )
324
    copied_fields = COMMON_TARGET_FIELDS
2✔
325
    moved_fields = ()
2✔
326

327

328
# -----------------------------------------------------------------------------------------------
329
# `go_package` target
330
# -----------------------------------------------------------------------------------------------
331

332

333
class GoPackageSourcesField(MultipleSourcesField):
2✔
334
    default = ("*.go",)
2✔
335
    expected_file_extensions = (
2✔
336
        ".go",
337
        ".s",
338
        ".S",
339
        ".sx",
340
        ".c",
341
        ".h",
342
        ".hh",
343
        ".hpp",
344
        ".hxx",
345
        ".cc",
346
        ".cpp",
347
        ".cxx",
348
        ".m",
349
        ".f",
350
        ".F",
351
        ".for",
352
        ".f90",
353
        ".syso",
354
    )
355
    ban_subdirectories = True
2✔
356
    help = generate_multiple_sources_field_help_message(
2✔
357
        "Example: `sources=['example.go', '*_test.go', '!test_ignore.go']`"
358
    )
359

360
    @classmethod
2✔
361
    def compute_value(
2✔
362
        cls, raw_value: Iterable[str] | None, address: Address
363
    ) -> tuple[str, ...] | None:
364
        value_or_default = super().compute_value(raw_value, address)
×
365
        if not value_or_default:
×
366
            raise InvalidFieldException(
×
367
                f"The {repr(cls.alias)} field in target {address} must be set to files/globs in "
368
                f"the target's directory, but it was set to {repr(value_or_default)}."
369
            )
370
        return value_or_default
×
371

372

373
class GoPackageDependenciesField(Dependencies):
2✔
374
    pass
2✔
375

376

377
class SkipGoTestsField(BoolField):
2✔
378
    alias = "skip_tests"
2✔
379
    default = False
2✔
380
    help = "If true, don't run this package's tests."
2✔
381

382

383
class GoTestExtraEnvVarsField(TestExtraEnvVarsField):
2✔
384
    alias = "test_extra_env_vars"
2✔
385

386

387
class GoTestTimeoutField(TestTimeoutField):
2✔
388
    alias = "test_timeout"
2✔
389
    valid_numbers = ValidNumbers.positive_and_zero
2✔
390

391

392
class GoPackageTarget(Target):
2✔
393
    alias = "go_package"
2✔
394
    core_fields = (
2✔
395
        *COMMON_TARGET_FIELDS,
396
        GoPackageDependenciesField,
397
        GoPackageSourcesField,
398
        GoTestExtraEnvVarsField,
399
        GoTestTimeoutField,
400
        GoTestRaceDetectorEnabledField,
401
        GoTestMemorySanitizerEnabledField,
402
        GoTestAddressSanitizerEnabledField,
403
        GoAssemblerFlagsField,
404
        GoCompilerFlagsField,
405
        SkipGoTestsField,
406
    )
407
    help = help_text(
2✔
408
        """
409
        A first-party Go package (corresponding to a directory with `.go` files).
410

411
        Expects that there is a `go_mod` target in its directory or in an ancestor
412
        directory.
413
        """
414
    )
415

416

417
# -----------------------------------------------------------------------------------------------
418
# `go_binary` target
419
# -----------------------------------------------------------------------------------------------
420

421

422
class GoBinaryMainPackageField(StringField, AsyncFieldMixin):
2✔
423
    alias = "main"
2✔
424
    help = help_text(
2✔
425
        """
426
        Address of the `go_package` with the `main` for this binary.
427

428
        If not specified, will default to the `go_package` for the same
429
        directory as this target's BUILD file. You should usually rely on this default.
430
        """
431
    )
432
    value: str
2✔
433

434

435
class GoBinaryDependenciesField(Dependencies):
2✔
436
    # This is only used to inject a dependency from the `GoBinaryMainPackageField`. Users should
437
    # add any explicit dependencies to the `go_package`.
438
    alias = "_dependencies"
2✔
439

440

441
class GoBinaryTarget(Target):
2✔
442
    alias = "go_binary"
2✔
443
    core_fields = (
2✔
444
        *COMMON_TARGET_FIELDS,
445
        OutputPathField,
446
        GoBinaryMainPackageField,
447
        GoBinaryDependenciesField,
448
        GoCgoEnabledField,
449
        GoRaceDetectorEnabledField,
450
        GoMemorySanitizerEnabledField,
451
        GoAddressSanitizerEnabledField,
452
        GoAssemblerFlagsField,
453
        GoCompilerFlagsField,
454
        GoLinkerFlagsField,
455
        RestartableField,
456
        EnvironmentField,
457
    )
458
    help = "A Go binary."
2✔
459

460

461
# -----------------------------------------------------------------------------------------------
462
# Support for codegen targets that need to specify an owning go_mod target
463
# -----------------------------------------------------------------------------------------------
464

465

466
class GoOwningGoModAddressField(StringField):
2✔
467
    alias = "go_mod_address"
2✔
468
    help = help_text(
2✔
469
        """
470
        Address of the `go_mod` target representing the Go module that this target is part of.
471

472
        This field is similar to the `resolve` field used in the Python and JVM backends. If a codegen
473
        target such as `protobuf_sources` will be used in multiple Go modules, then you should use
474
        the `parametrize` built-in to parametrize that `protobuf_sources` target for each Go module.
475

476
        If there is a single `go_mod` target in the repository, then this field defaults to the address
477
        for that single `go_mod` target.
478
        """
479
    )
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

© 2026 Coveralls, Inc