From e3cac314cef8495d588ad4dcc743fe1c0aea8965 Mon Sep 17 00:00:00 2001 From: Johan Nilsson Date: Mon, 9 Dec 2024 15:23:16 +0100 Subject: [PATCH] fix: Add option to skip target without srcs Add option 'skip_if_no_srcs' to lint_clang_tidy aspect Set to True to skip target if it provides CcInfo but has no source files. By default this will generate an error. --- docs/clang-tidy.md | 3 ++- lint/clang_tidy.bzl | 13 ++++++++++--- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/docs/clang-tidy.md b/docs/clang-tidy.md index 993b40f9..5f1658fd 100644 --- a/docs/clang-tidy.md +++ b/docs/clang-tidy.md @@ -122,7 +122,7 @@ is_parent_in_list(dir, binary, configs, global_config, header_filter, lint_target_headers, - angle_includes_are_system, verbose) + angle_includes_are_system, skip_if_no_srcs, verbose) A factory function to create a linter aspect. @@ -138,6 +138,7 @@ A factory function to create a linter aspect. | header_filter | optional, set to a posix regex to supply to clang-tidy with the -header-filter option | `""` | | lint_target_headers | optional, set to True to pass a pattern that includes all headers with the target's directory prefix. This crude control may include headers from the linted target in the results. If supplied, overrides the header_filter option. | `False` | | angle_includes_are_system | controls how angle includes are passed to clang-tidy. By default, Bazel passes these as -isystem. Change this to False to pass these as -I, which allows clang-tidy to regard them as regular header files. | `True` | +| skip_if_no_srcs | optional, set to True to skip target if it provides CcInfo but has no source files. By default this will generate an error. | `False` | | verbose | print debug messages including clang-tidy command lines being invoked. | `False` | diff --git a/lint/clang_tidy.bzl b/lint/clang_tidy.bzl index 0c78aa47..e8ec5664 100644 --- a/lint/clang_tidy.bzl +++ b/lint/clang_tidy.bzl @@ -177,10 +177,12 @@ def _is_source(file): return (file.is_source and file.extension in permitted_source_types) # modification of filter_srcs in lint_aspect.bzl that filters out header files -def _filter_srcs(rule): +def _filter_srcs(rule, skip_if_no_srcs = False): if "lint-genfiles" in rule.attr.tags: return rule.files.srcs else: + if skip_if_no_srcs and not hasattr(rule.files, "srcs"): + return [] return [s for s in rule.files.srcs if _is_source(s)] def is_parent_in_list(dir, list): @@ -369,7 +371,7 @@ def _clang_tidy_aspect_impl(target, ctx): if not CcInfo in target: return [] - files_to_lint = _filter_srcs(ctx.rule) + files_to_lint = _filter_srcs(ctx.rule, ctx.attr._skip_if_no_srcs) compilation_context = target[CcInfo].compilation_context if hasattr(ctx.rule.attr, "implementation_deps"): compilation_context = cc_common.merge_compilation_contexts( @@ -394,7 +396,7 @@ def _clang_tidy_aspect_impl(target, ctx): clang_tidy_action(ctx, compilation_context, ctx.executable, files_to_lint, outputs.machine.out, outputs.machine.exit_code) return [info] -def lint_clang_tidy_aspect(binary, configs = [], global_config = [], header_filter = "", lint_target_headers = False, angle_includes_are_system = True, verbose = False): +def lint_clang_tidy_aspect(binary, configs = [], global_config = [], header_filter = "", lint_target_headers = False, angle_includes_are_system = True, skip_if_no_srcs = False, verbose = False): """A factory function to create a linter aspect. Args: @@ -419,6 +421,8 @@ def lint_clang_tidy_aspect(binary, configs = [], global_config = [], header_filt angle_includes_are_system: controls how angle includes are passed to clang-tidy. By default, Bazel passes these as -isystem. Change this to False to pass these as -I, which allows clang-tidy to regard them as regular header files. + skip_if_no_srcs: optional, set to True to skip target if it provides CcInfo but has no source files. By + default this will generate an error. verbose: print debug messages including clang-tidy command lines being invoked. """ @@ -449,6 +453,9 @@ def lint_clang_tidy_aspect(binary, configs = [], global_config = [], header_filt "_angle_includes_are_system": attr.bool( default = angle_includes_are_system, ), + "_skip_if_no_srcs": attr.bool( + default = skip_if_no_srcs, + ), "_verbose": attr.bool( default = verbose, ),