]> git.lizzy.rs Git - rust.git/blob - src/tools/tidy/src/unstable_book.rs
Rollup merge of #61879 - stjepang:stabilize-todo, r=withoutboats
[rust.git] / src / tools / tidy / src / unstable_book.rs
1 use std::collections::BTreeSet;
2 use std::fs;
3 use std::path::{PathBuf, Path};
4 use crate::features::{CollectedFeatures, Features, Feature, Status};
5
6 pub const PATH_STR: &str = "doc/unstable-book";
7
8 pub const COMPILER_FLAGS_DIR: &str = "src/compiler-flags";
9
10 pub const LANG_FEATURES_DIR: &str = "src/language-features";
11
12 pub const LIB_FEATURES_DIR: &str = "src/library-features";
13
14 /// Builds the path to the Unstable Book source directory from the Rust 'src' directory.
15 pub fn unstable_book_path(base_src_path: &Path) -> PathBuf {
16     base_src_path.join(PATH_STR)
17 }
18
19 /// Builds the path to the directory where the features are documented within the Unstable Book
20 /// source directory.
21 pub fn unstable_book_lang_features_path(base_src_path: &Path) -> PathBuf {
22     unstable_book_path(base_src_path).join(LANG_FEATURES_DIR)
23 }
24
25 /// Builds the path to the directory where the features are documented within the Unstable Book
26 /// source directory.
27 pub fn unstable_book_lib_features_path(base_src_path: &Path) -> PathBuf {
28     unstable_book_path(base_src_path).join(LIB_FEATURES_DIR)
29 }
30
31 /// Tests whether `DirEntry` is a file.
32 fn dir_entry_is_file(dir_entry: &fs::DirEntry) -> bool {
33     dir_entry
34         .file_type()
35         .expect("could not determine file type of directory entry")
36         .is_file()
37 }
38
39 /// Retrieves names of all unstable features.
40 pub fn collect_unstable_feature_names(features: &Features) -> BTreeSet<String> {
41     features
42         .iter()
43         .filter(|&(_, ref f)| f.level == Status::Unstable)
44         .map(|(name, _)| name.replace('_', "-"))
45         .collect()
46 }
47
48 pub fn collect_unstable_book_section_file_names(dir: &Path) -> BTreeSet<String> {
49     fs::read_dir(dir)
50         .expect("could not read directory")
51         .map(|entry| entry.expect("could not read directory entry"))
52         .filter(dir_entry_is_file)
53         .map(|entry| entry.path())
54         .filter(|path| path.extension().map(|e| e.to_str().unwrap()) == Some("md"))
55         .map(|path| path.file_stem().unwrap().to_str().unwrap().into())
56         .collect()
57 }
58
59 /// Retrieves file names of all library feature sections in the Unstable Book with:
60 ///
61 /// * hyphens replaced by underscores,
62 /// * the markdown suffix ('.md') removed.
63 fn collect_unstable_book_lang_features_section_file_names(base_src_path: &Path)
64                                                           -> BTreeSet<String> {
65     collect_unstable_book_section_file_names(&unstable_book_lang_features_path(base_src_path))
66 }
67
68 /// Retrieves file names of all language feature sections in the Unstable Book with:
69 ///
70 /// * hyphens replaced by underscores,
71 /// * the markdown suffix ('.md') removed.
72 fn collect_unstable_book_lib_features_section_file_names(base_src_path: &Path) -> BTreeSet<String> {
73     collect_unstable_book_section_file_names(&unstable_book_lib_features_path(base_src_path))
74 }
75
76 pub fn check(path: &Path, features: CollectedFeatures, bad: &mut bool) {
77     let lang_features = features.lang;
78     let mut lib_features = features.lib.into_iter().filter(|&(ref name, _)| {
79         !lang_features.contains_key(name)
80     }).collect::<Features>();
81
82     // This library feature is defined in the `compiler_builtins` crate, which
83     // has been moved out-of-tree. Now it can no longer be auto-discovered by
84     // `tidy`, because we need to filter out its (submodule) directory. Manually
85     // add it to the set of known library features so we can still generate docs.
86     lib_features.insert("compiler_builtins_lib".to_owned(), Feature {
87         level: Status::Unstable,
88         since: None,
89         has_gate_test: false,
90         tracking_issue: None,
91     });
92
93     // Library features
94     let unstable_lib_feature_names = collect_unstable_feature_names(&lib_features);
95     let unstable_book_lib_features_section_file_names =
96         collect_unstable_book_lib_features_section_file_names(path);
97
98     // Language features
99     let unstable_lang_feature_names = collect_unstable_feature_names(&lang_features);
100     let unstable_book_lang_features_section_file_names =
101         collect_unstable_book_lang_features_section_file_names(path);
102
103     // Check for Unstable Book sections that don't have a corresponding unstable feature
104     for feature_name in &unstable_book_lib_features_section_file_names -
105                         &unstable_lib_feature_names {
106         if !unstable_lang_feature_names.contains(&feature_name) {
107             tidy_error!(bad,
108                         "The Unstable Book has a 'library feature' section '{}' which doesn't \
109                          correspond to an unstable library feature",
110                         feature_name);
111         }
112     }
113
114     // Check for Unstable Book sections that don't have a corresponding unstable feature.
115     for feature_name in &unstable_book_lang_features_section_file_names -
116                         &unstable_lang_feature_names {
117         tidy_error!(bad,
118                     "The Unstable Book has a 'language feature' section '{}' which doesn't \
119                      correspond to an unstable language feature",
120                     feature_name)
121     }
122
123     // List unstable features that don't have Unstable Book sections.
124     // Remove the comment marker if you want the list printed.
125     /*
126     println!("Lib features without unstable book sections:");
127     for feature_name in &unstable_lang_feature_names -
128                         &unstable_book_lang_features_section_file_names {
129         println!("    * {} {:?}", feature_name, lib_features[&feature_name].tracking_issue);
130     }
131
132     println!("Lang features without unstable book sections:");
133     for feature_name in &unstable_lib_feature_names-
134                         &unstable_book_lib_features_section_file_names {
135         println!("    * {} {:?}", feature_name, lang_features[&feature_name].tracking_issue);
136     }
137     // */
138 }