|
15 | 15 | //! export FOO=42
|
16 | 16 | //! # tidy-ticket-foo
|
17 | 17 | use std::fs;
|
18 |
| -use std::path::Path; |
| 18 | +use std::fs::OpenOptions; |
| 19 | +use std::path::{Path, PathBuf}; |
19 | 20 |
|
20 | 21 | use md5::{Digest, Md5};
|
| 22 | +use serde::{Deserialize, Serialize}; |
| 23 | +use serde_json; |
21 | 24 |
|
22 | 25 | #[cfg(test)]
|
23 | 26 | mod tests;
|
24 | 27 |
|
| 28 | +#[derive(Deserialize, Serialize, Debug)] |
| 29 | +struct TagGroups { |
| 30 | + tag_groups: Vec<TagGroup>, |
| 31 | +} |
| 32 | + |
| 33 | +#[derive(Deserialize, Serialize, Debug)] |
| 34 | +struct TagGroup { |
| 35 | + name: String, |
| 36 | + #[serde(skip_serializing_if = "is_false")] |
| 37 | + #[serde(default)] |
| 38 | + /// if group sync in broken but you don't want to remove it |
| 39 | + is_off: bool, |
| 40 | + tags: Vec<Tag>, |
| 41 | +} |
| 42 | + |
| 43 | +#[derive(Deserialize, Serialize, Debug)] |
| 44 | +struct Tag { |
| 45 | + /// path to file |
| 46 | + path: PathBuf, |
| 47 | + /// md5 tag of tag content |
| 48 | + hash: String, |
| 49 | + /// tag string |
| 50 | + tag: String, |
| 51 | +} |
| 52 | + |
| 53 | +fn is_false(b: &bool) -> bool { |
| 54 | + !b |
| 55 | +} |
| 56 | + |
25 | 57 | /// Return hash for source text between 2 tag occurrence,
|
26 | 58 | /// ignoring lines where tag written
|
27 | 59 | ///
|
28 | 60 | /// Expecting:
|
29 | 61 | /// tag is not multiline
|
30 | 62 | /// source always have at least 2 occurrence of tag (>2 ignored)
|
31 |
| -fn span_hash(source: &str, tag: &str, bad: &mut bool) -> Result<String, ()> { |
| 63 | +fn span_hash(source: &str, tag: &str, bad: &mut bool, file_path: &Path) -> Result<String, ()> { |
32 | 64 | let start_idx = match source.find(tag) {
|
33 | 65 | Some(idx) => idx,
|
34 |
| - None => return Err(tidy_error!(bad, "tag {} should exist in provided text", tag)), |
| 66 | + None => { |
| 67 | + return Err(tidy_error!( |
| 68 | + bad, |
| 69 | + "tag {} should exist in file {}", |
| 70 | + tag, |
| 71 | + file_path.display() |
| 72 | + )); |
| 73 | + } |
35 | 74 | };
|
36 | 75 | let end_idx = {
|
37 | 76 | let end = match source[start_idx + tag.len()..].find(tag) {
|
@@ -61,120 +100,77 @@ fn span_hash(source: &str, tag: &str, bad: &mut bool) -> Result<String, ()> {
|
61 | 100 | Ok(format!("{:x}", hasher.finalize()))
|
62 | 101 | }
|
63 | 102 |
|
64 |
| -fn check_entry(entry: &ListEntry<'_>, group_idx: usize, bad: &mut bool, root_path: &Path) { |
65 |
| - let file = fs::read_to_string(root_path.join(Path::new(entry.0))) |
66 |
| - .unwrap_or_else(|e| panic!("{:?}, path: {}", e, entry.0)); |
67 |
| - let actual_hash = span_hash(&file, entry.2, bad).unwrap(); |
68 |
| - if actual_hash != entry.1 { |
69 |
| - // Write tidy error description for wather only once. |
70 |
| - // Will not work if there was previous errors of other types. |
71 |
| - if *bad == false { |
72 |
| - tidy_error!( |
73 |
| - bad, |
74 |
| - "The code blocks tagged with tidy watcher has changed.\n\ |
| 103 | +fn check_entry( |
| 104 | + entry: &mut Tag, |
| 105 | + tag_group_name: &str, |
| 106 | + bad: &mut bool, |
| 107 | + root_path: &Path, |
| 108 | + bless: bool, |
| 109 | +) { |
| 110 | + let file_path = root_path.join(Path::new(&entry.path)); |
| 111 | + let file = fs::read_to_string(&file_path) |
| 112 | + .unwrap_or_else(|e| panic!("{:?}, path: {}", e, entry.path.display())); |
| 113 | + let actual_hash = span_hash(&file, &entry.tag, bad, &file_path).unwrap(); |
| 114 | + if actual_hash != entry.hash { |
| 115 | + if !bless { |
| 116 | + // Write tidy error description for watcher only once. |
| 117 | + // Will not work if there was previous errors of other types. |
| 118 | + if *bad == false { |
| 119 | + tidy_error!( |
| 120 | + bad, |
| 121 | + "The code blocks tagged with tidy watcher has changed.\n\ |
75 | 122 | It's likely that code blocks with the following tags need to be changed too. Check src/tools/tidy/src/watcher.rs, find tag/hash in TIDY_WATCH_LIST list \
|
76 | 123 | and verify that sources for provided group of tags in sync. Once that done, run tidy again and update hashes in TIDY_WATCH_LIST with provided actual hashes."
|
77 |
| - ) |
| 124 | + ) |
| 125 | + } |
| 126 | + tidy_error!( |
| 127 | + bad, |
| 128 | + "hash for tag `{}` in path `{}` mismatch:\n actual: `{}`, expected: `{}`\n \ |
| 129 | + Verify that tags from tag_group `{}` in sync.", |
| 130 | + entry.tag, |
| 131 | + entry.path.display(), |
| 132 | + actual_hash, |
| 133 | + entry.hash, |
| 134 | + tag_group_name, |
| 135 | + ); |
| 136 | + } else { |
| 137 | + entry.hash = actual_hash; |
78 | 138 | }
|
79 |
| - tidy_error!( |
80 |
| - bad, |
81 |
| - "hash for tag `{}` in path `{}` mismatch:\n actual: `{}`, expected: `{}`\n \ |
82 |
| - Verify that tags `{:?}` in sync.", |
83 |
| - entry.2, |
84 |
| - entry.0, |
85 |
| - actual_hash, |
86 |
| - entry.1, |
87 |
| - TIDY_WATCH_LIST[group_idx].iter().map(|e| e.2).collect::<Vec<&str>>() |
88 |
| - ); |
89 | 139 | }
|
90 | 140 | }
|
91 | 141 |
|
92 |
| -macro_rules! add_group { |
93 |
| - ($($entry:expr),*) => { |
94 |
| - &[$($entry),*] |
95 |
| - }; |
96 |
| -} |
97 |
| - |
98 |
| -/// (path, hash, tag) |
99 |
| -type ListEntry<'a> = (&'a str, &'a str, &'a str); |
100 |
| - |
101 |
| -/// List of tags to watch, along with paths and hashes |
102 |
| -#[rustfmt::skip] |
103 |
| -const TIDY_WATCH_LIST: &[&[ListEntry<'_>]] = &[ |
104 |
| - add_group!( |
105 |
| - ("compiler/rustc_ast/src/token.rs", "2df3e863dc4caffb31a7ddf001517232", "tidy-ticket-ast-from_token"), |
106 |
| - ("compiler/rustc_ast/src/token.rs", "3279df5da05e0455f45630917fe2a797", "tidy-ticket-ast-can_begin_literal_maybe_minus"), |
107 |
| - ("compiler/rustc_parse/src/parser/expr.rs", "479655a8587512fc26f7361d7bbd75a5", "tidy-ticket-rustc_parse-can_begin_literal_maybe_minus") |
108 |
| - ), |
109 |
| - |
110 |
| - add_group!( |
111 |
| - ("compiler/rustc_builtin_macros/src/assert/context.rs", "dbac73cc47a451d4822ccd3010c40a0f", "tidy-ticket-all-expr-kinds"), |
112 |
| - ("tests/ui/macros/rfc-2011-nicer-assert-messages/all-expr-kinds.rs", "78ce54cc25baeac3ae07c876db25180c", "tidy-ticket-all-expr-kinds") |
113 |
| - ), |
114 |
| - |
115 |
| - add_group!( |
116 |
| - ("compiler/rustc_const_eval/src/interpret/validity.rs", "c4e96ecd3f81dcb54541b8ea41042e8f", "tidy-ticket-try_visit_primitive"), |
117 |
| - ("compiler/rustc_const_eval/src/interpret/validity.rs", "cbe69005510c1a87ab07db601c0d36b8", "tidy-ticket-visit_value") |
118 |
| - ), |
119 |
| - |
| 142 | +/* |
120 | 143 | // sync self-profile-events help mesage with actual list of events
|
121 | 144 | add_group!(
|
122 | 145 | ("compiler/rustc_data_structures/src/profiling.rs", "881e7899c7d6904af1bc000594ee0418", "tidy-ticket-self-profile-events"),
|
123 | 146 | ("compiler/rustc_session/src/options.rs", "012ee5a3b61ee1377744e5c6913fa00a", "tidy-ticket-self-profile-events")
|
124 | 147 | ),
|
125 | 148 |
|
126 |
| - add_group!( |
127 |
| - ("compiler/rustc_errors/src/json.rs", "3963a8c4eee7f87eeb076622b8a92891", "tidy-ticket-UnusedExterns"), |
128 |
| - ("src/librustdoc/doctest.rs", "14da85663568149c9b21686f4b7fa7b0", "tidy-ticket-UnusedExterns") |
129 |
| - ), |
130 |
| - |
131 |
| - add_group!( |
132 |
| - ("compiler/rustc_middle/src/ty/util.rs", "cae64b1bc854e7ee81894212facb5bfa", "tidy-ticket-static_ptr_ty"), |
133 |
| - ("compiler/rustc_middle/src/ty/util.rs", "6f5ead08474b4d3e358db5d3c7aef970", "tidy-ticket-thread_local_ptr_ty") |
134 |
| - ), |
135 |
| - |
136 | 149 | // desynced, pieces in compiler/rustc_pattern_analysis/src/rustc.rs
|
137 | 150 | // add_group!(
|
138 | 151 | // ("compiler/rustc_pattern_analysis/src/constructor.rs", "c17706947fc814aa5648972a5b3dc143", "tidy-ticket-arity"),
|
139 | 152 | // // ("compiler/rustc_mir_build/src/thir/pattern/deconstruct_pat.rs", "7ce77b84c142c22530b047703ef209f0", "tidy-ticket-wildcards")
|
140 | 153 | // ),
|
141 | 154 |
|
142 |
| - add_group!( |
143 |
| - ("compiler/rustc_monomorphize/src/partitioning.rs", "f4f33e9c14f4e0c3a20b5240ae36a7c8", "tidy-ticket-short_description"), |
144 |
| - ("compiler/rustc_codegen_ssa/src/back/write.rs", "5286f7f76fcf564c98d7a8eaeec39b18", "tidy-ticket-short_description") |
145 |
| - ), |
146 |
| - |
147 |
| - add_group!( |
148 |
| - ("compiler/rustc_session/src/config/sigpipe.rs", "330e0776ba5a6c0a7439a5235297f08f", "tidy-ticket-sigpipe"), |
149 |
| - ("library/std/src/sys/pal/unix/mod.rs", "2cdc37081831cdcf44f3331efbe440af", "tidy-ticket-sigpipe") |
150 |
| - ), |
151 |
| - |
152 |
| - add_group!( |
153 |
| - ("compiler/rustc_next_trait_solver/src/solve/assembly/structural_traits.rs", "8726918d084e0ac5bb07184008403f88", "tidy-ticket-extract_tupled_inputs_and_output_from_callable"), |
154 |
| - ("compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs", "be2967d323633c7458533c6cec228273", "tidy-ticket-assemble_fn_pointer_candidates") |
155 |
| - ), |
156 |
| - |
157 |
| - add_group!( |
158 |
| - ("compiler/rustc_trait_selection/src/traits/project.rs", "262d10feb1b7ba8d3ffb4a95314bf404", "tidy-ticket-assemble_candidates_from_impls-UserDefined"), |
159 |
| - ("compiler/rustc_ty_utils/src/instance.rs", "a51a6022efb405c5ee86acdf49ec222d", "tidy-ticket-resolve_associated_item-UserDefined") |
160 |
| - ), |
161 |
| - |
162 | 155 | // desynced, pieces in compiler/rustc_hir_analysis/src/lib.rs missing?
|
163 | 156 | //add_group!( // bad
|
164 | 157 | // ("compiler/rustc_hir_analysis/src/lib.rs", "842e23fb65caf3a96681686131093316", "tidy-ticket-sess-time-item_types_checking"),
|
165 | 158 | // ("src/librustdoc/core.rs", "85d9dd0cbb94fd521e2d15a8ed38a75f", "tidy-ticket-sess-time-item_types_checking")
|
166 | 159 | // ),
|
167 |
| - |
168 |
| - add_group!( |
169 |
| - ("library/core/src/ptr/metadata.rs", "357c958a096c33bed67cfc7212d940a2", "tidy-ticket-static_assert_expected_bounds_for_metadata"), |
170 |
| - ("library/core/tests/ptr.rs", "d8c47e54b871d72dfdce56e6a89b5c31", "tidy-ticket-static_assert_expected_bounds_for_metadata") |
171 |
| - ), |
172 |
| -]; |
173 |
| - |
174 |
| -pub fn check(root_path: &Path, bad: &mut bool) { |
175 |
| - for (group_idx, group) in TIDY_WATCH_LIST.iter().enumerate() { |
176 |
| - for entry in group.iter() { |
177 |
| - check_entry(entry, group_idx, bad, root_path); |
| 160 | +*/ |
| 161 | +pub fn check(root_path: &Path, bless: bool, bad: &mut bool) { |
| 162 | + let config_path = root_path.join(Path::new("src/tools/tidy/src/watcher_list.json")); |
| 163 | + let config_file = fs::read_to_string(&config_path).unwrap_or_else(|e| panic!("{:?}", e)); |
| 164 | + let mut tag_groups: TagGroups = serde_json::from_str(&config_file).unwrap(); |
| 165 | + for tag_group in tag_groups.tag_groups.iter_mut() { |
| 166 | + if !tag_group.is_off { |
| 167 | + for entry in tag_group.tags.iter_mut() { |
| 168 | + check_entry(entry, &tag_group.name, bad, root_path, bless); |
| 169 | + } |
178 | 170 | }
|
179 | 171 | }
|
| 172 | + if bless { |
| 173 | + let f = OpenOptions::new().write(true).truncate(true).open(config_path).unwrap(); |
| 174 | + serde_json::to_writer_pretty(f, &tag_groups).unwrap(); |
| 175 | + } |
180 | 176 | }
|
0 commit comments