44import static io .quarkus .gradle .workspace .descriptors .ProjectDescriptor .TaskType .RESOURCES ;
55
66import java .io .File ;
7- import java .util .Collections ;
7+ import java .util .ArrayList ;
8+ import java .util .Collection ;
9+ import java .util .HashMap ;
810import java .util .HashSet ;
911import java .util .LinkedHashMap ;
12+ import java .util .List ;
1013import java .util .Map ;
1114import java .util .Set ;
1215import java .util .concurrent .atomic .AtomicReference ;
1619import org .gradle .api .tasks .SourceSet ;
1720import org .gradle .api .tasks .SourceSetContainer ;
1821import org .gradle .api .tasks .compile .AbstractCompile ;
19- import org .gradle .api .tasks .testing .Test ;
2022import org .gradle .language .jvm .tasks .ProcessResources ;
2123import org .jetbrains .kotlin .gradle .tasks .KotlinJvmCompile ;
2224
23- import com .google .common .collect .ImmutableSet ;
25+ import io .quarkus .bootstrap .workspace .ArtifactSources ;
26+ import io .quarkus .bootstrap .workspace .DefaultArtifactSources ;
27+ import io .quarkus .bootstrap .workspace .SourceDir ;
28+ import io .quarkus .bootstrap .workspace .WorkspaceModule ;
29+ import io .quarkus .bootstrap .workspace .WorkspaceModuleId ;
30+ import io .quarkus .maven .dependency .ArtifactCoords ;
2431
2532public class ProjectDescriptorBuilder {
2633
27- private static final Set <String > DEPENDENCY_SOURCE_SETS = ImmutableSet .of (SourceSet .MAIN_SOURCE_SET_NAME ,
28- SourceSet .TEST_SOURCE_SET_NAME , "test-fixtures" );
29-
3034 private final File projectDir ;
3135 private final File buildDir ;
3236 private final File buildFile ;
3337 private final Map <String , QuarkusTaskDescriptor > tasks ;
3438 private final Map <String , Set <String >> sourceSetTasks ;
3539 private final Map <String , Set <String >> sourceSetTasksRaw ;
36- private final Set <String > collectOnlySourceSets ;
3740
38- private ProjectDescriptorBuilder (Project project , Set <String > collectOnlySourceSets ) {
41+ private final WorkspaceModuleId moduleId ;
42+ private final Map <String , ClassifiedSources > classifiedSources = new HashMap <>();
43+
44+ private ProjectDescriptorBuilder (Project project ) {
3945 this .tasks = new LinkedHashMap <>();
4046 this .sourceSetTasks = new LinkedHashMap <>();
4147 this .sourceSetTasksRaw = new LinkedHashMap <>();
48+ this .moduleId = WorkspaceModuleId .of (String .valueOf (project .getGroup ()), project .getName (),
49+ String .valueOf (project .getVersion ()));
4250 this .buildFile = project .getBuildFile ();
4351 this .projectDir = project .getLayout ().getProjectDirectory ().getAsFile ();
4452 this .buildDir = project .getLayout ().getBuildDirectory ().get ().getAsFile ();
45- this .collectOnlySourceSets = collectOnlySourceSets ;
4653 }
4754
48- public static Provider <DefaultProjectDescriptor > buildForApp (Project target ) {
49- ProjectDescriptorBuilder builder = new ProjectDescriptorBuilder (target , Collections .emptySet ());
50- target .afterEvaluate (project -> {
51- project .getTasks ().withType (AbstractCompile .class )
52- .configureEach (builder ::readConfigurationFor );
53- builder .withKotlinJvmCompileType (project );
54- project .getTasks ().withType (ProcessResources .class )
55- .configureEach (builder ::readConfigurationFor );
56- project .getTasks ().withType (Test .class )
57- .configureEach (builder ::readConfigurationFor );
55+ public static Provider <DefaultProjectDescriptor > buildForApp (Project project ) {
56+ final ProjectDescriptorBuilder builder = new ProjectDescriptorBuilder (project );
57+ project .afterEvaluate (evaluated -> {
58+ evaluated .getTasks ().withType (AbstractCompile .class ).configureEach (builder ::readConfigurationFor );
59+ builder .withKotlinJvmCompileType (evaluated );
60+ project .getTasks ().withType (ProcessResources .class ).configureEach (builder ::readConfigurationFor );
5861 });
59- return target .getProviders ().provider (() -> new DefaultProjectDescriptor (
60- builder .projectDir ,
61- builder .buildDir ,
62- builder .buildFile ,
63- builder .tasks ,
64- builder .sourceSetTasks ,
65- builder .sourceSetTasksRaw ));
66- }
6762
68- public static Provider <DefaultProjectDescriptor > buildForDependency (Project target ) {
69- ProjectDescriptorBuilder builder = new ProjectDescriptorBuilder (target , DEPENDENCY_SOURCE_SETS );
70- target .afterEvaluate (project -> {
71- project .getTasks ().withType (AbstractCompile .class )
72- .configureEach (builder ::readConfigurationFor );
73- builder .withKotlinJvmCompileType (project );
74- project .getTasks ().withType (ProcessResources .class )
75- .configureEach (builder ::readConfigurationFor );
63+ return project .getProviders ().provider (() -> {
64+
65+ var moduleBuilder = WorkspaceModule .builder ()
66+ .setModuleId (builder .moduleId )
67+ .setBuildFile (builder .buildFile .toPath ())
68+ .setBuildDir (builder .buildDir .toPath ())
69+ .setModuleDir (builder .projectDir .toPath ());
70+
71+ for (var classifiedSources : builder .classifiedSources .values ()) {
72+ moduleBuilder .addArtifactSources (classifiedSources .toArtifactSources ());
73+ }
74+
75+ return new DefaultProjectDescriptor (
76+ builder .projectDir ,
77+ builder .buildDir ,
78+ builder .buildFile ,
79+ builder .tasks ,
80+ builder .sourceSetTasks ,
81+ builder .sourceSetTasksRaw ,
82+ moduleBuilder );
7683 });
77- return target .getProviders ().provider (() -> new DefaultProjectDescriptor (
78- builder .projectDir ,
79- builder .buildDir ,
80- builder .buildFile ,
81- builder .tasks ,
82- builder .sourceSetTasks ,
83- builder .sourceSetTasksRaw ));
84+
8485 }
8586
8687 private void readConfigurationFor (AbstractCompile task ) {
@@ -95,18 +96,17 @@ private void readConfigurationFor(AbstractCompile task) {
9596 tasks .put (task .getName (), new QuarkusTaskDescriptor (task .getName (), COMPILE , srcDir , destDir ));
9697 SourceSetContainer sourceSets = task .getProject ().getExtensions ().getByType (SourceSetContainer .class );
9798 sourceSets .stream ().filter (sourceSet -> sourceSet .getOutput ().getClassesDirs ().contains (destDir ))
98- .forEach (sourceSet -> sourceSetTasks
99- .computeIfAbsent (sourceSet .getName (), s -> new HashSet <>())
100- .add (task .getName ()));
99+ .forEach (sourceSet -> {
100+ sourceSetTasks .computeIfAbsent (sourceSet .getName (), s -> new HashSet <>()).add (task .getName ());
101+ classifiedSources .computeIfAbsent (getClassifier (sourceSet ), ClassifiedSources ::new )
102+ .addSources (srcDir , destDir );
103+ });
101104 fileVisitDetails .stopVisiting ();
102105 }
103106 });
104107 }
105108 }
106109
107- private void readConfigurationFor (Test task ) {
108- }
109-
110110 private void readConfigurationFor (ProcessResources task ) {
111111 if (task .getEnabled () && !task .getSource ().isEmpty ()) {
112112 File destDir = task .getDestinationDir ();
@@ -116,9 +116,11 @@ private void readConfigurationFor(ProcessResources task) {
116116 tasks .put (task .getName (), new QuarkusTaskDescriptor (task .getName (), RESOURCES , srcDir , destDir ));
117117 SourceSetContainer sourceSets = task .getProject ().getExtensions ().getByType (SourceSetContainer .class );
118118 sourceSets .stream ().filter (sourceSet -> destDir .equals (sourceSet .getOutput ().getResourcesDir ()))
119- .forEach (sourceSet -> sourceSetTasks
120- .computeIfAbsent (sourceSet .getName (), s -> new HashSet <>())
121- .add (task .getName ()));
119+ .forEach (sourceSet -> {
120+ sourceSetTasks .computeIfAbsent (sourceSet .getName (), s -> new HashSet <>()).add (task .getName ());
121+ classifiedSources .computeIfAbsent (getClassifier (sourceSet ), ClassifiedSources ::new )
122+ .addResources (srcDir , destDir );
123+ });
122124 fileVisitDetails .stopVisiting ();
123125 }
124126 });
@@ -147,9 +149,75 @@ private void readConfigurationFor(KotlinJvmCompile task) {
147149 tasks .put (task .getName (), new QuarkusTaskDescriptor (task .getName (), COMPILE , srcDir .get (), destDir ));
148150 SourceSetContainer sourceSets = task .getProject ().getExtensions ().getByType (SourceSetContainer .class );
149151 sourceSets .stream ().filter (sourceSet -> sourceSet .getOutput ().getClassesDirs ().contains (destDir ))
150- .forEach (sourceSet -> sourceSetTasks
151- .computeIfAbsent (sourceSet .getName (), s -> new HashSet <>())
152- .add (task .getName ()));
152+ .forEach (sourceSet -> {
153+ sourceSetTasks .computeIfAbsent (sourceSet .getName (), s -> new HashSet <>()).add (task .getName ());
154+ classifiedSources .computeIfAbsent (getClassifier (sourceSet ), ClassifiedSources ::new )
155+ .addSources (srcDir .get (), destDir );
156+ });
153157 }
154158 }
159+
160+ private static String getClassifier (SourceSet sourceSet ) {
161+ return switch (sourceSet .getName ()) {
162+ case SourceSet .MAIN_SOURCE_SET_NAME -> ArtifactCoords .DEFAULT_CLASSIFIER ;
163+ case SourceSet .TEST_SOURCE_SET_NAME -> "tests" ;
164+ case "testFixtures" -> "test-fixtures" ;
165+ default -> sourceSet .getName ();
166+ };
167+ }
168+
169+ private static class ClassifiedSources {
170+ private final String classifier ;
171+ private final List <SourceOutputDir > sources = new ArrayList <>(1 );
172+ private final List <SourceOutputDir > resources = new ArrayList <>(1 );
173+
174+ public ClassifiedSources (String classifier ) {
175+ this .classifier = classifier ;
176+ }
177+
178+ private void addSources (File src , File output ) {
179+ addIfNotPresent (sources , src , output );
180+ }
181+
182+ private void addResources (File src , File output ) {
183+ addIfNotPresent (resources , src , output );
184+ }
185+
186+ private static Collection <SourceDir > toSourceDir (List <SourceOutputDir > dirs ) {
187+ if (dirs .isEmpty ()) {
188+ return List .of ();
189+ }
190+ if (dirs .size () == 1 ) {
191+ return List .of (dirs .get (0 ).toSourceDir ());
192+ }
193+ final List <SourceDir > result = new ArrayList <>(dirs .size ());
194+ for (var dir : dirs ) {
195+ result .add (dir .toSourceDir ());
196+ }
197+ return result ;
198+ }
199+
200+ private ArtifactSources toArtifactSources () {
201+ return new DefaultArtifactSources (classifier , toSourceDir (sources ), toSourceDir (resources ));
202+ }
203+
204+ private static void addIfNotPresent (List <SourceOutputDir > resources , File src , File output ) {
205+ if (resources .isEmpty ()) {
206+ resources .add (new SourceOutputDir (src , output ));
207+ } else {
208+ for (var added : resources ) {
209+ if (added .src ().equals (src )) {
210+ return ;
211+ }
212+ }
213+ resources .add (new SourceOutputDir (src , output ));
214+ }
215+ }
216+ }
217+
218+ private record SourceOutputDir (File src , File output ) {
219+ private SourceDir toSourceDir () {
220+ return SourceDir .of (src .toPath (), output .toPath ());
221+ }
222+ };
155223}
0 commit comments