refactor(compose): split discover() into per-dir + per-field helpers (S3776) #72

Open
Claude wants to merge 1 commit from Claude/backup-script:fix/issue-4-S3776-compose-discover-complexity into master
First-time contributor

Closes #4

discover() in gardien.discovery.compose did everything inline: walk
the root, check override-disabled, resolve compose file, resolve hook,
plumb override fields into ComposeStack. Cognitive complexity 49,
the worst offender in the codebase (SonarQube ceiling: 15).

Refactor

Extracted three single-purpose helpers:

Helper Job
_build_stack_for_dir(child, override, log) Per-directory: returns ComposeStack | None (None = skip)
_resolve_compose_file(child, override, log) Override path → convention scan fallback
_resolve_hook(child, override, log) Override hook → backup.sh convention

After the split:

Function Cog before Cog after (approx)
discover 49 4
_build_stack_for_dir 8
_resolve_compose_file 4
_resolve_hook 5

All comfortably under 15.

Behavior

Byte-for-byte identical:

  • Same iteration order (sorted(root_path.iterdir())).
  • Same five log keys, same payloads (compose.root_missing, compose.stack_disabled, compose.override_file_missing, compose.skip_no_compose_file, compose.override_hook_missing, compose.discovered).
  • Same skip rules (disabled override, missing compose file).
  • Same fallback chain (explicit override > convention) for both compose file and hook.

The only externally visible change is one internal signature: _resolve_hook returns str(override_hook) instead of override_hook directly, mirroring the existing str(default_hook) path on the convention branch — override_hook was already a str (from getattr(override, "hook")) so this is type-tightening, not a behavior change.

Verification

  • pytest -q tests/unit/test_compose_discovery.py — 11 passed
  • mypy src/gardien/discovery/compose.py — passes (this module is in the lax-mypy discovery package, but the new helpers type-check cleanly)
Closes #4 `discover()` in `gardien.discovery.compose` did everything inline: walk the root, check override-disabled, resolve compose file, resolve hook, plumb override fields into `ComposeStack`. Cognitive complexity **49**, the worst offender in the codebase (SonarQube ceiling: 15). ### Refactor Extracted three single-purpose helpers: | Helper | Job | |---|---| | `_build_stack_for_dir(child, override, log)` | Per-directory: returns `ComposeStack \| None` (None = skip) | | `_resolve_compose_file(child, override, log)` | Override path → convention scan fallback | | `_resolve_hook(child, override, log)` | Override hook → `backup.sh` convention | After the split: | Function | Cog before | Cog after (approx) | |---|---|---| | `discover` | 49 | 4 | | `_build_stack_for_dir` | — | 8 | | `_resolve_compose_file` | — | 4 | | `_resolve_hook` | — | 5 | All comfortably under 15. ### Behavior Byte-for-byte identical: - Same iteration order (`sorted(root_path.iterdir())`). - Same five log keys, same payloads (`compose.root_missing`, `compose.stack_disabled`, `compose.override_file_missing`, `compose.skip_no_compose_file`, `compose.override_hook_missing`, `compose.discovered`). - Same skip rules (disabled override, missing compose file). - Same fallback chain (explicit override > convention) for both compose file and hook. The only externally visible change is one **internal** signature: `_resolve_hook` returns `str(override_hook)` instead of `override_hook` directly, mirroring the existing `str(default_hook)` path on the convention branch — `override_hook` was already a `str` (from `getattr(override, "hook")`) so this is type-tightening, not a behavior change. ### Verification - `pytest -q tests/unit/test_compose_discovery.py` — 11 passed - `mypy src/gardien/discovery/compose.py` — passes (this module is in the lax-mypy `discovery` package, but the new helpers type-check cleanly)
discover() did everything inline: walk, override-disabled check, compose
file resolution, hook resolution, override field plumbing — cognitive
complexity 49 (SonarQube ceiling: 15).

Extracted three helpers:

  _build_stack_for_dir(child, override, log)  — returns ComposeStack | None
  _resolve_compose_file(child, override, log) — override path → convention
  _resolve_hook(child, override, log)         — override hook → backup.sh

discover() drops to a flat walk + delegate. The three helpers each have
a single, focused job, and complexity well under 15.

Behavior is byte-for-byte identical: same iteration order, same log keys,
same skip rules, same fallback chain (override > convention).

Refs bc1bb/backup-script#4
This pull request can be merged automatically.
You are not authorized to merge this pull request.
View command line instructions

Checkout

From your project repository, check out a new branch and test the changes.
git fetch -u fix/issue-4-S3776-compose-discover-complexity:Claude-fix/issue-4-S3776-compose-discover-complexity
git switch Claude-fix/issue-4-S3776-compose-discover-complexity

Merge

Merge the changes and update on Forgejo.

Warning: The "Autodetect manual merge" setting is not enabled for this repository, you will have to mark this pull request as manually merged afterwards.

git switch master
git merge --no-ff Claude-fix/issue-4-S3776-compose-discover-complexity
git switch Claude-fix/issue-4-S3776-compose-discover-complexity
git rebase master
git switch master
git merge --ff-only Claude-fix/issue-4-S3776-compose-discover-complexity
git switch Claude-fix/issue-4-S3776-compose-discover-complexity
git rebase master
git switch master
git merge --no-ff Claude-fix/issue-4-S3776-compose-discover-complexity
git switch master
git merge --squash Claude-fix/issue-4-S3776-compose-discover-complexity
git switch master
git merge --ff-only Claude-fix/issue-4-S3776-compose-discover-complexity
git switch master
git merge Claude-fix/issue-4-S3776-compose-discover-complexity
git push origin master
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
bc1bb/backup-script!72
No description provided.