diff --git a/skills/explain-diff-html/SKILL.md b/skills/explain-diff-html/SKILL.md index fbd1a1a..6500474 100644 --- a/skills/explain-diff-html/SKILL.md +++ b/skills/explain-diff-html/SKILL.md @@ -414,9 +414,29 @@ gh pr view --json url -q .url # https://github.com/owner/repo/pull/ # strip the trailing /pull/ # Branch, commit range, single commit, or no argument: -git remote get-url origin | sed -E 's#^git@([^:]+):#https://\1/#; s#\.git$##' +git remote get-url origin | sed -E ' + # Drop a port. This runs before the scheme goes, because after that the + # owner in git@github.com:1234/repo.git would read like a port. + s#^([a-z+]+://[^/]*):[0-9]+/#\1/# + # Drop the scheme, such as https://, ssh://, or git+ssh://. + s#^[a-z+]+://## + # Drop credentials, such as git@ or user:token@, so no token reaches a link. + s#^[^@/]*@## + # Turn the host:owner form into host/owner. + s#^([^:/]+):#\1/# + # Drop a trailing .git, then a trailing slash. + s#\.git/?$## + s#/$## + # Print nothing unless the host is exactly github.com. + /^github\.com\//!d + s#^#https://#' ``` +Empty output means leave every reference bare. A CI clone's remote can embed a +token, as in `https://x-access-token:@github.com/owner/repo.git`, and +without the credentials line that token lands in every link on a page meant +for sharing. + Build each link against the same commit the provenance line names, using the full 40-character sha: @@ -463,7 +483,8 @@ it does today. This is GitHub only, on purpose. A url from `gh` names a GitHub-family host by construction, so link against whatever host it gives you. A parsed remote could -be any forge, so link it only when the host is exactly `github.com`. GitLab and +be any forge, so link it only when the host is exactly `github.com`, which the +`sed` above enforces. GitLab and Bitbucket build blob URLs differently, and a GitHub-shaped URL aimed at them resolves to nothing. Leave those references bare rather than guess. diff --git a/skills/explain-diff-html/references/validation.md b/skills/explain-diff-html/references/validation.md index fa68430..e312d27 100644 --- a/skills/explain-diff-html/references/validation.md +++ b/skills/explain-diff-html/references/validation.md @@ -74,10 +74,10 @@ that mistake now fails instead of passing. still opens offline. - The page linked the references it should have, and every link names the - provenance commit. The script prints both counts as `references=N linked=M`, - then fails on any `/blob/` link that does not name the short commit. It also - fails on a link to a `.md` or `.markdown` file that has a line anchor and no - `?plain=1`. + provenance commit in full. The script prints both counts as + `references=N linked=M`, then fails on any `/blob/` link whose sha is not the + full 40 characters starting with the short commit. It also fails on a link to + a `.md` or `.markdown` file that has a line anchor and no `?plain=1`. The script's count needs both the `tr` and the `sed`. A `.filename` label reads `class="filename">path:line` when bare and diff --git a/skills/explain-diff-html/scripts/validate-output.sh b/skills/explain-diff-html/scripts/validate-output.sh index 31c5dd1..0b1c1ba 100644 --- a/skills/explain-diff-html/scripts/validate-output.sh +++ b/skills/explain-diff-html/scripts/validate-output.sh @@ -14,6 +14,10 @@ if [ -z "$page" ] || [ -z "$sha" ]; then echo "usage: sh validate-output.sh " >&2 exit 2 fi +if ! printf '%s\n' "$sha" | grep -qE '^[0-9a-f]{4,40}$'; then + echo "usage: must be 4 to 40 lowercase hex characters" >&2 + exit 2 +fi # A directory passes test -s, and step 8's $out is a directory, so require a # regular file as well. @@ -30,13 +34,16 @@ refs=$(tr '\n' ' ' < "$page" | sed -E 's#]*>##g; s/ +/ /g' \ links=$(grep -o 'class="srcref"' "$page" | wc -l | tr -d ' ') echo "references=$refs linked=$links" -wrong=$(grep -o 'href="[^"]*/blob/[^"]*"' "$page" | grep -v "$sha") +# A link names the full 40-character sha. GitHub resolves an abbreviation only +# while the commit is on a branch, so a short sha 404s once a squash merge lands. +full="/blob/${sha}[0-9a-f]{$((40 - ${#sha}))}/" +wrong=$(grep -o 'href="[^"]*/blob/[^"]*"' "$page" | grep -vE "$full") if [ -n "$wrong" ]; then - echo "FAIL: links that do not name $sha:" + echo "FAIL: links that do not name the full 40-character sha starting $sha:" echo "$wrong" status=1 else - echo "pass: no blob link names another commit" + echo "pass: every blob link names the full sha of $sha" fi # GitHub renders Markdown, and the rendered view ignores a line anchor. Match