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

pantsbuild / pants / 18822648545

26 Oct 2025 07:24PM UTC coverage: 79.831% (-0.4%) from 80.28%
18822648545

Pull #22809

github

web-flow
Merge 9401c4830 into 170094e99
Pull Request #22809: golang: fix Go SDK version check for coverage experiment

0 of 1 new or added line in 1 file covered. (0.0%)

439 existing lines in 25 files now uncovered.

77436 of 97000 relevant lines covered (79.83%)

3.35 hits per line

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

48.42
/src/python/pants/backend/go/util_rules/first_party_pkg_test.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
1✔
5

6
import os.path
1✔
7
from textwrap import dedent
1✔
8

9
import pytest
1✔
10

11
from pants.backend.go import target_type_rules
1✔
12
from pants.backend.go.target_types import GoModTarget, GoPackageTarget
1✔
13
from pants.backend.go.util_rules import (
1✔
14
    assembly,
15
    build_pkg,
16
    first_party_pkg,
17
    go_mod,
18
    link,
19
    sdk,
20
    third_party_pkg,
21
)
22
from pants.backend.go.util_rules.build_opts import GoBuildOptions
1✔
23
from pants.backend.go.util_rules.embedcfg import EmbedConfig
1✔
24
from pants.backend.go.util_rules.first_party_pkg import (
1✔
25
    FallibleFirstPartyPkgAnalysis,
26
    FallibleFirstPartyPkgDigest,
27
    FirstPartyPkgAnalysisRequest,
28
    FirstPartyPkgDigestRequest,
29
    FirstPartyPkgImportPath,
30
    FirstPartyPkgImportPathRequest,
31
)
32
from pants.core.target_types import ResourcesGeneratorTarget
1✔
33
from pants.engine.addresses import Address
1✔
34
from pants.engine.fs import PathGlobs, Snapshot
1✔
35
from pants.engine.rules import QueryRule
1✔
36
from pants.testutil.rule_runner import RuleRunner, engine_error
1✔
37

38

39
@pytest.fixture
1✔
40
def rule_runner() -> RuleRunner:
1✔
41
    rule_runner = RuleRunner(
1✔
42
        rules=[
43
            *go_mod.rules(),
44
            *first_party_pkg.rules(),
45
            *sdk.rules(),
46
            *third_party_pkg.rules(),
47
            *target_type_rules.rules(),
48
            *build_pkg.rules(),
49
            *link.rules(),
50
            *assembly.rules(),
51
            QueryRule(FallibleFirstPartyPkgAnalysis, [FirstPartyPkgAnalysisRequest]),
52
            QueryRule(FallibleFirstPartyPkgDigest, [FirstPartyPkgDigestRequest]),
53
            QueryRule(FirstPartyPkgImportPath, [FirstPartyPkgImportPathRequest]),
54
        ],
55
        target_types=[
56
            GoModTarget,
57
            GoPackageTarget,
58
            ResourcesGeneratorTarget,
59
        ],
60
    )
61
    rule_runner.set_options([], env_inherit={"PATH"})
1✔
62
    return rule_runner
1✔
63

64

65
@pytest.mark.parametrize("mod_dir", ("", "src/go/"))
1✔
66
def test_import_path(rule_runner: RuleRunner, mod_dir: str) -> None:
1✔
67
    rule_runner.write_files(
1✔
68
        {
69
            f"{mod_dir}BUILD": "go_mod(name='mod')\ngo_package(name='pkg')",
70
            f"{mod_dir}go.mod": "module go.example.com/foo",
71
            f"{mod_dir}f.go": "",
72
            f"{mod_dir}dir/f.go": "",
73
            f"{mod_dir}dir/BUILD": "go_package()",
74
        }
75
    )
76
    info = rule_runner.request(
1✔
77
        FirstPartyPkgImportPath,
78
        [FirstPartyPkgImportPathRequest(Address(mod_dir, target_name="pkg"))],
79
    )
UNCOV
80
    assert info.import_path == "go.example.com/foo"
×
UNCOV
81
    assert info.dir_path_rel_to_gomod == ""
×
82

UNCOV
83
    info = rule_runner.request(
×
84
        FirstPartyPkgImportPath,
85
        [FirstPartyPkgImportPathRequest(Address(os.path.join(mod_dir, "dir")))],
86
    )
UNCOV
87
    assert info.import_path == "go.example.com/foo/dir"
×
UNCOV
88
    assert info.dir_path_rel_to_gomod == "dir"
×
89

90

91
def test_package_analysis(rule_runner: RuleRunner) -> None:
1✔
92
    rule_runner.write_files(
1✔
93
        {
94
            "foo/BUILD": "go_mod()\n",
95
            "foo/go.mod": dedent(
96
                """\
97
                module go.example.com/foo
98
                go 1.16
99
                require github.com/google/uuid v1.3.0
100
                require (
101
                    rsc.io/quote v1.5.2
102
                    golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c // indirect
103
                    rsc.io/sampler v1.3.0 // indirect
104
                )
105
                """
106
            ),
107
            "foo/go.sum": dedent(
108
                """\
109
                github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
110
                github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
111
                golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c h1:qgOY6WgZOaTkIIMiVjBQcw93ERBE4m30iBm00nkL0i8=
112
                golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
113
                rsc.io/quote v1.5.2 h1:w5fcysjrx7yqtD/aO+QwRjYZOKnaM9Uh2b40tElTs3Y=
114
                rsc.io/quote v1.5.2/go.mod h1:LzX7hefJvL54yjefDEDHNONDjII0t9xZLPXsUe+TKr0=
115
                rsc.io/sampler v1.3.0 h1:7uVkIFmeBqHfdjD+gZwtXXI+RODJ2Wc4O7MPEh/QiW4=
116
                rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=
117
                """
118
            ),
119
            "foo/pkg/foo.go": dedent(
120
                """\
121
                package pkg
122
                import "github.com/google/uuid"
123
                import "rsc.io/quote"
124

125
                func Grok() string {
126
                    return "Hello World"
127
                }
128
                """
129
            ),
130
            "foo/pkg/BUILD": "go_package()",
131
            "foo/cmd/main.go": dedent(
132
                """\
133
                package main
134
                import (
135
                    "fmt"
136
                    "go.example.com/foo/pkg"
137
                )
138
                func main() {
139
                    fmt.Printf("%s\n", pkg.Grok())
140
                }
141
                """
142
            ),
143
            "foo/cmd/bar_test.go": dedent(
144
                """\
145
                package main
146
                import "testing"
147
                func TestBar(t *testing.T) {}
148
                """
149
            ),
150
            "foo/cmd/BUILD": "go_package()",
151
        }
152
    )
153

154
    def assert_analysis(
1✔
155
        dir_path: str,
156
        *,
157
        imports: list[str],
158
        test_imports: list[str],
159
        xtest_imports: list[str],
160
        go_files: list[str],
161
        test_files: list[str],
162
        xtest_files: list[str],
163
    ) -> None:
164
        addr = Address(os.path.join("foo", dir_path))
1✔
165
        maybe_analysis = rule_runner.request(
1✔
166
            FallibleFirstPartyPkgAnalysis,
167
            [FirstPartyPkgAnalysisRequest(addr, build_opts=GoBuildOptions())],
168
        )
UNCOV
169
        assert maybe_analysis.analysis is not None
×
UNCOV
170
        analysis = maybe_analysis.analysis
×
171

UNCOV
172
        assert analysis.imports == tuple(imports)
×
UNCOV
173
        assert analysis.test_imports == tuple(test_imports)
×
UNCOV
174
        assert analysis.xtest_imports == tuple(xtest_imports)
×
UNCOV
175
        assert analysis.go_files == tuple(go_files)
×
UNCOV
176
        assert analysis.test_go_files == tuple(test_files)
×
UNCOV
177
        assert analysis.xtest_go_files == tuple(xtest_files)
×
UNCOV
178
        assert not analysis.s_files
×
179

UNCOV
180
        assert analysis.minimum_go_version == "1.16"
×
181

UNCOV
182
        assert analysis.embed_patterns == ()
×
UNCOV
183
        assert analysis.test_embed_patterns == ()
×
UNCOV
184
        assert analysis.xtest_embed_patterns == ()
×
185

UNCOV
186
        maybe_digest = rule_runner.request(
×
187
            FallibleFirstPartyPkgDigest,
188
            [FirstPartyPkgDigestRequest(addr, build_opts=GoBuildOptions())],
189
        )
UNCOV
190
        assert maybe_digest.pkg_digest is not None
×
UNCOV
191
        pkg_digest = maybe_digest.pkg_digest
×
UNCOV
192
        actual_snapshot = rule_runner.request(Snapshot, [pkg_digest.digest])
×
UNCOV
193
        expected_snapshot = rule_runner.request(Snapshot, [PathGlobs([f"foo/{dir_path}/*.go"])])
×
UNCOV
194
        assert actual_snapshot == expected_snapshot
×
UNCOV
195
        assert pkg_digest.embed_config is None
×
UNCOV
196
        assert pkg_digest.xtest_embed_config is None
×
UNCOV
197
        assert pkg_digest.xtest_embed_config is None
×
198

199
    assert_analysis(
1✔
200
        "pkg",
201
        imports=["github.com/google/uuid", "rsc.io/quote"],
202
        test_imports=[],
203
        xtest_imports=[],
204
        go_files=["foo.go"],
205
        test_files=[],
206
        xtest_files=[],
207
    )
UNCOV
208
    assert_analysis(
×
209
        "cmd",
210
        imports=["fmt", "go.example.com/foo/pkg"],
211
        test_imports=["testing"],
212
        xtest_imports=[],
213
        go_files=["main.go"],
214
        test_files=["bar_test.go"],
215
        xtest_files=[],
216
    )
217

218

219
def test_invalid_package(rule_runner) -> None:
1✔
220
    rule_runner.write_files(
1✔
221
        {
222
            "BUILD": "go_mod(name='mod')\ngo_package(name='pkg')",
223
            "go.mod": dedent(
224
                """\
225
                module go.example.com/foo
226
                go 1.17
227
                """
228
            ),
229
            "bad.go": "invalid!!!",
230
        }
231
    )
232
    maybe_analysis = rule_runner.request(
1✔
233
        FallibleFirstPartyPkgAnalysis,
234
        [FirstPartyPkgAnalysisRequest(Address("", target_name="pkg"), build_opts=GoBuildOptions())],
235
    )
UNCOV
236
    assert maybe_analysis.analysis is None
×
UNCOV
237
    assert maybe_analysis.exit_code == 1
×
UNCOV
238
    assert "bad.go:1:1: expected 'package', found invalid\n" in maybe_analysis.stderr
×
239

240

241
@pytest.mark.xfail(reason="cgo is ignored")
1✔
242
def test_cgo_not_supported(rule_runner: RuleRunner) -> None:
1✔
243
    rule_runner.write_files(
1✔
244
        {
245
            "BUILD": "go_mod(name='mod')\ngo_package(name='pkg')",
246
            "go.mod": dedent(
247
                """\
248
                module go.example.com/foo
249
                go 1.17
250
                """
251
            ),
252
            "hello.go": dedent(
253
                """\
254
                package main
255

256
                // int fortytwo()
257
                // {
258
                //            return 42;
259
                // }
260
                import "C"
261
                import "fmt"
262

263
                func main() {
264
                    f := C.intFunc(C.fortytwo)
265
                    fmt.Println(C.intFunc(C.fortytwo))
266
                }
267
                """
268
            ),
269
        }
270
    )
271
    with engine_error(NotImplementedError):
1✔
272
        rule_runner.request(
1✔
273
            FallibleFirstPartyPkgAnalysis,
274
            [
275
                FirstPartyPkgAnalysisRequest(
276
                    Address("", target_name="pkg"), build_opts=GoBuildOptions()
277
                )
278
            ],
279
        )
280

281

282
def test_embeds_supported(rule_runner: RuleRunner) -> None:
1✔
283
    go_sources = {
1✔
284
        "foo.go": dedent(
285
            """\
286
            package foo
287
            import _ "embed"
288
            //go:embed grok.txt
289
            var message
290
            """
291
        ),
292
        "foo_test.go": dedent(
293
            """\
294
            package foo
295
            import _ "embed"
296
            //go:embed test_grok.txt
297
            var testMessage
298
            """
299
        ),
300
        "bar_test.go": dedent(
301
            """\
302
            package foo_test
303
            import _ "embed"
304
            //go:embed xtest_grok.txt
305
            var testMessage
306
            """
307
        ),
308
    }
309
    resources = {
1✔
310
        "grok.txt": "This will be embedded in a Go binary.",
311
        "test_grok.txt": "This will be embedded in a Go binary.",
312
        "xtest_grok.txt": "This will be embedded in a Go binary.",
313
    }
314
    rule_runner.write_files(
1✔
315
        {
316
            "BUILD": dedent(
317
                """
318
                go_mod(name='mod')
319
                go_package(name='pkg', dependencies=[":resources"])
320
                resources(
321
                  name="resources",
322
                  sources=["*.txt"],
323
                )
324
                """
325
            ),
326
            "go.mod": dedent(
327
                """\
328
                module go.example.com/foo
329
                go 1.17
330
                """
331
            ),
332
            **resources,
333
            **go_sources,
334
        }
335
    )
336
    maybe_analysis = rule_runner.request(
1✔
337
        FallibleFirstPartyPkgAnalysis,
338
        [FirstPartyPkgAnalysisRequest(Address("", target_name="pkg"), build_opts=GoBuildOptions())],
339
    )
UNCOV
340
    assert maybe_analysis.analysis is not None
×
UNCOV
341
    analysis = maybe_analysis.analysis
×
UNCOV
342
    assert analysis.embed_patterns == ("grok.txt",)
×
UNCOV
343
    assert analysis.test_embed_patterns == ("test_grok.txt",)
×
UNCOV
344
    assert analysis.xtest_embed_patterns == ("xtest_grok.txt",)
×
345

UNCOV
346
    maybe_digest = rule_runner.request(
×
347
        FallibleFirstPartyPkgDigest,
348
        [FirstPartyPkgDigestRequest(Address("", target_name="pkg"), build_opts=GoBuildOptions())],
349
    )
UNCOV
350
    assert maybe_digest.pkg_digest is not None
×
UNCOV
351
    pkg_digest = maybe_digest.pkg_digest
×
UNCOV
352
    actual_snapshot = rule_runner.request(Snapshot, [pkg_digest.digest])
×
UNCOV
353
    expected_snapshot = rule_runner.make_snapshot(
×
354
        {
355
            **go_sources,
356
            **resources,
357
        }
358
    )
UNCOV
359
    assert actual_snapshot == expected_snapshot
×
360

UNCOV
361
    assert pkg_digest.embed_config == EmbedConfig(
×
362
        {"grok.txt": ["grok.txt"]}, {"grok.txt": "grok.txt"}
363
    )
UNCOV
364
    assert pkg_digest.test_embed_config == EmbedConfig(
×
365
        {"grok.txt": ["grok.txt"], "test_grok.txt": ["test_grok.txt"]},
366
        {"grok.txt": "grok.txt", "test_grok.txt": "test_grok.txt"},
367
    )
UNCOV
368
    assert pkg_digest.xtest_embed_config == EmbedConfig(
×
369
        {"xtest_grok.txt": ["xtest_grok.txt"]}, {"xtest_grok.txt": "xtest_grok.txt"}
370
    )
371

372

373
def test_missing_embeds(rule_runner: RuleRunner) -> None:
1✔
374
    """Failing to set up embeds should not crash Pants."""
375
    rule_runner.write_files(
1✔
376
        {
377
            "BUILD": dedent(
378
                """
379
                go_mod(name='mod')
380
                go_package(name='pkg')
381
                """
382
            ),
383
            "go.mod": dedent(
384
                """\
385
                module go.example.com/foo
386
                go 1.17
387
                """
388
            ),
389
            "foo.go": dedent(
390
                """\
391
                package foo
392
                import _ "embed"
393
                //go:embed fake.txt
394
                var message
395
                """
396
            ),
397
        }
398
    )
399
    maybe_digest = rule_runner.request(
1✔
400
        FallibleFirstPartyPkgDigest,
401
        [FirstPartyPkgDigestRequest(Address("", target_name="pkg"), build_opts=GoBuildOptions())],
402
    )
UNCOV
403
    assert maybe_digest.pkg_digest is None
×
UNCOV
404
    assert maybe_digest.exit_code != 0
×
UNCOV
405
    assert maybe_digest.stderr is not None
×
UNCOV
406
    assert "Failed to find embedded resources: could not embed fake.txt" in maybe_digest.stderr
×
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