Skip to content

Commit f6feefb

Browse files
committed
noot
1 parent 30bcc90 commit f6feefb

File tree

13 files changed

+168
-124
lines changed

13 files changed

+168
-124
lines changed

.githook.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
set -e
1111
# constants
1212

13-
GITHOOK_VERSION="0.1.17"
13+
GITHOOK_VERSION="0.1.19"
1414
GITHOOK_API_URL="https://githook.sh"
1515
GITHOOK_DIR=".githook"
1616
GITHOOK_INTERNAL_DIR=".githook/_"

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
# build output
22
githook.sh
3+
site/dist/

Dockerfile

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,21 @@
11
# Build stage
22
FROM alpine:3.19 AS builder
33

4-
RUN apk add --no-cache make coreutils
4+
RUN apk add --no-cache make coreutils m4
55

66
WORKDIR /build
77
COPY src/ src/
8+
COPY site/src/ site/src/
89
COPY Makefile .
910

1011
RUN make build
1112

1213
# Runtime stage
1314
FROM caddy:2-alpine
1415

15-
COPY site/ /srv/site/
16+
COPY --from=builder /build/site/dist/ /srv/site/
1617
COPY --from=builder /build/.githook.sh /srv/site/githook.sh
17-
COPY Caddyfile /etc/caddy/Caddyfile
18+
COPY site/Caddyfile /etc/caddy/Caddyfile
1819

1920
EXPOSE 80
2021

Makefile

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
.PHONY: build clean test test-hooks test-all
1+
.PHONY: build script site clean test test-hooks test-all
22

33
SRC := src/header.sh \
44
src/constants.sh \
@@ -9,14 +9,43 @@ SRC := src/header.sh \
99

1010
OUT ?= .githook.sh
1111

12-
build: $(OUT)
12+
build: script site
13+
14+
script: $(OUT)
1315

1416
$(OUT): $(SRC)
1517
@cat $(SRC) > $(OUT)
1618
@chmod +x $(OUT)
1719

20+
SITE_BASE := site/src/_base.m4
21+
SITE_STATIC := site/src/style.css site/src/copy.js site/src/llms.txt
22+
23+
site: site/dist/index.html site/dist/docs/index.html site/dist/style.css site/dist/copy.js site/dist/llms.txt
24+
25+
site/dist/index.html: site/src/index.m4 $(SITE_BASE) | site/dist
26+
@cd site/src && m4 index.m4 > ../dist/index.html
27+
28+
site/dist/docs/index.html: site/src/docs/index.m4 $(SITE_BASE) | site/dist/docs
29+
@cd site/src && m4 docs/index.m4 > ../dist/docs/index.html
30+
31+
site/dist/%.css: site/src/%.css | site/dist
32+
@cp $< $@
33+
34+
site/dist/%.js: site/src/%.js | site/dist
35+
@cp $< $@
36+
37+
site/dist/%.txt: site/src/%.txt | site/dist
38+
@cp $< $@
39+
40+
site/dist:
41+
@mkdir -p site/dist
42+
43+
site/dist/docs: | site/dist
44+
@mkdir -p site/dist/docs
45+
1846
clean:
1947
rm -f $(OUT)
48+
rm -rf site/dist
2049

2150
test: build
2251
@sh test/run.sh
File renamed without changes.

site/copy.js

Lines changed: 0 additions & 12 deletions
This file was deleted.

site/index.html

Lines changed: 0 additions & 47 deletions
This file was deleted.

site/src/_base.m4

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
dnl Base template macros - prefixed with _ to avoid conflicts
2+
dnl
3+
define(`_HEAD',`<!DOCTYPE html>
4+
<html lang="en">
5+
<head>
6+
<meta charset="UTF-8">
7+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
8+
<meta name="description" content="$1">
9+
<title>$2</title>
10+
<link rel="stylesheet" href="/style.css">
11+
</head>
12+
<body>')dnl
13+
dnl
14+
define(`_FOOT',`<script src="/copy.js"></script>
15+
</body>
16+
</html>')dnl
17+
dnl
18+
define(`_CODE',`<pre>$1<button class="copy-btn"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 640"><path d="M480 400L288 400C279.2 400 272 392.8 272 384L272 128C272 119.2 279.2 112 288 112L421.5 112C425.7 112 429.8 113.7 432.8 116.7L491.3 175.2C494.3 178.2 496 182.3 496 186.5L496 384C496 392.8 488.8 400 480 400zM288 448L480 448C515.3 448 544 419.3 544 384L544 186.5C544 169.5 537.3 153.2 525.3 141.2L466.7 82.7C454.7 70.7 438.5 64 421.5 64L288 64C252.7 64 224 92.7 224 128L224 384C224 419.3 252.7 448 288 448zM160 192C124.7 192 96 220.7 96 256L96 512C96 547.3 124.7 576 160 576L352 576C387.3 576 416 547.3 416 512L416 496L368 496L368 512C368 520.8 360.8 528 352 528L160 528C151.2 528 144 520.8 144 512L144 256C144 247.2 151.2 240 160 240L176 240L176 192L160 192z"/></svg></button></pre>')dnl
19+
dnl
20+
define(`_CMD',`<code class="cmd">$1</code>')dnl

site/src/copy.js

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
document.querySelectorAll('.copy-btn').forEach(btn => {
2+
btn.onclick = () => {
3+
const pre = btn.closest('pre');
4+
const text = pre.textContent.slice(0, -1); // trim button area
5+
navigator.clipboard.writeText(text);
6+
btn.classList.add('copied');
7+
setTimeout(() => btn.classList.remove('copied'), 1500);
8+
};
9+
});
10+
11+
document.querySelectorAll('code').forEach(code => {
12+
code.ondblclick = () => {
13+
const sel = window.getSelection();
14+
const range = document.createRange();
15+
range.selectNodeContents(code);
16+
sel.removeAllRanges();
17+
sel.addRange(range);
18+
};
19+
});
Lines changed: 52 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,5 @@
1-
<!DOCTYPE html>
2-
<html lang="en">
3-
<head>
4-
<meta charset="UTF-8">
5-
<meta name="viewport" content="width=device-width, initial-scale=1.0">
6-
<meta name="description" content="githook.sh documentation and guides">
7-
<title>githook.sh - docs</title>
8-
<link rel="stylesheet" href="/style.css">
9-
</head>
10-
<body>
1+
include(`_base.m4')dnl
2+
_HEAD(`githook.sh documentation and guides',`githook.sh - docs')
113
<h1><a href="/">githook.sh</a> docs</h1>
124
<nav>
135
<div>
@@ -36,59 +28,63 @@ <h1><a href="/">githook.sh</a> docs</h1>
3628

3729
<h2 id="creating">creating a hook</h2>
3830
<p>add an executable script to <code>.githook/</code> named after the git hook you want:</p>
39-
<pre>echo '#!/bin/sh
40-
npm test' > .githook/pre-commit
41-
chmod +x .githook/pre-commit</pre>
31+
_CODE(`echo '"'"'#!/bin/sh
32+
npm test'"'"' > .githook/pre-commit
33+
chmod +x .githook/pre-commit')
4234
<p>the script must be executable (<code>chmod +x</code>) and start with a shebang (<code>#!/bin/sh</code>).</p>
4335
<p>supported hooks: <code>pre-commit</code>, <code>commit-msg</code>, <code>pre-push</code>, <code>prepare-commit-msg</code>, <code>post-commit</code>, <code>post-merge</code>, <code>pre-rebase</code>, <code>post-checkout</code>, <code>post-rewrite</code>, <code>pre-auto-gc</code>, <code>applypatch-msg</code>, <code>pre-applypatch</code>, <code>post-applypatch</code>.</p>
4436

4537
<h2 id="examples">common hooks</h2>
4638
<p><strong>pre-commit</strong> — runs before commit is created. use for linting, formatting, tests:</p>
47-
<pre>#!/bin/sh
48-
npm run lint && npm test</pre>
39+
_CODE(`#!/bin/sh
40+
npm run lint && npm test')
4941
<p><strong>commit-msg</strong> — validate commit message format. <code>$1</code> is the temp file containing the message:</p>
50-
<pre>#!/bin/sh
42+
changequote([,])dnl
43+
_CODE([#!/bin/sh
5144
if ! grep -qE "^(feat|fix|docs|style|refactor|test|chore)(\(.+\))?: .+" "$1"; then
5245
echo "error: commit message must follow conventional commits format"
5346
echo "example: feat(auth): add login endpoint"
5447
exit 1
55-
fi</pre>
48+
fi])
49+
changequote(`,')dnl
5650
<p><strong>pre-push</strong> — runs before push. use for full test suite or build verification:</p>
57-
<pre>#!/bin/sh
58-
npm run build && npm run test:all</pre>
51+
_CODE(`#!/bin/sh
52+
npm run build && npm run test:all')
5953
<p><strong>post-merge</strong> — runs after merge/pull. use to reinstall deps if lockfile changed:</p>
60-
<pre>#!/bin/sh
54+
changequote([,])dnl
55+
_CODE([#!/bin/sh
6156
changed_files=$(git diff-tree -r --name-only ORIG_HEAD HEAD)
6257
if echo "$changed_files" | grep -q "package-lock.json"; then
6358
echo "package-lock.json changed, running npm install..."
6459
npm install
65-
fi</pre>
60+
fi])
61+
changequote(`,')dnl
6662

6763
<h2 id="testing">testing hooks</h2>
6864
<p>run your hook directly without making a commit:</p>
69-
<pre>./.githook/pre-commit</pre>
65+
_CODE(`./.githook/pre-commit')
7066
<p>to test that hooks block commits properly, add <code>exit 1</code>:</p>
71-
<pre>#!/bin/sh
67+
_CODE(`#!/bin/sh
7268
echo "this will block the commit"
73-
exit 1</pre>
69+
exit 1')
7470
<p>a non-zero exit code aborts the git operation. exit 0 (or no exit) allows it to proceed.</p>
7571

7672
<h2 id="skipping">skipping hooks</h2>
77-
<p>for a single command, use git's built-in <code>--no-verify</code> flag:</p>
78-
<pre>git commit --no-verify -m "wip"
79-
git push --no-verify</pre>
73+
<p>for a single command, use git'"'"'s built-in <code>--no-verify</code> flag:</p>
74+
_CODE(`git commit --no-verify -m "wip"
75+
git push --no-verify')
8076
<p>to disable all hooks for multiple commands:</p>
81-
<pre>GITHOOK=0 git commit -m "skip"
82-
GITHOOK=0 git push</pre>
77+
_CODE(`GITHOOK=0 git commit -m "skip"
78+
GITHOOK=0 git push')
8379
<p>or export it for your session:</p>
84-
<pre>export GITHOOK=0
80+
_CODE(`export GITHOOK=0
8581
git commit -m "first"
8682
git commit -m "second"
87-
unset GITHOOK</pre>
83+
unset GITHOOK')
8884

8985
<h2 id="ci">ci/cd and docker</h2>
9086
<p>hooks are for local development—disable them in CI/CD and containers with <code>GITHOOK=0</code>:</p>
91-
<pre># github actions
87+
_CODE(`# github actions
9288
env:
9389
GITHOOK: 0
9490

@@ -97,71 +93,71 @@ <h2 id="ci">ci/cd and docker</h2>
9793
GITHOOK: "0"
9894

9995
# docker
100-
ENV GITHOOK=0</pre>
96+
ENV GITHOOK=0')
10197

10298
<h2 id="package-json">package.json integration</h2>
10399
<p>auto-install hooks when developers run <code>npm install</code>:</p>
104100
<p><strong>npm / pnpm / bun:</strong></p>
105-
<pre>npm pkg set scripts.prepare="./.githook.sh install"</pre>
101+
_CODE(`npm pkg set scripts.prepare="./.githook.sh install"')
106102
<p><strong>yarn:</strong></p>
107-
<pre>npm pkg set scripts.postinstall="./.githook.sh install"</pre>
103+
_CODE(`npm pkg set scripts.postinstall="./.githook.sh install"')
108104
<p>yarn uses <code>postinstall</code> instead of <code>prepare</code>.</p>
109105

110106
<h2 id="makefile">makefile integration</h2>
111107
<p>add a target for installing hooks:</p>
112-
<pre>.PHONY: prepare
108+
_CODE(`.PHONY: prepare
113109
prepare:
114-
./.githook.sh install</pre>
110+
./.githook.sh install')
115111
<p>run after cloning:</p>
116-
<pre>make prepare</pre>
112+
_CODE(`make prepare')
117113

118114
<h2 id="husky">migrating from husky</h2>
119115
<p>hooks are automatically migrated during setup if <code>.husky/</code> exists. to migrate manually:</p>
120-
<pre>./.githook.sh migrate husky</pre>
116+
_CODE(`./.githook.sh migrate husky')
121117
<p>this copies hook scripts from <code>.husky/</code> to <code>.githook/</code>. after verifying:</p>
122-
<pre>rm -rf .husky
123-
npm uninstall husky</pre>
118+
_CODE(`rm -rf .husky
119+
npm uninstall husky')
124120

125121
<h2 id="languages">using other languages</h2>
126122
<p>hooks can be written in any language. use a shell wrapper:</p>
127-
<pre>#!/bin/sh
128-
node .githook/pre-commit.js</pre>
123+
_CODE(`#!/bin/sh
124+
node .githook/pre-commit.js')
129125
<p>or use a shebang directly (the file must still be executable):</p>
130-
<pre>#!/usr/bin/env python3
126+
_CODE(`#!/usr/bin/env python3
131127
import subprocess
132128
import sys
133129
result = subprocess.run(["pytest", "-x"])
134-
sys.exit(result.returncode)</pre>
135-
<pre>#!/usr/bin/env ruby
136-
system("bundle exec rubocop") || exit(1)</pre>
130+
sys.exit(result.returncode)')
131+
_CODE(`#!/usr/bin/env ruby
132+
system("bundle exec rubocop") || exit(1)')
137133

138134
<h2 id="nvm">node version managers</h2>
139135
<p>gui clients and ides may not load your shell profile, causing "command not found" errors. create <code>~/.config/githook/init.sh</code> to fix this globally:</p>
140-
<pre>mkdir -p ~/.config/githook
136+
changequote([,])dnl
137+
_CODE([mkdir -p ~/.config/githook
141138
cat > ~/.config/githook/init.sh << 'EOF'
142139
export NVM_DIR="$HOME/.nvm"
143140
[ -s "$NVM_DIR/nvm.sh" ] && . "$NVM_DIR/nvm.sh"
144-
EOF</pre>
141+
EOF])
142+
changequote(`,')dnl
145143
<p>this is sourced before every hook runs. for fnm use <code>eval "$(fnm env)"</code>, for volta add <code>$VOLTA_HOME/bin</code> to PATH.</p>
146144

147145
<h2 id="debug">debugging</h2>
148146
<p>enable debug output:</p>
149-
<pre>GITHOOK_DEBUG=1 git commit -m "test"</pre>
147+
_CODE(`GITHOOK_DEBUG=1 git commit -m "test"')
150148
<p>common issues:</p>
151149
<p>• <strong>"command not found"</strong> — see <a href="#nvm">nvm section</a></p>
152-
<p><strong>hook not running</strong> — check it's executable: <code>ls -la .githook/</code></p>
150+
<p>• <strong>hook not running</strong> — check it'"'"'s executable: <code>ls -la .githook/</code></p>
153151
<p>• <strong>wrong directory</strong> — hooks run from repo root</p>
154152

155153
<h2 id="uninstall">uninstalling</h2>
156154
<p>remove git configuration (keeps your hook scripts):</p>
157-
<pre>./.githook.sh uninstall</pre>
155+
_CODE(`./.githook.sh uninstall')
158156
<p>to fully remove:</p>
159-
<pre>rm -rf .githook .githook.sh</pre>
157+
_CODE(`rm -rf .githook .githook.sh')
160158

161159
<h2 id="how">how it works</h2>
162160
<p>githook.sh sets <code>core.hooksPath</code> to <code>.githook/_</code> which contains wrapper scripts. when git runs a hook, the wrapper sources <code>~/.config/githook/init.sh</code>, checks <code>GITHOOK=0</code>, then runs your script from <code>.githook/</code>.</p>
163161
<p>quick setup (<code>curl | sh</code>) runs install if already setup.</p>
164162
<p>each developer runs <code>./.githook.sh install</code> once after cloning because git config is local.</p>
165-
<script src="/copy.js"></script>
166-
</body>
167-
</html>
163+
_FOOT

0 commit comments

Comments
 (0)