-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy pathshell.nix
More file actions
232 lines (209 loc) · 8.94 KB
/
Copy pathshell.nix
File metadata and controls
232 lines (209 loc) · 8.94 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
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
{pkgs ? import <nixpkgs> {}}: let
container-digest = pkgs.callPackage ./container-digest.nix {};
npm-refresh = pkgs.callPackage ./npm-refresh.nix {};
# Helper scripts
update-fetcher-repos = pkgs.writeShellScriptBin "update-fetcher-repos" ''
set -euo pipefail
SRCFILE=''${PROJECT_ROOT:-$(pwd)}/apps/fetcher/repos-src.nix
TOMLFILE=''${PROJECT_ROOT:-$(pwd)}/apps/fetcher/repos.toml
TMP_FILE=$(${pkgs.coreutils}/bin/mktemp "''${SRCFILE}.XXXXXX.nix")
trap 'rm -f "$TMP_FILE"' EXIT
echo "####################################" > "$TMP_FILE"
echo "# Auto-generated -- do not modify! #" >> "$TMP_FILE"
echo "####################################" >> "$TMP_FILE"
echo "{pkgs, ...}: {" >> "$TMP_FILE"
${pkgs.tomlq}/bin/tq --file "$TOMLFILE" --output json '.repos' | \
${pkgs.jq}/bin/jq -c '.[]' | \
while IFS= read -r repo; do
name=$(echo "$repo" | ${pkgs.jq}/bin/jq -r '.name')
url=$(echo "$repo" | ${pkgs.jq}/bin/jq -r '.url')
rev=$(echo "$repo" | ${pkgs.jq}/bin/jq -r '.rev // empty')
# Optional per-repo fetcher override. gitea.com gates its archive
# tarball endpoint behind login, breaking fetchFromGitea; force
# fetchgit (anonymous git clone is ungated) via fetcher = "fetchgit".
fetcher=$(echo "$repo" | ${pkgs.jq}/bin/jq -r '.fetcher // empty')
fetcher_arg=""
if [ -n "$fetcher" ]; then
fetcher_arg="-f $fetcher"
fi
# Validate TOML data before embedding it in generated Nix source.
rendered_name=$(${./apps/fetcher/render-nix-attr-name.sh} "$name")
if [ -n "$rev" ]; then
processed_url=pkgs.$(${pkgs.nurl}/bin/nurl $fetcher_arg "$url" "$rev" | tr -d '\n')
else
processed_url=pkgs.$(${pkgs.nurl}/bin/nurl $fetcher_arg "$url" | tr -d '\n')
fi
echo " ''${rendered_name} = ''${processed_url};"
done >> "$TMP_FILE"
echo "}" >> "$TMP_FILE"
${pkgs.alejandra}/bin/alejandra --quiet "$TMP_FILE"
mv "$TMP_FILE" "$SRCFILE"
'';
system-flake-rebuild = pkgs.writeShellScriptBin "system-flake-rebuild" ''
if [ ! -z "$1" ]; then
export CMD="$1"
else
export CMD=switch
fi
if [ ! -z "$2" ]; then
export HOST="$2"
else
export HOST=$(hostname --short)
fi
if [ "$(uname -s)" = "Darwin" ]; then
if [ "$HOST" = "freds-macbook-pro" ] || [ "$HOST" = "fred-macbook-pro-wireless" ] || [ "$HOST" = "freds-mbp" ] || [ "$HOST" = "Freds-MBP" ] || [ "$HOST" = "Mac" ] || [ "$HOST" = "mac" ]; then
darwin-rebuild --show-trace --flake .#macbook-pro $CMD
elif [ "$HOST" = "Laisas-Mac-mini" ] || [ "$HOST" = "laisas-mac-mini" ]; then
darwin-rebuild --show-trace --flake .#laisas-mac-mini $CMD
else
darwin-rebuild --show-trace --flake .#"$HOST" $CMD
fi
else
nixos-rebuild --show-trace --flake .#"$HOST" $CMD
fi
'';
update-container-digests = pkgs.writeShellScriptBin "update-container-digests" ''
set -euo pipefail
SHA_FILE=''${PROJECT_ROOT:-$(pwd)}/apps/fetcher/containers-sha.nix
TMP_FILE=$(${pkgs.coreutils}/bin/mktemp "''${SHA_FILE}.XXXXXX")
trap 'rm -f "$TMP_FILE"' EXIT
echo "Updating container digests..."
echo "####################################" > "$TMP_FILE"
echo "# Auto-generated -- do not modify! #" >> "$TMP_FILE"
echo "####################################" >> "$TMP_FILE"
${container-digest}/bin/container-digest --containers ''${PROJECT_ROOT:-$(pwd)}/apps/fetcher/containers.toml --output-format nix >> "$TMP_FILE"
${pkgs.gnused}/bin/sed -i 's/^{\.\.\.}: {$/_: {/' "$TMP_FILE"
${pkgs.alejandra}/bin/alejandra --quiet "$TMP_FILE"
mv "$TMP_FILE" "$SHA_FILE"
'';
update-claude-plugins = pkgs.writeShellScriptBin "update-claude-plugins" ''
SRCFILE=''${PROJECT_ROOT:-$(pwd)}/apps/fetcher/claude-plugins-src.nix
TOMLFILE=''${PROJECT_ROOT:-$(pwd)}/apps/fetcher/claude-plugins.toml
echo "####################################" > $SRCFILE
echo "# Auto-generated -- do not modify! #" >> $SRCFILE
echo "####################################" >> $SRCFILE
echo "{pkgs, ...}: {" >> $SRCFILE
${pkgs.tomlq}/bin/tq --file $TOMLFILE --output json '.repos' | \
${pkgs.jq}/bin/jq -c '.[]' | \
while IFS= read -r repo; do
name=$(echo "$repo" | ${pkgs.jq}/bin/jq -r '.name')
url=$(echo "$repo" | ${pkgs.jq}/bin/jq -r '.url')
rev=$(echo "$repo" | ${pkgs.jq}/bin/jq -r '.rev // empty')
fetcher=$(echo "$repo" | ${pkgs.jq}/bin/jq -r '.fetcher // empty')
# Validate TOML data before embedding it in generated Nix source.
rendered_name=$(${./apps/fetcher/render-nix-attr-name.sh} "$name")
if [ "$fetcher" = "tarball" ]; then
# Resolve to a concrete commit so the URL is reproducible.
if [ -n "$rev" ]; then
resolved_rev="$rev"
else
resolved_rev=$(${pkgs.git}/bin/git ls-remote "$url" HEAD | ${pkgs.coreutils}/bin/cut -f1)
fi
archive_url="$url/archive/''${resolved_rev}.tar.gz"
sha256=$(${pkgs.nix}/bin/nix-prefetch-url --type sha256 --unpack "$archive_url" 2>/dev/null)
echo " ''${rendered_name} = builtins.fetchTarball {"
echo " url = \"''${archive_url}\";"
echo " sha256 = \"''${sha256}\";"
echo " };"
else
if [ -n "$rev" ]; then
processed_url=pkgs.$(${pkgs.nurl}/bin/nurl "$url" "$rev" | tr -d '\n')
else
processed_url=pkgs.$(${pkgs.nurl}/bin/nurl "$url" | tr -d '\n')
fi
echo " ''${rendered_name} = ''${processed_url};"
fi
done >> $SRCFILE
echo "}" >> $SRCFILE
${pkgs.alejandra}/bin/alejandra --quiet $SRCFILE
'';
update-npm-packages = pkgs.writeShellScriptBin "update-npm-packages" ''
TOML_FILE=''${PROJECT_ROOT:-$(pwd)}/apps/fetcher/npm-packages.toml
NIX_FILE=''${PROJECT_ROOT:-$(pwd)}/apps/fetcher/npm-packages.nix
echo "Updating NPM packages..."
${npm-refresh}/bin/npm-refresh $TOML_FILE > $NIX_FILE
${pkgs.alejandra}/bin/alejandra --quiet $NIX_FILE
'';
in
pkgs.mkShell {
buildInputs = with pkgs; [
colmena
git
gh
hcloud
just
alejandra
nixos-anywhere
nixd
nurl
tomlq
statix
nodejs_22
uv
deadnix
python3
python3Packages.pyyaml
# Additional dependencies needed by scripts
# jq
# Helper scripts
update-fetcher-repos
update-claude-plugins
system-flake-rebuild
update-container-digests
update-npm-packages
];
# Environment variables for Aider
AIDER_LINT_CMD = "statix check";
AIDER_TEST_CMD = "just build";
AIDER_AUTO_TEST = "true";
shellHook = ''
# Add user's local bin to PATH
export PATH="$PATH:$HOME/.local/bin"
# Load the Hetzner Cloud API token at runtime (never via readFile, which
# would bake the secret into the world-readable nix store).
if [ -r "$HOME/.config/sops-nix/secrets/hetzner-home-api-token" ]; then
export HCLOUD_TOKEN="$(cat "$HOME/.config/sops-nix/secrets/hetzner-home-api-token")"
fi
# Authenticate GitHub API calls (nurl in update-claude-plugins, etc.) so
# they don't hit the unauthenticated 60 req/hr limit and 403. Fall back to
# the gh CLI's token if GITHUB_TOKEN isn't already set in the environment.
if [ -z "''${GITHUB_TOKEN:-}" ] && command -v gh >/dev/null 2>&1; then
_gh_token="$(gh auth token 2>/dev/null)"
if [ -n "$_gh_token" ]; then
export GITHUB_TOKEN="$_gh_token"
fi
unset _gh_token
fi
# Set PROJECT_ROOT to the actual working directory, not the nix store copy
export PROJECT_ROOT="$PWD"
# Keep local Git pre-commit checks aligned with /commit-and-push for Nix repos:
# just format; just lint; deadnix.
if command -v git >/dev/null 2>&1 && git rev-parse --is-inside-work-tree >/dev/null 2>&1; then
_git_hook_path="$(git rev-parse --git-path hooks/pre-commit)"
mkdir -p "$(dirname "$_git_hook_path")"
cat > "$_git_hook_path" <<'EOF'
#!/usr/bin/env bash
set -euo pipefail
repo_root="$(git rev-parse --show-toplevel)"
cd "$repo_root"
echo "Running Nix pre-commit checks..."
_before_format="$(mktemp)"
_after_format="$(mktemp)"
trap 'rm -f "$_before_format" "$_after_format"' EXIT
git diff --binary > "$_before_format"
just format
git diff --binary > "$_after_format"
if ! cmp -s "$_before_format" "$_after_format"; then
echo "just format changed files. Review and stage the formatted changes, then commit again." >&2
exit 1
fi
just lint
deadnix
EOF
chmod +x "$_git_hook_path"
unset _git_hook_path
fi
echo "Nix development shell activated"
echo "Project root: $PROJECT_ROOT"
'';
}