Skip to content

feat(overlays): add spec-set-macros overlay#134

Draft
reubeno wants to merge 1 commit intomicrosoft:mainfrom
reubeno:feat/spec-set-macros
Draft

feat(overlays): add spec-set-macros overlay#134
reubeno wants to merge 1 commit intomicrosoft:mainfrom
reubeno:feat/spec-set-macros

Conversation

@reubeno
Copy link
Copy Markdown
Member

@reubeno reubeno commented Apr 29, 2026

Summary

Adds a new declarative overlay type, spec-set-macros, for setting %global / %define macro values in RPM spec files. This replaces ~25 fragile spec-search-replace regex toggles across azurelinuxgcc.comp.toml alone has 8 such macro flips today.

Before

[[components.gcc.overlays]]
description = "Disable Ada frontend; not supported on AZL toolchain"
type = "spec-search-replace"
regex = '^%global build_ada 1$'
replacement = '%global build_ada 0'

# … 7 more nearly-identical blocks in the same file …

After

[[components.gcc.overlays]]
description = "Disable language frontends and offload targets not supported on AZL toolchain"
type = "spec-set-macros"
macros = {
    build_ada           = { value = "0" },
    build_objc          = { value = "0" },
    build_go            = { value = "0" },
    build_d             = { value = "0" },
    build_m2            = { value = "0" },
    build_cobol         = { value = "0" },
    build_offload_nvptx = { value = "0" },
    build_offload_amdgcn = { value = "0" },
}

Behavior

  • The overlay accepts a map of macro names → settings; each entry has a required value and an optional kind (global or define) that forces a specific directive form.
  • The directive form is auto-detected from the existing spec — users don't need to know whether upstream uses %global or %define.
  • Fails if any named macro is not present in the spec — catches typos and upstream removals (a key advantage over silent regex no-ops).
  • Multiple occurrences of the same macro are all updated; per-macro iteration order is sorted for deterministic rendering.
  • Indentation of the original line is preserved (e.g., a %global inside an %if block stays indented). Inter-token whitespace is normalized to single spaces.

Implementation notes / divergences from the design doc

The design doc lives at the repository's TODO/01-spec-set-macros.md (not part of this PR). A few intentional divergences:

  1. No inline-comment preservation. RPM does not treat # mid-line on %global / %define lines as a comment — the # and everything after it is part of the macro value. "Preserving" a trailing # comment as the design doc suggested would silently truncate legitimate values. We just replace the value portion in full.
  2. ErrNoSuchMacro in the spec package rather than wrapping ErrOverlayDidNotApply. This matches the existing ErrNoSuchTag / ErrPatternNotFound convention in internal/rpm/spec/edit.go.
  3. Stricter post-name match guard (\s|$) instead of \b. A request for build_ada would otherwise match %define build_ada() (function-like macro) or %global build_adapter (shared prefix). The custom guard avoids this.
  4. Multi-line definitions rejected rather than rewritten. Lines ending in \ continuation get a clear ErrUnsupportedMacroDefinition error; a single-line rewrite would orphan continuation lines.
  5. Macro-name validation at config load: reject empty, whitespace, %, or parentheses. Multi-line values are also rejected at load time.
  6. No section / sub-package scoping in v1. Macros are typically top-level in real specs; can be added later if needed.

Testing

  • 14 new SetMacro unit tests (internal/rpm/spec/edit_test.go) covering shared-prefix non-match, function-like non-match, multi-line rejection, kind override, multiple occurrences, whitespace tolerance, value-with-spaces, indentation preservation.
  • 10 new validation cases (internal/projectconfig/overlay_test.go) for the new schema.
  • 5 new integration cases (internal/app/azldev/core/sources/overlays_test.go) exercising the full overlay-application path including the multi-macro gcc-style case.
  • mage fix all, mage check all, mage unit, mage build all pass locally.
  • Schema (schemas/azldev.schema.json) regenerated.

Migration

Out of scope for this PR; a follow-up PR in azurelinux will migrate the affected *.comp.toml files (gcc, qemu, firefox, libsoup3, grub2, nbdkit, systemd, the python-* docs toggles, etc.).

Coordination

Independent of TODO 02 (spec-insert-lines-after/before + match cardinality) and TODO 03 (spec-deps). No ordering required between them.

Copilot AI review requested due to automatic review settings April 29, 2026 20:39
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a new spec-set-macros overlay to declaratively update RPM %global / %define macro definitions in spec files, reducing reliance on fragile regex-based spec-search-replace overlays.

Changes:

  • Introduces spec-set-macros overlay type with config/schema support (macros map with optional kind).
  • Implements Spec.SetMacro() in the RPM spec editor and wires it into overlay application with deterministic macro application order.
  • Updates user-facing config docs and regenerates the JSON schema.

Reviewed changes

Copilot reviewed 8 out of 8 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
schemas/azldev.schema.json Adds schema support for spec-set-macros and MacroSetSpec.
internal/rpm/spec/edit.go Adds SetMacro editing primitive + new macro-related errors.
internal/rpm/spec/edit_test.go Adds unit tests for SetMacro.
internal/projectconfig/overlay.go Adds overlay config fields/types + validation for macro setting entries.
internal/projectconfig/overlay_test.go Adds validation tests + marks new overlay as spec-modifying.
internal/app/azldev/core/sources/overlays.go Applies spec-set-macros overlays in stable sorted order.
internal/app/azldev/core/sources/overlays_test.go Adds integration tests for applying macro overlays end-to-end.
docs/user/reference/config/overlays.md Documents the new overlay type and configuration.

Comment thread internal/rpm/spec/edit.go
Comment thread internal/rpm/spec/edit.go Outdated
Comment thread internal/projectconfig/overlay.go
Adds a new declarative overlay type for setting %global / %define macro
values in RPM spec files, replacing ~25 fragile spec-search-replace
regex toggles across azurelinux (gcc alone has 8 macro toggles).

The overlay accepts a map of macro names to settings and updates each
existing macro definition in place. The directive form (%global vs
%define) is auto-detected from the spec; an optional `kind` field
forces a specific form. The overlay fails if any named macro is not
present in the spec, catching typos and upstream removals.

Implementation notes / divergences from the design doc:

- No inline-comment preservation. RPM does not treat `#` mid-line on
  %global/%define lines as a comment, so "preserving" trailing `#`
  text would silently truncate legitimate macro values.
- Uses a new ErrNoSuchMacro in the spec package rather than wrapping
  ErrOverlayDidNotApply, matching the existing ErrNoSuchTag /
  ErrPatternNotFound convention in internal/rpm/spec/edit.go.
- Stricter post-name match guard `(\s|$)` instead of `\b` so a request
  for `build_ada` does not match `%define build_ada()` (function-like
  macro) or `%global build_adapter` (shared prefix).
- Multi-line definitions (lines ending in `\` continuation) are
  detected and rejected with ErrUnsupportedMacroDefinition rather than
  silently corrupting the spec by orphaning continuation lines.
- Macro-name validation (no whitespace, `%`, or parentheses) and
  multi-line value rejection happen at config load time.
- Multiple occurrences of the same macro are all updated; per-macro
  iteration order is sorted for deterministic rendering.
- No section / sub-package scoping in v1 since macros are typically
  at top level in real specs; can be added later if a need arises.

Tests: 14 SetMacro unit tests (incl. shared-prefix, function-like,
multi-line, kind override, multiple occurrences), 10 new validation
cases, 5 new integration cases.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@reubeno reubeno force-pushed the feat/spec-set-macros branch from 4d612d2 to e9dce20 Compare April 29, 2026 21:48
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants