tidy/
rustdoc_json.rs

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