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

pantsbuild / pants / 25441711719

06 May 2026 02:31PM UTC coverage: 92.915%. Remained the same
25441711719

push

github

web-flow
use sha pin (with comment) format for generated actions (#23312)

Per the GitHub Action best practices we recently enabled at #23249, we
should pin each action to a SHA so that the reference is actually
immutable.

This will -- I hope -- knock out a large chunk of the 421 alerts we
currently get from zizmor. The next followup would then be upgrades and
harmonizing the generated and none-generated pins.

Notice: This idea was suggested by Claude while going over pinact output
and I was surprised to see that post processing the yaml wasn't too
gross.

92206 of 99237 relevant lines covered (92.91%)

4.04 hits per line

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

96.49
/src/python/pants/bsp/spec/lifecycle.py
1
# Copyright 2022 Pants project contributors (see CONTRIBUTORS.md).
2
# Licensed under the Apache License, Version 2.0 (see LICENSE).
3
from __future__ import annotations
2✔
4

5
from dataclasses import dataclass
2✔
6
from typing import Any
2✔
7

8
from pants.bsp.spec.base import Uri
2✔
9
from pants.bsp.utils import freeze_json
2✔
10

11

12
@dataclass(frozen=True)
2✔
13
class BuildClientCapabilities:
2✔
14
    # The languages that this client supports.
15
    # The ID strings for each language are defined in the LSP.
16
    # The server must never respond with build targets for other
17
    # languages than those that appear in this list.
18
    language_ids: tuple[str, ...]
2✔
19

20
    @classmethod
2✔
21
    def from_json_dict(cls, d):
2✔
22
        return cls(language_ids=tuple(d.get("languageIds", [])))
1✔
23

24
    def to_json_dict(self):
2✔
25
        return {
1✔
26
            "languageIds": self.language_ids,
27
        }
28

29

30
@dataclass(frozen=True)
2✔
31
class InitializeBuildParams:
2✔
32
    # Name of the client
33
    display_name: str
2✔
34

35
    # The version of the client
36
    version: str
2✔
37

38
    # The BSP version that the client speaks
39
    bsp_version: str
2✔
40

41
    # The rootUri of the workspace
42
    root_uri: Uri
2✔
43

44
    # The capabilities of the client
45
    capabilities: BuildClientCapabilities
2✔
46

47
    # Additional metadata about the client
48
    data: Any | None
2✔
49

50
    @classmethod
2✔
51
    def from_json_dict(cls, d):
2✔
52
        return cls(
1✔
53
            display_name=d["displayName"],
54
            version=d["version"],
55
            bsp_version=d["bspVersion"],
56
            root_uri=d["rootUri"],
57
            capabilities=BuildClientCapabilities.from_json_dict(d["capabilities"]),
58
            data=freeze_json(d.get("data")),
59
        )
60

61
    def to_json_dict(self):
2✔
62
        result = {
1✔
63
            "displayName": self.display_name,
64
            "version": self.version,
65
            "bspVersion": self.bsp_version,
66
            "rootUri": self.root_uri,
67
            "capabilities": self.capabilities.to_json_dict(),
68
        }
69
        if self.data is not None:
1✔
70
            result["data"] = self.data
1✔
71
        return result
1✔
72

73

74
@dataclass(frozen=True)
2✔
75
class CompileProvider:
2✔
76
    language_ids: tuple[str, ...]
2✔
77

78
    @classmethod
2✔
79
    def from_json_dict(cls, d):
2✔
80
        return cls(language_ids=tuple(d.get("languageIds", [])))
1✔
81

82
    def to_json_dict(self):
2✔
83
        return {
1✔
84
            "languageIds": self.language_ids,
85
        }
86

87

88
@dataclass(frozen=True)
2✔
89
class RunProvider:
2✔
90
    language_ids: tuple[str, ...]
2✔
91

92
    @classmethod
2✔
93
    def from_json_dict(cls, d):
2✔
94
        return cls(language_ids=tuple(d.get("languageIds", [])))
1✔
95

96
    def to_json_dict(self):
2✔
97
        return {
1✔
98
            "languageIds": self.language_ids,
99
        }
100

101

102
@dataclass(frozen=True)
2✔
103
class DebugProvider:
2✔
104
    language_ids: tuple[str, ...]
2✔
105

106
    @classmethod
2✔
107
    def from_json_dict(cls, d):
2✔
108
        return cls(language_ids=tuple(d.get("languageIds", [])))
1✔
109

110
    def to_json_dict(self):
2✔
111
        return {
1✔
112
            "languageIds": self.language_ids,
113
        }
114

115

116
@dataclass(frozen=True)
2✔
117
class TestProvider:
2✔
118
    language_ids: tuple[str, ...]
2✔
119

120
    @classmethod
2✔
121
    def from_json_dict(cls, d):
2✔
122
        return cls(language_ids=tuple(d.get("languageIds", [])))
1✔
123

124
    def to_json_dict(self):
2✔
125
        return {
1✔
126
            "languageIds": self.language_ids,
127
        }
128

129

130
@dataclass(frozen=True)
2✔
131
class BuildServerCapabilities:
2✔
132
    # The languages the server supports compilation via method buildTarget/compile.
133
    compile_provider: CompileProvider | None
2✔
134

135
    # The languages the server supports test execution via method buildTarget/test
136
    test_provider: TestProvider | None
2✔
137

138
    # The languages the server supports run via method buildTarget/run
139
    run_provider: RunProvider | None
2✔
140

141
    # The languages the server supports debugging via method debugSession/start
142
    debug_provider: DebugProvider | None
2✔
143

144
    # The server can provide a list of targets that contain a
145
    # single text document via the method buildTarget/inverseSources
146
    inverse_sources_provider: bool | None
2✔
147

148
    # The server provides sources for library dependencies
149
    # via method buildTarget/dependencySources
150
    dependency_sources_provider: bool | None
2✔
151

152
    # The server can provide a list of dependency modules (libraries with meta information)
153
    # via method buildTarget/dependencyModules
154
    dependency_modules_provider: bool | None
2✔
155

156
    # The server provides all the resource dependencies
157
    # via method buildTarget/resources
158
    resources_provider: bool | None
2✔
159

160
    # Reloading the build state through workspace/reload is supported
161
    can_reload: bool | None
2✔
162

163
    # The server sends notifications to the client on build
164
    # target change events via buildTarget/didChange
165
    build_target_changed_provider: bool | None
2✔
166

167
    @classmethod
2✔
168
    def from_json_dict(cls, d):
2✔
169
        return cls(
1✔
170
            compile_provider=(
171
                CompileProvider.from_json_dict(d["compileProvider"])
172
                if "compileProvider" in d
173
                else None
174
            ),
175
            test_provider=(
176
                TestProvider.from_json_dict(d["testProvider"]) if "testProvider" in d else None
177
            ),
178
            run_provider=(
179
                RunProvider.from_json_dict(d["runProvider"]) if "runProvider" in d else None
180
            ),
181
            debug_provider=(
182
                DebugProvider.from_json_dict(d["debugProvider"]) if "debugProvider" in d else None
183
            ),
184
            inverse_sources_provider=d.get("inverseSourcesProvider"),
185
            dependency_sources_provider=d.get("dependencySourcesProvider"),
186
            dependency_modules_provider=d.get("dependencyModulesProvider"),
187
            resources_provider=d.get("resourcesProvider"),
188
            can_reload=d.get("canReload"),
189
            build_target_changed_provider=d.get("buildTargetChangedProvider"),
190
        )
191

192
    def to_json_dict(self):
2✔
193
        result = {}
1✔
194
        if self.compile_provider is not None:
1✔
195
            result["compileProvider"] = self.compile_provider.to_json_dict()
1✔
196
        if self.test_provider is not None:
1✔
197
            result["testProvider"] = self.test_provider.to_json_dict()
1✔
198
        if self.run_provider is not None:
1✔
199
            result["runProvider"] = self.run_provider.to_json_dict()
1✔
200
        if self.debug_provider is not None:
1✔
201
            result["debugProvider"] = self.debug_provider.to_json_dict()
1✔
202
        if self.inverse_sources_provider is not None:
1✔
203
            result["inverseSourcesProvider"] = self.inverse_sources_provider
×
204
        if self.dependency_sources_provider is not None:
1✔
205
            result["dependencySourcesProvider"] = self.dependency_sources_provider
1✔
206
        if self.dependency_modules_provider is not None:
1✔
207
            result["dependencyModulesProvider"] = self.dependency_modules_provider
1✔
208
        if self.resources_provider is not None:
1✔
209
            result["resourcesProvider"] = self.resources_provider
1✔
210
        if self.can_reload is not None:
1✔
211
            result["canReload"] = self.can_reload
×
212
        if self.build_target_changed_provider is not None:
1✔
213
            result["buildTargetChangedProvider"] = self.build_target_changed_provider
×
214
        return result
1✔
215

216

217
@dataclass(frozen=True)
2✔
218
class InitializeBuildResult:
2✔
219
    # Name of the server
220
    display_name: str
2✔
221

222
    # The version of the server
223
    version: str
2✔
224

225
    # The BSP version that the server speaks
226
    bsp_version: str
2✔
227

228
    # The capabilities of the build server
229
    capabilities: BuildServerCapabilities
2✔
230

231
    # Additional metadata about the server
232
    data: Any | None
2✔
233

234
    @classmethod
2✔
235
    def from_json_dict(cls, d):
2✔
236
        return cls(
1✔
237
            display_name=d["displayName"],
238
            version=d["version"],
239
            bsp_version=d["bspVersion"],
240
            capabilities=BuildServerCapabilities.from_json_dict(d["capabilities"]),
241
            data=d.get("data"),
242
        )
243

244
    def to_json_dict(self):
2✔
245
        result = {
1✔
246
            "displayName": self.display_name,
247
            "version": self.version,
248
            "bspVersion": self.bsp_version,
249
            "capabilities": self.capabilities.to_json_dict(),
250
        }
251
        if self.data is not None:
1✔
252
            # TODO: Figure out whether to encode/decode data in a generic manner.
253
            result["data"] = self.data
×
254
        return result
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