2

如何创建 Checkstyle 规则来限制不同根包之间的交互?

我有以下 3 个根包:

  • models
  • views
  • controllers

(它们不是类似的东西com.mycompany.myproject.models。它们是根包。)

我想禁止访问modelstoviews和 from viewsto models(以及其他一些)。

我尝试使用 Checkstyle 的ImportControl-Checker

  • 尝试 1:使用一个import-control.xml. 问题:我只能提供一个 Root-XML-Element ( <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>
    
4

2 回答 2

1

不幸的是,使用开箱即用的 ImportControl 检查很难实现您想要的。
原因如下:

您已经知道为什么您的选项 1 不起作用:只能有一个根包。

选项 2 是可能的,但很费力。让我深入一点。我使用了以下两个导入控制文件,它们不允许使用modelsfromviewsviewsfrom models

<!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 control file does not handle this package。这是因为 ImportControl 检查期望所有包都驻留在公共根目录下(通过查看 Checkstyle 5.6 源代码进行验证)。因此,在models包中,您会从为包配置的检查实例中收到警告,views反之亦然。
还有一个额外的问题是 ImportControl 检查仅适用于 import 语句,但找不到代码中直接使用的完全限定引用。

所以,你可以做什么?

  • 更改您的应用程序,以便您拥有一个共同的根。这是最佳实践,通常也是一个好主意。
  • 实现一个自定义检查作为其子类,ImportControlCheck它添加了一个用于启用/禁用“导入控制文件不处理此包”消息的选项,否则使用您的选项 2。
  • 如果您使用的是 Eclipse,还有第三种解决方案。您可以使用 Checkstyle Eclipse 插件提供的高级配置对话框来将 ImportControl 实例限制在它们各自的文件中。这也将消除“导入控制文件不处理此包”消息。
于 2013-04-22T20:50:08.260 回答
1

您可以通过混合构建工具配置和 checkstyle 配置来实现这一点。例如,使用 gradle,您可以将源放在单独的源集中,并使用

checkStyleModels {
    excludes = ['views/**']
    configFile file('checkstyle-models.xml')
}
checkStyleViews {
    excludes = ['models/**']
    configFile file('checkstyle-views.xml')
}

然后在 checkstyle-models.xml 中禁止视图。两个配置都可以有不同的根目录而没有问题。

于 2021-04-01T10:21:24.583 回答