Merge pull request #805 from omacom/fix/redirect-watch-probe
upstream-watch: probe redirect watches past a staged rollout
This commit is contained in:
2 files changed
+30
-2
No files matched your search
@@ -26,6 +26,8 @@ VERSION = re.compile(r"[A-Za-z0-9][A-Za-z0-9._+]*\Z")
|
|||||||
SCALAR = re.compile(r"[A-Za-z0-9._+/-]+\Z")
|
SCALAR = re.compile(r"[A-Za-z0-9._+/-]+\Z")
|
||||||
SUM = re.compile(r"(md5|sha1|sha224|sha256|sha384|sha512|b2)sums(_[a-z0-9_]+)?\Z")
|
SUM = re.compile(r"(md5|sha1|sha224|sha256|sha384|sha512|b2)sums(_[a-z0-9_]+)?\Z")
|
||||||
HASHES = {"b2": "blake2b"}
|
HASHES = {"b2": "blake2b"}
|
||||||
|
# How many times a redirect watch probes before it calls the feed unmatched.
|
||||||
|
REDIRECT_PROBES = 5
|
||||||
|
|
||||||
|
|
||||||
def run(args, **kwargs):
|
def run(args, **kwargs):
|
||||||
@@ -286,8 +288,16 @@ def discover(watch, fetch):
|
|||||||
values.update({name: json_path(data, path) for name, path in watch.get("fields", {}).items()})
|
values.update({name: json_path(data, path) for name, path in watch.get("fields", {}).items()})
|
||||||
results.append(candidate(watch, values))
|
results.append(candidate(watch, values))
|
||||||
elif provider == "redirect":
|
elif provider == "redirect":
|
||||||
final_url = run(["curl", "--proto", "=https", "--proto-redir", "=https", "-fsSLI", "--max-time", "60", "-o", "/dev/null", "-w", "%{url_effective}", feed], text=True)
|
# A download redirect can be a staged rollout: some requests land on a
|
||||||
results.extend(matches(watch, final_url))
|
# newer build the pattern deliberately rejects (Dropbox, 2026-10-04:
|
||||||
|
# 4 of 100 HEADs ended at 274.3.4801 instead of 272.4.3798), so one
|
||||||
|
# probe that misses is not an answer. Keep the first one that matches.
|
||||||
|
for _ in range(REDIRECT_PROBES):
|
||||||
|
final_url = run(["curl", "--proto", "=https", "--proto-redir", "=https", "-fsSLI", "--max-time", "60", "--retry", "2",
|
||||||
|
"-o", "/dev/null", "-w", "%{url_effective}", feed], text=True)
|
||||||
|
results.extend(matches(watch, final_url))
|
||||||
|
if results:
|
||||||
|
break
|
||||||
elif provider == "regex":
|
elif provider == "regex":
|
||||||
text = fetch.text(feed)
|
text = fetch.text(feed)
|
||||||
if watch.get("unescape_json"):
|
if watch.get("unescape_json"):
|
||||||
|
|||||||
@@ -160,6 +160,24 @@ b2sums=('old' 'local-b2')
|
|||||||
output = w.replace_array(text, 'sha256sums', ['abc'])
|
output = w.replace_array(text, 'sha256sums', ['abc'])
|
||||||
self.assertEqual(output, "sha256sums=('abc') # trailing\npackage() { :; }\n")
|
self.assertEqual(output, "sha256sums=('abc') # trailing\npackage() { :; }\n")
|
||||||
|
|
||||||
|
def test_redirect_probes_past_a_staged_rollout(self):
|
||||||
|
watch = {"redirect": "https://example.test/download",
|
||||||
|
"pattern": r"tool-(?P<version>[0-9]+\.4\.[0-9]+)\.tar\.gz"}
|
||||||
|
rollout = "https://cdn.example.test/tool-274.3.4801.tar.gz"
|
||||||
|
stable = "https://cdn.example.test/tool-272.4.3798.tar.gz"
|
||||||
|
with patch.object(w, 'run', side_effect=[rollout, rollout, stable]) as probe:
|
||||||
|
releases = w.discover(watch, self.fetch)
|
||||||
|
self.assertEqual([r["pkgver"] for r in releases], ["272.4.3798"])
|
||||||
|
self.assertEqual(probe.call_count, 3)
|
||||||
|
|
||||||
|
def test_redirect_gives_up_after_its_probes(self):
|
||||||
|
watch = {"redirect": "https://example.test/download",
|
||||||
|
"pattern": r"tool-(?P<version>[0-9]+\.4\.[0-9]+)\.tar\.gz"}
|
||||||
|
with patch.object(w, 'run', return_value="https://cdn.example.test/tool-274.3.4801.tar.gz") as probe, \
|
||||||
|
self.assertRaisesRegex(ValueError, 'no matching releases'):
|
||||||
|
w.discover(watch, self.fetch)
|
||||||
|
self.assertEqual(probe.call_count, w.REDIRECT_PROBES)
|
||||||
|
|
||||||
def test_git_hash_matches_makepkg(self):
|
def test_git_hash_matches_makepkg(self):
|
||||||
repo = self.root / 'git'
|
repo = self.root / 'git'
|
||||||
repo.mkdir()
|
repo.mkdir()
|
||||||
|
|||||||
Reference in new issue
Block a user