@@ -47,7 +47,7 @@ def workspace_release(release):
4747 tests that are not about the version.
4848 """
4949 text = (ROOT / "Cargo.toml" ).read_text (encoding = "utf-8" )
50- match = re .search (r'version = "(\d+\.\d+\.\d+-djbclark \.\d+)"' , text )
50+ match = re .search (r'version = "(\d+\.\d+\.\d+-sudo \.\d+)"' , text )
5151 assert match , "workspace Cargo.toml is not stamped with a downstream version"
5252 return release .parse_release (match .group (1 ))
5353
@@ -75,27 +75,31 @@ def workspace_release(release):
7575
7676
7777def test_release_identity_is_derived_from_the_serial (release , cut ):
78- cut = release .parse_release ("0.19.1-djbclark.2 " )
79- assert cut .serial == 2
80- assert cut .version == "0.19.1-djbclark.2 "
81- assert cut .tag == "v0.19.1-djbclark.2 "
82- assert cut .title == "SecretSpec 0.19.1 — sudo-secretspec downstream 2 "
78+ cut = release .parse_release ("0.19.1-sudo.5 " )
79+ assert cut .serial == 5
80+ assert cut .version == "0.19.1-sudo.5 "
81+ assert cut .tag == "v0.19.1-sudo.5 "
82+ assert cut .title == "SecretSpec 0.19.1 — sudo-secretspec downstream 5 "
8383 assert cut .archive_url == (
8484 "https://github.com/djbclark/sudo-secretspec/archive/refs/tags/"
85- "v0.19.1-djbclark.2 .tar.gz"
85+ "v0.19.1-sudo.5 .tar.gz"
8686 )
8787
8888
8989def test_only_downstream_versions_on_the_pinned_upstream_base_are_accepted (release ):
9090 # The upstream base stays a constant: rebasing onto a new upstream tag is a
9191 # separate decision, not something a --version argument may do implicitly.
9292 for bad in (
93- "0.20.0-djbclark .1" ,
93+ "0.20.0-sudo .1" ,
9494 "0.19.1" ,
95- "v0.19.1-djbclark .1" ,
96- "0.19.1-djbclark .0" ,
97- "0.19.1-djbclark .01" ,
95+ "v0.19.1-sudo .1" ,
96+ "0.19.1-sudo .0" ,
97+ "0.19.1-sudo .01" ,
9898 "0.19.1-other.1" ,
99+ # The pre-rename spelling is no longer a version this script may cut.
100+ # It still has to be *recognized* when restamping a formula, which is
101+ # ANY_VERSION_RE's job, not parse_release's.
102+ "0.19.1-djbclark.4" ,
99103 "" ,
100104 ):
101105 with pytest .raises (release .ReleaseError ):
@@ -104,7 +108,7 @@ def test_only_downstream_versions_on_the_pinned_upstream_base_are_accepted(relea
104108
105109def test_https_release_url_guard (release ):
106110 release .validate_release_url (
107- "https://github.com/djbclark/sudo-secretspec/archive/refs/tags/v0.19.1-djbclark .1.tar.gz"
111+ "https://github.com/djbclark/sudo-secretspec/archive/refs/tags/v0.19.1-sudo .1.tar.gz"
108112 )
109113 for url in ("http://github.com/x" , "file:///tmp/x" , "https://example.com/x" ):
110114 with pytest .raises (release .ReleaseError ):
@@ -127,13 +131,15 @@ def test_formula_rewrite_restamps_every_version_site(tmp_path: Path, release, cu
127131 " end\n " ,
128132 encoding = "utf-8" ,
129133 )
130- cut = release .parse_release ("0.19.1-djbclark.2 " )
134+ cut = release .parse_release ("0.19.1-sudo.5 " )
131135
132136 release .rewrite_formula (formula , cut , "a" * 64 )
133137
134138 text = formula .read_text (encoding = "utf-8" )
139+ # The fixture is deliberately on the pre-rename spelling: a formula carried
140+ # across the djbclark -> sudo rename must be restamped, not left behind.
135141 assert "0.19.1-djbclark.1" not in text , text
136- assert text .count ("0.19.1-djbclark.2 " ) == release .FORMULA_VERSION_SITES
142+ assert text .count ("0.19.1-sudo.5 " ) == release .FORMULA_VERSION_SITES
137143 assert f'url "{ cut .archive_url } "' in text
138144 assert f'sha256 "{ "a" * 64 } "' in text
139145
@@ -150,7 +156,7 @@ def test_formula_rewrite_refuses_an_unexpected_number_of_version_sites(
150156 )
151157 with pytest .raises (release .ReleaseError , match = "version references" ):
152158 release .rewrite_formula (
153- formula , release .parse_release ("0.19.1-djbclark.2 " ), "a" * 64
159+ formula , release .parse_release ("0.19.1-sudo.5 " ), "a" * 64
154160 )
155161
156162
@@ -226,7 +232,7 @@ def test_preflight_refuses_a_serial_that_is_already_published(monkeypatch, relea
226232
227233 def fake_run (argv , ** kwargs ):
228234 if argv [:2 ] == ["git" , "ls-remote" ]:
229- return completed (argv , "9f4c…\t refs/tags/v0.19.1-djbclark .9\n " )
235+ return completed (argv , "9f4c…\t refs/tags/v0.19.1-sudo .9\n " )
230236 if argv [:4 ] == ["gh" , "repo" , "view" , "djbclark/sudo-secretspec" ]:
231237 return completed (
232238 argv ,
@@ -263,7 +269,50 @@ def fake_run(argv, **kwargs):
263269 monkeypatch .setattr (release , "run" , fake_run )
264270 # A serial nobody will ever cut, so it cannot match the real Cargo.toml.
265271 with pytest .raises (release .ReleaseError , match = "bump Cargo.toml" ):
266- release .preflight (release .parse_release ("0.19.1-djbclark.999" ), allow_dirty = False )
272+ release .preflight (release .parse_release ("0.19.1-sudo.999" ), allow_dirty = False )
273+
274+
275+ def test_preflight_refuses_a_lockfile_that_disagrees_with_the_manifest (
276+ monkeypatch , release
277+ ):
278+ """The guard that v0.19.1-sudo.4 shipped without.
279+
280+ That release bumped Cargo.toml and left Cargo.lock naming the previous
281+ version. The formula builds with `cargo install --locked`, so the published
282+ tag aborted before compiling anything. `cargo metadata --locked` is the
283+ cheapest way to ask, and asking in preflight means the failure lands before
284+ a tag exists rather than after it is public.
285+ """
286+
287+ def fake_run (argv , ** kwargs ):
288+ if argv [:2 ] == ["cargo" , "metadata" ]:
289+ assert "--locked" in argv
290+ assert kwargs .get ("check" ) is False , "must not raise past the guard"
291+ return completed (argv , returncode = 101 )
292+ if argv [:4 ] == ["gh" , "repo" , "view" , "djbclark/sudo-secretspec" ]:
293+ return completed (
294+ argv ,
295+ json .dumps (
296+ {
297+ "nameWithOwner" : "djbclark/sudo-secretspec" ,
298+ "parent" : {"nameWithOwner" : "cachix/secretspec" },
299+ "defaultBranchRef" : {"name" : "sudo-main" },
300+ }
301+ ),
302+ )
303+ return completed (argv , PREFLIGHT_GIT_OUTPUTS .get (tuple (argv ), "" ))
304+
305+ monkeypatch .setattr (release , "run" , fake_run )
306+ with pytest .raises (release .ReleaseError , match = "Cargo.lock is out of date" ):
307+ release .preflight (workspace_release (release ), allow_dirty = False )
308+
309+
310+ def test_any_version_re_matches_both_downstream_spellings (release ):
311+ """Restamping must recognize the pre-rename spelling as well as the current
312+ one, or a formula carried across the rename keeps its stale version."""
313+ assert release .ANY_VERSION_RE .findall (
314+ 'url ".../v0.19.1-djbclark.3.tar.gz"\n version "0.19.1-sudo.4"\n '
315+ ) == ["0.19.1-djbclark.3" , "0.19.1-sudo.4" ]
267316
268317
269318def test_parent_slug_accepts_every_gh_parent_shape (release ):
0 commit comments