1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
#!/usr/bin/env python3
"""Check staged release assets against the crate's cargo-binstall metadata.
``cargo binstall`` derives the asset URL from ``pkg-url`` and then looks inside
the downloaded archive at the path ``bin-dir`` renders to. Those two templates
live in ``Cargo.toml``; the archive is built by the release workflow. Nothing
connects them at build time, so this script renders both templates for a target
and asserts that the staged directory really contains what they promise.
It is the shared checker behind the release-packaging contract test and the
runner-backed packaging dry run in continuous integration.
Example:
$ python3 scripts/verify_binstall_layout.py \\
--artifact-dir artifacts/linux-x86_64 \\
--target x86_64-unknown-linux-gnu
mdtablefix-0.5.1-x86_64-unknown-linux-gnu.tar.gz -> mdtablefix
"""
# Binstall writes placeholders with padding, as in `{ binary-ext }`.
=
"""Raised when the staged assets contradict the binstall metadata.
The message names the asset and the template it failed to satisfy, so a
failing release job reports which of the two sides drifted.
"""
"""Substitute binstall placeholders in a template string.
Parameters
----------
template : str
A ``pkg-url`` or ``bin-dir`` template, whose placeholders may carry
padding, as in ``{ binary-ext }``.
values : dict of str to str
The substitutions to apply, keyed by placeholder name.
Returns
-------
str
The template with every placeholder replaced.
Raises
------
LayoutError
If the template names a placeholder absent from ``values``.
Examples
--------
>>> render("{ name }-{ version }", {"name": "tool", "version": "1.0"})
'tool-1.0'
"""
=
return
return
"""Return the package and binstall tables from a Cargo manifest.
Parameters
----------
manifest : Path
The ``Cargo.toml`` to read.
Returns
-------
tuple of dict
The ``[package]`` table and the ``[package.metadata.binstall]`` table.
Raises
------
LayoutError
If the manifest declares no binstall metadata, if ``bin-dir`` is
``"."``, or if the metadata carries per-target overrides.
OSError
If the manifest cannot be read.
"""
=
=
=
# Overrides are legitimate in general, but this crate publishes one
# archive shape for every target, so an override would mean the single
# rendered contract checked here no longer describes every platform.
return ,
"""Build the placeholder table binstall would use for a target.
Parameters
----------
package : dict
The manifest's ``[package]`` table.
target : str
The Rust target triple the templates are rendered for.
Returns
-------
dict of str to str
Every placeholder this checker understands, including the Windows-only
``binary-ext``.
Raises
------
KeyError
If the package table omits a name, version or repository.
"""
=
return
"""Return the SHA-256 digest of a file.
Parameters
----------
path : Path
The file to read. Release assets are small enough to read whole.
Returns
-------
str
The digest as lowercase hexadecimal.
Raises
------
OSError
If the file cannot be read.
"""
return
"""Check that an asset's checksum sidecar is present and correct.
Parameters
----------
asset : Path
The staged asset whose ``.sha256`` sidecar is checked.
Returns
-------
None
Nothing. The check reports failure by raising.
Raises
------
LayoutError
If the sidecar is missing, does not name the asset alone, or records a
digest that does not match the asset.
OSError
If the asset or the sidecar cannot be read.
"""
=
=
"""Return the member names inside a gzip tarball.
Parameters
----------
archive : Path
The ``.tar.gz`` to inspect.
Returns
-------
list of str
The member names, in archive order.
Raises
------
tarfile.TarError
If the archive cannot be opened or read.
"""
return
"""Check one target's staged assets against the binstall templates.
Parameters
----------
artifact_dir : Path
The staging directory holding the archive and its sidecar.
manifest : Path
The ``Cargo.toml`` supplying ``pkg-url``, ``bin-dir`` and ``pkg-fmt``.
target : str
The Rust target triple the templates are rendered for.
Returns
-------
tuple of str
The archive name and the archive-relative binary path, both as
rendered from the manifest.
Raises
------
LayoutError
If the format is not ``tgz``, the archive named by ``pkg-url`` is
absent, its checksum sidecar is wrong, or its members are not exactly
the single path ``bin-dir`` renders to.
"""
, =
=
=
= .
= /
=
=
return ,
"""Parse the command line for the verification entry point.
Parameters
----------
argv : list of str, optional
Arguments to parse. Defaults to ``sys.argv[1:]``.
Returns
-------
argparse.Namespace
The parsed arguments.
Raises
------
SystemExit
If the arguments are invalid, as raised by :mod:`argparse`.
"""
=
return
"""Check the staged assets described by the command line.
Parameters
----------
argv : list of str, optional
Arguments to parse. Defaults to ``sys.argv[1:]``.
Returns
-------
int
Zero on success, having printed the archive name and the binary path
it contains.
Raises
------
SystemExit
If the staged assets contradict the manifest's binstall metadata.
"""
=
, =
return 0