From b9fc7f9016d144db78e6d716ebbcd4dc06f78857 Mon Sep 17 00:00:00 2001 From: Oliver Nordbjerg Date: Thu, 4 Aug 2022 18:41:33 +0200 Subject: [PATCH] feat: install missing deps on build --- cli/src/cmd/forge/build/mod.rs | 28 +++++++++++++++++++++++++--- cli/src/cmd/forge/install.rs | 19 +++++++++++++++++-- 2 files changed, 42 insertions(+), 5 deletions(-) diff --git a/cli/src/cmd/forge/build/mod.rs b/cli/src/cmd/forge/build/mod.rs index 84c5b0eca690..d6310815e44b 100644 --- a/cli/src/cmd/forge/build/mod.rs +++ b/cli/src/cmd/forge/build/mod.rs @@ -1,11 +1,18 @@ -//! build command - +//! Build command use crate::{ - cmd::{forge::watch::WatchArgs, Cmd}, + cmd::{ + forge::{ + install::{self, DependencyInstallOpts}, + watch::WatchArgs, + }, + Cmd, + }, compile, + utils::p_println, }; use clap::Parser; use ethers::solc::{Project, ProjectCompileOutput}; +use eyre::WrapErr; use foundry_config::{ figment::{ self, @@ -68,6 +75,21 @@ impl Cmd for BuildArgs { fn run(self) -> eyre::Result { let project = self.project()?; + if install::has_missing_dependencies(&project.root()) { + // The extra newline is needed, otherwise the compiler output will overwrite the + // message + p_println!(!self.args.silent => "Missing dependencies found. Installing now.\n"); + install::install( + &project.root(), + Vec::new(), + DependencyInstallOpts { + // TODO(onbjerg): We should settle on --quiet or --silent. + quiet: self.args.silent, + ..Default::default() + }, + ).wrap_err("Your project has missing dependencies that could not be installed. Please ensure git is installed and available.")? + } + if self.args.silent { compile::suppress_compile(&project) } else { diff --git a/cli/src/cmd/forge/install.rs b/cli/src/cmd/forge/install.rs index 0750f8366abe..10fe5705acc7 100644 --- a/cli/src/cmd/forge/install.rs +++ b/cli/src/cmd/forge/install.rs @@ -144,7 +144,22 @@ pub(crate) fn install( Ok(()) } -/// installs the dependency as an ordinary folder instead of a submodule +/// Checks if any submodules have not been initialized yet. +/// +/// `git submodule status` will return a new line per submodule in the repository. If any line +/// starts with `-` then it has not been initialized yet. +pub fn has_missing_dependencies(root: impl AsRef) -> bool { + Command::new("git") + .args(&["submodule", "status"]) + .current_dir(root) + .output() + .map(|output| { + String::from_utf8_lossy(&output.stdout).lines().any(|line| line.starts_with('-')) + }) + .unwrap_or(false) +} + +/// Installs the dependency as an ordinary folder instead of a submodule fn install_as_folder(dep: &Dependency, libs: &Path, target_dir: &str) -> eyre::Result<()> { // install the dep git_clone(dep, libs, target_dir)?; @@ -158,7 +173,7 @@ fn install_as_folder(dep: &Dependency, libs: &Path, target_dir: &str) -> eyre::R Ok(()) } -/// installs the dependency as new submodule +/// Installs the dependency as new submodule fn install_as_submodule( dep: &Dependency, libs: &Path,