Skip to content

Commit faf873b

Browse files
committed
Fix broken cross-package Haddock links on hosted docs site
Fixes #601. Links to dependency packages (cardano-ledger-*, plutus-*, etc.) were relative paths pointing to directories that don't exist on the hosted site, resulting in 404s. Add a post-processing script that rewrites these relative links to absolute URLs pointing at the correct external documentation sites.
1 parent 1c39fba commit faf873b

2 files changed

Lines changed: 102 additions & 0 deletions

File tree

.github/workflows/github-page.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,10 @@ jobs:
4141
mkdir website
4242
cabal haddock-project --output=./website --internal --foreign-libraries
4343
44+
- name: Fix cross-package Haddock links
45+
run: |
46+
./scripts/fix-haddock-links.sh ./website
47+
4448
- name: Build typedoc documentation
4549
run: |
4650
nix build .#wasm-typedoc

scripts/fix-haddock-links.sh

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
#!/usr/bin/env bash
2+
# fix-haddock-links.sh
3+
#
4+
# Rewrites relative cross-package Haddock links in generated HTML to point
5+
# at the correct external documentation sites. Without this, links to
6+
# dependencies (cardano-ledger-*, plutus-*, etc.) are broken 404s because
7+
# the hosted site only contains docs for packages in this repo.
8+
#
9+
# Usage: ./scripts/fix-haddock-links.sh <website-directory>
10+
11+
set -euo pipefail
12+
13+
WEBSITE_DIR="${1:?Usage: $0 <website-directory>}"
14+
15+
if [ ! -d "$WEBSITE_DIR" ]; then
16+
echo "Error: $WEBSITE_DIR is not a directory" >&2
17+
exit 1
18+
fi
19+
20+
# Mapping of package-name-prefix -> base URL
21+
# Each entry is: "prefix|base_url"
22+
# The generated links look like: ../PACKAGE/Module.html
23+
# We rewrite them to: BASE_URL/PACKAGE/Module.html
24+
PACKAGE_URLS=(
25+
# cardano-ledger repo packages
26+
"cardano-crypto-wrapper|https://cardano-ledger.cardano.intersectmbo.org"
27+
"cardano-data|https://cardano-ledger.cardano.intersectmbo.org"
28+
"cardano-ledger-allegra|https://cardano-ledger.cardano.intersectmbo.org"
29+
"cardano-ledger-alonzo|https://cardano-ledger.cardano.intersectmbo.org"
30+
"cardano-ledger-api|https://cardano-ledger.cardano.intersectmbo.org"
31+
"cardano-ledger-babbage|https://cardano-ledger.cardano.intersectmbo.org"
32+
"cardano-ledger-binary|https://cardano-ledger.cardano.intersectmbo.org"
33+
"cardano-ledger-byron|https://cardano-ledger.cardano.intersectmbo.org"
34+
"cardano-ledger-conway|https://cardano-ledger.cardano.intersectmbo.org"
35+
"cardano-ledger-core|https://cardano-ledger.cardano.intersectmbo.org"
36+
"cardano-ledger-dijkstra|https://cardano-ledger.cardano.intersectmbo.org"
37+
"cardano-ledger-mary|https://cardano-ledger.cardano.intersectmbo.org"
38+
"cardano-ledger-shelley|https://cardano-ledger.cardano.intersectmbo.org"
39+
"cardano-protocol-tpraos|https://cardano-ledger.cardano.intersectmbo.org"
40+
"small-steps|https://cardano-ledger.cardano.intersectmbo.org"
41+
42+
# cardano-base repo packages
43+
"cardano-binary|https://base.cardano.intersectmbo.org"
44+
"cardano-crypto-class|https://base.cardano.intersectmbo.org"
45+
"cardano-crypto-praos|https://base.cardano.intersectmbo.org"
46+
"cardano-slotting|https://base.cardano.intersectmbo.org"
47+
"cardano-strict-containers|https://base.cardano.intersectmbo.org"
48+
49+
# plutus repo packages
50+
"plutus-core|https://plutus.cardano.intersectmbo.org/haddock/latest"
51+
"plutus-ledger-api|https://plutus.cardano.intersectmbo.org/haddock/latest"
52+
53+
# ouroboros-consensus repo packages
54+
"ouroboros-consensus|https://ouroboros-consensus.cardano.intersectmbo.org/haddocks"
55+
56+
# ouroboros-network repo packages
57+
"cardano-diffusion|https://ouroboros-network.cardano.intersectmbo.org"
58+
59+
# io-sim repo packages
60+
"io-classes|https://input-output-hk.github.io/io-sim"
61+
62+
)
63+
64+
# Hackage packages use a different URL structure:
65+
# ../base/Data-Bool.html -> https://hackage.haskell.org/package/base/docs/Data-Bool.html
66+
# The package name directory is replaced by /package/<pkg>/docs/
67+
HACKAGE_PACKAGES=(
68+
base
69+
bytestring
70+
containers
71+
deepseq
72+
mtl
73+
ghc-internal
74+
)
75+
76+
# Build a single sed expression that handles all rewrites.
77+
# Links appear in two forms depending on module nesting depth:
78+
# href="../PACKAGE/Module.html..." (from top-level: cardano-api/Foo.html)
79+
# href="../../PACKAGE/Module.html..." (from internal: cardano-api/internal/Foo.html)
80+
SED_ARGS=()
81+
for entry in "${PACKAGE_URLS[@]}"; do
82+
pkg="${entry%%|*}"
83+
url="${entry##*|}"
84+
SED_ARGS+=(-e "s|href=\"\\.\\./${pkg}/|href=\"${url}/${pkg}/|g")
85+
SED_ARGS+=(-e "s|href=\"\\.\\./\\.\\./${pkg}/|href=\"${url}/${pkg}/|g")
86+
done
87+
88+
for pkg in "${HACKAGE_PACKAGES[@]}"; do
89+
SED_ARGS+=(-e "s|href=\"\\.\\./${pkg}/|href=\"https://hackage.haskell.org/package/${pkg}/docs/|g")
90+
SED_ARGS+=(-e "s|href=\"\\.\\./\\.\\./${pkg}/|href=\"https://hackage.haskell.org/package/${pkg}/docs/|g")
91+
done
92+
93+
echo "Fixing cross-package Haddock links in $WEBSITE_DIR..."
94+
95+
find "$WEBSITE_DIR" -name '*.html' -print0 | xargs -0 -P "$(nproc)" sed -i "${SED_ARGS[@]}"
96+
97+
TOTAL=$(( ${#PACKAGE_URLS[@]} + ${#HACKAGE_PACKAGES[@]} ))
98+
echo "Done. Rewrote links for $TOTAL external packages."

0 commit comments

Comments
 (0)