From 6b18056ece786c602b8873aab01c024bea2f6398 Mon Sep 17 00:00:00 2001 From: Sasha Aldrick Date: Tue, 5 Nov 2024 11:29:18 +0000 Subject: [PATCH] change to git submodule init + warnings for submodule status --- methods/build.rs | 99 ++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 84 insertions(+), 15 deletions(-) diff --git a/methods/build.rs b/methods/build.rs index 7212ce41..59cc061c 100644 --- a/methods/build.rs +++ b/methods/build.rs @@ -21,22 +21,9 @@ use risc0_build_ethereum::generate_solidity_files; const SOLIDITY_IMAGE_ID_PATH: &str = "../contracts/ImageID.sol"; const SOLIDITY_ELF_PATH: &str = "../tests/Elf.sol"; -fn run_git_submodule_update() { - let output = Command::new("git") - .args(["submodule", "update", "--init"]) - .output() - .expect("failed to run git submodule update in methods/build.rs"); - - if !output.status.success() { - panic!( - "git submodule update failed (methods/build.rs): {}", - String::from_utf8_lossy(&output.stderr) - ); - } -} - fn main() { - run_git_submodule_update(); + git_submodule_init(); + check_submodule_state(); println!("cargo:rerun-if-changed=.gitmodules"); // Builds can be made deterministic, and thereby reproducible, by using Docker to build the @@ -62,3 +49,85 @@ fn main() { generate_solidity_files(guests.as_slice(), &solidity_opts).unwrap(); } + +/// Initializes git submodules by adding their configurations to .git/config. +/// This is a one-time setup step that only needs to run on first clone of the repository. +/// Does not fetch or update submodule contents. +/// +/// # Warnings +/// Prints a warning to stderr if the initialization fails, but does not interrupt the build process. +fn git_submodule_init() { + let output = Command::new("git") + .args(["submodule", "init"]) + .output() + .expect("failed to run git submodule init in methods/build.rs"); + + if !output.status.success() { + eprintln!( + "WARNING: git submodule init failed (methods/build.rs): {}", + String::from_utf8_lossy(&output.stderr) + ); + } +} + +/// Checks and reports the status of all git submodules in the project. +/// Runs on every build to inform developers about the state of their submodules. +/// +/// # Status Indicators +/// - `-`: submodule is not initialized +/// - `+`: submodule has local changes +/// - ` `: submodule is clean (no warning displayed) +/// +/// # Warnings +/// Prints warnings for any non-clean states, but does not modify submodules +/// or interrupt the build process. +fn check_submodule_state() { + let status = Command::new("git") + .args(["submodule", "status"]) + .output() + .expect("failed to run git submodule status"); + + if !status.status.success() { + println!( + "cargo:warning=failed to check git submodule status: {}", + String::from_utf8_lossy(&status.stderr) + ); + return; + } + + let output = String::from_utf8_lossy(&status.stdout); + let mut has_uninitialized = false; + let mut has_local_changes = false; + + for line in output.lines() { + let path = line + .split_whitespace() + .nth(1) + .unwrap_or("unknown path") + .replace("../", ""); + + if let Some(first_char) = line.chars().next() { + match first_char { + '-' => { + println!("cargo:warning=git submodule not initialized: {}", path); + has_uninitialized = true; + } + '+' => { + println!("cargo:warning=git submodule has local changes, this may cause unexpected behaviour: {}", path); + has_local_changes = true; + } + _ => (), + } + } + } + + if has_uninitialized { + println!( + "cargo:warning=to initialize missing submodules, run: git submodule update --init" + ); + } + + if has_local_changes { + println!("cargo:warning=to reset submodules to their expected versions, run: git submodule update --recursive"); + } +} \ No newline at end of file