jdaugherty commented on code in PR #432:
URL:
https://github.com/apache/grails-intellij-plugin/pull/432#discussion_r4191542891
##########
plugin/src/main/java/org/apache/grails/intellij/plugin/projectView/impl/Grails3NodeProvider.java:
##########
@@ -77,4 +118,52 @@ public class Grails3NodeProvider implements
GrailsViewNodeProvider {
result.add(new GrailsPluginsNode(application.getProject(), settings));
return result;
}
+
+ /**
+ * Discovers the test source roots to lift out of {@code src}. {@code
ProjectFileIndex} is consulted
+ * first, but only as positive evidence: a module registers the whole
content root as one SOURCE root,
+ * so it reports a non-test type for every candidate — including in this
project's own light fixture —
+ * and on its own would lift nothing. The structural rule below is therefore
the heuristic that
+ * carries discovery wherever the module does not register each phase as its
own test source root.
+ */
+ private static @NotNull List<PsiDirectory>
findTestSourceDirectories(@NotNull PsiDirectory src) {
+ ProjectFileIndex index = ProjectFileIndex.getInstance(src.getProject());
+ List<PsiDirectory> result = new ArrayList<>();
+ for (VirtualFile child : src.getVirtualFile().getChildren()) {
+ if (!child.isDirectory() || !isTestSourceRoot(index, child)) continue;
+ PsiDirectory directory =
PsiManager.getInstance(src.getProject()).findDirectory(child);
+ if (directory != null) result.add(directory);
+ }
+ return result;
+ }
+
+ private static boolean isTestSourceRoot(@NotNull ProjectFileIndex index,
@NotNull VirtualFile child) {
+ JpsModuleSourceRootType<?> type = index.getContainingSourceRootType(child);
+ if (type != null && type.isForTests()) return true;
+ // src/main is the production root, and a built-in phase is a test root
whatever it holds. Any other
+ // child qualifies only on the shape of a Grails source root: it holds a
conventional code source
+ // directory, which is what a custom testPhases entry generates.
+ //
+ // This rule assumes every non-main code-source root under src is a phase.
A project with a
+ // non-standard production root there (src/legacy/groovy, say) has it
lifted out of src and labelled
+ // Tests:legacy. Skipping the rule when the index reports a production
root would not help: Gradle
+ // registers the whole content root as one SOURCE root, so the index
reports non-test for every
+ // candidate and the rule would stop lifting anything at all.
+ String name = child.getName();
+ if ("main".equals(name)) return false;
+ if (PHASE_TITLES.containsKey(name)) return true;
+ for (VirtualFile grandChild : child.getChildren()) {
+ if (grandChild.isDirectory() &&
CODE_SOURCE_DIRS.contains(grandChild.getName())) return true;
Review Comment:
[P2] Discover custom phases from the registered source roots
The shape-based fallback moves production code into the test section even
when the IDE knows it is production. I reproduced this by adding
`src/generated/java/GeneratedClient.java` and registering `src/generated/java`
as `JavaSourceRootType.SOURCE`: `createNodes()` still emits `Tests:generated`,
and the `src` filter excludes that directory.
The index lookup above checks `src/generated`, not the registered root below
it. This also causes the opposite failure: registering
`src/smoke-test/resources` as `JavaResourceRootType.TEST_RESOURCE` does not
produce a phase node when there is no Groovy/Java directory. Both cases fail in
light-fixture tests configured through `ModuleRootModificationUtil.updateModel`
and `ContentEntry.addSourceFolder`.
Please derive custom phases from actual registered test source/resource
roots and map them to their direct child of `src`, rather than treating every
non-main code directory as a test. A conventional-name fallback can still cover
the built-in phases before import. The fixture can register roots explicitly
for this coverage. Also, `ProjectFileIndex.isInTestSourceContent()` is
available on this platform (inherited from `FileIndex`); the reproducer
compiles and uses it successfully, as does the existing
`GspFileImpl.getFileResolveScope()`.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]