Skip to content

Commit 26eb57a

Browse files
committed
add tests
1 parent 7e55b5f commit 26eb57a

File tree

10 files changed

+105
-17
lines changed

10 files changed

+105
-17
lines changed

MODULE.bazel

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ bazel_dep(name = "rules_shell", version = "0.5.0")
2424
bazel_dep(name = "rules_rust", version = "0.50.1")
2525
git_override(
2626
module_name = "rules_rust",
27-
commit = "4bf3797ff86bdeddbefca177ae6034a1ca0bc82c", # tip of "blorente/extract_action_for_rules_lint",
27+
commit = "b76a1bb3e596a1816b8f91bbb608b5965c2c8f70", # tip of "blorente/extract_action_for_rules_lint",
2828
remote = "https://github.com/blorente/rules_rust.git",
2929
)
3030

example/MODULE.bazel

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ bazel_dep(name = "rules_python", version = "0.26.0")
2020
bazel_dep(name = "rules_rust", version = "0.50.1")
2121
git_override(
2222
module_name = "rules_rust",
23-
commit = "4bf3797ff86bdeddbefca177ae6034a1ca0bc82c", # tip of "blorente/extract_action_for_rules_lint",
23+
commit = "b76a1bb3e596a1816b8f91bbb608b5965c2c8f70", # tip of "blorente/extract_action_for_rules_lint",
2424
remote = "https://github.com/blorente/rules_rust.git",
2525
)
2626

example/src/BUILD.bazel

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ load("@io_bazel_rules_go//go:def.bzl", "go_binary")
66
load("@rules_kotlin//kotlin:jvm.bzl", "kt_jvm_library")
77
load("@rules_proto//proto:defs.bzl", "proto_library")
88
load("@rules_python//python:defs.bzl", "py_library")
9-
load("@rules_rust//rust:defs.bzl", "rust_binary")
109
load("@rules_shell//shell:sh_library.bzl", "sh_library")
1110
load("//tools/lint:linters.bzl", "eslint_test")
1211

@@ -135,9 +134,3 @@ format_test(
135134
"hello.sh",
136135
],
137136
)
138-
139-
# FIXME: Try it with transitive deps
140-
rust_binary(
141-
name = "hello_rust",
142-
srcs = ["hello.rs"],
143-
)

example/src/rust/BUILD.bazel

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
load("@rules_rust//rust:defs.bzl", "rust_binary", "rust_library")
2+
3+
rust_library(
4+
name = "bad_lib",
5+
srcs = ["bad_lib.rs"],
6+
visibility = [
7+
"//src/rust:__pkg__",
8+
"//test:__pkg__",
9+
],
10+
)
11+
12+
rust_binary(
13+
name = "bad_binary",
14+
srcs = ["bad_binary.rs"],
15+
visibility = [
16+
"//src/rust:__pkg__",
17+
"//test:__pkg__",
18+
],
19+
)
20+
21+
rust_binary(
22+
name = "ok_binary",
23+
srcs = ["ok_binary.rs"],
24+
visibility = [
25+
"//src/rust:__pkg__",
26+
"//test:__pkg__",
27+
],
28+
)
29+
30+
rust_binary(
31+
name = "ok_binary_with_bad_dep",
32+
srcs = ["ok_binary.rs"],
33+
visibility = [
34+
"//src/rust:__pkg__",
35+
"//test:__pkg__",
36+
],
37+
deps = [":bad_lib"],
38+
)
Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,4 @@
11
fn main() {
22
// Will fail clippy because we could just write println!("Hello World").
33
println!("{}", "Hello World");
4-
5-
// Will pass clippy
6-
// println!("Hello World!");
74
}

example/src/rust/bad_lib.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
fn bad() {
2+
// Will fail clippy because we could just write println!("Hello World").
3+
println!("{}", "Hello World");
4+
}

example/src/rust/ok_binary.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
fn main() {
2+
println!("Hello World");
3+
}

example/test/BUILD.bazel

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ load("@aspect_rules_ts//ts:defs.bzl", "ts_project")
55
load("@bazel_skylib//rules:write_file.bzl", "write_file")
66
load("@rules_python//python:defs.bzl", "py_library")
77
load("@rules_shell//shell:sh_library.bzl", "sh_library")
8-
load("//tools/lint:linters.bzl", "checkstyle_test", "eslint_test", "flake8_test", "pmd_test", "ruff_test", "shellcheck_test")
8+
load("//tools/lint:linters.bzl", "checkstyle_test", "clippy_test", "eslint_test", "flake8_test", "pmd_test", "ruff_test", "shellcheck_test")
99

1010
write_file(
1111
name = "ts_code_generator",
@@ -156,3 +156,32 @@ format_test(
156156
srcs = [":generated_sh"],
157157
tags = ["manual"],
158158
)
159+
160+
clippy_test(
161+
name = "clippy_ok_binary",
162+
srcs = ["//src/rust:ok_binary"],
163+
)
164+
165+
clippy_test(
166+
name = "clippy_ok_binary_with_bad_dep",
167+
srcs = ["//src/rust:ok_binary_with_bad_dep"],
168+
# Expected to fail based on current content of the file.
169+
# Normally you'd fix the file instead of tagging this test.
170+
tags = ["manual"],
171+
)
172+
173+
clippy_test(
174+
name = "clippy_bad_binary",
175+
srcs = ["//src/rust:bad_binary"],
176+
# Expected to fail based on current content of the file.
177+
# Normally you'd fix the file instead of tagging this test.
178+
tags = ["manual"],
179+
)
180+
181+
clippy_test(
182+
name = "clippy_bad_library",
183+
srcs = ["//src/rust:bad_library"],
184+
# Expected to fail based on current content of the file.
185+
# Normally you'd fix the file instead of tagging this test.
186+
tags = ["manual"],
187+
)

example/tools/lint/linters.bzl

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@ clippy = lint_clippy_aspect(
2424
config = Label("//:.clippy.toml"),
2525
)
2626

27+
clippy_test = lint_test(aspect = clippy)
28+
2729
eslint = lint_eslint_aspect(
2830
binary = Label("//tools/lint:eslint"),
2931
# ESLint will resolve the configuration file by looking in the working directory first.

lint/clippy.bzl

Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,24 @@ load("//lint/private:lint_aspect.bzl", "LintOptionsInfo", "OPTIONAL_SARIF_PARSER
4545

4646
_MNEMONIC = "AspectRulesLintClippy"
4747

48+
def _marker_to_exit_code(ctx, marker, exit_code):
49+
"""Write 0 to exit_code if marker exists, fail otherwise.
50+
51+
rules_rust won't write the exit code to the success_marker, so we assert that it exists and write the exit code ourselves.
52+
If there is no success marker, the action has failed anyway.
53+
54+
Args:
55+
ctx (ctx): The rule or aspect context. Must have access to `ctx.actions.run_shell`
56+
marker (File): A file that will only exist if the action has succeeded
57+
exit_code (File): A file that will be written with the exit code 0 if marker exists
58+
"""
59+
ctx.actions.run_shell(
60+
outputs = [exit_code],
61+
inputs = [marker],
62+
arguments = [exit_code.path],
63+
command = "echo '0' > $1",
64+
)
65+
4866
# buildifier: disable=function-docstring
4967
def _clippy_aspect_impl(target, ctx):
5068
if not should_visit(ctx.rule, ctx.attr._rule_kinds):
@@ -73,31 +91,35 @@ def _clippy_aspect_impl(target, ctx):
7391
# (1) modify the patcher so that it can run an action through a macro, or
7492
# (2) modify rules_rust so that it gives us a struct with a command line we can run it with the patcher.
7593

94+
human_success_indicator = ctx.actions.declare_file(OUTFILE_FORMAT.format(label = target.label.name, mnemonic = _MNEMONIC, suffix = "human_success_indicator"))
7695
rust_clippy_action.action(
7796
ctx,
7897
clippy_executable = clippy_bin,
7998
process_wrapper = ctx.executable._process_wrapper,
80-
src = crate_info,
99+
crate_info = crate_info,
81100
config = ctx.file._config_file,
82101
output = outputs.human.out,
83-
success_marker = outputs.human.exit_code, # This won't write the exit code, but it wil only write the file if the process has succeeded.
102+
success_marker = human_success_indicator,
84103
cap_at_warnings = True, # We don't want to crash the process if there are clippy errors, we just want to report them.
85104
extra_clippy_flags = extra_options,
86105
)
106+
_marker_to_exit_code(ctx, human_success_indicator, outputs.human.exit_code)
87107

108+
machine_success_indicator = ctx.actions.declare_file(OUTFILE_FORMAT.format(label = target.label.name, mnemonic = _MNEMONIC, suffix = "machine_success_indicator"))
88109
raw_machine_report = ctx.actions.declare_file(OUTFILE_FORMAT.format(label = target.label.name, mnemonic = _MNEMONIC, suffix = "raw_machine_report"))
89110
rust_clippy_action.action(
90111
ctx,
91112
clippy_executable = clippy_bin,
92113
process_wrapper = ctx.executable._process_wrapper,
93-
src = crate_info,
114+
crate_info = crate_info,
94115
config = ctx.file._config_file,
95116
output = raw_machine_report,
96-
success_marker = outputs.machine.exit_code, # This won't write the exit code, but it wil only write the file if the process has succeeded.
117+
success_marker = machine_success_indicator,
97118
cap_at_warnings = True,
98119
extra_clippy_flags = extra_options,
99120
error_format = "json",
100121
)
122+
_marker_to_exit_code(ctx, machine_success_indicator, outputs.machine.exit_code)
101123

102124
# clippy uses rustc's IO format, which doesn't have a SARIF output mode built in,
103125
# and they're not planning to add one.

0 commit comments

Comments
 (0)