@@ -426,26 +426,34 @@ func (p *sourcePreparerImpl) applyArchiveOverlayGroup(
426426 return repackedArchives , nil
427427}
428428
429- // collectOverlays gathers all overlays for a component into a single ordered slice:
430- // macros-load first, then user overlays, followed by check-skip and file-header overlays.
429+ // collectOverlays gathers all overlays for a component into a single ordered slice: the
430+ // macros-load directive first, then user overlays, then check-skip overlays, then the
431+ // macros source registration, and finally the file-header overlay. The macros source
432+ // registration is deliberately ordered after user overlays so it claims the next free
433+ // source number without colliding with any sources the user added.
431434func (p * sourcePreparerImpl ) collectOverlays (
432435 component components.Component , macrosFileName string ,
433436) ([]projectconfig.ComponentOverlay , error ) {
434437 config := component .GetConfig ()
435438
436- var allOverlays []projectconfig.ComponentOverlay
439+ var (
440+ allOverlays []projectconfig.ComponentOverlay
441+ macroSourceOverlays []projectconfig.ComponentOverlay
442+ )
437443
438444 if macrosFileName != "" {
439- macroOverlays , err := synthesizeMacroLoadOverlays (macrosFileName )
445+ loadDirective , sourceRegistration , err := synthesizeMacroLoadOverlays (macrosFileName )
440446 if err != nil {
441447 return nil , fmt .Errorf ("failed to compute macros load overlays:\n %w" , err )
442448 }
443449
444- allOverlays = append (allOverlays , macroOverlays ... )
450+ allOverlays = append (allOverlays , loadDirective ... )
451+ macroSourceOverlays = sourceRegistration
445452 }
446453
447454 allOverlays = append (allOverlays , config .Overlays ... )
448455 allOverlays = append (allOverlays , synthesizeCheckSkipOverlays (config .Build .Check )... )
456+ allOverlays = append (allOverlays , macroSourceOverlays ... )
449457 allOverlays = append (allOverlays , generateFileHeaderOverlay ()... )
450458
451459 return allOverlays , nil
@@ -1288,19 +1296,25 @@ func renderMacrosFile(macros map[string]string) string {
12881296 return strings .Join (lines , "\n " ) + "\n "
12891297}
12901298
1291- func synthesizeMacroLoadOverlays (macrosFileName string ) ([]projectconfig.ComponentOverlay , error ) {
1299+ // synthesizeMacroLoadOverlays returns the overlays that wire a component's generated
1300+ // macros file into its spec. The load-directive overlay prepends the %{load:...} line; the
1301+ // source-registration overlay adds the macros file as a numbered Source. They are returned
1302+ // separately so the caller can apply the source registration after user overlays, letting
1303+ // it claim the next free source number without colliding with sources the user added.
1304+ func synthesizeMacroLoadOverlays (
1305+ macrosFileName string ,
1306+ ) (loadDirective , sourceRegistration []projectconfig.ComponentOverlay , err error ) {
12921307 // Basic check that the macros file name is valid and doesn't require escaping.
12931308 if strings .ContainsFunc (macrosFileName , func (r rune ) bool {
12941309 return ! unicode .IsLetter (r ) && ! unicode .IsDigit (r ) && r != '.' && r != '-' && r != '_' && r != '+'
12951310 }) {
1296- return nil , fmt .Errorf (
1311+ return nil , nil , fmt .Errorf (
12971312 "macros file name %#q contains invalid characters; does the component name contain invalid characters?" ,
12981313 macrosFileName ,
12991314 )
13001315 }
13011316
1302- // We inject an overlay to prepend a line to the spec to load the macros file.
1303- return []projectconfig.ComponentOverlay {
1317+ loadDirective = []projectconfig.ComponentOverlay {
13041318 {
13051319 // Prepend the %{load:...} directive to the spec.
13061320 Type : projectconfig .ComponentOverlayPrependSpecLines ,
@@ -1311,16 +1325,18 @@ func synthesizeMacroLoadOverlays(macrosFileName string) ([]projectconfig.Compone
13111325 "" ,
13121326 },
13131327 },
1328+ }
1329+
1330+ sourceRegistration = []projectconfig.ComponentOverlay {
13141331 {
13151332 // Ensure that the macros file is manifested as a source in the spec so that
13161333 // mock and other tools know it needs to be present in the build root.
1317- // Use InsertSpecTag to place it after the last existing Source* tag, avoiding
1318- // misplacement after macros like %fontpkg or inside %if conditionals.
1319- Type : projectconfig .ComponentOverlayInsertSpecTag ,
1320- Tag : "Source9999" , // Use a high number to avoid conflicts with existing sources.
1334+ Type : componentOverlayAddSource ,
13211335 Value : macrosFileName ,
13221336 },
1323- }, nil
1337+ }
1338+
1339+ return loadDirective , sourceRegistration , nil
13241340}
13251341
13261342// generateFileHeaderOverlay generates an overlay that prepends a header to the spec.
0 commit comments