-
Notifications
You must be signed in to change notification settings - Fork 331
Description
I created an IdentifierAssociation for my classes, which grouped them into modules. I'd now like to process the modules and do assertions on them, but I can't figure out a way to get a JavaClasses from an ArchModule.
The simplest would be to expose "JavaClasses.of(Collection)", or something along those lines. Right now the only option seems to take them back to raw Class<> and do a full re-import using ClassImporter.
I was imagining something like this:
@Test
void packagesMustBePrefixedByTheirGradleModulePath() {
for (ArchModule module : GRADLE_MODULES) {
// Cleanly map module path to a subpackage requirement
String moduleBaseJavaPackage = Constants.TOPLEVEL_PACKAGE + "." + String.join(".",
module.getIdentifier());
// This reads like a specification
classes()
.should()
.resideInAPackage(moduleBaseJavaPackage + "..")
.check(module.classes());
}
}
(it would also be nice to be able to assert this about the packages to avoid duplicate messages)
(it would also be nice to be able to specify the separator for joining the identifier elements in a module identifier: . or / are both relevant)
What I've done instead is to make a custom ArchCondition, that calculates the modulePath for every class, and then figures out the package and does the check there. But this scales poorly as all my module-based logic has to always recalculate the classes and all the context, vs essentially knowing "it's this module, so it should have these constraints".
Background:
I've got a gradle monorepo with many modules, and would like to specify a rule like: "the java packages in the gradle module correspond to the path of the gradle module itself. For example, my org is "com.toplevel", I have a gradle module "client/bubble/api", and I want to assert that all the packages in this module are rooted at com.toplevel.client.bubble.api.
I'm currently getting the gradle module by using a class import that looks at the JavaClass.getSource, and extracts the piece between /build/ and the top of the repo. I also use this information to enforce that no packages appear in more than one module.
As far as I can see, it's difficult to do this at the package-level, because i don't enforce that modules are a particular depth, so have to walk all possible levels upwards until i find a matching module.
I also have a similar hand-built stateful rule saying that a given java package shouldn't appear in more than one module.
On the positive side, it's working with this workaround, but I was excited to see the "ArchModule" idea to represent my gradle modules, but then unfortunately it isn't obvious how to do assertions around their contents.