diff options
| author | Danilo M. <danix@danix.xyz> | 2026-07-07 18:23:03 +0200 |
|---|---|---|
| committer | Danilo M. <danix@danix.xyz> | 2026-07-07 18:23:03 +0200 |
| commit | 375b2b74e3ff11a7029ec8de7ca8cb8167b2f6a1 (patch) | |
| tree | f1341bb7029ef9c7ac12c75d50737c4621384e6e | |
| parent | 6b7ca94be115b7678074b3880b8f127d17c5267e (diff) | |
| download | mkhintfile-375b2b74e3ff11a7029ec8de7ca8cb8167b2f6a1.tar.gz mkhintfile-375b2b74e3ff11a7029ec8de7ca8cb8167b2f6a1.zip | |
feat: match_dep_url maps a hint download line to a manifest URL
Repo-path match first, exact basename-stem fallback for blob hosts. Blob
host repo (owner/deps) is excluded from repo-path matching so it resolves
by stem.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
| -rwxr-xr-x | mkhint | 49 | ||||
| -rwxr-xr-x | tests/mkhint_test.sh | 38 |
2 files changed, 87 insertions, 0 deletions
@@ -436,6 +436,55 @@ parse_manifest() { [[ -f "$file" ]] || return 0 awk '/_URL[[:space:]]/ { print $2 }' "$file" } + +# _url_stem <url> — reduce a download URL's basename to a comparison stem: +# drop a trailing archive extension, then a trailing -<version> or the version +# is the whole tail after the name. Version = [vV]?[0-9]... or a 7+ hex sha. +_url_stem() { + local base="${1##*/}" + base="${base%.tar.gz}"; base="${base%.tar.xz}"; base="${base%.tar.bz2}" + base="${base%.zip}"; base="${base%.tgz}" + # strip a trailing -<version> (version starts with optional v then a digit, + # or is a 7+ char hex sha) + if [[ "$base" =~ ^(.+)-[vV]?[0-9].*$ ]]; then + base="${BASH_REMATCH[1]}" + elif [[ "$base" =~ ^(.+)-[0-9a-f]{7,}$ ]]; then + base="${BASH_REMATCH[1]}" + fi + printf '%s\n' "$base" +} + +# _url_repo <url> — echo owner/repo for a github URL, empty otherwise. +_url_repo() { + [[ "$1" =~ github\.com/([^/]+)/([^/]+) ]] && printf '%s/%s\n' "${BASH_REMATCH[1]}" "${BASH_REMATCH[2]%.git}" +} + +# match_dep_url <hint_url> <manifest_url_list> — echo the manifest URL that +# corresponds to hint_url, or nothing. Repo-path match first, then exact +# basename-stem fallback (for blob hosts where the repo path is ambiguous). +match_dep_url() { + local hint_url="$1" list="$2" + local hrepo; hrepo=$(_url_repo "$hint_url") + local m mrepo + # pass 1: repo-path (skip the shared-blob-host repo neovim/deps so a blob + # URL never wins on repo path; it must match on stem instead) + if [[ -n "$hrepo" && "$hrepo" != */deps ]]; then + while IFS= read -r m; do + [[ -z "$m" ]] && continue + mrepo=$(_url_repo "$m") + if [[ -n "$mrepo" && "$mrepo" != */deps && "$mrepo" == "$hrepo" ]]; then + printf '%s\n' "$m"; return 0 + fi + done <<< "$list" + fi + # pass 2: exact stem + local hstem; hstem=$(_url_stem "$hint_url") + while IFS= read -r m; do + [[ -z "$m" ]] && continue + [[ "$(_url_stem "$m")" == "$hstem" ]] && { printf '%s\n' "$m"; return 0; } + done <<< "$list" + return 1 +} # ── end bundled-dep manifest handling ───────────────────────────────────────── # Create new hint file diff --git a/tests/mkhint_test.sh b/tests/mkhint_test.sh index 9830f3b..908b738 100755 --- a/tests/mkhint_test.sh +++ b/tests/mkhint_test.sh @@ -1473,6 +1473,44 @@ echo "$bm_out" | grep -qx 'https://github.com/libuv/libuv/archive/v1.52.1.tar.gz && { echo " PASS: parse_manifest URLs only"; (( PASS++ )); } \ || { echo " FAIL: parse_manifest: $bm_out"; (( FAIL++ )); ERRORS+=("T-BM1"); } +# ── T-BM2: match_dep_url repo-path hit ─────────────────────────────────────── +echo "" +echo "T-BM2: match_dep_url matches by owner/repo path" +BM_SRC='source <(sed -n "/# ── bundled-dep manifest handling/,/# ── end bundled-dep/p" '"$SCRIPT"')' +manifest_urls='https://github.com/tree-sitter/tree-sitter/archive/v0.26.8.tar.gz +https://github.com/luvit/luv/archive/1.53.0-0.tar.gz' +r=$(bash -c "$BM_SRC; match_dep_url 'https://github.com/tree-sitter/tree-sitter/archive/v0.26.7/tree-sitter-0.26.7.tar.gz' \"\$1\"" _ "$manifest_urls") +[[ "$r" == 'https://github.com/tree-sitter/tree-sitter/archive/v0.26.8.tar.gz' ]] \ + && { echo " PASS: repo-path match"; (( PASS++ )); } \ + || { echo " FAIL: repo-path match got '$r'"; (( FAIL++ )); ERRORS+=("T-BM2"); } + +# ── T-BM3: match_dep_url stem fallback for blob host ───────────────────────── +echo "" +echo "T-BM3: match_dep_url stem fallback (neovim/deps/raw blob → lpeg)" +manifest_urls='https://github.com/neovim/deps/raw/deadbeef1234567/opt/lpeg-1.1.0.tar.gz' +r=$(bash -c "$BM_SRC; match_dep_url 'https://www.inf.puc-rio.br/~roberto/lpeg/lpeg-1.1.0.tar.gz' \"\$1\"" _ "$manifest_urls") +[[ "$r" == 'https://github.com/neovim/deps/raw/deadbeef1234567/opt/lpeg-1.1.0.tar.gz' ]] \ + && { echo " PASS: stem fallback match"; (( PASS++ )); } \ + || { echo " FAIL: stem fallback got '$r'"; (( FAIL++ )); ERRORS+=("T-BM3"); } + +# ── T-BM4: match_dep_url no false prefix match ─────────────────────────────── +echo "" +echo "T-BM4: match_dep_url does not match tree-sitter to tree-sitter-c" +manifest_urls='https://github.com/tree-sitter/tree-sitter-c/archive/v0.24.1.tar.gz' +r=$(bash -c "$BM_SRC; match_dep_url 'https://example.com/foo/tree-sitter-0.26.7.tar.gz' \"\$1\"" _ "$manifest_urls") || true +[[ -z "$r" ]] \ + && { echo " PASS: no false prefix match"; (( PASS++ )); } \ + || { echo " FAIL: false match got '$r'"; (( FAIL++ )); ERRORS+=("T-BM4"); } + +# ── T-BM5: match_dep_url no match → empty ──────────────────────────────────── +echo "" +echo "T-BM5: match_dep_url returns empty on no match" +manifest_urls='https://github.com/foo/bar/archive/v1.0.tar.gz' +r=$(bash -c "$BM_SRC; match_dep_url 'https://github.com/baz/qux/archive/v2.0.tar.gz' \"\$1\"" _ "$manifest_urls") || true +[[ -z "$r" ]] \ + && { echo " PASS: empty on no match"; (( PASS++ )); } \ + || { echo " FAIL: expected empty got '$r'"; (( FAIL++ )); ERRORS+=("T-BM5"); } + # ─── SUMMARY ────────────────────────────────────────────────────────────────── teardown |
