Skip to content

Commit e13822a

Browse files
committed
fix(web): preserve source checkout casing
Git clones the technical CodeWhale repository slug into a case-matching directory by default, so keep the following cd command exact for case-sensitive filesystems. Extend the docs drift gate to reject future clone-directory casing mismatches. Signed-off-by: Hunter B <hmbown@gmail.com>
1 parent 24e1e0c commit e13822a

2 files changed

Lines changed: 30 additions & 6 deletions

File tree

web/app/[locale]/install/page.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ docker run --rm -it \\
5454
ghcr.io/hmbown/codewhale:latest`;
5555

5656
const FROM_SOURCE = `git clone https://github.com/Hmbown/CodeWhale
57-
cd Codewhale
57+
cd CodeWhale
5858
cargo build --release --locked
5959
6060
# Install both binaries from the local checkout

web/scripts/check-docs.mjs

Lines changed: 29 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,22 @@ function checkInstallSnippets() {
102102
stale.push({ found: v, expected: version, context: ref[0].slice(0, 60) });
103103
}
104104
}
105-
return { ok: stale.length === 0, stale };
105+
106+
// A clone without an explicit destination creates a directory whose name
107+
// matches the repository slug exactly. Keep the following `cd` command
108+
// case-correct so source installation works on case-sensitive filesystems.
109+
const sourceCheckout = src.match(
110+
/git clone https:\/\/github\.com\/Hmbown\/([^\s`]+)\s*\ncd\s+([^\s`]+)/,
111+
);
112+
const checkout = sourceCheckout
113+
? {
114+
cloned: sourceCheckout[1].replace(/\.git$/, ""),
115+
entered: sourceCheckout[2],
116+
}
117+
: null;
118+
const checkoutOk = checkout !== null && checkout.cloned === checkout.entered;
119+
120+
return { ok: stale.length === 0 && checkoutOk, stale, checkout };
106121
}
107122

108123
/* ------------------------------------------------------------------ */
@@ -139,12 +154,21 @@ function main() {
139154
// Check 3: install snippets
140155
const install = checkInstallSnippets();
141156
if (!install.ok && !install.note) {
142-
console.error("[check-docs] FAIL — stale version in install snippets:");
143-
for (const s of install.stale) {
144-
console.error(` found "${s.found}", expected "${s.expected}" in: ${s.context}`);
157+
if (install.stale.length > 0) {
158+
console.error("[check-docs] FAIL — stale version in install snippets:");
159+
for (const s of install.stale) {
160+
console.error(` found "${s.found}", expected "${s.expected}" in: ${s.context}`);
161+
}
162+
}
163+
if (install.checkout === null) {
164+
console.error("[check-docs] FAIL — source checkout clone/cd commands not found");
165+
} else if (install.checkout.cloned !== install.checkout.entered) {
166+
console.error(
167+
`[check-docs] FAIL — source checkout clones "${install.checkout.cloned}" but enters "${install.checkout.entered}"`,
168+
);
145169
}
146170
// #3770: a stale install snippet must fail the gate, not fall through to
147-
// the final PASS. Mirror the exit(1) used by checks 1 and 2 above.
171+
// the final PASS. The same applies to source checkout copy drift.
148172
process.exit(1);
149173
}
150174
console.log(`[check-docs] OK — install snippets${install.note ? ` (${install.note})` : ""}`);

0 commit comments

Comments
 (0)