Skip to content

Commit 98bdff1

Browse files
committed
fetch tags dynamically
1 parent 05f9c10 commit 98bdff1

1 file changed

Lines changed: 67 additions & 39 deletions

File tree

packages/cli/src/cli/patch_wasm_bindgen.rs

Lines changed: 67 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -316,71 +316,99 @@ impl PatchWasmBindgen {
316316
#[cfg(test)]
317317
mod tests {
318318
use super::*;
319+
use krates::semver::Prerelease;
320+
use std::sync::OnceLock;
321+
322+
/// Tags fetched live from DioxusLabs/wasm-bindgen-wry, once per test run.
323+
/// `None` when the fetch failed (offline / rate-limited); callers skip.
324+
fn fetched_tags() -> Option<&'static [String]> {
325+
static TAGS: OnceLock<Option<Vec<String>>> = OnceLock::new();
326+
TAGS.get_or_init(|| {
327+
tokio::runtime::Builder::new_current_thread()
328+
.enable_all()
329+
.build()
330+
.unwrap()
331+
.block_on(fetch_available_tags())
332+
.map_err(|e| eprintln!("skipping: could not fetch tags from GitHub: {e}"))
333+
.ok()
334+
})
335+
.as_deref()
336+
}
319337

320-
/// The tags published on DioxusLabs/wasm-bindgen-wry at the time of writing
321-
fn real_tags() -> Vec<String> {
322-
["v0.2.106", "v0.2.122-alpha.2", "v0.2.122-alpha.4"]
323-
.map(String::from)
324-
.to_vec()
338+
fn parsed_tags(tags: &[String]) -> Vec<Version> {
339+
let versions: Vec<_> = tags.iter().filter_map(|t| parse_version(t)).collect();
340+
assert!(!versions.is_empty(), "no parseable tags published");
341+
versions
325342
}
326343

327344
fn v(s: &str) -> Version {
328345
Version::parse(s).unwrap()
329346
}
330347

348+
fn base(v: &Version) -> Version {
349+
Version::new(v.major, v.minor, v.patch)
350+
}
351+
331352
#[test]
332353
fn fork_pin_requires_exact_tag() {
333-
// The workspace pins wasm-bindgen-x =0.2.122-alpha.5 but no such tag exists yet:
334-
// every upstream version must select nothing (warn-and-skip), never a stale tag.
335-
let pin = v("0.2.122-alpha.5");
336-
for upstream in ["0.2.100", "0.2.106", "0.2.122", "0.2.123"] {
354+
let Some(tags) = fetched_tags() else { return };
355+
let versions = parsed_tags(tags);
356+
357+
for pin in &versions {
358+
// Pinning to a published tag selects exactly that tag
359+
let selected = find_best_matching_tag(&base(pin), Some(pin), tags)
360+
.and_then(|tag| parse_version(&tag));
361+
assert_eq!(selected.as_ref(), Some(pin));
362+
363+
// A pin with no published tag must select nothing (warn-and-skip), never a stale tag
364+
let mut absent = pin.clone();
365+
absent.pre = Prerelease::new("alpha.99999").unwrap();
366+
assert!(!versions.contains(&absent));
337367
assert_eq!(
338-
find_best_matching_tag(&v(upstream), Some(&pin), &real_tags()),
368+
find_best_matching_tag(&base(pin), Some(&absent), tags),
339369
None,
340-
"upstream {upstream} must not match any tag with pin {pin}"
370+
"pin {absent} must not match any tag"
341371
);
342372
}
343-
344-
// Once the pinned tag exists, it is selected exactly
345-
let pin = v("0.2.122-alpha.4");
346-
assert_eq!(
347-
find_best_matching_tag(&v("0.2.122"), Some(&pin), &real_tags()),
348-
Some("v0.2.122-alpha.4".to_string())
349-
);
350373
}
351374

352375
#[test]
353376
fn no_fork_pin_selects_highest_compatible_base() {
354-
// Without a fork pin, pick the highest tag whose base can shadow the upstream version.
355-
// Notably 0.2.106 must NOT be pinned to the stale v0.2.106 prototype tag.
356-
for upstream in ["0.2.100", "0.2.106", "0.2.122"] {
357-
assert_eq!(
358-
find_best_matching_tag(&v(upstream), None, &real_tags()),
359-
Some("v0.2.122-alpha.4".to_string()),
360-
"upstream {upstream} should select the newest compatible tag"
361-
);
377+
let Some(tags) = fetched_tags() else { return };
378+
let versions = parsed_tags(tags);
379+
380+
// Without a fork pin, every published tag's base must be shadowable by a tag from the
381+
// same minor line that is at least as new
382+
for tag in &versions {
383+
let selected = find_best_matching_tag(&base(tag), None, tags)
384+
.and_then(|t| parse_version(&t))
385+
.expect("a published tag must match its own base version");
386+
assert!(versions.contains(&selected));
387+
assert_eq!((selected.major, selected.minor), (tag.major, tag.minor));
388+
assert!(selected >= *tag);
362389
}
363390

364391
// An upstream newer than every tag base cannot be shadowed
365-
assert_eq!(
366-
find_best_matching_tag(&v("0.2.123"), None, &real_tags()),
367-
None
368-
);
392+
let newest = versions.iter().map(base).max().unwrap();
393+
let beyond = Version::new(newest.major, newest.minor, newest.patch + 1);
394+
assert_eq!(find_best_matching_tag(&beyond, None, tags), None);
369395

370-
// A different minor line never matches
371-
assert_eq!(
372-
find_best_matching_tag(&v("0.3.0"), None, &real_tags()),
373-
None
374-
);
396+
// A minor line with no published tags never matches
397+
assert!(versions.iter().all(|t| (t.major, t.minor) != (0, 999)));
398+
assert_eq!(find_best_matching_tag(&v("0.999.0"), None, tags), None);
375399
}
376400

377401
#[test]
378402
fn stable_tag_outranks_prereleases() {
379-
let mut tags = real_tags();
380-
tags.push("v0.2.122".to_string());
403+
let Some(tags) = fetched_tags() else { return };
404+
let newest = parsed_tags(tags).into_iter().max().unwrap();
405+
let stable = base(&newest);
406+
407+
let mut tags = tags.to_vec();
408+
tags.push(format!("v{stable}"));
381409
assert_eq!(
382-
find_best_matching_tag(&v("0.2.122"), None, &tags),
383-
Some("v0.2.122".to_string())
410+
find_best_matching_tag(&stable, None, &tags),
411+
Some(format!("v{stable}"))
384412
);
385413
}
386414
}

0 commit comments

Comments
 (0)