Skip to content

Commit

Permalink
feat: migrate blueprint-build-utils
Browse files Browse the repository at this point in the history
  • Loading branch information
Serial-ATA committed Dec 25, 2024
1 parent b49d63b commit 9c3fcca
Show file tree
Hide file tree
Showing 5 changed files with 134 additions and 1 deletion.
8 changes: 8 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ broken_intra_doc_links = "deny"
# Blueprint utils
blueprint-util-meta = { version = "0.1.0", path = "./crates/blueprint", default-features = false }
blueprint-metadata = { version = "0.2.1", path = "./crates/blueprint/metadata", default-features = false }
blueprint-build-utils = { version = "0.1.0", path = "./crates/blueprint/build-utils", default-features = false }
gadget-blueprint-serde = { version = "0.3.1", path = "./crates/blueprint/serde", default-features = false }

# Crypto
Expand Down
4 changes: 3 additions & 1 deletion crates/blueprint/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ edition.workspace = true
license.workspace = true
homepage.workspace = true
repository.workspace = true
publish = false

[dependencies]
blueprint-metadata.workspace = true
blueprint-metadata.workspace = true
blueprint-build-utils.workspace = true
16 changes: 16 additions & 0 deletions crates/blueprint/build-utils/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
[package]
name = "blueprint-build-utils"
version = "0.1.0"
description = "Tangle Blueprint build utils"
authors.workspace = true
edition.workspace = true
license.workspace = true
homepage.workspace = true
repository.workspace = true
publish = false

[dependencies]
gadget-std = { workspace = true, features = ["std"] }

[lints]
workspace = true
106 changes: 106 additions & 0 deletions crates/blueprint/build-utils/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
use gadget_std::env;
use gadget_std::path::PathBuf;
use gadget_std::process::Command;

/// Build the Smart contracts at the specified directories.
///
/// This function will automatically rerun the build if changes are detected in the `src`
/// directory within any of the directories specified. Due to this, it is recommended to
/// ensure that you only pass in directories that contain the `src` directory and won't be
/// modified by anything else in the build script (otherwise, the build will always rerun).
///
/// # Panics
/// - If the Cargo Manifest directory is not found.
/// - If the `forge` executable is not found.
pub fn build_contracts(contract_dirs: Vec<&str>) {
for dir in contract_dirs.clone() {
let dir = format!("{}/src", dir);
println!("cargo::rerun-if-changed={dir}");
}

// Get the project root directory
let root = PathBuf::from(env::var("CARGO_MANIFEST_DIR").unwrap());

// Try to find the `forge` executable dynamically
let forge_executable = find_forge_executable();

for dir in contract_dirs {
let full_path = root.join(dir).canonicalize().unwrap_or_else(|_| {
println!(
"Directory not found or inaccessible: {}",
root.join(dir).display()
);
root.join(dir)
});

if full_path.exists() {
let status = Command::new(&forge_executable)
.current_dir(&full_path)
.arg("build")
.status()
.expect("Failed to execute Forge build");

assert!(
status.success(),
"Forge build failed for directory: {}",
full_path.display()
);
} else {
println!(
"Directory not found or does not exist: {}",
full_path.display()
);
}
}
}

/// Run soldeer's `update` command to populate the `dependencies` directory.
///
/// # Panics
/// - If the Cargo Manifest directory is not found.
/// - If the `forge` executable is not found.
/// - If forge's `soldeer` is not installed.
pub fn soldeer_update() {
// Get the project root directory
let root = PathBuf::from(env::var("CARGO_MANIFEST_DIR").unwrap());

// Try to find the `forge` executable dynamically
let forge_executable = find_forge_executable();

println!("Populating dependencies directory");
let status = Command::new(&forge_executable)
.current_dir(&root)
.args(["soldeer", "install"])
.status()
.expect("Failed to execute 'forge soldeer update'");

assert!(status.success(), "'forge soldeer install' failed");

let status = Command::new(&forge_executable)
.current_dir(&root)
.args(["soldeer", "update", "-d"])
.status()
.expect("Failed to execute 'forge soldeer update'");

assert!(status.success(), "'forge soldeer update' failed");
}

/// Returns a string with the path to the `forge` executable.
///
/// # Panics
/// - If the `forge` executable is not found i.e., if Foundry is not installed.
#[must_use]
pub fn find_forge_executable() -> String {
// Try to find the `forge` executable dynamically
match Command::new("which").arg("forge").output() {
Ok(output) => {
let path = String::from_utf8_lossy(&output.stdout).trim().to_string();
assert!(
!path.is_empty(),
"Forge executable not found. Make sure Foundry is installed."
);
path
}
Err(e) => panic!("Failed to find `forge` executable: {e}"),
}
}

0 comments on commit 9c3fcca

Please sign in to comment.