xtask/
update_langs.rs

1use std::fs;
2
3use anyhow::Result;
4use lazy_regex::regex_replace;
5
6use crate::add_lang;
7
8pub fn run() -> Result<()> {
9    let langs_toml_path = crate::WORKSPACE_DIR.join("syntastica-macros/languages.toml");
10    let langs_toml = fs::read_to_string(&langs_toml_path)?;
11    let langs = langs_toml
12        .split("\n\n")
13        .zip(&crate::LANGUAGE_CONFIG.languages)
14        .map(|(toml, lang)| {
15            println!("\x1b[1;34m>>> updating {}\x1b[0m", lang.name);
16
17            // fetch new versions
18            let rev = add_lang::get_rev(&lang.parser.git.url)?;
19            println!("rev: {} -> {rev}", &lang.parser.git.rev);
20            let crates_io = add_lang::try_get_crates_io_version(&lang.parser.package);
21            println!("crates.io: {:?} -> {crates_io:?}", &lang.parser.crates_io);
22            // TODO: check compat for gitdep?
23            let content_url = add_lang::url_to_content_url(&lang.parser.git.url, &rev);
24            let path_in_url = match &lang.parser.git.path {
25                Some(path) => format!("/{path}"),
26                None => String::new(),
27            };
28            let external_c = content_url.as_ref().is_some_and(|url| {
29                reqwest::blocking::get(format!("{url}{path_in_url}/src/scanner.c"))
30                    .is_ok_and(|response| response.status().is_success())
31            });
32            println!("external C: {external_c}");
33            let external_cpp = content_url.as_ref().is_some_and(|url| {
34                reqwest::blocking::get(format!("{url}{path_in_url}/src/scanner.cc"))
35                    .is_ok_and(|response| response.status().is_success())
36            });
37            println!("external C++: {external_cpp}");
38
39            // update in toml string
40            let toml = regex_replace!(
41                r#"^(\s*git\s*=\s*\{\s*url\s*=\s*"[^"]*"\s*,\s*rev\s*=\s*")[^"]*("\s*(?:,\s*path\s*=\s*"[^"]*"\s*)?\}\s*)$"#m,
42                toml,
43                |_, start, end| format!("{start}{rev}{end}"),
44            );
45            let toml = if let Some(crates_io) = crates_io {
46                regex_replace!(
47                    r#"^(?:\s*#\s*)?(\s*crates-io\s*=\s*")[^"]*("\s*)$"#m,
48                    &toml,
49                    |_, start, end| format!("{start}{crates_io}{end}"),
50                )
51            } else if let Some(old_crates_io) = &lang.parser.crates_io {
52                // no longer compatible, remove crates-io version
53                regex_replace!(
54                    r#"^(?:\s*#\s*)?(\s*crates-io\s*=\s*")[^"]*("\s*)$"#m,
55                    &toml,
56                    |_, start, end| format!("# {start}{old_crates_io}{end}"),
57                )
58            } else {
59                toml
60            };
61            let toml = regex_replace!(
62                r#"^(\s*external-scanner\s*=\s*\{\s*c\s*=\s*)(?:true|false)(\s*,\s*cpp\s*=\s*)(?:true|false)(\s*\}\s*)$"#m,
63                &toml,
64                |_, start, middle, end| format!("{start}{external_c}{middle}{external_cpp}{end}"),
65            );
66
67            Ok(toml.into_owned())
68        })
69        .collect::<Result<Vec<_>>>()?
70        .join("\n\n");
71    fs::write(&langs_toml_path, langs)?;
72
73    Ok(())
74}