Skip to content

Commit

Permalink
feat(config): auto update libs section on install (#1559)
Browse files Browse the repository at this point in the history
  • Loading branch information
mattsse authored May 9, 2022
1 parent 85f69d9 commit ed4eb2d
Show file tree
Hide file tree
Showing 6 changed files with 139 additions and 4 deletions.
22 changes: 22 additions & 0 deletions Cargo.lock

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

11 changes: 9 additions & 2 deletions cli/src/cmd/forge/install.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use std::{path::PathBuf, str};

use crate::{cmd::Cmd, opts::forge::Dependency, utils::p_println};
use clap::{Parser, ValueHint};
use foundry_config::find_project_root_path;
use foundry_config::{find_project_root_path, Config};
use yansi::Paint;

use std::{
Expand Down Expand Up @@ -49,7 +49,14 @@ impl Cmd for InstallArgs {
fn run(self) -> eyre::Result<Self::Output> {
let InstallArgs { root, .. } = self;
let root = root.unwrap_or_else(|| find_project_root_path().unwrap());
install(root, self.dependencies, self.opts)
install(&root, self.dependencies, self.opts)?;
let mut config = Config::load_with_root(root);
let lib = PathBuf::from("lib");
if !config.libs.contains(&lib) {
config.libs.push(lib);
config.update_libs()?;
}
Ok(())
}
}

Expand Down
8 changes: 8 additions & 0 deletions cli/test-utils/src/util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -400,6 +400,14 @@ impl TestCommand {
config
}

/// Runs `git init` inside the project's dir
pub fn git_init(&self) -> process::Output {
let mut cmd = Command::new("git");
cmd.arg("init").current_dir(self.project.root());
let output = cmd.output().unwrap();
self.expect_success(output)
}

/// Runs and captures the stdout of the given command.
pub fn stdout(&mut self) -> String {
let o = self.output();
Expand Down
26 changes: 25 additions & 1 deletion cli/tests/it/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -443,7 +443,6 @@ forgetest_init!(can_detect_lib_foundry_toml, |prj: TestProject, mut cmd: TestCom
// so that `dep/=lib/a/src` will take precedent over `dep/=lib/a/lib/b/src`
forgetest_init!(can_prioritise_closer_lib_remappings, |prj: TestProject, mut cmd: TestCommand| {
let config = cmd.config();
let remappings = config.get_all_remappings();

// create a new lib directly in the `lib` folder with conflicting remapping `forge-std/`
let mut config = config.clone();
Expand All @@ -465,3 +464,28 @@ forgetest_init!(can_prioritise_closer_lib_remappings, |prj: TestProject, mut cmd
]
);
});

// test to check that foundry.toml libs section updates on install
forgetest!(can_update_libs_section, |prj: TestProject, mut cmd: TestCommand| {
cmd.set_current_dir(prj.root());
cmd.git_init();

// explicitly set gas_price
let init = Config { libs: vec!["node_modules".into()], ..Default::default() };
prj.write_config(init.clone());

cmd.args(["install", "foundry-rs/forge-std"]);
cmd.assert_non_empty_stdout();

let config = cmd.forge_fuse().config();
// `lib` was added automatically
let expected = vec![PathBuf::from("node_modules"), PathBuf::from("lib")];
assert_eq!(config.libs, expected);

// additional install don't edit `libs`
cmd.forge_fuse().args(["install", "dapphub/ds-test"]);
cmd.assert_non_empty_stdout();

let config = cmd.forge_fuse().config();
assert_eq!(config.libs, expected);
});
2 changes: 1 addition & 1 deletion config/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,9 @@ ethers-core = { git = "https://github.com/gakonst/ethers-rs", default-features =
ethers-solc = { git = "https://github.com/gakonst/ethers-rs", default-features = false, features = ["async", "svm-solc"] }
Inflector = "0.11.4"
regex = "1.5.5"
#globset = { version = "0.4.8", features = ["serde1"] }
globset = "0.4.8"
walkdir = "2.3.2"
toml_edit = "0.14.3"

[dev-dependencies]
pretty_assertions = "1.0.0"
Expand Down
74 changes: 74 additions & 0 deletions config/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -747,6 +747,54 @@ impl Config {
}
}

/// Updates the `foundry.toml` file for the given `root` based on the provided closure.
///
/// **Note:** the closure will only be invoked if the `foundry.toml` file exists, See
/// [Self::get_config_path()] and if the closure returns `true`.
pub fn update_at<F>(root: impl Into<PathBuf>, f: F) -> eyre::Result<()>
where
F: FnOnce(&Config, &mut toml_edit::Document) -> bool,
{
let config = Self::load_with_root(root).sanitized();
config.update(|doc| f(&config, doc))
}

/// Updates the `foundry.toml` file this `Config` ias based on with the provided closure.
///
/// **Note:** the closure will only be invoked if the `foundry.toml` file exists, See
/// [Self::get_config_path()] and if the closure returns `true`
pub fn update<F>(&self, f: F) -> eyre::Result<()>
where
F: FnOnce(&mut toml_edit::Document) -> bool,
{
let file_path = self.get_config_path();
if !file_path.exists() {
return Ok(())
}
let cargo_toml_content = fs::read_to_string(&file_path)?;
let mut doc = cargo_toml_content.parse::<toml_edit::Document>()?;
if f(&mut doc) {
fs::write(file_path, doc.to_string())?;
}
Ok(())
}

/// Sets the `libs` entry inside a `foundry.toml` file but only if it exists
///
/// # Errors
///
/// An error if the `foundry.toml` could not be parsed.
pub fn update_libs(&self) -> eyre::Result<()> {
self.update(|doc| {
let profile = self.profile.as_str().as_str();
let libs: toml_edit::Value =
self.libs.iter().map(|p| toml_edit::Value::from(&*p.to_string_lossy())).collect();
let libs = toml_edit::value(libs);
doc[profile]["libs"] = libs;
true
})
}

/// Serialize the config type as a String of TOML.
///
/// This serializes to a table with the name of the profile
Expand Down Expand Up @@ -781,6 +829,11 @@ impl Config {
))
}

/// Returns the path to the `foundry.toml` of this `Config`
pub fn get_config_path(&self) -> PathBuf {
self.__root.0.join(Config::FILE_NAME)
}

/// Returns the selected profile
///
/// If the `FOUNDRY_PROFILE` env variable is not set, this returns the `DEFAULT_PROFILE`
Expand Down Expand Up @@ -1904,6 +1957,27 @@ mod tests {
});
}

#[test]
fn test_can_update_libs() {
figment::Jail::expect_with(|jail| {
jail.create_file(
"foundry.toml",
r#"
[default]
libs = ["node_modules"]
"#,
)?;

let mut config = Config::load();
config.libs.push("libs".into());
config.update_libs().unwrap();

let config = Config::load();
assert_eq!(config.libs, vec![PathBuf::from("node_modules"), PathBuf::from("libs"),]);
Ok(())
});
}

#[test]
fn test_large_gas_limit() {
figment::Jail::expect_with(|jail| {
Expand Down

0 comments on commit ed4eb2d

Please sign in to comment.