Skip to content

Commit 4b4e721

Browse files
fix(dso-q523): validate.sh handles missing APP_DIR and unbound variable errors
- Guard `cd "$APP_DIR"` with existence check; falls back to REPO_ROOT when the app directory does not exist (e.g. DSO plugin repo has no app/ subdir) - Fix `$CI` unbound variable: use `${CI:-}` at lines 657/858 for set -u safety - Fix `CLEANUP_PIDS[@]` unbound variable: use safe empty-array expansion pattern - Remove `args=-q --tb=line` from tests run_check call (was passed literally to pytest as a file path, causing "file or directory not found" failures) - Update test-validate-config-driven.sh: replace config-workaround test with a structural test verifying the code-level guard in validate.sh Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent 6be9fb0 commit 4b4e721

File tree

4 files changed

+24
-13
lines changed

4 files changed

+24
-13
lines changed

.claude-plugin/plugin.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "dso",
3-
"version": "0.5.0",
3+
"version": "0.5.1",
44
"description": "Workflow infrastructure plugin for Claude Code projects",
55
"commands": "./commands/",
66
"skills": "./skills/",

.tickets/dso-q523.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,3 +35,7 @@ CHECKPOINT 2/6: RED tests confirmed - 5 new tests fail as expected. Now applying
3535
**2026-03-18T19:00:52Z**
3636

3737
CHECKPOINT 3/6: GREEN - tests pass. workflow-config.conf updated with paths.app_dir=. and all missing command keys (commands.syntax_check=true, commands.lint_ruff=ruff..., commands.lint_mypy=true, commands.test_plugin=true). validate.sh no longer shows 'cd: app: No such file'. Pre-existing CLEANUP_PIDS unbound variable error and tests:FAIL (args=-q --tb=line appended to CMD_TEST_UNIT) are not caused by our changes.
38+
39+
**2026-03-18T19:24:54Z**
40+
41+
CHECKPOINT 6/6: Done ✓ — Fixed validate.sh: (1) guard cd APP_DIR with existence check, (2) $CI → ${CI:-} at lines 657/858, (3) CLEANUP_PIDS[@] → safe empty-array expansion, (4) removed args=-q --tb=line from tests run_check call (broke custom pytest CMD). Also fixed test-validate-config-driven.sh to verify the code-level guard instead of config workaround. All 1606 script tests pass, validate.sh --ci exits 0.

scripts/validate.sh

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -180,7 +180,7 @@ timestamp=$(date -u +%Y-%m-%dT%H:%M:%SZ)"
180180
fi
181181
fi
182182
fi
183-
for pid in "${CLEANUP_PIDS[@]}"; do
183+
for pid in "${CLEANUP_PIDS[@]+"${CLEANUP_PIDS[@]}"}"; do
184184
kill -TERM "$pid" 2>/dev/null || true
185185
kill -KILL "$pid" 2>/dev/null || true
186186
done
@@ -608,7 +608,13 @@ check_ci() {
608608
}
609609

610610
# Launch all independent checks in parallel
611-
cd "$APP_DIR"
611+
# Guard: if APP_DIR doesn't exist (e.g. DSO plugin repo has no app/ subdir),
612+
# fall back to running checks from REPO_ROOT.
613+
if [ -d "$APP_DIR" ]; then
614+
cd "$APP_DIR"
615+
else
616+
cd "$REPO_ROOT"
617+
fi
612618
# Track launched checks for crash detection (missing .rc file = process crash)
613619
# REVIEW-DEFENSE: Keep this list in sync with the run_check/check_* calls below.
614620
# Each name must match the first argument passed to run_check or check_*.
@@ -626,7 +632,7 @@ run_check "ruff" "$TIMEOUT_RUFF" $CMD_LINT_RUFF &
626632
# shellcheck disable=SC2086
627633
run_check "mypy" "$TIMEOUT_MYPY" $CMD_LINT_MYPY &
628634
# shellcheck disable=SC2086
629-
run_check "tests" "$TIMEOUT_TESTS" $CMD_TEST_UNIT args="-q --tb=line" &
635+
run_check "tests" "$TIMEOUT_TESTS" $CMD_TEST_UNIT &
630636
# shellcheck disable=SC2086
631637
(cd "$REPO_ROOT" && run_check "plugin" "$TIMEOUT_PLUGIN" $CMD_TEST_PLUGIN) &
632638
check_migrations &
@@ -648,7 +654,7 @@ if [ $CHECK_CI -eq 1 ]; then
648654
# Only trigger when CI definitively completed with failure and we are not
649655
# already inside a CI environment (where the E2E block above handles it).
650656
if [ "$local_ci_rc" != "0" ] && [ "$local_ci_rc" != "skip" ] && \
651-
[[ "$local_e2e_result" == completed:* ]] && [ -z "$CI" ]; then
657+
[[ "$local_e2e_result" == completed:* ]] && [ -z "${CI:-}" ]; then
652658
[ "$VERBOSE" = "1" ] && verbose_print "e2e" "running (parallel, CI failed)"
653659
# shellcheck disable=SC2086
654660
run_check "e2e" "$TIMEOUT_E2E" $CMD_TEST_E2E
@@ -848,8 +854,8 @@ if [ $CHECK_CI -eq 1 ]; then
848854
fi
849855

850856
# E2E tests: skip if CI passed for main, always run in CI environment
851-
cd "$APP_DIR"
852-
if [ -n "$CI" ]; then
857+
if [ -d "$APP_DIR" ]; then cd "$APP_DIR"; else cd "$REPO_ROOT"; fi
858+
if [ -n "${CI:-}" ]; then
853859
# In CI environment: always run E2E tests
854860
E2E_RAN=1
855861
[ "$VERBOSE" = "1" ] && verbose_print "e2e" "running"

tests/scripts/test-validate-config-driven.sh

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -116,14 +116,15 @@ done
116116

117117
assert_pass_if_clean "test_workflow_config_has_all_validate_keys"
118118

119-
# ── test_workflow_config_has_paths_app_dir ────────────────────────────────
120-
# workflow-config.conf must define paths.app_dir so validate.sh does not
121-
# default to "app" (which does not exist in the DSO plugin repo).
119+
# ── test_validate_handles_missing_app_dir ────────────────────────────────
120+
# validate.sh must not fail with "cd: app: No such file" when APP_DIR
121+
# does not exist (e.g. DSO plugin repo has no app/ subdirectory).
122+
# The guard in validate.sh falls back to REPO_ROOT when APP_DIR is absent.
122123
_snapshot_fail
123124

124-
found=$(grep -c "^paths\.app_dir=" "$REAL_CONFIG" || true)
125-
assert_ne "workflow-config.conf has paths.app_dir" "0" "$found"
125+
found=$(grep -c '"\$APP_DIR" \]; then' "$VALIDATE_SH" || true)
126+
assert_ne "validate_sh_guards_cd_to_app_dir" "0" "$found"
126127

127-
assert_pass_if_clean "test_workflow_config_has_paths_app_dir"
128+
assert_pass_if_clean "test_validate_handles_missing_app_dir"
128129

129130
print_summary

0 commit comments

Comments
 (0)