diff options
| author | clubby789 <jamie@hill-daniel.co.uk> | 2023-05-23 01:51:25 +0000 |
|---|---|---|
| committer | clubby789 <jamie@hill-daniel.co.uk> | 2023-05-25 23:49:35 +0000 |
| commit | f97fddab91fbf290ea5b691fe355d6f915220b6e (patch) | |
| tree | 42228619ea3f9f572316bbd072540f1f077f03d2 /src/tools | |
| parent | a2b1646c597329d0a25efa3889b66650f65de1de (diff) | |
Ensure Fluent messages are in alphabetical order
Diffstat (limited to 'src/tools')
| -rw-r--r-- | src/tools/tidy/src/fluent_alphabetical.rs | 72 | ||||
| -rw-r--r-- | src/tools/tidy/src/lib.rs | 1 | ||||
| -rw-r--r-- | src/tools/tidy/src/main.rs | 1 |
3 files changed, 74 insertions, 0 deletions
diff --git a/src/tools/tidy/src/fluent_alphabetical.rs b/src/tools/tidy/src/fluent_alphabetical.rs new file mode 100644 index 00000000000..5f8eaebf531 --- /dev/null +++ b/src/tools/tidy/src/fluent_alphabetical.rs @@ -0,0 +1,72 @@ +//! Checks that all Flunt files have messages in alphabetical order + +use crate::walk::{filter_dirs, walk}; +use std::{fs::OpenOptions, io::Write, path::Path}; + +use regex::Regex; + +lazy_static::lazy_static! { + static ref MESSAGE: Regex = Regex::new(r#"(?m)^([a-zA-Z0-9_]+)\s*=\s*"#).unwrap(); +} + +fn filter_fluent(path: &Path) -> bool { + if let Some(ext) = path.extension() { ext.to_str() != Some("ftl") } else { true } +} + +fn check_alphabetic(filename: &str, fluent: &str, bad: &mut bool) { + let mut matches = MESSAGE.captures_iter(fluent).peekable(); + while let Some(m) = matches.next() { + if let Some(next) = matches.peek() { + let name = m.get(1).unwrap(); + let next = next.get(1).unwrap(); + if name.as_str() > next.as_str() { + tidy_error!( + bad, + "{filename}: message `{}` appears before `{}`, but is alphabetically later than it +run tidy with `--bless` to sort the file correctly", + name.as_str(), + next.as_str() + ); + } + } else { + break; + } + } +} + +fn sort_messages(fluent: &str) -> String { + let mut chunks = vec![]; + let mut cur = String::new(); + for line in fluent.lines() { + if MESSAGE.is_match(line) { + chunks.push(std::mem::take(&mut cur)); + } + cur += line; + cur.push('\n'); + } + chunks.push(cur); + chunks.sort(); + let mut out = chunks.join(""); + out = out.trim().to_string(); + out.push('\n'); + out +} + +pub fn check(path: &Path, bless: bool, bad: &mut bool) { + walk( + path, + |path, is_dir| filter_dirs(path) || (!is_dir && filter_fluent(path)), + &mut |ent, contents| { + if bless { + let sorted = sort_messages(contents); + if sorted != contents { + let mut f = + OpenOptions::new().write(true).truncate(true).open(ent.path()).unwrap(); + f.write(sorted.as_bytes()).unwrap(); + } + } else { + check_alphabetic(ent.path().to_str().unwrap(), contents, bad); + } + }, + ); +} diff --git a/src/tools/tidy/src/lib.rs b/src/tools/tidy/src/lib.rs index 35000320d1a..e467514a7a3 100644 --- a/src/tools/tidy/src/lib.rs +++ b/src/tools/tidy/src/lib.rs @@ -59,6 +59,7 @@ pub mod edition; pub mod error_codes; pub mod extdeps; pub mod features; +pub mod fluent_alphabetical; pub mod mir_opt_tests; pub mod pal; pub mod primitive_docs; diff --git a/src/tools/tidy/src/main.rs b/src/tools/tidy/src/main.rs index f59406c404b..1c4d96c321c 100644 --- a/src/tools/tidy/src/main.rs +++ b/src/tools/tidy/src/main.rs @@ -96,6 +96,7 @@ fn main() { // Checks that only make sense for the compiler. check!(error_codes, &root_path, &[&compiler_path, &librustdoc_path], verbose); + check!(fluent_alphabetical, &compiler_path, bless); // Checks that only make sense for the std libs. check!(pal, &library_path); |
