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