-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathsetup
More file actions
197 lines (179 loc) · 8.37 KB
/
Copy pathsetup
File metadata and controls
197 lines (179 loc) · 8.37 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
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
#!/bin/bash
set -uo pipefail
errors=()
# Run nix-env but keep the console output compact.
# - Raw nix fetch/build logs are swallowed (kept in a logfile for diagnostics).
# - On a TTY: a single status line is refreshed with the current package.
# - Otherwise (e.g. `devpod up` logs): one concise line per package.
# - Always ends with a ✅/❌ summary.
install_nix_packages() {
local log sep sb="" rc fetched built
log=$(mktemp "${TMPDIR:-/tmp}/nix-install.XXXXXX.log")
if [ -t 1 ]; then sep='\r\033[K'; else sep='\n'; fi
command -v stdbuf > /dev/null 2>&1 && sb="stdbuf -oL -eL"
# tarball-ttl: trust the cached nixpkgs channel tarball for a week instead of
# the 1h default, so a persistent ~/.cache spares the ~50s fetchTarball+eval
NIX_CONFIG="tarball-ttl = 604800" \
$sb nix-env -f "$HOME/.config/nixpkgs/install.nix" -iA myPackages --impure 2>&1 \
| tee "$log" \
| while IFS= read -r line; do
case "$line" in
*"copying path '/nix/store/"*)
n=${line#*store/}; n=${n%%\'*}; n=${n#*-}
printf "${sep} \xe2\xac\x87 %-48.48s" "$n"
;;
*"building '/nix/store/"*)
n=${line#*store/}; n=${n%%.drv*}; n=${n#*-}
printf "${sep} \xf0\x9f\x94\xa8 %-48.48s" "$n"
;;
esac
done
rc=${PIPESTATUS[0]}
fetched=$(grep -c "copying path '/nix/store/" "$log" 2> /dev/null || echo 0)
built=$(grep -c "building '/nix/store/" "$log" 2> /dev/null || echo 0)
if [ "$rc" -eq 0 ]; then
printf "${sep} \xe2\x9c\x85 Nix packages installed (%s fetched, %s built)\n" "$fetched" "$built"
rm -f "$log"
else
printf "${sep} \xe2\x9d\x8c Nix install failed (%s fetched, %s built before error)\n" "$fetched" "$built"
grep -iE "error:|failed" "$log" | sed 's/^/ /' | tail -15
echo " Full log kept at: $log"
errors+=("nix-env install failed — see $log or run 'nix-env -f ~/.config/nixpkgs/install.nix -iA myPackages --impure' manually")
fi
return "$rc"
}
# Named-volume mountpoints may be root:root (volume predates the image's
# ownership seeding, or onCreateCommand didn't run). Chown them back before
# chezmoi/nix/mise try to write.
for d in "$HOME/.cache" "$HOME/.local" "$HOME/.local/share/mise"; do
mkdir -p "$d" 2>/dev/null
if [ ! -w "$d" ]; then
# ~/.local contains the bind-mounted workspace: don't chown host files
rflag="-R"; [ "$d" = "$HOME/.local" ] && rflag=""
if sudo -n chown $rflag "$(id -u):$(id -g)" "$d" 2>/dev/null; then
echo "🔧 fixed ownership of $d"
else
errors+=("$d is not writable and could not be chowned — run 'sudo chown -R $(id -un) $d'")
fi
fi
done
# ~/.pi and ~/.claude are bind mounts; Docker creates a missing host-side
# source dir root-owned. Heal only when actually mounted — never mkdir.
for d in "$HOME/.pi" "$HOME/.claude"; do
if [ -d "$d" ] && [ ! -w "$d" ]; then
if sudo -n chown -R "$(id -u):$(id -g)" "$d" 2>/dev/null; then
echo "🔧 fixed ownership of $d"
else
errors+=("$d is not writable and could not be chowned — run 'sudo chown -R $(id -un) $d'")
fi
fi
done
LOCAL_BIN="$HOME/.local/bin"
GPGID=0x03BC4AD253B82986
mkdir -p $LOCAL_BIN
# If $HOME/.local/bin not in path, add it
if [ -d "$LOCAL_BIN" ] && [[ ":$PATH:" != *":$LOCAL_BIN:"* ]]; then
PATH="${PATH:+"$PATH:"}$LOCAL_BIN"
fi
# Setup gpg. Import the public key from the repo copy when available: a fresh
# keyring's `gpg --receive-keys` was measured at 2+ minutes (dirmngr keyserver
# connect timeouts) while a local import is instant and offline.
SCRIPT_DIR=$(cd "$(dirname "${BASH_SOURCE[0]:-$0}")" 2>/dev/null && pwd)
PUBKEY_FILE="${SCRIPT_DIR:-.}/.devcontainer/gpg-pubkey.asc"
if gpg --list-keys "$GPGID" > /dev/null 2>&1; then
: # already in the keyring
elif [ -f "$PUBKEY_FILE" ]; then
if ! gpg --import "$PUBKEY_FILE" 2>&1; then
errors+=("GPG key import from $PUBKEY_FILE failed — run 'gpg --receive-keys $GPGID' manually")
fi
else
# Fallback: keyserver fetch, but capped so it can't stall setup for minutes
if ! timeout 60 gpg --keyserver hkps://keyserver.ubuntu.com:443 --receive-keys "$GPGID" 2>&1; then
errors+=("GPG key retrieval failed — run 'gpg --receive-keys $GPGID' manually")
fi
fi
# Install and initialize chezmoi in one go
if ! command -v chezmoi > /dev/null; then
chezmoi_log=$(mktemp "${TMPDIR:-/tmp}/chezmoi-init.XXXXXX.log")
if sh -c "$(curl -fsLS get.chezmoi.io)" -- -b $LOCAL_BIN init --apply git@github.com:nimser/private-dotfiles-devcontainer.git --exclude=encrypted 2>&1 | tee "$chezmoi_log"; then
echo "🥁 Only non-encrypted files where applied. Please run 'chezmoi apply --include=encrypted' if needed."
rm -f "$chezmoi_log"
else
# A non-zero exit here is usually a post-apply hook failure (e.g. one
# package failing to install via mise), not chezmoi itself. Name the
# actual culprit when we can find one, instead of blaming chezmoi.
failed_tools=$(grep -oP '(?<=Failed to install ).*?(?=: )' "$chezmoi_log" | sort -u)
if [ -n "$failed_tools" ]; then
while IFS= read -r tool; do
errors+=("package install failed: $tool — dotfiles were still applied; see $chezmoi_log or retry with 'mise install'")
done <<< "$failed_tools"
else
errors+=("chezmoi init/apply reported an error — see $chezmoi_log or check network connection")
fi
fi
fi
# Install nix for dependencies that don't have a binary on github (would use mise otherwise)
# and detect install path from nix feature instead for devcontainers
for f in /nix/var/nix/profiles/default/etc/profile.d/nix-daemon.sh /etc/profile.d/nix.sh ~/.nix-profile/etc/profile.d/nix.sh; do
if [ -f "$f" ]; then
source "$f"
break
fi
done
# Fallback: aggressively hunt for nix-env anywhere under /nix or ~/.nix-profile
if ! command -v nix-env &>/dev/null; then
for d in /nix/var/nix/profiles/default/bin ~/.nix-profile/bin; do
if [ -x "$d/nix-env" ]; then
export PATH="$PATH:$d"
break
fi
done
# Last resort: find the binary wherever it lives
if ! command -v nix-env &>/dev/null; then
nix_env_path=$(find /nix /root/.nix-profile "$HOME/.nix-profile" -name nix-env -type f 2>/dev/null | head -1 || true)
if [ -n "$nix_env_path" ] && [ -x "$nix_env_path" ]; then
export PATH="$PATH:$(dirname "$nix_env_path")"
fi
fi
fi
if ! command -v nix-env &>/dev/null && [ ! -d "/nix" ]; then
echo "🥁 nix-env command not found. Attempting to install Nix..."
if sh <(curl -L https://nixos.org/nix/install) --daemon --yes 2>&1; then
if [ -f /etc/profile.d/nix.sh ]; then source /etc/profile.d/nix.sh; fi
else
errors+=("Nix installation failed — reinstall shell or source /etc/profile.d/nix.sh")
fi
fi
if command -v nix-env &>/dev/null; then
if [ -f $HOME/.config/nixpkgs/config.nix ]; then
# Set system type if not provided via cli
export SYSTEM_TYPE=${SYSTEM_TYPE:-server}
export NIX_REMOTE=""
# Install all packages defined in install.nix (compact, filtered output)
install_nix_packages || true
else
echo "💥 WARNING: Nix configuration file not found"
echo "Ensure chezmoi has run and deployed it correctly."
errors+=("Nix config not found at ~/.config/nixpkgs/config.nix — check chezmoi apply")
fi
else
echo "⚠️ nix-env not available after install attempt — skipping nix package install"
echo " Restart your shell or run: source /etc/profile.d/nix.sh && nix-env -f $HOME/.config/nixpkgs/install.nix -iA myPackages --impure"
errors+=("nix-env not available — packages from install.nix were not installed")
fi
# Summary
if [ "${#errors[@]}" -gt 0 ]; then
echo ""
echo "╔════════════════════════════════════════════════════════╗"
echo "║ ⚠️ Setup completed with errors ║"
echo "╠════════════════════════════════════════════════════════╣"
for err in "${errors[@]}"; do
echo "║ ❌ $err"
done
echo "╚════════════════════════════════════════════════════════╝"
echo ""
echo " 🏁 Setup continues — workspace will still be usable. Fix the above at your convenience."
echo ""
fi
echo "✅ Finished setting up dotfiles"
exit 0