mirror of https://github.com/garrytan/gstack.git
fix(careful): BSD sed compatibility for safe exception detection on macOS
The sed regex in check-careful.sh uses \s+, which is a GNU sed
extension not supported by BSD sed (macOS default). On macOS, this
causes the RM_ARGS strip to fail silently, making rm -rf of safe
exceptions (node_modules, .next, dist, etc.) trigger the destructive
warning instead of being permitted as designed.
Fix: replace \s+ with POSIX [[:space:]]+, which works on both GNU sed
(Linux) and BSD sed (macOS).
The existing test/hook-scripts.test.ts already documented this
limitation via a detectSafeRmWorks() helper and a platform-conditional
assertion ("if GNU sed: expect undefined, else: expect ask"). Now that
the regex works on both platforms, this dead path is removed and the
safe-exception tests assert the same expectation on every OS.
Note: the grep regex in the same file also uses \s+, but BSD grep -E
on macOS does support \s (verified via bash -x trace), so only the
sed expression needs the fix.
Discovered while translating the careful skill for a Japanese
derivative project (uzustack). Reference:
https://github.com/uzumaki-inc/uzustack/commit/bc67c8d
This commit is contained in:
parent
5d4fe7df07
commit
e719af0508
|
|
@ -28,7 +28,7 @@ CMD_LOWER=$(printf '%s' "$CMD" | tr '[:upper:]' '[:lower:]')
|
|||
# --- Check for safe exceptions (rm -rf of build artifacts) ---
|
||||
if printf '%s' "$CMD" | grep -qE 'rm\s+(-[a-zA-Z]*r[a-zA-Z]*\s+|--recursive\s+)' 2>/dev/null; then
|
||||
SAFE_ONLY=true
|
||||
RM_ARGS=$(printf '%s' "$CMD" | sed -E 's/.*rm\s+(-[a-zA-Z]+\s+)*//;s/--recursive\s*//')
|
||||
RM_ARGS=$(printf '%s' "$CMD" | sed -E 's/.*rm[[:space:]]+(-[a-zA-Z]+[[:space:]]+)*//;s/--recursive[[:space:]]*//')
|
||||
for target in $RM_ARGS; do
|
||||
case "$target" in
|
||||
*/node_modules|node_modules|*/\.next|\.next|*/dist|dist|*/__pycache__|__pycache__|*/\.cache|\.cache|*/build|build|*/\.turbo|\.turbo|*/coverage|coverage)
|
||||
|
|
|
|||
|
|
@ -56,13 +56,6 @@ function withFreezeDir(freezePath: string, fn: (stateDir: string) => void) {
|
|||
}
|
||||
}
|
||||
|
||||
// Detect whether the safe-rm-targets regex works on this platform.
|
||||
// macOS sed -E does not support \s, so the safe exception check fails there.
|
||||
function detectSafeRmWorks(): boolean {
|
||||
const { output } = runHook(CAREFUL_SCRIPT, carefulInput('rm -rf node_modules'));
|
||||
return output.permissionDecision === undefined;
|
||||
}
|
||||
|
||||
// ============================================================
|
||||
// check-careful.sh tests
|
||||
// ============================================================
|
||||
|
|
@ -88,24 +81,13 @@ describe('check-careful.sh', () => {
|
|||
test('rm -rf node_modules allows (safe exception)', () => {
|
||||
const { exitCode, output } = runHook(CAREFUL_SCRIPT, carefulInput('rm -rf node_modules'));
|
||||
expect(exitCode).toBe(0);
|
||||
if (detectSafeRmWorks()) {
|
||||
// GNU sed: safe exception triggers, allows through
|
||||
expect(output.permissionDecision).toBeUndefined();
|
||||
} else {
|
||||
// macOS sed: safe exception regex uses \\s which is unsupported,
|
||||
// so the safe-targets check fails and the command warns
|
||||
expect(output.permissionDecision).toBe('ask');
|
||||
}
|
||||
expect(output.permissionDecision).toBeUndefined();
|
||||
});
|
||||
|
||||
test('rm -rf .next dist allows (multiple safe targets)', () => {
|
||||
const { exitCode, output } = runHook(CAREFUL_SCRIPT, carefulInput('rm -rf .next dist'));
|
||||
expect(exitCode).toBe(0);
|
||||
if (detectSafeRmWorks()) {
|
||||
expect(output.permissionDecision).toBeUndefined();
|
||||
} else {
|
||||
expect(output.permissionDecision).toBe('ask');
|
||||
}
|
||||
expect(output.permissionDecision).toBeUndefined();
|
||||
});
|
||||
|
||||
test('rm -rf node_modules /var/data warns (mixed safe+unsafe)', () => {
|
||||
|
|
|
|||
Loading…
Reference in New Issue