Skip to content

Commit 4bbf229

Browse files
committed
fix regression stackpanel root
1 parent 3751018 commit 4bbf229

2 files changed

Lines changed: 119 additions & 160 deletions

File tree

.stackpanel-root

Lines changed: 0 additions & 1 deletion
This file was deleted.

nix/stackpanel/lib/paths.nix

Lines changed: 119 additions & 159 deletions
Original file line numberDiff line numberDiff line change
@@ -8,18 +8,15 @@
88
# -----------------------------
99
# This library uses SUBDIRECTORY NAMES, not full paths:
1010
# - rootDir = ".stackpanel" (the stackpanel home directory)
11-
# - stateDir = "state" (subdirectory name, NOT ".stack/state")
12-
# - genDir = "gen" (subdirectory name, NOT ".stack/gen")
11+
# - stateDir = "state" (subdirectory name, NOT ".stackpanel/state")
12+
# - genDir = "gen" (subdirectory name, NOT ".stackpanel/gen")
1313
#
1414
# Full paths are computed as: $root/${rootDir}/${stateDir}
15-
# For example: /path/to/project/.stack/state
15+
# For example: /path/to/project/.stackpanel/state
1616
#
17-
# If you're getting duplicate path segments like ".stack/.stack/state",
17+
# If you're getting duplicate path segments like ".stackpanel/.stackpanel/state",
1818
# you're passing a full path where a subdirectory name is expected!
1919
#
20-
# Uses a root marker file pattern (similar to devenv's .devenv-root) to allow
21-
# tools to find the project root from any subdirectory.
22-
#
2320
# Features:
2421
# - Shell functions for finding project root (stackpanel_find_root)
2522
# - Path resolution utilities (stackpanel_resolve_paths)
@@ -38,195 +35,158 @@
3835
# STACKPANEL_ROOT=$(stackpanel_find_root)
3936
# ==============================================================================
4037
# ==============================================================================
41-
{ lib }:
42-
let
38+
{lib}: let
4339
# Default configuration (can be overridden)
4440
defaults = {
45-
rootDir = ".stack";
46-
rootMarker = ".stackpanel-root";
47-
stateDir = "profile";
48-
keysDir = "keys";
41+
rootDir = ".stackpanel";
42+
stateDir = "state";
4943
genDir = "gen";
5044
};
5145

52-
# Shell function to find project root by looking for root marker
53-
mkShellFindRoot =
54-
{
55-
rootDir ? defaults.rootDir,
56-
rootMarker ? defaults.rootMarker,
57-
}:
58-
''
59-
stackpanel_find_root() {
60-
local dir="$PWD"
61-
local marker="${rootMarker}"
46+
# Shell function to find project root
47+
mkShellFindRoot = {rootDir ? defaults.rootDir}: ''
48+
stackpanel_find_root() {
49+
local dir="$PWD"
6250
63-
# First, try to find the marker file by walking up the directory tree
64-
while [[ "$dir" != "/" ]]; do
65-
if [[ -f "$dir/$marker" ]]; then
66-
cat "$dir/$marker"
67-
return 0
68-
fi
69-
dir="$(dirname "$dir")"
70-
done
51+
# First, check if STACKPANEL_ROOT is already set (preferred)
52+
if [[ -n "''${STACKPANEL_ROOT:-}" ]]; then
53+
echo "$STACKPANEL_ROOT"
54+
return 0
55+
fi
7156
72-
# Fallback 1: check if STACKPANEL_ROOT is already set
73-
if [[ -n "''${STACKPANEL_ROOT:-}" ]]; then
74-
echo "$STACKPANEL_ROOT"
57+
# Fallback 1: use git repository root if available
58+
if command -v git >/dev/null 2>&1; then
59+
local git_root
60+
git_root="$(git rev-parse --show-toplevel 2>/dev/null)" || true
61+
if [[ -n "$git_root" ]]; then
62+
echo "$git_root"
7563
return 0
7664
fi
65+
fi
7766
78-
# Fallback 2: use git repository root if available
79-
# This handles running `nix develop` from subdirectories before marker exists
80-
if command -v git >/dev/null 2>&1; then
81-
local git_root
82-
git_root="$(git rev-parse --show-toplevel 2>/dev/null)" || true
83-
if [[ -n "$git_root" ]]; then
84-
echo "$git_root"
85-
return 0
86-
fi
67+
# Fallback 2: look for .stackpanel directory by walking up from PWD
68+
dir="$PWD"
69+
while [[ "$dir" != "/" ]]; do
70+
if [[ -d "$dir/${rootDir}" ]]; then
71+
echo "$dir"
72+
return 0
8773
fi
74+
dir="$(dirname "$dir")"
75+
done
8876
89-
# Fallback 3: look for flake.nix by walking up from PWD
90-
dir="$PWD"
91-
while [[ "$dir" != "/" ]]; do
92-
if [[ -f "$dir/flake.nix" ]]; then
93-
echo "$dir"
94-
return 0
95-
fi
96-
dir="$(dirname "$dir")"
97-
done
77+
# Fallback 3: look for flake.nix by walking up from PWD
78+
dir="$PWD"
79+
while [[ "$dir" != "/" ]]; do
80+
if [[ -f "$dir/flake.nix" ]]; then
81+
echo "$dir"
82+
return 0
83+
fi
84+
dir="$(dirname "$dir")"
85+
done
9886
99-
echo "Error: Could not find stackpanel root (no $marker, git repo, or flake.nix found)" >&2
100-
return 1
101-
}
102-
'';
87+
echo "Error: Could not find stackpanel root (no STACKPANEL_ROOT env var, git repo, ${rootDir} dir, or flake.nix found)" >&2
88+
return 1
89+
}
90+
'';
10391

10492
# Shell function to resolve all stackpanel paths
105-
mkShellResolvePaths =
106-
{
107-
rootDir ? defaults.rootDir,
108-
stateDir ? defaults.stateDir,
109-
keysDir ? defaults.keysDir,
110-
genDir ? defaults.genDir,
111-
rootMarker ? defaults.rootMarker,
112-
}:
113-
''
114-
stackpanel_resolve_paths() {
115-
local root="''${1:-$(stackpanel_find_root)}"
116-
if [[ -z "$root" ]]; then
117-
return 1
118-
fi
119-
if [[ ! -d "$root" ]]; then
120-
echo "Error: Resolved stackpanel root is not a directory: $root"
121-
echo "You may need to run on your stackpanel root dir:"
122-
echo
123-
echo " echo \"\$PWD\" > ${rootMarker}"
124-
echo
125-
return 1
126-
fi
127-
export STACKPANEL_ROOT="$root"
128-
export STACKPANEL_ROOT_DIR="$root/${rootDir}"
129-
export STACKPANEL_STATE_DIR="$root/${rootDir}/${stateDir}"
130-
export STACKPANEL_KEYS_DIR="$root/${rootDir}/${keysDir}"
131-
export STACKPANEL_GEN_DIR="$root/${rootDir}/${genDir}"
132-
}
133-
'';
134-
in
135-
{
93+
mkShellResolvePaths = {
94+
rootDir ? defaults.rootDir,
95+
stateDir ? defaults.stateDir,
96+
genDir ? defaults.genDir,
97+
}: ''
98+
stackpanel_resolve_paths() {
99+
local root="''${1:-$(stackpanel_find_root)}"
100+
if [[ -z "$root" ]]; then
101+
return 1
102+
fi
103+
if [[ ! -d "$root" ]]; then
104+
echo "Error: Resolved stackpanel root is not a directory: $root"
105+
echo "You may need to set STACKPANEL_ROOT or run from a git repository"
106+
return 1
107+
fi
108+
export STACKPANEL_ROOT="$root"
109+
export STACKPANEL_ROOT_DIR="$root/${rootDir}"
110+
export STACKPANEL_STATE_DIR="$root/${rootDir}/${stateDir}"
111+
export STACKPANEL_GEN_DIR="$root/${rootDir}/${genDir}"
112+
}
113+
'';
114+
in {
136115
inherit defaults mkShellFindRoot mkShellResolvePaths;
137116

138117
# Combined shell setup script with all path utilities
139118
# IMPORTANT: stateDir and genDir must be SUBDIRECTORY NAMES, not full paths!
140-
mkShellPathUtils =
141-
cfg:
142-
let
143-
rootDir = cfg.rootDir or defaults.rootDir;
144-
rootMarker = cfg.rootMarker or defaults.rootMarker;
145-
stateDir = cfg.stateDir or defaults.stateDir;
146-
keysDir = cfg.keysDir or defaults.keysDir;
147-
genDir = cfg.genDir or defaults.genDir;
119+
mkShellPathUtils = cfg: let
120+
rootDir = cfg.rootDir or defaults.rootDir;
121+
stateDir = cfg.stateDir or defaults.stateDir;
122+
genDir = cfg.genDir or defaults.genDir;
148123

149-
validatedStateDir =
150-
if lib.hasPrefix "." stateDir && stateDir != "." then
151-
throw ''
152-
paths.nix: stateDir should be a subdirectory name (e.g., "profile"), not a full path!
153-
Got: "${stateDir}"
154-
Expected: just the subdirectory name like "profile"
155-
The full path is computed as: $root/${rootDir}/${stateDir}
156-
''
157-
else
158-
stateDir;
124+
# Validate that stateDir doesn't look like a full path (starts with ".")
125+
validatedStateDir =
126+
if lib.hasPrefix "." stateDir && stateDir != "."
127+
then
128+
throw ''
129+
paths.nix: stateDir should be a subdirectory name (e.g., "state"), not a full path!
130+
Got: "${stateDir}"
131+
Expected: just the subdirectory name like "state"
132+
The full path is computed as: $root/${rootDir}/${stateDir}
133+
''
134+
else stateDir;
159135

160-
validatedKeysDir =
161-
if lib.hasPrefix "." keysDir && keysDir != "." then
162-
throw ''
163-
paths.nix: keysDir should be a subdirectory name (e.g., "keys"), not a full path!
164-
Got: "${keysDir}"
165-
''
166-
else
167-
keysDir;
168-
169-
validatedGenDir =
170-
if lib.hasPrefix "." genDir && genDir != "." then
171-
throw ''
172-
paths.nix: genDir should be a subdirectory name (e.g., "gen"), not a full path!
173-
Got: "${genDir}"
174-
Expected: just the subdirectory name like "gen"
175-
The full path is computed as: $root/${rootDir}/${genDir}
176-
''
177-
else
178-
genDir;
179-
in
180-
''
181-
# Stackpanel path utilities
182-
${mkShellFindRoot { inherit rootDir rootMarker; }}
183-
${mkShellResolvePaths {
184-
rootDir = rootDir;
185-
stateDir = validatedStateDir;
186-
keysDir = validatedKeysDir;
187-
genDir = validatedGenDir;
188-
}}
189-
'';
136+
# Validate that genDir doesn't look like a full path (starts with ".")
137+
validatedGenDir =
138+
if lib.hasPrefix "." genDir && genDir != "."
139+
then
140+
throw ''
141+
paths.nix: genDir should be a subdirectory name (e.g., "gen"), not a full path!
142+
Got: "${genDir}"
143+
Expected: just the subdirectory name like "gen"
144+
The full path is computed as: $root/${rootDir}/${genDir}
145+
''
146+
else genDir;
147+
in ''
148+
# Stackpanel path utilities
149+
${mkShellFindRoot {inherit rootDir;}}
150+
${mkShellResolvePaths {
151+
rootDir = rootDir;
152+
stateDir = validatedStateDir;
153+
genDir = validatedGenDir;
154+
}}
155+
'';
190156

191157
# ============================================================================
192158
# NIX-TIME PATH HELPERS
193159
# Pure functions for computing paths at Nix evaluation time
194160
# ============================================================================
195161

196162
# Compute derived paths from config
197-
mkPaths =
198-
{
199-
rootDir ? defaults.rootDir,
200-
stateDir ? defaults.stateDir,
201-
keysDir ? defaults.keysDir,
202-
genDir ? defaults.genDir,
203-
configDir ? null,
204-
}:
205-
{
206-
root = rootDir;
207-
state = "${rootDir}/${stateDir}";
208-
keys = "${rootDir}/${keysDir}";
209-
gen = "${rootDir}/${genDir}";
210-
config = if configDir != null then toString configDir else null;
211-
};
163+
mkPaths = {
164+
rootDir ? defaults.rootDir,
165+
stateDir ? defaults.stateDir,
166+
genDir ? defaults.genDir,
167+
configDir ? null,
168+
}: {
169+
root = rootDir;
170+
state = "${rootDir}/${stateDir}";
171+
gen = "${rootDir}/${genDir}";
172+
config =
173+
if configDir != null
174+
then toString configDir
175+
else null;
176+
};
212177

213178
# ============================================================================
214179
# GITIGNORE HELPERS
215180
# ============================================================================
216181

217182
# Generate .gitignore content for the stackpanel root directory
218-
mkGitignore =
219-
{
220-
rootMarker ? defaults.rootMarker,
221-
stateDir ? defaults.stateDir,
222-
keysDir ? defaults.keysDir,
223-
extraEntries ? [ ],
224-
}:
183+
mkGitignore = {
184+
stateDir ? defaults.stateDir,
185+
extraEntries ? [],
186+
}:
225187
lib.concatStringsSep "\n" (
226188
[
227189
"${stateDir}/"
228-
"${keysDir}/"
229-
rootMarker
230190
]
231191
++ extraEntries
232192
);

0 commit comments

Comments
 (0)