-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy pathsetup-config.sh
More file actions
executable file
·126 lines (110 loc) · 4.21 KB
/
setup-config.sh
File metadata and controls
executable file
·126 lines (110 loc) · 4.21 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
#!/bin/bash
# SPDX-License-Identifier: GPL-3.0-only
# Copyright (c) 2026 Marcus Krueger
# Copy configuration files to workspace based on file-manifest.json
CONFIG_DIR="${CONFIG_SOURCE_DIR:?CONFIG_SOURCE_DIR not set}"
MANIFEST="$CONFIG_DIR/file-manifest.json"
log() { echo "[setup-config] $*"; }
warn() { echo "[setup-config] WARNING: $*"; }
err() { echo "[setup-config] ERROR: $*" >&2; }
# Deprecation notice if legacy OVERWRITE_CONFIG is still set
if [ -n "${OVERWRITE_CONFIG+x}" ]; then
warn "OVERWRITE_CONFIG is deprecated. Use per-file 'overwrite' in config/file-manifest.json instead."
fi
# ── Legacy fallback ──────────────────────────────────────────────
legacy_copy() {
local target_dir="${CLAUDE_CONFIG_DIR:?CLAUDE_CONFIG_DIR not set}"
warn "file-manifest.json not found, falling back to legacy copy"
mkdir -p "$target_dir"
for file in defaults/settings.json defaults/keybindings.json defaults/main-system-prompt.md; do
if [ -f "$CONFIG_DIR/$file" ]; then
local basename="${file##*/}"
cp "$CONFIG_DIR/$file" "$target_dir/$basename"
chown "$(id -un):$(id -gn)" "$target_dir/$basename" 2>/dev/null || true
log "Copied $basename (legacy)"
fi
done
log "Configuration complete (legacy)"
}
if [ ! -f "$MANIFEST" ]; then
legacy_copy
exit 0
fi
# ── Validate manifest JSON ──────────────────────────────────────
if ! jq empty "$MANIFEST" 2>/dev/null; then
err "Invalid JSON in file-manifest.json"
exit 1
fi
# ── Variable expansion ───────────────────────────────────────────
expand_vars() {
local val="$1"
val="${val//\$\{CLAUDE_CONFIG_DIR\}/$CLAUDE_CONFIG_DIR}"
val="${val//\$\{WORKSPACE_ROOT\}/$WORKSPACE_ROOT}"
val="${val//\$\{HOME\}/$HOME}"
# Warn on any remaining unresolved ${...} tokens
if [[ "$val" =~ \$\{[^}]+\} ]]; then
warn "Unresolved variable in: $val"
fi
echo "$val"
}
# ── Change detection ─────────────────────────────────────────────
should_copy() {
local src="$1" dest="$2"
[ ! -f "$dest" ] && return 0
local src_hash dest_hash
src_hash=$(sha256sum "$src" | cut -d' ' -f1)
dest_hash=$(sha256sum "$dest" | cut -d' ' -f1)
[ "$src_hash" != "$dest_hash" ]
}
# ── Process manifest ─────────────────────────────────────────────
log "Copying configuration files..."
# Single jq invocation to extract all fields (reduces N×5 subprocess calls to 1)
# Note: empty destFilename uses "__NONE__" sentinel because bash read collapses
# consecutive tab delimiters, which shifts fields when destFilename is empty.
jq -r '.[] | [.src, .dest, (.destFilename // "__NONE__"), (.enabled // true | tostring), (.overwrite // "if-changed")] | @tsv' "$MANIFEST" |
while IFS=$'\t' read -r src dest dest_filename enabled overwrite; do
# Skip disabled entries
if [ "$enabled" = "false" ]; then
log "Skipping $src (disabled)"
continue
fi
# Resolve paths
src_path="$CONFIG_DIR/$src"
dest_dir=$(expand_vars "$dest")
[ "$dest_filename" = "__NONE__" ] && dest_filename=""
filename="${dest_filename:-${src##*/}}"
dest_path="$dest_dir/$filename"
# Validate source exists
if [ ! -f "$src_path" ]; then
warn "$src not found in config dir, skipping"
continue
fi
# Ensure destination directory exists
mkdir -p "$dest_dir"
# Apply overwrite strategy
case "$overwrite" in
always)
cp "$src_path" "$dest_path"
log "Copied $src → $dest_path (always)"
;;
never)
if [ ! -f "$dest_path" ]; then
cp "$src_path" "$dest_path"
log "Copied $src → $dest_path (new)"
else
log "Skipping $src (exists, overwrite=never)"
fi
;;
if-changed | *)
if should_copy "$src_path" "$dest_path"; then
cp "$src_path" "$dest_path"
log "Copied $src → $dest_path (changed)"
else
log "Skipping $src (unchanged)"
fi
;;
esac
# Fix ownership
chown "$(id -un):$(id -gn)" "$dest_path" 2>/dev/null || true
done
log "Configuration complete"