From 896404c7ead29c4c19564581ccb53b913440a583 Mon Sep 17 00:00:00 2001 From: Pascal Kuthe Date: Fri, 14 Apr 2023 16:59:52 +0200 Subject: [PATCH] emit cargo metadata duiring build scripts to avoid outdated buildscript outputs (#6743) * rebuild on revision change * rerun grammar build if grammars change --- helix-loader/build.rs | 39 ++++++++++++++++++++++++++++++++++++- helix-loader/src/grammar.rs | 12 ++++++++++++ 2 files changed, 50 insertions(+), 1 deletion(-) diff --git a/helix-loader/build.rs b/helix-loader/build.rs index c4b89e6b..63548a0c 100644 --- a/helix-loader/build.rs +++ b/helix-loader/build.rs @@ -1,4 +1,5 @@ use std::borrow::Cow; +use std::path::Path; use std::process::Command; const VERSION: &str = include_str!("../VERSION"); @@ -11,7 +12,7 @@ fn main() { .filter(|output| output.status.success()) .and_then(|x| String::from_utf8(x.stdout).ok()); - let version: Cow<_> = match git_hash { + let version: Cow<_> = match &git_hash { Some(git_hash) => format!("{} ({})", VERSION, &git_hash[..8]).into(), None => VERSION.into(), }; @@ -23,4 +24,40 @@ fn main() { println!("cargo:rerun-if-changed=../VERSION"); println!("cargo:rustc-env=VERSION_AND_GIT_HASH={}", version); + + if git_hash.is_none() { + return; + } + + // we need to revparse because the git dir could be anywhere if you are + // using detached worktrees but there is no good way to obtain an OsString + // from command output so for now we can't accept non-utf8 paths here + // probably rare enouch where it doesn't matter tough we could use gitoxide + // here but that would be make it a hard dependency and slow compile times + let Some(git_dir): Option = Command::new("git") + .args(["rev-parse", "--git-dir"]) + .output() + .ok() + .filter(|output| output.status.success()) + .and_then(|x| String::from_utf8(x.stdout).ok()) + else{ return; }; + // If heads starts pointing at something else (different branch) + // we need to return + let head = Path::new(&git_dir).join("HEAD"); + if head.exists() { + println!("cargo:rerun-if-changed={}", head.display()); + } + // if the thing head points to (branch) itself changes + // we need to return + let Some(head_ref): Option = Command::new("git") + .args(["symbolic-ref", "HEAD"]) + .output() + .ok() + .filter(|output| output.status.success()) + .and_then(|x| String::from_utf8(x.stdout).ok()) + else{ return; }; + let head_ref = Path::new(&git_dir).join(head_ref); + if head_ref.exists() { + println!("cargo:rerun-if-changed={}", head_ref.display()); + } } diff --git a/helix-loader/src/grammar.rs b/helix-loader/src/grammar.rs index a85cb274..2eb59a38 100644 --- a/helix-loader/src/grammar.rs +++ b/helix-loader/src/grammar.rs @@ -413,6 +413,18 @@ fn build_tree_sitter_library( let mut library_path = parser_lib_path.join(&grammar.grammar_id); library_path.set_extension(DYLIB_EXTENSION); + // if we are running inside a buildscript emit cargo metadata + // to detect if we are running from a buildscript check some env variables + // that cargo only sets for build scripts + if std::env::var("OUT_DIR").is_ok() && std::env::var("CARGO").is_ok() { + if let Some(scanner_path) = scanner_path.as_ref().and_then(|path| path.to_str()) { + println!("cargo:rerun-if-changed={scanner_path}"); + } + if let Some(parser_path) = parser_path.to_str() { + println!("cargo:rerun-if-changed={parser_path}"); + } + } + let recompile = needs_recompile(&library_path, &parser_path, &scanner_path) .context("Failed to compare source and binary timestamps")?;