Skip to content

Commit 882a102

Browse files
committed
fix: Module selection with -m now expands POM aggregators to children
When -m selects a nested aggregator (packaging=pom), the build now includes all child modules under that aggregator plus their transitive dependencies, matching Maven 4 behaviour. Previously, the filter naively included all modules preceding the selected one in the topological sort, which pulled in unrelated modules like docview and uidesigner when selecting fpgui-examples. The filter logic is moved from TReactorCommand to TModuleRegistry.FilterBuildOrder for testability.
1 parent 201ee5f commit 882a102

File tree

3 files changed

+307
-61
lines changed

3 files changed

+307
-61
lines changed

src/main/pascal/PasBuild.Command.Reactor.pas

Lines changed: 2 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -128,69 +128,10 @@ procedure TReactorCommand.DisplayDependencyGraph;
128128
end;
129129

130130
procedure TReactorCommand.FilterBuildOrderForSelectedModule(var BuildOrder: TList);
131-
var
132-
I: Integer;
133-
Module: TModuleInfo;
134-
SelectedModuleInfo: TModuleInfo;
135-
FilteredOrder: TList;
136-
IncludeModule: Boolean;
137131
begin
138-
{ Find the selected module by name }
139-
SelectedModuleInfo := nil;
140-
for I := 0 to FRegistry.Modules.Count - 1 do
141-
begin
142-
Module := TModuleInfo(FRegistry.Modules[I]);
143-
if CompareText(Module.Name, FSelectedModule) = 0 then
144-
begin
145-
SelectedModuleInfo := Module;
146-
Break;
147-
end;
148-
end;
149-
150-
if SelectedModuleInfo = nil then
151-
begin
132+
FRegistry.FilterBuildOrder(BuildOrder, FSelectedModule);
133+
if BuildOrder.Count = 0 then
152134
TUtils.LogError('Module not found: ' + FSelectedModule);
153-
{ Clear build order to signal error }
154-
BuildOrder.Clear;
155-
Exit;
156-
end;
157-
158-
{ Filter: Keep only modules that the selected module depends on (and the selected module itself) }
159-
{ The build order is topologically sorted, so all dependencies come before the selected module }
160-
FilteredOrder := TList.Create;
161-
try
162-
for I := 0 to BuildOrder.Count - 1 do
163-
begin
164-
Module := TModuleInfo(BuildOrder[I]);
165-
IncludeModule := False;
166-
167-
{ Include the selected module itself }
168-
if CompareText(Module.Name, FSelectedModule) = 0 then
169-
IncludeModule := True
170-
{ Include if this module is a (direct or transitive) dependency of the selected module }
171-
{ Since build order is sorted, we only include modules up to and including selected }
172-
else
173-
begin
174-
{ Check if this module is transitively needed by selected module }
175-
{ For now, include all modules that come before selected in build order }
176-
IncludeModule := True;
177-
end;
178-
179-
if IncludeModule then
180-
FilteredOrder.Add(Module);
181-
182-
{ Stop once we've added the selected module }
183-
if CompareText(Module.Name, FSelectedModule) = 0 then
184-
Break;
185-
end;
186-
187-
{ Replace build order with filtered order }
188-
BuildOrder.Clear;
189-
for I := 0 to FilteredOrder.Count - 1 do
190-
BuildOrder.Add(FilteredOrder[I]);
191-
finally
192-
FilteredOrder.Free;
193-
end;
194135
end;
195136

196137
function TReactorCommand.Execute: Integer;

src/main/pascal/PasBuild.Types.pas

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -230,6 +230,7 @@ TModuleRegistry = class
230230
function FindModuleByName(const AName: string): TModuleInfo;
231231
function FindModuleByPath(const APath: string): TModuleInfo;
232232
function GetBuildOrder: TList;
233+
procedure FilterBuildOrder(var ABuildOrder: TList; const ASelectedModule: string);
233234
procedure ResolveArtifacts(AModule: TModuleInfo);
234235

235236
property Modules: TObjectList read FModules;
@@ -565,6 +566,85 @@ function TModuleRegistry.GetBuildOrder: TList;
565566
end;
566567
end;
567568

569+
procedure TModuleRegistry.FilterBuildOrder(var ABuildOrder: TList; const ASelectedModule: string);
570+
571+
procedure CollectTransitiveDeps(const AModuleName: string; ANeeded: TStringList);
572+
var
573+
Module: TModuleInfo;
574+
I: Integer;
575+
begin
576+
if ANeeded.IndexOf(AModuleName) >= 0 then
577+
Exit;
578+
ANeeded.Add(AModuleName);
579+
580+
Module := FindModuleByName(AModuleName);
581+
if Module = nil then
582+
Exit;
583+
584+
for I := 0 to Module.Dependencies.Count - 1 do
585+
CollectTransitiveDeps(Module.Dependencies[I], ANeeded);
586+
end;
587+
588+
var
589+
SelectedModuleInfo: TModuleInfo;
590+
Needed: TStringList;
591+
FilteredOrder: TList;
592+
Module: TModuleInfo;
593+
I: Integer;
594+
begin
595+
SelectedModuleInfo := FindModuleByName(ASelectedModule);
596+
if SelectedModuleInfo = nil then
597+
begin
598+
ABuildOrder.Clear;
599+
Exit;
600+
end;
601+
602+
Needed := TStringList.Create;
603+
try
604+
Needed.Duplicates := dupIgnore;
605+
Needed.Sorted := True;
606+
607+
{ If selected module is an aggregator (POM), expand to its child modules (Maven 4 behaviour) }
608+
if (SelectedModuleInfo.Config <> nil) and
609+
(SelectedModuleInfo.Config.BuildConfig.ProjectType = ptPom) then
610+
begin
611+
{ Add the aggregator itself (will be skipped at build time, but shown in summary) }
612+
Needed.Add(ASelectedModule);
613+
614+
{ Find all modules whose path is under this aggregator's path }
615+
for I := 0 to FModules.Count - 1 do
616+
begin
617+
Module := TModuleInfo(FModules[I]);
618+
if Pos(ExcludeTrailingPathDelimiter(SelectedModuleInfo.Path) + DirectorySeparator,
619+
Module.Path) = 1 then
620+
CollectTransitiveDeps(Module.Name, Needed);
621+
end;
622+
end
623+
else
624+
{ Non-aggregator: just collect the module and its transitive dependencies }
625+
CollectTransitiveDeps(ASelectedModule, Needed);
626+
627+
{ Filter build order to only include needed modules, preserving topological order }
628+
FilteredOrder := TList.Create;
629+
try
630+
for I := 0 to ABuildOrder.Count - 1 do
631+
begin
632+
Module := TModuleInfo(ABuildOrder[I]);
633+
if Needed.IndexOf(Module.Name) >= 0 then
634+
FilteredOrder.Add(Module);
635+
end;
636+
637+
ABuildOrder.Clear;
638+
for I := 0 to FilteredOrder.Count - 1 do
639+
ABuildOrder.Add(FilteredOrder[I]);
640+
finally
641+
FilteredOrder.Free;
642+
end;
643+
finally
644+
Needed.Free;
645+
end;
646+
end;
647+
568648
procedure TModuleRegistry.ResolveArtifacts(AModule: TModuleInfo);
569649
var
570650
VisitedModules: TStringList;

0 commit comments

Comments
 (0)