fix(overlays): expand overlay files after config resolution#256
Conversation
There was a problem hiding this comment.
Pull request overview
This pull request moves overlay-files glob expansion from raw config-file loading to the component resolution phase, enabling overlay-files to be inherited via default-component-config (project/distro/component-group) and resolved relative to each concrete component (or spec directory for spec-discovered components).
Changes:
- Expand and validate per-file overlay documents during component resolution (
ExpandResolvedOverlayFiles), then clearOverlayFilesto prevent double expansion. - Adjust overlay-file glob semantics: patterns with no matches are treated as a no-op instead of an error, and invalid overlays are validated with clearer per-overlay context.
- Update inheritance behavior so a non-empty
overlay-fileslist overrides inherited values, plus update schema/snapshots/docs/tests to reflect the new behavior.
Reviewed changes
Copilot reviewed 12 out of 12 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| schemas/azldev.schema.json | Updates schema description to reflect post-resolution overlay-file expansion and spec-dir-relative behavior. |
| scenario/snapshots/TestSnapshotsContainer_config_generate-schema_stdout_1.snap | Updates generated schema snapshot description text. |
| scenario/snapshots/TestSnapshots_config_generate-schema_stdout_1.snap | Updates generated schema snapshot description text. |
| internal/projectconfig/overlay_file.go | Replaces loader-time expansion with ExpandResolvedOverlayFiles; changes no-match glob handling; validates overlays during overlay-file parsing. |
| internal/projectconfig/overlay_file_test.go | Updates and expands unit tests for new no-op semantics, per-overlay validation, and post-resolution expansion behavior. |
| internal/projectconfig/loader.go | Removes overlay-file expansion from raw config loading. |
| internal/projectconfig/component.go | Updates OverlayFiles doc/schema tag and changes merge semantics so non-empty overlay-files override inherited values. |
| internal/projectconfig/component_test.go | Adds tests covering overlay-files override vs inheritance behavior in merges. |
| internal/app/azldev/core/components/resolver.go | Expands overlay-files after config inheritance is applied, using an appropriate reference directory (config dir or spec dir). |
| internal/app/azldev/core/components/resolver_test.go | Adds resolver test ensuring spec-discovered components inherit and expand overlay-files defaults correctly. |
| docs/user/reference/config/overlays.md | Updates user docs for new inheritance behavior, reference-dir rules, and no-op no-match semantics. |
| docs/user/reference/config/components.md | Updates component config docs to reflect post-resolution expansion and inheritance semantics. |
6924435 to
4b5f72c
Compare
Tonisal-byte
left a comment
There was a problem hiding this comment.
Good work! Just one small comment
| return nil, fmt.Errorf("failed to scan for overlay files matching %q:\n%w", pattern, err) | ||
| case len(matches) == 0: | ||
| return nil, fmt.Errorf("%w: %q", ErrOverlayFilesNoMatches, pattern) | ||
| continue |
There was a problem hiding this comment.
Should a no-match here really be silent? We dropped ErrOverlayFilesNoMatches, so a typo'd literal path (e.g. overlasy/foo.toml) now applies nothing with no error. Could we keep tolerating real globs but still error on literal paths that match nothing, like containsPattern does for includes in loader.go?
There was a problem hiding this comment.
Agree here, we should at least emit a warning, but ideally there is some way to distinguish between globs that we expect to fail, vs. "real" entries.
There was a problem hiding this comment.
Thanks, fixed. overlay-files now distinguishes literal paths from glob patterns after expansion: missing literal paths return an error, while glob patterns with no matches remain a no-op.
|
|
||
| Set `overlay-files` on the component to one or more globs (relative to the component config) and drop one overlay file per logical change into a directory of your choosing. The conventional layout uses a sibling `overlays/` directory and a `*.overlay.toml` filename suffix, but neither is required — `overlay-files` is just a glob, so any layout you can describe with `**`/`*` patterns works. | ||
|
|
||
| `overlay-files` can also be inherited from `default-component-config` at the project, distro, or component-group level. Inherited relative patterns are still resolved for each concrete component: from its component config file when it has one, or from the matched spec file's directory when it is discovered by a component group's `specs` pattern. This makes defaults useful for component-local discovery patterns such as `overlay-files = ["overlays/*.overlay.toml"]`. If a component sets a non-empty `overlay-files` list, that list replaces the inherited list; include both patterns explicitly when you want to keep default discovery and add component-specific locations. |
There was a problem hiding this comment.
Not your bug but probably should be fixed either here or with a fast follow PR.
Tracing the flow, I think component groups may not work. GroupsByComponent is populated from a group's Componets list. GetComponentGroupByName finds glob'd specs, but aren't written back, and applyInheritedDefaultsToComponent uses the GroupsByComponent[name] map, so a glob'd spec won't get the new overlays.
There was a problem hiding this comment.
Good catch. I fixed this in the resolver by carrying dynamic component-group membership for spec-discovered components into inherited default resolution. I also found and fixed the related direct SpecPaths filter case, where a component resolved by spec path could still miss group defaults.
| return nil, fmt.Errorf("failed to scan for overlay files matching %q:\n%w", pattern, err) | ||
| case len(matches) == 0: | ||
| return nil, fmt.Errorf("%w: %q", ErrOverlayFilesNoMatches, pattern) | ||
| continue |
There was a problem hiding this comment.
Agree here, we should at least emit a warning, but ideally there is some way to distinguish between globs that we expect to fail, vs. "real" entries.
| return fmt.Errorf("failed to merge project info:\n%w", err) | ||
| } | ||
|
|
||
| if len(otherOverlayFiles) > 0 { |
There was a problem hiding this comment.
Should we have a way to make overlay-files = [] in a component override the inherited values? ie we don't want them for some specific package.
There was a problem hiding this comment.
Fixed. overlay-files = [] now explicitly clears inherited overlay-file patterns, while an omitted value still inherits lower-priority defaults and a non-empty value replaces them.
Resolve inherited overlay-file globs only after component defaults are merged so relative patterns can be interpreted for each concrete component. This also consumes the glob list after expansion to avoid duplicate overlay loading.
4b5f72c to
49e2840
Compare
Bump the azldev pin from 4b5f72c to 35d8fae, the merged form of the overlay-files-after-resolution change (microsoft/azure-linux-dev-tools#256). The merged commit incorporates the review follow-ups — notably allowing an empty overlay-files list to disable inherited patterns and clearer literal-path handling. Regenerate external/schemas/azldev.schema.json to match (overlay-files description updated). No lock drift; config loads cleanly. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Pin azldev to 35d8fae562980db7bda057d79322cc51ddad8d62, the merged form of the overlay-files-after-resolution change (microsoft/azure-linux-dev-tools#256). This version supports inheriting overlay-files from a project-wide [default-component-config] and allows an empty overlay-files list to disable inherited patterns. Regenerate external/schemas/azldev.schema.json against the pinned tool so the authoritative schema knows the new metadata / overlay-files / BugRef fields. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
… BEFORE MERGE] TEMPORARY: this commit exists solely so the PR checks run against an azldev build that understands the new overlay-files / metadata / BugRef config. It MUST be reverted before the PR is merged. Pin azldev to 35d8fae562980db7bda057d79322cc51ddad8d62, the merged form of the overlay-files-after-resolution change (microsoft/azure-linux-dev-tools#256). This version supports inheriting overlay-files from a project-wide [default-component-config] and allows an empty overlay-files list to disable inherited patterns. Regenerate external/schemas/azldev.schema.json against the pinned tool so the authoritative schema knows the new metadata / overlay-files / BugRef fields. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Summary
This updates
overlay-filesexpansion so per-file overlay documents are loaded after component config resolution instead of during raw config file loading.That means
overlay-filescan now be declared indefault-component-configat the project, distro, or component-group level and inherited by every applicable component. Relative patterns are interpreted for each concrete component, so a shared default such as:can discover component-local overlay files for each component.
Behavior Changes
Fixed #253