Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
71 changes: 29 additions & 42 deletions cli/src/forge.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ mod forge_opts;
use forge_opts::{EvmType, Opts, Subcommands};

use crate::forge_opts::FullContractInfo;
use std::{collections::HashMap, convert::TryFrom, path::Path, sync::Arc};
use std::{collections::HashMap, convert::TryFrom, sync::Arc};

mod cmd;
mod utils;
Expand Down Expand Up @@ -167,7 +167,6 @@ fn main() -> eyre::Result<()> {
}
// TODO: Make it work with updates?
Subcommands::Install { dependencies } => {
let repo = git2::Repository::open(".")?;
let libs = std::path::Path::new("lib");

dependencies.iter().try_for_each(|dep| -> eyre::Result<_> {
Expand All @@ -177,58 +176,46 @@ fn main() -> eyre::Result<()> {
dep.name, path, dep.url, dep.tag
);

// get the submodule and clone it
let mut submodule = repo.submodule(&dep.url, &path, true)?;
submodule.clone(None)?;

// get the repo & checkout the provided tag if necessary
// ref: https://stackoverflow.com/a/67240436
let submodule = submodule.open()?;
if let Some(ref tag) = dep.tag {
let (object, reference) = submodule.revparse_ext(tag)?;
submodule.checkout_tree(&object, None).expect("Failed to checkout");

match reference {
// gref is an actual reference like branches or tags
Some(gref) => submodule.set_head(gref.name().unwrap()),
// this is a commit, not a reference
None => submodule.set_head_detached(object.id()),
}
.expect("Failed to set HEAD");
}
// install the dep
std::process::Command::new("git")
.args(&["submodule", "add", &dep.url, &path.display().to_string()])
.spawn()?
.wait()?;

// call update on it
std::process::Command::new("git")
.args(&["submodule", "update", "--init", "--recursive"])
.args(&[
"submodule",
"update",
"--init",
"--recursive",
&path.display().to_string(),
])
.spawn()?
.wait()?;

// commit the submodule's installation
let sig = repo.signature()?;
let mut index = repo.index()?;
// stage `.gitmodules` and the lib
index.add_path(Path::new(".gitmodules"))?;
index.add_path(&path)?;
// need to write the index back to disk
index.write()?;
// checkout the tag if necessary
let message = if let Some(ref tag) = dep.tag {
std::process::Command::new("git")
.args(&["checkout", "--recurse-submodules", &tag])
.current_dir(&path)
.spawn()?
.wait()?;

let id = index.write_tree().unwrap();
let tree = repo.find_tree(id).unwrap();
std::process::Command::new("git")
.args(&["add", &path.display().to_string()])
.spawn()?
.wait()?;

let message = if let Some(ref tag) = dep.tag {
format!("forge install: {}\n\n{}", dep.name, tag)
} else {
format!("forge install: {}", dep.name)
};

// committing to the parent may make running the installation step
// in parallel challenging..
let parent = repo
.head()?
.resolve()?
.peel(git2::ObjectType::Commit)?
.into_commit()
.map_err(|err| eyre::eyre!("cannot get parent commit: {:?}", err))?;
repo.commit(Some("HEAD"), &sig, &sig, &message, &tree, &[&parent])?;
std::process::Command::new("git")
.args(&["commit", "-m", &message])
.spawn()?
.wait()?;

Ok(())
})?
Expand Down