如何用 ArchUnit 检查项目类是否使用统一包名前缀?
数据阿明
结论
可以用 ArchUnit 的 resideInAPackage 规则约束类的包名。先将项目自己的编译输出目录导入检查,再验证其中的类是否都位于指定包名前缀下。这样也能检查包名写错、落在前缀之外的项目类。
编写 ArchUnit 规则
下面的示例假设项目使用 com.example 作为包名前缀,并采用 Gradle 默认的 Java 主源码编译输出目录:
import com.tngtech.archunit.core.domain.JavaClasses;
import com.tngtech.archunit.core.importer.ClassFileImporter;
import com.tngtech.archunit.lang.ArchRule;
import org.junit.jupiter.api.Test;
import java.nio.file.Paths;
import static com.tngtech.archunit.lang.syntax.ArchRuleDefinition.classes;
class PackageArchitectureTest {
@Test
void allProjectClassesShouldUseExpectedPackagePrefix() {
JavaClasses projectClasses = new ClassFileImporter()
.importPath(Paths.get("build/classes/java/main"));
ArchRule rule = classes()
.should().resideInAPackage("com.example..");
rule.check(projectClasses);
}
}
com.example.. 匹配 com.example 包及其子包。请将它替换为项目实际要求的前缀。importPath 只导入指定编译目录中的类,通常更适合检查项目中的所有类。
根据项目调整导入范围
如果还要检查测试源码,可以将测试类的编译输出目录也传给 importPath,例如 Gradle 常见的 build/classes/java/test。多模块项目需要把要检查的各模块输出目录都加入导入范围。实际目录可能因 Gradle 配置而异,请根据项目的编译设置调整。
不要只导入目标前缀对应的包来做这项检查。前缀之外的类可能不会进入检查集合,规则也就无法发现它们。外部依赖通常不在项目自己的编译输出目录中,因此这个示例不会一并检查它们。
如果只想限制部分类,例如排除生成代码或某些特定类型,可以在规则中添加适合项目的筛选条件。筛选范围应符合“所有项目源码类”的检查要求。
备注:内容仅供参考。
