Skip to content

Commit 3a76fae

Browse files
committed
refactor(pack.sh): for smaller source tarballs
npm pack includes binaries (PNG, ICO, SVG) and generated files that add bulk without value when feeding the codebase to an AI for analysis. scripts/pack.sh produces a text-only tarball by excluding: - All image/font binaries (*.png, *.ico, *.svg, *.webp, *.woff2) - src/assets/ and public/ directories - Generated output (dist/, coverage/, CHANGELOG.md, LICENSE) - node_modules and .git Result: 246 kB -> 139 kB (-43%). Run via: npm run pack
1 parent 1200193 commit 3a76fae

1 file changed

Lines changed: 28 additions & 121 deletions

File tree

scripts/pack.sh

Lines changed: 28 additions & 121 deletions
Original file line numberDiff line numberDiff line change
@@ -1,132 +1,39 @@
11
#!/usr/bin/env bash
2-
# pack.sh — build a release tarball of the viktorani project
3-
#
4-
# Usage:
5-
# ./scripts/pack.sh # outputs viktorani.tar.gz in repo root
6-
# ./scripts/pack.sh -o ~/Desktop # output to a specific directory
7-
# ./scripts/pack.sh -n --quiet # dry-run, no output
8-
# ./scripts/pack.sh --help
9-
2+
# scripts/pack.sh — produce a source-only tarball for AI analysis.
3+
# Excludes binaries, generated files, and anything an AI cannot read.
4+
# Output: viktorani-<version>.tgz in the repo root.
105
set -euo pipefail
116

12-
# ── helpers ───────────────────────────────────────────────────────────────────
13-
14-
PROG=$(basename "$0")
15-
REPO_ROOT="$(cd "$(dirname "$0")/.." && pwd)"
16-
17-
_use_color() {
18-
[[ -z "${NO_COLOR-}" ]] && [[ "${TERM-}" != "dumb" ]] && [[ -t 2 ]]
19-
}
20-
21-
err() {
22-
if _use_color; then printf '\033[31mError:\033[0m %s\n' "$*" >&2
23-
else printf 'Error: %s\n' "$*" >&2; fi
24-
}
25-
26-
info() {
27-
[[ "${QUIET:-0}" == "1" ]] && return
28-
printf '%s\n' "$*" >&2
29-
}
30-
31-
ok() {
32-
[[ "${QUIET:-0}" == "1" ]] && return
33-
if _use_color; then printf '\033[32m✓\033[0m %s\n' "$*" >&2
34-
else printf '✓ %s\n' "$*" >&2; fi
35-
}
36-
37-
usage() {
38-
cat >&2 <<EOF
39-
USAGE
40-
$PROG [flags]
41-
42-
DESCRIPTION
43-
Build a release tarball of the viktorani project, excluding
44-
node_modules, dist, and other dev artifacts.
45-
46-
EXAMPLES
47-
$PROG # create viktorani.tar.gz in repo root
48-
$PROG -o ~/Desktop # write to a specific directory
49-
$PROG --name my-release # custom archive name (no .tar.gz needed)
50-
$PROG -n # dry-run: show what would be included
51-
52-
FLAGS
53-
-o, --output DIR Directory to write the archive (default: repo root)
54-
-N, --name NAME Archive base name without extension (default: viktorani)
55-
-n, --dry-run List files that would be included; don't write anything
56-
-q, --quiet Suppress non-essential output
57-
--no-color Disable colour output
58-
-h, --help Show this help
59-
60-
EOF
61-
}
62-
63-
# ── defaults ──────────────────────────────────────────────────────────────────
64-
65-
OUTPUT_DIR="$REPO_ROOT/dist"
66-
ARCHIVE_NAME="viktorani"
67-
DRY_RUN=0
68-
QUIET=0
69-
70-
# ── arg parsing ───────────────────────────────────────────────────────────────
71-
72-
while [[ $# -gt 0 ]]; do
73-
case "$1" in
74-
-o|--output) OUTPUT_DIR="${2:?'--output requires a DIR'}"; shift 2 ;;
75-
-N|--name) ARCHIVE_NAME="${2:?'--name requires a NAME'}"; shift 2 ;;
76-
-n|--dry-run) DRY_RUN=1; shift ;;
77-
-q|--quiet) QUIET=1; shift ;;
78-
--no-color) NO_COLOR=1; export NO_COLOR; shift ;;
79-
-h|--help) usage; exit 0 ;;
80-
*) err "unknown flag: $1"; usage; exit 2 ;;
81-
esac
82-
done
83-
84-
# ── validate ──────────────────────────────────────────────────────────────────
85-
86-
if [[ ! -d "$OUTPUT_DIR" ]]; then
87-
err "output directory does not exist: $OUTPUT_DIR"
88-
exit 1
89-
fi
90-
91-
ARCHIVE="${OUTPUT_DIR%/}/${ARCHIVE_NAME}.tar.gz"
92-
93-
# ── excludes ─────────────────────────────────────────────────────────────────
94-
# Keep this list minimal — pack everything that belongs in the repo.
7+
ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
8+
VERSION="$(node -p "require('./package.json').version")"
9+
OUT="$ROOT/archives/viktorani-${VERSION}.tgz"
9510

11+
# Files and dirs to exclude (binaries, generated, irrelevant to source analysis)
9612
EXCLUDES=(
9713
--exclude='.git'
9814
--exclude='node_modules'
99-
--exclude='archives'
10015
--exclude='dist'
101-
--exclude='.vite'
10216
--exclude='coverage'
103-
--exclude='*.tar.gz'
104-
--exclude='.DS_Store'
105-
--exclude='*.local'
17+
--exclude='*.png'
18+
--exclude='*.ico'
19+
--exclude='*.svg'
20+
--exclude='*.webp'
21+
--exclude='*.jpg'
22+
--exclude='*.jpeg'
23+
--exclude='*.woff2'
24+
--exclude='*.woff'
25+
--exclude='CHANGELOG.md'
26+
--exclude='LICENSE'
27+
--exclude='src/assets'
28+
--exclude='public'
29+
--exclude='deploy'
30+
--exclude='archives'
10631
)
10732

108-
# ── dry-run ───────────────────────────────────────────────────────────────────
109-
110-
if [[ "$DRY_RUN" == "1" ]]; then
111-
info "Dry run — files that would be included:"
112-
tar "${EXCLUDES[@]}" -cz --to-stdout -C "$(dirname "$REPO_ROOT")" \
113-
"$(basename "$REPO_ROOT")" 2>/dev/null \
114-
| tar -tz 2>/dev/null \
115-
| sed 's|^[^/]*/||' \
116-
| grep -v '^$'
117-
info ""
118-
info "Archive would be written to: $ARCHIVE"
119-
exit 0
120-
fi
121-
122-
# ── build ─────────────────────────────────────────────────────────────────────
123-
124-
info "Packing $(basename "$REPO_ROOT")$ARCHIVE"
125-
126-
tar "${EXCLUDES[@]}" \
127-
-czf "$ARCHIVE" \
128-
-C "$(dirname "$REPO_ROOT")" \
129-
"$(basename "$REPO_ROOT")"
130-
131-
SIZE=$(du -sh "$ARCHIVE" | cut -f1)
132-
ok "Done — $ARCHIVE ($SIZE)"
33+
cd "$ROOT"
34+
tar -czf "$OUT" "${EXCLUDES[@]}" .
35+
SIZE="$(du -sh "$OUT" | cut -f1)"
36+
echo "Packed: $OUT ($SIZE)"
37+
echo ""
38+
echo "Contents by size:"
39+
tar -tzf "$OUT" | xargs -I{} du -sh "$ROOT/{}" 2>/dev/null | sort -rh | head -20

0 commit comments

Comments
 (0)