Drafted by GitHub Copilot CLI while reviewing PR #132.
Spec.RemoveSection and Spec.RemoveSubpackage (internal/rpm/spec/edit.go) operate on whole-section line ranges and have no awareness of %if/%endif conditionals. When a section is wrapped in a conditional block, the %endif is typically consumed as part of the trailing removed section, while the matching %if remains in place. The result is a syntactically invalid spec written to disk; the build then fails far away with a confusing error.
This limitation is honestly documented for both overlays in docs/user/reference/config/overlays.md and in the Go doc-comment on RemoveSubpackage, but the API still returns nil and silently writes a broken spec.
Reproduction
Name: test
Version: 1.0
%description
Main.
%if 0%{?with_devel}
%package devel
Summary: Devel files
%description devel
Devel description.
%files devel
/usr/include/test.h
%endif
%files
/usr/bin/test
Applying:
[[components.test.overlays]]
type = "spec-remove-subpackage"
package = "devel"
…produces:
Name: test
Version: 1.0
%description
Main.
%if 0%{?with_devel}
%files
/usr/bin/test
The %endif was consumed as part of the trailing %files devel section (it sits between that section header and the next section header), and the %if is now unbalanced.
Proposed fix
Spec.collectSectionRanges already runs inside Visit, whose context tracks conditionalDepthChange. Detect ranges that:
- Start at non-zero conditional depth, or
- Have a non-zero net conditional balance change across the range.
In either case, return a clear, actionable error (e.g. "section %q (package=%q) is wrapped in %if/%endif; remove the conditional first or use spec-search-replace") instead of writing invalid output.
Apply uniformly to RemoveSection and RemoveSubpackage. After the fix, update the limitation prose in docs/user/reference/config/overlays.md to describe the new failure mode (clear error at overlay-application time) rather than the silent-corruption mode.
Workaround until fixed
Use a spec-search-replace overlay to remove the conditional block, or remove the %if/%endif first via additional overlays before applying the section/sub-package removal.
Spec.RemoveSectionandSpec.RemoveSubpackage(internal/rpm/spec/edit.go) operate on whole-section line ranges and have no awareness of%if/%endifconditionals. When a section is wrapped in a conditional block, the%endifis typically consumed as part of the trailing removed section, while the matching%ifremains in place. The result is a syntactically invalid spec written to disk; the build then fails far away with a confusing error.This limitation is honestly documented for both overlays in
docs/user/reference/config/overlays.mdand in the Go doc-comment onRemoveSubpackage, but the API still returnsniland silently writes a broken spec.Reproduction
Applying:
…produces:
The
%endifwas consumed as part of the trailing%files develsection (it sits between that section header and the next section header), and the%ifis now unbalanced.Proposed fix
Spec.collectSectionRangesalready runs insideVisit, whose context tracksconditionalDepthChange. Detect ranges that:In either case, return a clear, actionable error (e.g. "section %q (package=%q) is wrapped in %if/%endif; remove the conditional first or use spec-search-replace") instead of writing invalid output.
Apply uniformly to
RemoveSectionandRemoveSubpackage. After the fix, update the limitation prose indocs/user/reference/config/overlays.mdto describe the new failure mode (clear error at overlay-application time) rather than the silent-corruption mode.Workaround until fixed
Use a
spec-search-replaceoverlay to remove the conditional block, or remove the%if/%endiffirst via additional overlays before applying the section/sub-package removal.