diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index df1df56..9d22778 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -19,7 +19,7 @@ jobs: - uses: actions-rs/cargo@v1 with: command: test - args: --all-features + args: --all-features -- --nocapture fmt: name: Rustfmt diff --git a/build.rs b/build.rs index c08e00b..94ba40b 100644 --- a/build.rs +++ b/build.rs @@ -1,8 +1,10 @@ use std::{ + cell::OnceCell, env, fs::File, io::Write, path::{Path, PathBuf}, + process::Command, }; #[derive(Debug)] @@ -10,6 +12,7 @@ struct Sitter { path: PathBuf, src: PathBuf, lang: String, + version: OnceCell, } impl Sitter { @@ -23,6 +26,7 @@ impl Sitter { path, src, lang: lang.to_owned(), + version: OnceCell::new(), } } None => { @@ -33,6 +37,7 @@ impl Sitter { src: path.join("src"), path, lang, + version: OnceCell::new(), } } }; @@ -48,6 +53,19 @@ impl Sitter { self.src.clone() } + fn version(&self) -> &str { + self.version.get_or_init(|| { + let output = Command::new("git") + .arg("rev-parse") + .arg(format!("HEAD:{}", self.src.display())) + .output() + .expect("git rev-parse") + .stdout; + + String::from_utf8(output).expect("utf-8").trim().to_owned() + }) + } + fn grammar(&self) -> Option { let p = self.path.join("grammar.js"); p.exists().then_some(p) @@ -140,6 +158,8 @@ fn write_pepegsit(sitter @ Sitter { lang, .. }: &Sitter) -> std::io::Result<()> let dest_path = Path::new(&env::var_os("OUT_DIR").unwrap()).join(format!("lang_{lang}.rs")); let mut output = File::create(dest_path)?; + let version = sitter.version(); + writeln!( output, r#" @@ -155,6 +175,11 @@ fn write_pepegsit(sitter @ Sitter { lang, .. }: &Sitter) -> std::io::Result<()> pub fn language() -> Language {{ unsafe {{ tree_sitter_{lang}() }} }} + + /// Get the commit hash or version of this grammar. + pub const fn version() -> &'static str {{ + "{version}" + }} "# )?; @@ -227,6 +252,10 @@ fn write_pepegsit(sitter @ Sitter { lang, .. }: &Sitter) -> std::io::Result<()> output, r#" #[test] + fn test_print_version() {{ + println!("{{}}", super::version()); + }} + #[test] fn test_can_load_grammar() {{ let mut parser = tree_sitter::Parser::new(); parser