1use std::path::Path;
5use std::str::FromStr;
6
7use crate::diagnostics::{CheckId, DiagCtx};
8
9const RUSTDOC_JSON_TYPES: &str = "src/rustdoc-json-types";
10
11pub fn check(src_path: &Path, ci_info: &crate::CiInfo, diag_ctx: DiagCtx) {
12 let mut check = diag_ctx.start_check(CheckId::new("rustdoc_json").path(src_path));
13
14 let Some(base_commit) = &ci_info.base_commit else {
15 check.verbose_msg("No base commit, skipping rustdoc_json check");
16 return;
17 };
18
19 if !crate::files_modified(ci_info, |p| p.starts_with(RUSTDOC_JSON_TYPES)) {
21 return;
23 }
24
25 check.message("`rustdoc-json-types` modified, checking format version");
26
27 match crate::git_diff(base_commit, src_path.join("rustdoc-json-types")) {
29 Some(output) => {
30 let mut format_version_updated = false;
31 let mut latest_feature_comment_updated = false;
32 let mut new_version = None;
33 let mut old_version = None;
34 for line in output.lines() {
35 if line.starts_with("+pub const FORMAT_VERSION: u32 =") {
36 format_version_updated = true;
37 new_version = line
38 .split('=')
39 .nth(1)
40 .and_then(|s| s.trim().split(';').next())
41 .and_then(|s| u32::from_str(s.trim()).ok());
42 } else if line.starts_with("-pub const FORMAT_VERSION: u32 =") {
43 old_version = line
44 .split('=')
45 .nth(1)
46 .and_then(|s| s.trim().split(';').next())
47 .and_then(|s| u32::from_str(s.trim()).ok());
48 } else if line.starts_with("+// Latest feature:") {
49 latest_feature_comment_updated = true;
50 }
51 }
52 if format_version_updated != latest_feature_comment_updated {
53 let msg = if latest_feature_comment_updated {
54 format!(
55 "`Latest feature` comment was updated whereas `FORMAT_VERSION` wasn't in `{RUSTDOC_JSON_TYPES}/lib.rs`"
56 )
57 } else {
58 format!(
59 "`Latest feature` comment was not updated whereas `FORMAT_VERSION` was in `{RUSTDOC_JSON_TYPES}/lib.rs`"
60 )
61 };
62 check.error(msg);
63 }
64 match (new_version, old_version) {
65 (Some(new_version), Some(old_version)) if new_version != old_version + 1 => {
66 check.error(format!(
67 "invalid `FORMAT_VERSION` increase in `{RUSTDOC_JSON_TYPES}/lib.rs`, should be `{}`, found `{new_version}`",
68 old_version + 1,
69 ));
70 }
71 _ => {}
72 }
73 }
74 None => {
75 check.error("failed to run `git diff` in rustdoc_json check");
76 }
77 }
78}