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

pantsbuild / pants / 21457998286

28 Jan 2026 10:32PM UTC coverage: 80.281% (+0.01%) from 80.269%
21457998286

Pull #23037

github

web-flow
Merge 43b38d939 into 0fdb40370
Pull Request #23037: Enable publish without package 2

275 of 328 new or added lines in 13 files covered. (83.84%)

46 existing lines in 9 files now uncovered.

78960 of 98355 relevant lines covered (80.28%)

3.36 hits per line

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

92.75
/src/python/pants/core/goals/publish_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 json
1✔
7
from dataclasses import dataclass
1✔
8
from textwrap import dedent
1✔
9

10
import pytest
1✔
11

12
from pants.backend.python.goals import package_dists
1✔
13
from pants.backend.python.macros.python_artifact import PythonArtifact
1✔
14
from pants.backend.python.target_types import PythonDistribution, PythonSourcesGeneratorTarget
1✔
15
from pants.backend.python.target_types_rules import rules as python_target_type_rules
1✔
16
from pants.core.goals import package, publish
1✔
17
from pants.core.goals.publish import (
1✔
18
    PreemptiveSkipRequest,
19
    Publish,
20
    PublishFieldSet,
21
    PublishPackages,
22
    PublishProcesses,
23
    PublishRequest,
24
    SkippedPublishPackages,
25
)
26
from pants.engine.process import Process, ProcessCacheScope
1✔
27
from pants.engine.rules import rule
1✔
28
from pants.engine.target import StringSequenceField
1✔
29
from pants.engine.unions import UnionRule
1✔
30
from pants.testutil.rule_runner import RuleRunner
1✔
31

32

33
class MockRepositoriesField(StringSequenceField):
1✔
34
    alias = "repositories"
1✔
35

36

37
@dataclass(frozen=True)
1✔
38
class MockPublishRequest(PublishRequest):
1✔
39
    pass
1✔
40

41

42
@dataclass(frozen=True)
1✔
43
class PublishTestFieldSet(PublishFieldSet):
1✔
44
    publish_request_type = MockPublishRequest
1✔
45
    required_fields = (MockRepositoriesField,)
1✔
46

47
    repositories: MockRepositoriesField
1✔
48

49
    def make_skip_request(self, package_fs: package.PackageFieldSet) -> TestPreemptiveSkipRequest:
1✔
NEW
50
        return TestPreemptiveSkipRequest(publish_fs=self, package_fs=package_fs)
×
51

52

53
class TestPreemptiveSkipRequest(PreemptiveSkipRequest[PublishTestFieldSet]):
1✔
54
    pass
1✔
55

56

57
@rule
1✔
58
async def mock_check_if_skip(request: TestPreemptiveSkipRequest) -> SkippedPublishPackages:
1✔
NEW
59
    if not request.publish_fs.repositories.value:
×
NEW
60
        return SkippedPublishPackages.skip(names=[], data=request.publish_fs.get_output_data())
×
NEW
61
    return (
×
62
        SkippedPublishPackages.skip(
63
            names=["my_package-0.1.0-py3-none-any.whl", "my_package-0.1.0.tar.gz"],
64
            description="(requested)",
65
            data=request.publish_fs.get_output_data(),
66
        )
67
        if all(repo == "skip" for repo in request.publish_fs.repositories.value)
68
        else SkippedPublishPackages.no_skip()
69
    )
70

71

72
@rule
1✔
73
async def mock_publish(request: MockPublishRequest) -> PublishProcesses:
1✔
UNCOV
74
    return PublishProcesses(
×
75
        PublishPackages(
76
            names=tuple(
77
                artifact.relpath
78
                for pkg in request.packages
79
                for artifact in pkg.artifacts
80
                if artifact.relpath
81
            ),
82
            process=(
83
                None
84
                if repo == "skip"
85
                else Process(
86
                    ["/bin/echo", repo],
87
                    cache_scope=ProcessCacheScope.PER_SESSION,
88
                    description="mock publish",
89
                )
90
            ),
91
            description="(requested)" if repo == "skip" else repo,
92
        )
93
        for repo in request.field_set.repositories.value
94
    )
95

96

97
@pytest.fixture
1✔
98
def rule_runner() -> RuleRunner:
1✔
99
    return RuleRunner(
1✔
100
        rules=[
101
            *package.rules(),
102
            *publish.rules(),
103
            *package_dists.rules(),
104
            *python_target_type_rules(),
105
            mock_check_if_skip,
106
            mock_publish,
107
            PythonDistribution.register_plugin_field(MockRepositoriesField),
108
            *PublishTestFieldSet.rules(),
109
            UnionRule(PreemptiveSkipRequest, TestPreemptiveSkipRequest),
110
        ],
111
        target_types=[PythonSourcesGeneratorTarget, PythonDistribution],
112
        objects={"python_artifact": PythonArtifact},
113
    )
114

115

116
def test_noop(rule_runner: RuleRunner) -> None:
1✔
117
    rule_runner.write_files(
1✔
118
        {
119
            "src/BUILD": dedent(
120
                """\
121
                python_sources()
122
                python_distribution(
123
                  name="dist",
124
                  provides=python_artifact(
125
                    name="my-package",
126
                    version="0.1.0",
127
                  ),
128
                )
129
                """
130
            ),
131
        }
132
    )
133

134
    result = rule_runner.run_goal_rule(
1✔
135
        Publish,
136
        args=("src:dist",),
137
        env_inherit={"HOME", "PATH", "PYENV_ROOT"},
138
    )
139

140
    assert result.exit_code == 0
1✔
141
    assert "Nothing published." in result.stderr
1✔
142

143

144
def test_skipped_publish(rule_runner: RuleRunner) -> None:
1✔
145
    rule_runner.write_files(
1✔
146
        {
147
            "src/BUILD": dedent(
148
                """\
149
                python_sources()
150
                python_distribution(
151
                  name="dist",
152
                  provides=python_artifact(
153
                    name="my-package",
154
                    version="0.1.0",
155
                  ),
156
                  repositories=["skip"],
157
                )
158
                """
159
            ),
160
        }
161
    )
162

163
    result = rule_runner.run_goal_rule(
1✔
164
        Publish,
165
        args=("src:dist",),
166
        env_inherit={"HOME", "PATH", "PYENV_ROOT"},
167
    )
168

169
    assert result.exit_code == 0
1✔
170
    assert "my_package-0.1.0.tar.gz skipped (requested)." in result.stderr
1✔
171
    assert "my_package-0.1.0-py3-none-any.whl skipped (requested)." in result.stderr
1✔
172

173

174
def test_structured_output(rule_runner: RuleRunner) -> None:
1✔
175
    rule_runner.write_files(
1✔
176
        {
177
            "src/BUILD": dedent(
178
                """\
179
                python_sources()
180
                python_distribution(
181
                  name="dist",
182
                  provides=python_artifact(
183
                    name="my-package",
184
                    version="0.1.0",
185
                  ),
186
                  repositories=["skip"],
187
                )
188
                """
189
            ),
190
        }
191
    )
192

193
    result = rule_runner.run_goal_rule(
1✔
194
        Publish,
195
        args=(
196
            "--output=published.json",
197
            "src:dist",
198
        ),
199
        env_inherit={"HOME", "PATH", "PYENV_ROOT"},
200
    )
201

202
    assert result.exit_code == 0
1✔
203
    assert "my_package-0.1.0.tar.gz skipped (requested)." in result.stderr
1✔
204
    assert "my_package-0.1.0-py3-none-any.whl skipped (requested)." in result.stderr
1✔
205

206
    expected = [
1✔
207
        {
208
            "names": [
209
                "my_package-0.1.0-py3-none-any.whl",
210
                "my_package-0.1.0.tar.gz",
211
            ],
212
            "published": False,
213
            "status": "skipped (requested)",
214
            "target": "src:dist",
215
        },
216
    ]
217

218
    with rule_runner.pushd():
1✔
219
        with open("published.json") as fd:
1✔
220
            data = json.load(fd)
1✔
221
            assert data == expected
1✔
222

223

224
def test_mocked_publish(rule_runner: RuleRunner) -> None:
1✔
225
    rule_runner.write_files(
1✔
226
        {
227
            "src/BUILD": dedent(
228
                """\
229
                python_sources()
230
                python_distribution(
231
                  name="dist",
232
                  provides=python_artifact(
233
                    name="my-package",
234
                    version="0.1.0",
235
                  ),
236
                  repositories=["mocked-repo"],
237
                )
238
                """
239
            ),
240
        }
241
    )
242

243
    result = rule_runner.run_goal_rule(
1✔
244
        Publish,
245
        args=("src:dist",),
246
        env_inherit={"HOME", "PATH", "PYENV_ROOT"},
247
    )
248

249
    assert result.exit_code == 0
1✔
250
    assert "my_package-0.1.0.tar.gz published to mocked-repo." in result.stderr
1✔
251
    assert "my_package-0.1.0-py3-none-any.whl published to mocked-repo." in result.stderr
1✔
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