Skip to content

Commit efaa8de

Browse files
committed
接通Gradle原生Javadoc项目检查与保守反馈协议
1 parent adce1ac commit efaa8de

21 files changed

Lines changed: 5496 additions & 33 deletions

‎README.md‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1004,4 +1004,4 @@ Static discovery now retains every Maven/Groovy-Gradle/Kotlin-Gradle configurati
10041004

10051005
`gradle_javadoc_probe::observe` captures the native model and reruns enabled official Javadoc tasks in one offline Gradle invocation. It preserves project doclint/doclet/access/source-set settings and fixes only the diagnostic JVM language. Rust validates selected source bytes and diagnostic locations; native failures, unknown diagnostics and input changes remain incomplete. Four observations within one real Gradle 8.10.2/JDK21 conditional test produce 3 missing-comment, 2 missing-tag, 2 empty-description, and 0 diagnostics. These are not an independent precision corpus or production acceptance. Empty output remains `empty_output_unverified` with `rule_configuration_complete=false` and `coverage_proven=false`.
10061006

1007-
This internal service is not connected to public check quality tasks, agent feedback or repair closure. Existing check_feedback 0.62 still carries only the Gradle configuration model. Complete detailed documentation rules, JDK/source closure, multi-project/custom-doclet cases, both Maven/Gradle paths and per-language acceptance remain open. See [Gradle Javadoc acceptance](tests/acceptance/gradle-native-javadoc.md).
1007+
The development `check java` / `check all` entry now accepts explicit `--gradle-javadoc` with `--gradle-bundle`, `--java-home`, and repeatable `--gradle-project-file` inputs including root settings/build and Java files. One scheduled `java.gradle.javadoc` job captures the model and executes original documentation tasks in one native invocation. Check feedback 0.63 preserves `native_results.java_gradle_javadoc`; it does not launch a second model invocation. Model-only requests retain 0.62; `lint all` rejects documentation options. SIGINT preserves cancellation observations, and check_aborted 0.17 preserves documentation observations before a sibling failure. Public quality feedback is connected; automatic task persistence, repair recheck/closure, complete rules and JDK/source closure, multi-project/custom-doclet and per-language qualification remain open. See [public Javadoc acceptance](tests/acceptance/gradle-public-javadoc-check.md).

‎README.zh-CN.md‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -987,4 +987,4 @@ flowchart LR
987987

988988
新增 `gradle_javadoc_probe::observe` 在一次离线 Gradle 调用中采集模型并重跑已启用的官方 Javadoc 任务,使用原项目 doclint/doclet/访问范围/源集,只固定诊断 JVM 的英语语言。Rust 校验选定源码及诊断位置,原生失败、未知诊断、输入变化等保持未完成。真实 Gradle 8.10.2/JDK21 四组样例得到 3 条缺注释、2 条缺标签、2 条空标签描述、0 条诊断;这是一个原生条件测试中的四次观察,不是独立精度语料或生产验收。无诊断报告仍为 `empty_output_unverified`,`rule_configuration_complete=false`、`coverage_proven=false`。
989989

990-
此服务尚未接入公开 check 的质量任务、智能体反馈及修复关闭;现有 check_feedback 0.62 仍仅记录 Gradle 配置模型。完整详细注释规则、完整 JDK/源码闭包、跨项目/自定义 doclet、Maven/Gradle 双路径及各语言验收仍待完成。见 [Gradle Javadoc 验收记录](tests/acceptance/gradle-native-javadoc.md)。
990+
开发期 `check java` / `check all` 现可显式追加 `--gradle-javadoc`,同时提供 `--gradle-bundle`、`--java-home` 和可重复的 `--gradle-project-file`(含根 settings/build 及 Java 文件)。统一调度只生成一个 `java.gradle.javadoc` 任务,单次原生调用完成模型/注释检查,check_feedback 0.63 在 `native_results.java_gradle_javadoc` 保存诊断;不额外调用配置模型。仅模型请求仍使用 0.62;`lint all` 拒绝文档参数。SIGINT 保留取消观察,check_aborted 0.17 保留兄弟异常之前的文档观察。公开质量反馈已接入,自动任务持久化、复检关闭、完整规则及完整 JDK/源码闭包和跨项目/custom doclet 验收仍待完成。见 [公开 Javadoc 入口验收](tests/acceptance/gradle-public-javadoc-check.md)。

‎crates/codeguard-cli/src/check_command.rs‎

Lines changed: 128 additions & 25 deletions
Large diffs are not rendered by default.

‎crates/codeguard-cli/src/command_examples.rs‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ pub(crate) fn examples(command: &str) -> &'static [&'static str] {
4040
"check" => &[
4141
"codeguard check all . --timeout 60s --jobs 1 --format json",
4242
"codeguard check java . --gradle-bundle /absolute/gradle --java-home /absolute/jdk --gradle-project-file settings.gradle --gradle-project-file build.gradle --format json",
43+
"codeguard check java . --gradle-javadoc --gradle-bundle /absolute/gradle --java-home /absolute/jdk21 --gradle-project-file settings.gradle --gradle-project-file build.gradle --gradle-project-file src/main/java/Example.java --format json",
4344
"codeguard check go . --go-tool /absolute/sdk/bin/go --format json",
4445
"codeguard check swift . --swift-tool /absolute/swift --format json",
4546
"codeguard check kotlin . --kotlinc-tool /absolute/kotlinc --format json",

‎crates/codeguard-cli/tests/gradle_javadoc_probe.rs‎

Lines changed: 238 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -164,3 +164,241 @@ fn actual_gradle_javadoc_preserves_missing_comments_and_documented_counterexampl
164164
fs::write(path, serde_json::to_vec_pretty(&reports).unwrap()).unwrap();
165165
}
166166
}
167+
168+
fn public_command(project: &Project, selection: &str) -> std::process::Command {
169+
public_command_with_tools(
170+
project,
171+
selection,
172+
std::path::Path::new("/unavailable/gradle"),
173+
std::path::Path::new("/unavailable/jdk"),
174+
)
175+
}
176+
fn public_command_with_tools(
177+
project: &Project,
178+
selection: &str,
179+
bundle: &std::path::Path,
180+
jdk: &std::path::Path,
181+
) -> std::process::Command {
182+
let mut command = std::process::Command::new(env!("CARGO_BIN_EXE_codeguard"));
183+
command
184+
.args(["check", selection])
185+
.arg(&project.0)
186+
.args(["--gradle-javadoc", "--gradle-bundle"])
187+
.arg(bundle)
188+
.arg("--java-home")
189+
.arg(jdk)
190+
.args([
191+
"--gradle-project-file",
192+
"settings.gradle",
193+
"--gradle-project-file",
194+
"build.gradle",
195+
"--gradle-project-file",
196+
"src/main/java/Sample.java",
197+
"--format=json",
198+
])
199+
.env("PATH", "/no/tools");
200+
command
201+
}
202+
#[test]
203+
fn public_check_schedules_one_documentation_job_and_preserves_incomplete_feedback() {
204+
let project = Project::new("public class Sample {}\n");
205+
for selection in ["java", "all"] {
206+
let output = public_command(&project, selection).output().unwrap();
207+
assert_eq!(output.status.code(), Some(3), "{output:?}");
208+
let report: serde_json::Value = serde_json::from_slice(&output.stdout).unwrap();
209+
assert_eq!(report["schema_version"], "0.63.0");
210+
assert!(report["native_results"].get("java_gradle_model").is_none());
211+
assert_eq!(
212+
report["native_results"]["java_gradle_javadoc"]["native_status"],
213+
"incomplete"
214+
);
215+
let gradle_jobs = report["execution_tasks"]
216+
.as_array()
217+
.unwrap()
218+
.iter()
219+
.filter(|j| j["id"].as_str().unwrap().starts_with("java.gradle."))
220+
.collect::<Vec<_>>();
221+
assert_eq!(gradle_jobs.len(), 1);
222+
assert_eq!(gradle_jobs[0]["id"], "java.gradle.javadoc");
223+
assert_ne!(report["delivery_decision"], "allow");
224+
if let Some(dir) = std::env::var_os("CODEGUARD_TEST_GRADLE_JAVADOC_PUBLIC_REPORTS") {
225+
fs::create_dir_all(&dir).unwrap();
226+
fs::write(
227+
PathBuf::from(dir).join(format!("{selection}-incomplete.json")),
228+
serde_json::to_vec_pretty(&report).unwrap(),
229+
)
230+
.unwrap();
231+
}
232+
}
233+
}
234+
235+
#[test]
236+
fn public_javadoc_selection_rejects_missing_sources_duplicate_and_lint_scope() {
237+
let project = Project::new("public class Sample {}\n");
238+
for mut command in [
239+
{
240+
let mut c = public_command(&project, "java");
241+
c.arg("--gradle-javadoc");
242+
c
243+
},
244+
public_command(&project, "rust"),
245+
{
246+
let mut c = std::process::Command::new(env!("CARGO_BIN_EXE_codeguard"));
247+
c.args(["check", "java"])
248+
.arg(&project.0)
249+
.arg("--gradle-javadoc");
250+
c
251+
},
252+
{
253+
let mut c = std::process::Command::new(env!("CARGO_BIN_EXE_codeguard"));
254+
c.args(["lint", "all"])
255+
.arg(&project.0)
256+
.arg("--gradle-javadoc");
257+
c
258+
},
259+
{
260+
let mut c = std::process::Command::new(env!("CARGO_BIN_EXE_codeguard"));
261+
c.args(["check", "java"]).arg(&project.0).args([
262+
"--gradle-javadoc",
263+
"--gradle-bundle",
264+
"/unavailable/gradle",
265+
"--java-home",
266+
"/unavailable/jdk",
267+
"--gradle-project-file",
268+
"settings.gradle",
269+
"--gradle-project-file",
270+
"build.gradle",
271+
]);
272+
c
273+
},
274+
] {
275+
let output = command.env("PATH", "/no/tools").output().unwrap();
276+
assert_eq!(output.status.code(), Some(2), "{output:?}");
277+
assert!(output.stdout.is_empty());
278+
}
279+
}
280+
#[test]
281+
#[ignore = "requires explicit existing Gradle8.10.2/JDK21; never installs"]
282+
fn actual_public_check_preserves_native_documentation_findings_without_coverage_upgrade() {
283+
let bundle =
284+
PathBuf::from(std::env::var_os("CODEGUARD_TEST_GRADLE_BUNDLE").expect("existing Gradle"));
285+
let jdk = PathBuf::from(std::env::var_os("CODEGUARD_TEST_JAVA_HOME").expect("existing JDK"));
286+
for (name, source, expected_count, status) in [
287+
(
288+
"missing",
289+
"public class Sample {\n public Sample() {}\n public int add(int value) { return value + 1; }\n}\n",
290+
3,
291+
"findings_observed_unverified",
292+
),
293+
(
294+
"documented",
295+
"/** Provides an example. */\npublic class Sample {\n /** Creates the example. */\n public Sample() {}\n /** Adds one.\n * @param value input value\n * @return incremented value\n */\n public int add(int value) { return value + 1; }\n}\n",
296+
0,
297+
"empty_output_unverified",
298+
),
299+
] {
300+
let project = Project::new(source);
301+
let output = public_command_with_tools(&project, "java", &bundle, &jdk)
302+
.output()
303+
.unwrap();
304+
assert_eq!(output.status.code(), Some(3), "{output:?}");
305+
let report: serde_json::Value = serde_json::from_slice(&output.stdout).unwrap();
306+
assert_eq!(report["schema_version"], "0.63.0");
307+
let native = &report["native_results"]["java_gradle_javadoc"];
308+
assert_eq!(native["native_status"], status, "{report}");
309+
assert_eq!(native["findings"].as_array().unwrap().len(), expected_count);
310+
for finding in native["findings"].as_array().unwrap() {
311+
assert_eq!(finding["rule_id"], "JavadocMissingComment");
312+
assert_eq!(finding["path"], "src/main/java/Sample.java");
313+
}
314+
assert_eq!(native["coverage_proven"], false);
315+
assert_eq!(native["rule_configuration_complete"], false);
316+
assert_ne!(report["delivery_decision"], "allow");
317+
assert!(report["native_results"].get("java_gradle_model").is_none());
318+
assert_eq!(
319+
report["execution_tasks"]
320+
.as_array()
321+
.unwrap()
322+
.iter()
323+
.filter(|r| r["id"] == "java.gradle.javadoc")
324+
.count(),
325+
1
326+
);
327+
if let Some(dir) = std::env::var_os("CODEGUARD_TEST_GRADLE_JAVADOC_PUBLIC_REPORTS") {
328+
fs::create_dir_all(&dir).unwrap();
329+
fs::write(
330+
PathBuf::from(dir).join(format!("{name}-native.json")),
331+
serde_json::to_vec_pretty(&report).unwrap(),
332+
)
333+
.unwrap();
334+
}
335+
}
336+
}
337+
338+
#[test]
339+
fn public_javadoc_sigint_preserves_cancelled_native_observation() {
340+
use std::os::unix::fs::PermissionsExt;
341+
let project = Project::new("public class Sample {}\n");
342+
let bundle = project.0.join("native-gradle");
343+
let jdk = project.0.join("native-jdk");
344+
fs::create_dir_all(bundle.join("bin")).unwrap();
345+
fs::create_dir_all(jdk.join("bin")).unwrap();
346+
fs::write(jdk.join("bin/java"), "controlled fixture").unwrap();
347+
fs::write(jdk.join("release"), "JAVA_VERSION=\"21\"\n").unwrap();
348+
let marker = project.0.join("native-started");
349+
fs::write(
350+
bundle.join("bin/gradle"),
351+
format!(
352+
"#!/bin/sh\nprintf started > '{}'\nexec /bin/sleep 30\n",
353+
marker.display()
354+
),
355+
)
356+
.unwrap();
357+
fs::set_permissions(bundle.join("bin/gradle"), fs::Permissions::from_mode(0o700)).unwrap();
358+
let child = public_command_with_tools(&project, "java", &bundle, &jdk)
359+
.stdout(std::process::Stdio::piped())
360+
.stderr(std::process::Stdio::piped())
361+
.spawn()
362+
.unwrap();
363+
let until = Instant::now() + Duration::from_secs(10);
364+
while !marker.exists() && Instant::now() < until {
365+
std::thread::sleep(Duration::from_millis(10));
366+
}
367+
assert!(marker.exists(), "native process did not start");
368+
assert!(
369+
std::process::Command::new("/bin/kill")
370+
.args(["-INT", &child.id().to_string()])
371+
.status()
372+
.unwrap()
373+
.success()
374+
);
375+
let output = child.wait_with_output().unwrap();
376+
assert_eq!(output.status.code(), Some(130), "{output:?}");
377+
let report: serde_json::Value = serde_json::from_slice(&output.stdout).unwrap();
378+
assert_eq!(report["schema_version"], "0.63.0");
379+
assert_eq!(
380+
report["native_results"]["java_gradle_javadoc"]["reason"],
381+
"request_cancelled"
382+
);
383+
assert!(
384+
report["native_results"]["java_gradle_javadoc"]["findings"]
385+
.as_array()
386+
.unwrap()
387+
.is_empty()
388+
);
389+
assert!(
390+
report["execution_tasks"]
391+
.as_array()
392+
.unwrap()
393+
.iter()
394+
.any(|r| r["id"] == "java.gradle.javadoc" && r["status"] == "cancelled")
395+
);
396+
if let Some(dir) = std::env::var_os("CODEGUARD_TEST_GRADLE_JAVADOC_PUBLIC_REPORTS") {
397+
fs::create_dir_all(&dir).unwrap();
398+
fs::write(
399+
PathBuf::from(dir).join("sigint.json"),
400+
serde_json::to_vec_pretty(&report).unwrap(),
401+
)
402+
.unwrap();
403+
}
404+
}

‎docs/Codeguard-Architecture.md‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1410,4 +1410,4 @@ The development CLI now exposes this selected-input observation through `check j
14101410

14111411
`gradle_javadoc_probe::observe` captures the native model and reruns enabled official Javadoc tasks in one offline Gradle invocation. It preserves project doclint/doclet/access/source-set settings and fixes only the diagnostic JVM language. Rust validates selected source bytes and diagnostic locations; native failures, unknown diagnostics and input changes remain incomplete. Four observations within one real Gradle 8.10.2/JDK21 conditional test produce 3 missing-comment, 2 missing-tag, 2 empty-description, and 0 diagnostics. These are not an independent precision corpus or production acceptance. Empty output remains `empty_output_unverified` with `rule_configuration_complete=false` and `coverage_proven=false`.
14121412

1413-
This internal service is not connected to public check quality tasks, agent feedback or repair closure. Existing check_feedback 0.62 still carries only the Gradle configuration model. Complete detailed documentation rules, JDK/source closure, multi-project/custom-doclet cases, both Maven/Gradle paths and per-language acceptance remain open. See [Gradle Javadoc acceptance](../tests/acceptance/gradle-native-javadoc.md).
1413+
The development `check java` / `check all` entry now accepts explicit `--gradle-javadoc` with `--gradle-bundle`, `--java-home`, and repeatable `--gradle-project-file` inputs including root settings/build and Java files. One scheduled `java.gradle.javadoc` job captures the model and executes original documentation tasks in one native invocation. Check feedback 0.63 preserves `native_results.java_gradle_javadoc`; it does not launch a second model invocation. Model-only requests retain 0.62; `lint all` rejects documentation options. SIGINT preserves cancellation observations, and check_aborted 0.17 preserves documentation observations before a sibling failure. Public quality feedback is connected; automatic task persistence, repair recheck/closure, complete rules and JDK/source closure, multi-project/custom-doclet and per-language qualification remain open. See [public Javadoc acceptance](../tests/acceptance/gradle-public-javadoc-check.md).

‎docs/Codeguard-Architecture.zh_CN.md‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1410,4 +1410,4 @@ Rust 应用服务 `gradle_model_probe::observe` 可通过固定 init 脚本、
14101410

14111411
新增 `gradle_javadoc_probe::observe` 在一次离线 Gradle 调用中采集模型并重跑已启用的官方 Javadoc 任务,使用原项目 doclint/doclet/访问范围/源集,只固定诊断 JVM 的英语语言。Rust 校验选定源码及诊断位置,原生失败、未知诊断、输入变化等保持未完成。真实 Gradle 8.10.2/JDK21 四组样例得到 3 条缺注释、2 条缺标签、2 条空标签描述、0 条诊断;这是一个原生条件测试中的四次观察,不是独立精度语料或生产验收。无诊断报告仍为 `empty_output_unverified`,`rule_configuration_complete=false`、`coverage_proven=false`。
14121412

1413-
此服务尚未接入公开 check 的质量任务、智能体反馈及修复关闭;现有 check_feedback 0.62 仍仅记录 Gradle 配置模型。完整详细注释规则、完整 JDK/源码闭包、跨项目/自定义 doclet、Maven/Gradle 双路径及各语言验收仍待完成。见 [Gradle Javadoc 验收记录](../tests/acceptance/gradle-native-javadoc.md)。
1413+
开发期 `check java` / `check all` 现可显式追加 `--gradle-javadoc`,同时提供 `--gradle-bundle`、`--java-home` 和可重复的 `--gradle-project-file`(含根 settings/build 及 Java 文件)。统一调度只生成一个 `java.gradle.javadoc` 任务,单次原生调用完成模型/注释检查,check_feedback 0.63 在 `native_results.java_gradle_javadoc` 保存诊断;不额外调用配置模型。仅模型请求仍使用 0.62;`lint all` 拒绝文档参数。SIGINT 保留取消观察,check_aborted 0.17 保留兄弟异常之前的文档观察。公开质量反馈已接入,自动任务持久化、复检关闭、完整规则及完整 JDK/源码闭包和跨项目/custom doclet 验收仍待完成。见 [公开 Javadoc 入口验收](../tests/acceptance/gradle-public-javadoc-check.md)。

0 commit comments

Comments
 (0)