When generating IntelliJ IDEA run configurations (using the genIntellijRuns command) for a multi-project where the IDEA project is configured to build and test using IntelliJ rather than Gradle and the run configs contain source sets from other subprojects, two issues would occur:
The output folders for the other projects' source sets in the MOD_CLASSES environment folder, derived based on IntelliJ's default settings when building and testing using IntelliJ, would have the wrong parent location. Instead of using the correct directory of the other project to which the source set belongs, the directory used instead is of the same project where ForgeGradle is applied to.
This is fixed by using a solution similar to the one used in EclipseRunGenerator#mapModClassesToEclipse (added by #828): maintaining a map of source sets to source-set-specific data. In this case, the source-set-specific data stored in the map is the Project which owns the source set. This map is then queried later on for the source set's owning project and used instead of the previous behavior of using the project where ForgeGradle is applied to.
The output folders for the other projects' main source set in the MOD_CLASSES environment folder used the main identifier, rather than the special-cased production identifier[^1]. For example, for a project Boop's main source set, the output folder for classes would (incorrectly) be calculated as $PROJECT_DIR$/Boop/out/main/classes (assuming the above first issue is fixed).
This is fixed by replacing the instance comparison with checking the source set's name if it equals to main (from the constant SourceSet.MAIN_SOURCE_SET_NAME).
Additionally, #getIdeaPathsForSourceset was modified to use the information from IdeaModule and $MODULE_DIR$ instead of from IdeaProject and $PROJECT_DIR$. This is because of two reasons:
The IdeaProject is only present and non-null on the IdeaModel of the root project. This causes issues when, because of the above changes, a subproject is passed to the method with a present IdeaModel (because of the application of the IDEA plugin previous) but a null IdeaProject, causing a NullPointerException when trying to invoke IdeaProject#getPathFactory.[^2]
$PROJECT_DIR$ resolves to the directory of the root project, which means incorrect calculation of the output folder (because the output folder of a subproject exists under the subproject's directory). Changing to $MODULE_DIR fixes this (in conjunction with the above required change to use IdeaModel), as this properly points to the subproject's directory.[^3]
Finally, some miscellaneous cleanup was performed on IntellijRunGenerator to remove cruft and resolve warnings.
[^1]: By default, IntelliJ IDEA (when configured to build the project instead of Gradle) outputs the classes and resources of the main source set to out/production, and the classes and resources of the test source set to out/test.
[^2]: A NullPointerException never occurred previously here because neither ForgeGradle nor IntelliJ IDEA (at least, in my investigations) applied the IDEA plugin to the subproject. This meant that IdeaModel would be null, and therefore the (null) IdeaProject would not be queried or invoked.
[^3]: It should be noted that there is a difference in terminology between IntelliJ and Gradle which should be noted for this: an IntelliJ project is better mapped as the whole Gradle build (or root project at least), while an IntelliJ module is better mapped as a single Gradle project (whether the root project or a subproject thereof).
When generating IntelliJ IDEA run configurations (using the
genIntellijRuns
command) for a multi-project where the IDEA project is configured to build and test using IntelliJ rather than Gradle and the run configs contain source sets from other subprojects, two issues would occur:The output folders for the other projects' source sets in the
MOD_CLASSES
environment folder, derived based on IntelliJ's default settings when building and testing using IntelliJ, would have the wrong parent location. Instead of using the correct directory of the other project to which the source set belongs, the directory used instead is of the same project where ForgeGradle is applied to.This is fixed by using a solution similar to the one used in
EclipseRunGenerator#mapModClassesToEclipse
(added by #828): maintaining a map of source sets to source-set-specific data. In this case, the source-set-specific data stored in the map is theProject
which owns the source set. This map is then queried later on for the source set's owning project and used instead of the previous behavior of using the project where ForgeGradle is applied to.The output folders for the other projects' main source set in the
MOD_CLASSES
environment folder used themain
identifier, rather than the special-casedproduction
identifier[^1]. For example, for a projectBoop
's main source set, the output folder for classes would (incorrectly) be calculated as$PROJECT_DIR$/Boop/out/main/classes
(assuming the above first issue is fixed).This is fixed by replacing the instance comparison with checking the source set's name if it equals to
main
(from the constantSourceSet.MAIN_SOURCE_SET_NAME
).Additionally,
#getIdeaPathsForSourceset
was modified to use the information fromIdeaModule
and$MODULE_DIR$
instead of fromIdeaProject
and$PROJECT_DIR$
. This is because of two reasons:The
IdeaProject
is only present and non-null on theIdeaModel
of the root project. This causes issues when, because of the above changes, a subproject is passed to the method with a presentIdeaModel
(because of the application of the IDEA plugin previous) but a nullIdeaProject
, causing aNullPointerException
when trying to invokeIdeaProject#getPathFactory
.[^2]$PROJECT_DIR$
resolves to the directory of the root project, which means incorrect calculation of the output folder (because the output folder of a subproject exists under the subproject's directory). Changing to$MODULE_DIR
fixes this (in conjunction with the above required change to useIdeaModel
), as this properly points to the subproject's directory.[^3]Finally, some miscellaneous cleanup was performed on
IntellijRunGenerator
to remove cruft and resolve warnings.[^1]: By default, IntelliJ IDEA (when configured to build the project instead of Gradle) outputs the classes and resources of the main source set to
out/production
, and the classes and resources of the test source set toout/test
. [^2]: ANullPointerException
never occurred previously here because neither ForgeGradle nor IntelliJ IDEA (at least, in my investigations) applied the IDEA plugin to the subproject. This meant thatIdeaModel
would be null, and therefore the (null)IdeaProject
would not be queried or invoked. [^3]: It should be noted that there is a difference in terminology between IntelliJ and Gradle which should be noted for this: an IntelliJ project is better mapped as the whole Gradle build (or root project at least), while an IntelliJ module is better mapped as a single Gradle project (whether the root project or a subproject thereof).