如何创建Checkstyle规则来限制不同根包之间的交互?
我有以下三个根包:
-
models
-
views
-
controllers
(他们不是像com.mycompany.myproject.models
。它们是根包)
我想禁止从models
到views
和从views
到models
(和其他一些)的访问。
我尝试使用Checkstyle:
中的ImportControl-Checker- 尝试1:使用单个
import-control.xml
。问题:我只能提供一个根xml元素(<import-control pkg="models">
),这只包含一个包(但我想有多个)。 尝试2:使用多个
import-control.xml
。问题:如果我在checkstyle-config.xml
中导入多个,似乎都不起作用(没有错误,只是看起来我没有定义)。我在import-control.xml
中的定义:<module name="ImportControl"> <property name="id" value="ImportControlViews"/> <property name="file" value="${basedir}/project/import-control/views.xml"/> </module> <module name="ImportControl"> <property name="id" value="ImportControlModels"/> <property name="file" value="${basedir}/project/import-control/models.xml"/> </module>
不幸的是,使用现成的ImportControl复选框很难做到您想要的。
原因如下:
你已经知道为什么选项1不能工作了:只能有一个根包。
选项2是可能的,但很费力。让我再深入一点。我使用了以下两个导入控制文件,它们禁止从views
中使用models
,从models
中使用views
:
<!DOCTYPE import-control PUBLIC "-//Puppy Crawl//DTD Import Control 1.1//EN"
"http://www.puppycrawl.com/dtds/import_control_1_1.dtd">
<import-control pkg="views">
<allow pkg="views" />
<disallow pkg="models" />
</import-control>
<!DOCTYPE import-control PUBLIC "-//Puppy Crawl//DTD Import Control 1.1//EN"
"http://www.puppycrawl.com/dtds/import_control_1_1.dtd">
<import-control pkg="models">
<allow pkg="models" />
<disallow pkg="views" />
</import-control>
在我的测试设置中,这基本上是有效的,但是有一个缺点:每个类都得到一个Checkstyle警告,表明Import控制文件不处理这个包。这是因为ImportControl检查期望所有包驻留在一个公共根下(通过查看Checkstyle 5.6源代码进行验证)。因此,在models
包中,您将从为views
包配置的检查实例中获得警告,反之亦然。还有一个附加的问题是,ImportControl检查只对import语句起作用,而不能找到直接在代码中使用的完全限定的引用。
那么,你能做什么呢?
- 改变你的应用,这样你就有一个公共根。这是最佳实践,通常是个好主意。
- 实现自定义检查作为
ImportControlCheck
的子类,它增加了启用/禁用"导入控制文件不处理此包"消息的选项,否则继续使用选项2。 - 如果您正在使用Eclipse,还有第三种解决方案。您可以使用Checkstyle Eclipse插件提供的高级配置对话框,以便将ImportControl实例限制在各自的文件中。这也将消除"导入控制文件不处理此包"消息。
您可以通过混合使用构建工具配置和checkstyle配置来实现这一点。例如,在gradle中,您可以将源代码放在单独的源代码集中,并使用
checkStyleModels {
excludes = ['views/**']
configFile file('checkstyle-models.xml')
}
checkStyleViews {
excludes = ['models/**']
configFile file('checkstyle-views.xml')
}
然后禁止在checkstyle-models.xml中使用视图。