Repository navigation
fix(workflows): match overlay file extensions case-insensitively - #4531
jawwad-ali wants to merge 2 commits into
Conversation
|
Please include the corresponding case-insensitive check in Add coverage showing that an uppercase-extension overlay can also be disabled, removed, and have its priority changed. This completes the same behavior fix rather than expanding scope. Coordinate with #4141 through normal rebasing—whichever lands later should reconcile with the earlier change. Drafted for @mnriem with assistance from GitHub Copilot (model: GPT-6 Astra; interactive comment drafting). |
There was a problem hiding this comment.
🟡 Changes recommended
Overlay management commands still cannot find uppercase-extension overlays accepted by resolution.
Get a fresh assessment by requesting another Copilot review.
Pull request overview
Updates project overlay discovery to accept case-insensitive YAML extensions.
Changes:
- Normalizes overlay suffixes before matching.
- Adds regression and rejection tests.
File summaries
| File | Description |
|---|---|
src/specify_cli/workflows/overlays/layer_sources.py |
Adds case-insensitive extension matching. |
tests/workflows/test_overlay_layer_sources.py |
Tests mixed-case YAML and rejected extensions. |
Review details
- Files reviewed: 2/2 changed files
- Comments generated: 1
- Review effort level: Balanced
💡 Configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
mnriem
left a comment
There was a problem hiding this comment.
Please address Copilot feedback and resolve conflicts
c8ab0ac to
06f9932
Compare
|
@mnriem Conflicts resolved and feedback addressed (06f9932). Both halves are in:
Verified: 6 new cases fail with both sources reverted to Rebased as a single commit on current |
There was a problem hiding this comment.
Copilot review overview
🟡 Changes recommended
The new multi-command regression test is placed in the list command’s dedicated test suite, contrary to the repository’s mirrored test structure.
Review effort: Balanced
Findings: 1
Open (1)
Resolved since last review (1)
|
Please address Copilot feedback |
`ProjectOverlaySource.collect` matched `path.suffix` verbatim:
if not path.is_file() or path.suffix not in (".yml", ".yaml"):
continue
so a hand-placed overlay named `<id>.YML` or `<id>.Yaml` was skipped and never
applied, with nothing reported to say the file had been ignored. Overlay files
are explicitly hand-authored (docs/reference/workflows.md documents the format
and tells users to write them), so the casing is the author's choice.
Reproduced on main -- three overlays in one directory, differing only in
extension case:
files on disk: ['Mixed.Yaml', 'UPPER.YML', 'lower.yml']
COLLECTED : ['lower']
SKIPPED : ['mixed', 'upper']
Every other YAML discovery path in the package already lowercases before
matching: engine.py:941, _commands.py:1325, :1894, :2128. This brings the
overlay loader in line with them.
Rebased onto current main (files moved in the workflow/bundler restructure).
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
The `_find_overlay_file` regression test drove `disable`, `enable` and
`remove` from `test_command_list.py`, contrary to the mirrored test layout in
design/cli.md ("Command-focused tests mirror the source command surface").
Split it into one focused test per command, in `test_command_disable.py`,
`test_command_enable.py` and `test_command_remove.py`, each parametrized over
`lint.YML` and `lint.Yaml`. `test_command_list.py` is back to its `main`
content. Test-only change; all six new cases fail with the source reverted.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
06f9932 to
324dfef
Compare
|
@mnriem Copilot feedback addressed in 324dfef, and the thread is resolved. Per |
| # lowercasing the suffix and this helper not, a ``<id>.YML`` overlay was | ||
| # ACTIVE during resolution yet reported "not found" by overlay | ||
| # enable / disable / remove -- applied, but impossible to manage. | ||
| if not path.is_file() or path.suffix.lower() not in (".yml", ".yaml"): |
|
Please address Copilot feedback |


Problem
ProjectOverlaySource.collectmatches the extension verbatim:So a hand-placed overlay named
<id>.YMLor<id>.Yamlis skipped and never applied — and nothing is reported to say the file was ignored. Overlay files are explicitly hand-authored (docs/reference/workflows.mddocuments the format and tells users to write them), so the extension casing is the author's choice, not something the tool generated.Reproduction (before the fix)
Three overlays in one directory, differing only in extension case:
The author gets no error and no warning — the overlay simply has no effect.
Why this is the odd one out
Every other YAML discovery path in the package already lowercases before matching:
workflows/engine.py(WorkflowEngine.load_workflow)path.suffix.lower() in (".yml", ".yaml")workflows/command_add.py(two sites)dev_path.suffix.lower()/source_path.suffix.lower()workflows/command_run.pysource_path.suffix.lower() in (...)workflows/overlay/layer_sources.py(ProjectOverlaySource.collect)path.suffix in (...)← this PRworkflows/overlay/operations.py(_find_overlay_file)path.suffix in (...)← this PRFix
Lowercase the suffix in both overlay paths, so the resolver and the management commands agree on which files are overlays:
ProjectOverlaySource.collect— a<id>.YMLoverlay is now applied._find_overlay_file(added at @mnriem's request) — the same overlay is now reachable byworkflow overlay enable/disable/remove. Fixing only the loader would have left it applied, but impossible to manage: every management command reported it "not found".Verification
tests/workflows/test_overlay_layer_sources.py, parametrized over.YML,.Yaml,.YAML,.Yml. All 4 fail with the source reverted tomainand pass with the fix. A companion test asserts that broadening the case did not broaden which extensions are accepted:notes.txt,backup.yml.bak,README.mdanddata.jsonare still skipped.tests/specify_cli/workflows/overlay/test_command_disable.py,test_command_enable.py,test_command_remove.py), each parametrized overlint.YML/lint.Yaml. All 6 fail with the source reverted tomainand pass with the fix.tests/workflows,tests/specify_cli/workflows/overlayandtest_command_resolve.py: 235 passed. The 10 failures are the same pre-existing Windows symlink-privilege tests that fail on unmodifiedmain; none are new.uvx ruff@0.15.0 check src tests→ clean.Behaviour change, disclosed: files previously skipped now get read, and the overlay management commands now find them. If a project already holds a
.YML/.YAMLfile in an overlay directory that is not a valid overlay manifest, resolution will now report it rather than ignoring it — which is the intended outcome, but it is a change for such a project.Written with assistance from Claude Code. Bug found, reproduced, and verified by me on current
main.🤖 Generated with Claude Code