diff --git a/docs/checkstyle.md b/docs/checkstyle.md index b31f630d..91a5d0b1 100644 --- a/docs/checkstyle.md +++ b/docs/checkstyle.md @@ -79,7 +79,7 @@ fetch_checkstyle()
 load("@aspect_rules_lint//lint:checkstyle.bzl", "lint_checkstyle_aspect")
 
-lint_checkstyle_aspect(binary, config, data, rule_kinds)
+lint_checkstyle_aspect(binary, config, configs, data, rule_kinds)
 
A factory function to create a linter aspect. @@ -105,7 +105,28 @@ Attrs: | :------------- | :------------- | :------------- | | binary |

-

| none | | config |

-

| none | +| configs |

-

| `{}` | | data |

-

| `[]` | | rule_kinds |

-

| `["java_binary", "java_library"]` | + + +## rebuild_map + +
+load("@aspect_rules_lint//lint:checkstyle.bzl", "rebuild_map")
+
+rebuild_map(configs)
+
+ + + +**PARAMETERS** + + +| Name | Description | Default Value | +| :------------- | :------------- | :------------- | +| configs |

-

| none | + + diff --git a/example/BUILD.bazel b/example/BUILD.bazel index b8d151ee..f9426be4 100644 --- a/example/BUILD.bazel +++ b/example/BUILD.bazel @@ -17,6 +17,7 @@ exports_files( ".flake8", "pmd.xml", "checkstyle.xml", + "checkstyle_subdir.xml", "checkstyle-suppressions.xml", ".ruff.toml", ".shellcheckrc", diff --git a/example/checkstyle_subdir.xml b/example/checkstyle_subdir.xml new file mode 100644 index 00000000..30a3a9c5 --- /dev/null +++ b/example/checkstyle_subdir.xml @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + + + + diff --git a/example/src/subdir/BUILD.bazel b/example/src/subdir/BUILD.bazel index 927ce478..1d3dc557 100644 --- a/example/src/subdir/BUILD.bazel +++ b/example/src/subdir/BUILD.bazel @@ -24,3 +24,8 @@ ts_project( "//:node_modules/moment", ], ) + +java_library( + name = "bar", + srcs = ["Bar.java"], +) diff --git a/example/src/subdir/Bar.java b/example/src/subdir/Bar.java new file mode 100644 index 00000000..c8376689 --- /dev/null +++ b/example/src/subdir/Bar.java @@ -0,0 +1,10 @@ +package src.subdir; + +// Unused imports are suppressed in suppressions.xml, so this should not raise issue. +import java.util.Objects; +import java.io.BufferedInputStream; + +public class Bar { + // Max line length set to 20, so this should raise issue. + protected void finalize(int a) {} +} diff --git a/example/tools/lint/linters.bzl b/example/tools/lint/linters.bzl index 0e064715..c5131b89 100644 --- a/example/tools/lint/linters.bzl +++ b/example/tools/lint/linters.bzl @@ -52,9 +52,13 @@ pmd = lint_pmd_aspect( pmd_test = lint_test(aspect = pmd) checkstyle = lint_checkstyle_aspect( - binary = Label("@//tools/lint:checkstyle"), - config = Label("@//:checkstyle.xml"), - data = [Label("@//:checkstyle-suppressions.xml")], + binary = "@@//tools/lint:checkstyle", + config = "@@//:checkstyle.xml", + configs = { + "@@//:checkstyle.xml": "@@//src,@@//test", + "@@//:checkstyle_subdir.xml": "@@//src/subdir", + }, + data = ["@@//:checkstyle-suppressions.xml"], ) checkstyle_test = lint_test(aspect = checkstyle) diff --git a/lint/checkstyle.bzl b/lint/checkstyle.bzl index 5c2bef9b..fca11759 100644 --- a/lint/checkstyle.bzl +++ b/lint/checkstyle.bzl @@ -32,6 +32,13 @@ load("//lint/private:lint_aspect.bzl", "LintOptionsInfo", "filter_srcs", "noop_l _MNEMONIC = "AspectRulesLintCheckstyle" +def rebuild_map(configs): + directory_to_config = {} + for config, directories in configs.items(): + for directory in directories.split(","): + directory_to_config[directory] = config + return directory_to_config + def checkstyle_action(ctx, executable, srcs, config, data, stdout, exit_code = None, options = []): """Run Checkstyle as an action under Bazel. @@ -42,6 +49,7 @@ def checkstyle_action(ctx, executable, srcs, config, data, stdout, exit_code = N executable: label of the the Checkstyle program srcs: java files to be linted config: label of the checkstyle.xml file + configs: dictionary mapping package label to their respective checkstyle.xml file data: labels of additional xml files such as suppressions.xml stdout: output file to generate exit_code: output file to write the exit code. @@ -82,6 +90,17 @@ def _checkstyle_aspect_impl(target, ctx): return [] files_to_lint = filter_srcs(ctx.rule) + config_file = ctx.file._config + config_maps = rebuild_map(ctx.attr._configs) + if ctx.attr._configs: + label = str(target.label) + keys = sorted(config_maps.keys(), key=len, reverse = True) + for key in keys: + if label.startswith(key): + config = config_maps[key] + config_file = config.files.to_list()[0] + break + outputs, info = output_files(_MNEMONIC, target, ctx) if len(files_to_lint) == 0: noop_lint_action(ctx, outputs) @@ -91,7 +110,7 @@ def _checkstyle_aspect_impl(target, ctx): ctx, ctx.executable._checkstyle, files_to_lint, - ctx.file._config, + config_file, ctx.files._data, outputs.human.out, outputs.human.exit_code, @@ -101,7 +120,7 @@ def _checkstyle_aspect_impl(target, ctx): ctx, ctx.executable._checkstyle, files_to_lint, - ctx.file._config, + config_file, ctx.files._data, outputs.machine.out, outputs.machine.exit_code, @@ -109,7 +128,7 @@ def _checkstyle_aspect_impl(target, ctx): ) return [info] -def lint_checkstyle_aspect(binary, config, data = [], rule_kinds = ["java_binary", "java_library"]): +def lint_checkstyle_aspect(binary, config, configs = {}, data = [], rule_kinds = ["java_binary", "java_library"]): """A factory function to create a linter aspect. Attrs: @@ -147,6 +166,12 @@ def lint_checkstyle_aspect(binary, config, data = [], rule_kinds = ["java_binary doc = "Config file", default = config, ), + "_configs": attr.label_keyed_string_dict( + allow_empty = True, + allow_files = True, + doc = "Package and configuration files dictionary", + default = configs, + ), "_data": attr.label_list( doc = "Additional files to make available to Checkstyle such as any included XML files", allow_files = True,