From 69bea8748c90d2c4877397007181499c9817a997 Mon Sep 17 00:00:00 2001 From: Zeke Foppa Date: Mon, 24 Nov 2025 10:05:16 -0800 Subject: [PATCH] [bfops/revert-3568]: Revert "Remove the dependency on git ls-files from cli/build.rs (#3568)" This reverts commit 53f692dec673c0008923d00b5aa9ef83c4066d9d. --- crates/cli/build.rs | 55 +++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 51 insertions(+), 4 deletions(-) diff --git a/crates/cli/build.rs b/crates/cli/build.rs index 33ddc399094..45b2b7da86f 100644 --- a/crates/cli/build.rs +++ b/crates/cli/build.rs @@ -34,6 +34,10 @@ fn nix_injected_commit_hash() -> Option { } } +fn is_nix_build() -> bool { + nix_injected_commit_hash().is_some() +} + fn find_git_hash() -> String { nix_injected_commit_hash().unwrap_or_else(|| { // When we're *not* building in Nix, we can assume that git metadata is still present in the filesystem, @@ -156,10 +160,10 @@ fn generate_template_files() { } fn generate_template_entry(code: &mut String, template_path: &Path, source: &str, manifest_dir: &Path) { - let (template_files, resolved_base) = list_all_files(template_path, manifest_dir); + let (git_files, resolved_base) = get_git_tracked_files(template_path, manifest_dir); - if template_files.is_empty() { - panic!("Template '{}' has no files, check if the path is correct", source); + if git_files.is_empty() { + panic!("Template '{}' has no git-tracked files! Check that the directory exists and contains files tracked by git.", source); } // Example: /Users/user/SpacetimeDB @@ -192,7 +196,7 @@ fn generate_template_entry(code: &mut String, template_path: &Path, source: &str code.push_str(" {\n"); code.push_str(" let mut files = HashMap::new();\n"); - for file_path in template_files { + for file_path in git_files { // Example file_path: modules/quickstart-chat/src/lib.rs (relative to repo root) // Example resolved_base: modules/quickstart-chat // Example relative_path: src/lib.rs @@ -255,6 +259,18 @@ fn generate_template_entry(code: &mut String, template_path: &Path, source: &str code.push_str(" }\n\n"); } +/// Get a list of files tracked by git from a given directory +fn get_git_tracked_files(path: &Path, manifest_dir: &Path) -> (Vec, PathBuf) { + if is_nix_build() { + // When building in Nix, we already know that there are no untracked files in our source tree, + // so we just list all of the files. + list_all_files(path, manifest_dir) + } else { + // When building outside of Nix, we invoke `git` to list all the tracked files. + get_git_tracked_files_via_cli(path, manifest_dir) + } +} + fn list_all_files(path: &Path, manifest_dir: &Path) -> (Vec, PathBuf) { let manifest_dir = manifest_dir.canonicalize().unwrap_or_else(|err| { panic!( @@ -330,6 +346,37 @@ fn make_repo_root_relative(full_path: &Path, repo_root: &Path) -> PathBuf { }) } +fn get_git_tracked_files_via_cli(path: &Path, manifest_dir: &Path) -> (Vec, PathBuf) { + let repo_root = get_repo_root(); + let repo_root = repo_root.canonicalize().unwrap_or_else(|err| { + panic!( + "Failed to canonicalize repo_root path {}: {err:#?}", + repo_root.display(), + ) + }); + + let resolved_path = make_repo_root_relative(&get_full_path_within_manifest_dir(path, manifest_dir), &repo_root); + + let output = Command::new("git") + .args(["ls-files", resolved_path.to_str().unwrap()]) + .current_dir(repo_root) + .output() + .expect("Failed to execute git ls-files"); + + if !output.status.success() { + return (Vec::new(), resolved_path); + } + + let stdout = String::from_utf8(output.stdout).unwrap(); + let files: Vec = stdout + .lines() + .filter(|line| !line.is_empty()) + .map(PathBuf::from) + .collect(); + + (files, resolved_path) +} + fn get_repo_root() -> PathBuf { let manifest_dir = get_manifest_dir(); // Cargo doesn't expose a way to get the workspace root, AFAICT (pgoldman 2025-10-31).