Mercurial > core / rust/lib/util/src/bs/git.rs
changeset 698: |
96958d3eb5b0 |
parent: |
0ccbbd142694
|
author: |
Richard Westhaver <ellis@rwest.io> |
date: |
Fri, 04 Oct 2024 22:04:59 -0400 |
permissions: |
-rw-r--r-- |
description: |
fixes |
1 use std::{env, fs, fs::File, io, io::Read, path::PathBuf}; 2 /// Make sure the calling `build.rs` script is rerun when `.git/HEAD` or the ref 3 /// of `.git/HEAD` changed. 5 /// The file is searched from the `CARGO_MANIFEST_DIR` upwards. If the file can 6 /// not be found, a warning is generated. 7 pub fn rerun_if_git_head_changed() { 8 let mut manifest_dir = PathBuf::from( 9 env::var("CARGO_MANIFEST_DIR") 10 .expect("`CARGO_MANIFEST_DIR` is always set by cargo."), 12 let manifest_dir_copy = manifest_dir.clone(); 14 while manifest_dir.parent().is_some() { 15 match get_git_paths(&manifest_dir) { 17 eprintln!("cargo:warning=Unable to read the Git repository: {}", err); 24 println!("cargo:rerun-if-changed={}", p.display()); 35 "cargo:warning=Could not find `.git/HEAD` searching from `{}` upwards!", 36 manifest_dir_copy.display(), 40 // Code taken from https://github.com/rustyhorde/vergen/blob/8d522db8c8e16e26c0fc9ea8e6b0247cbf5cca84/src/output/envvar.rs 41 fn get_git_paths(path: &PathBuf) -> Result<Option<Vec<PathBuf>>, io::Error> { 42 let git_dir_or_file = path.join(".git"); 44 if let Ok(metadata) = fs::metadata(&git_dir_or_file) { 45 if metadata.is_dir() { 47 let git_head_path = git_dir_or_file.join("HEAD"); 49 // Determine where HEAD points and echo that path also. 50 let mut f = File::open(&git_head_path)?; 51 let mut git_head_contents = String::new(); 52 let _ = f.read_to_string(&mut git_head_contents)?; 53 let ref_vec: Vec<&str> = git_head_contents.split(": ").collect(); 55 if ref_vec.len() == 2 { 56 let current_head_file = ref_vec[1]; 57 let git_refs_path = git_dir_or_file.join(current_head_file); 59 Ok(Some(vec![git_head_path, git_refs_path])) 63 "You are most likely in a detached HEAD state", 66 } else if metadata.is_file() { 67 // We are in a worktree, so find out where the actual 68 // worktrees/<name>/HEAD file is. 69 let mut git_file = File::open(&git_dir_or_file)?; 70 let mut git_contents = String::new(); 71 let _ = git_file.read_to_string(&mut git_contents)?; 72 let dir_vec: Vec<&str> = git_contents.split(": ").collect(); 73 let git_path = dir_vec[1].trim(); 76 let git_head_path = PathBuf::from(git_path).join("HEAD"); 78 // Find out what the full path to the .git dir is. 79 let mut actual_git_dir = PathBuf::from(git_path); 83 // Determine where HEAD points and echo that path also. 84 let mut f = File::open(&git_head_path)?; 85 let mut git_head_contents = String::new(); 86 let _ = f.read_to_string(&mut git_head_contents)?; 87 let ref_vec: Vec<&str> = git_head_contents.split(": ").collect(); 89 if ref_vec.len() == 2 { 90 let current_head_file = ref_vec[1]; 91 let git_refs_path = actual_git_dir.join(current_head_file); 93 Ok(Some(vec![git_head_path, git_refs_path])) 97 "You are most likely in a detached HEAD state", 102 io::ErrorKind::Other, 103 "Invalid .git format (Not a directory or a file)",