Skip to content

Commit

Permalink
dep: rm confy as a dep (#10290)
Browse files Browse the repository at this point in the history
Co-authored-by: Alexey Shekhirin <a.shekhirin@gmail.com>
  • Loading branch information
tcoratger and shekhirin authored Aug 20, 2024
1 parent 56e1448 commit cd05a96
Show file tree
Hide file tree
Showing 13 changed files with 187 additions and 49 deletions.
29 changes: 4 additions & 25 deletions Cargo.lock

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

1 change: 0 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -527,7 +527,6 @@ secp256k1 = { version = "0.29", default-features = false, features = [
c-kzg = "1.0.0"

# config
confy = "0.6"
toml = "0.8"

# misc-testing
Expand Down
1 change: 0 additions & 1 deletion bin/reth/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,6 @@ tracing.workspace = true
fdlimit.workspace = true
serde.workspace = true
serde_json.workspace = true
confy.workspace = true
toml = { workspace = true, features = ["display"] }

# metrics
Expand Down
1 change: 0 additions & 1 deletion crates/cli/commands/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,6 @@ secp256k1 = { workspace = true, features = ["global-context", "rand-std", "recov

# io
fdlimit.workspace = true
confy.workspace = true
toml = { workspace = true, features = ["display"] }

# tui
Expand Down
3 changes: 2 additions & 1 deletion crates/cli/commands/src/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,8 @@ impl EnvironmentArgs {
}

let config_path = self.config.clone().unwrap_or_else(|| data_dir.config());
let mut config: Config = confy::load_path(config_path)

let mut config = Config::from_path(config_path)
.inspect_err(
|err| warn!(target: "reth::cli", %err, "Failed to load config file, using default"),
)
Expand Down
5 changes: 3 additions & 2 deletions crates/cli/commands/src/config_cmd.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,12 @@ impl Command {
Config::default()
} else {
let path = self.config.clone().unwrap_or_default();
// confy will create the file if it doesn't exist; we don't want this
// Check if the file exists
if !path.exists() {
bail!("Config file does not exist: {}", path.display());
}
confy::load_path::<Config>(&path)
// Read the configuration file
Config::from_path(&path)
.wrap_err_with(|| format!("Could not load config file: {}", path.display()))?
};
println!("{}", toml::to_string_pretty(&config)?);
Expand Down
4 changes: 3 additions & 1 deletion crates/cli/commands/src/p2p/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -74,13 +74,15 @@ pub enum Subcommands {
// RLPx utilities
Rlpx(rlpx::Command),
}

impl Command {
/// Execute `p2p` command
pub async fn execute(self) -> eyre::Result<()> {
let data_dir = self.datadir.clone().resolve_datadir(self.chain.chain);
let config_path = self.config.clone().unwrap_or_else(|| data_dir.config());

let mut config: Config = confy::load_path(&config_path).unwrap_or_default();
// Load configuration
let mut config = Config::from_path(&config_path).unwrap_or_default();

config.peers.trusted_nodes.extend(self.network.trusted_peers.clone());

Expand Down
4 changes: 2 additions & 2 deletions crates/config/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,9 @@ serde.workspace = true
humantime-serde.workspace = true

# toml
confy.workspace = true
toml.workspace = true
eyre.workspace = true

[dev-dependencies]
tempfile.workspace = true
toml.workspace = true
reth-network-peers.workspace = true
146 changes: 138 additions & 8 deletions crates/config/src/config.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
//! Configuration files.

use eyre::eyre;
use reth_network_types::{PeersConfig, SessionsConfig};
use reth_prune_types::PruneModes;
use reth_stages_types::ExecutionStageThresholds;
use serde::{Deserialize, Deserializer, Serialize};
use std::{
ffi::OsStr,
fs,
path::{Path, PathBuf},
time::Duration,
};
Expand All @@ -29,6 +31,31 @@ pub struct Config {
}

impl Config {
/// Load a [`Config`] from a specified path.
///
/// A new configuration file is created with default values if none
/// exists.
pub fn from_path(path: impl AsRef<Path>) -> eyre::Result<Self> {
let path = path.as_ref();
match fs::read_to_string(path) {
Ok(cfg_string) => {
toml::from_str(&cfg_string).map_err(|e| eyre!("Failed to parse TOML: {e}"))
}
Err(e) if e.kind() == std::io::ErrorKind::NotFound => {
if let Some(parent) = path.parent() {
fs::create_dir_all(parent)
.map_err(|e| eyre!("Failed to create directory: {e}"))?;
}
let cfg = Self::default();
let s = toml::to_string_pretty(&cfg)
.map_err(|e| eyre!("Failed to serialize to TOML: {e}"))?;
fs::write(path, s).map_err(|e| eyre!("Failed to write configuration file: {e}"))?;
Ok(cfg)
}
Err(e) => Err(eyre!("Failed to load configuration: {e}")),
}
}

/// Returns the [`PeersConfig`] for the node.
///
/// If a peers file is provided, the basic nodes from the file are added to the configuration.
Expand All @@ -48,9 +75,14 @@ impl Config {
return Err(std::io::Error::new(
std::io::ErrorKind::InvalidInput,
format!("reth config file extension must be '{EXTENSION}'"),
))
));
}
confy::store_path(path, self).map_err(|e| std::io::Error::new(std::io::ErrorKind::Other, e))

std::fs::write(
path,
toml::to_string(self)
.map_err(|e| std::io::Error::new(std::io::ErrorKind::InvalidData, e.to_string()))?,
)
}

/// Sets the pruning configuration.
Expand Down Expand Up @@ -384,7 +416,7 @@ where
mod tests {
use super::{Config, EXTENSION};
use reth_network_peers::TrustedPeer;
use std::{str::FromStr, time::Duration};
use std::{path::Path, str::FromStr, time::Duration};

fn with_tempdir(filename: &str, proc: fn(&std::path::Path)) {
let temp_dir = tempfile::tempdir().unwrap();
Expand All @@ -395,11 +427,91 @@ mod tests {
temp_dir.close().unwrap()
}

/// Run a test function with a temporary config path as fixture.
fn with_config_path(test_fn: fn(&Path)) {
// Create a temporary directory for the config file
let config_dir = tempfile::tempdir().expect("creating test fixture failed");
// Create the config file path
let config_path =
config_dir.path().join("example-app").join("example-config").with_extension("toml");
// Run the test function with the config path
test_fn(&config_path);
config_dir.close().expect("removing test fixture failed");
}

#[test]
fn test_load_path_works() {
with_config_path(|path| {
let config = Config::from_path(path).expect("load_path failed");
assert_eq!(config, Config::default());
})
}

#[test]
fn test_load_path_reads_existing_config() {
with_config_path(|path| {
let config = Config::default();

// Create the parent directory if it doesn't exist
if let Some(parent) = path.parent() {
std::fs::create_dir_all(parent).expect("Failed to create directories");
}

// Write the config to the file
std::fs::write(path, toml::to_string(&config).unwrap())
.expect("Failed to write config");

// Load the config from the file and compare it
let loaded = Config::from_path(path).expect("load_path failed");
assert_eq!(config, loaded);
})
}

#[test]
fn test_load_path_fails_on_invalid_toml() {
with_config_path(|path| {
let invalid_toml = "invalid toml data";

// Create the parent directory if it doesn't exist
if let Some(parent) = path.parent() {
std::fs::create_dir_all(parent).expect("Failed to create directories");
}

// Write invalid TOML data to the file
std::fs::write(path, invalid_toml).expect("Failed to write invalid TOML");

// Attempt to load the config should fail
let result = Config::from_path(path);
assert!(result.is_err());
})
}

#[test]
fn test_load_path_creates_directory_if_not_exists() {
with_config_path(|path| {
// Ensure the directory does not exist
let parent = path.parent().unwrap();
assert!(!parent.exists());

// Load the configuration, which should create the directory and a default config file
let config = Config::from_path(path).expect("load_path failed");
assert_eq!(config, Config::default());

// The directory and file should now exist
assert!(parent.exists());
assert!(path.exists());
});
}

#[test]
fn test_store_config() {
with_tempdir("config-store-test", |config_path| {
let config = Config::default();
confy::store_path(config_path, config).expect("Failed to store config");
std::fs::write(
config_path,
toml::to_string(&config).expect("Failed to serialize config"),
)
.expect("Failed to write config file");
})
}

Expand All @@ -415,9 +527,18 @@ mod tests {
fn test_load_config() {
with_tempdir("config-load-test", |config_path| {
let config = Config::default();
confy::store_path(config_path, &config).unwrap();

let loaded_config: Config = confy::load_path(config_path).unwrap();
// Write the config to a file
std::fs::write(
config_path,
toml::to_string(&config).expect("Failed to serialize config"),
)
.expect("Failed to write config file");

// Load the config from the file
let loaded_config = Config::from_path(config_path).unwrap();

// Compare the loaded config with the original config
assert_eq!(config, loaded_config);
})
}
Expand All @@ -427,9 +548,18 @@ mod tests {
with_tempdir("config-load-test", |config_path| {
let mut config = Config::default();
config.stages.execution.max_duration = Some(Duration::from_secs(10 * 60));
confy::store_path(config_path, &config).unwrap();

let loaded_config: Config = confy::load_path(config_path).unwrap();
// Write the config to a file
std::fs::write(
config_path,
toml::to_string(&config).expect("Failed to serialize config"),
)
.expect("Failed to write config file");

// Load the config from the file
let loaded_config = Config::from_path(config_path).unwrap();

// Compare the loaded config with the original config
assert_eq!(config, loaded_config);
})
}
Expand Down
1 change: 0 additions & 1 deletion crates/node/builder/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,6 @@ secp256k1 = { workspace = true, features = [
aquamarine.workspace = true
eyre.workspace = true
fdlimit.workspace = true
confy.workspace = true
rayon.workspace = true

# tracing
Expand Down
8 changes: 2 additions & 6 deletions crates/node/builder/src/launch/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ impl LaunchContext {
pub fn load_toml_config(&self, config: &NodeConfig) -> eyre::Result<reth_config::Config> {
let config_path = config.config.clone().unwrap_or_else(|| self.data_dir.config());

let mut toml_config = confy::load_path::<reth_config::Config>(&config_path)
let mut toml_config = reth_config::Config::from_path(&config_path)
.wrap_err_with(|| format!("Could not load config file {config_path:?}"))?;

Self::save_pruning_config_if_full_node(&mut toml_config, config, &config_path)?;
Expand Down Expand Up @@ -970,12 +970,8 @@ mod tests {
)
.unwrap();

assert_eq!(
reth_config.prune.as_ref().map(|p| p.block_interval),
node_config.prune_config().map(|p| p.block_interval)
);
let loaded_config = Config::from_path(config_path).unwrap();

let loaded_config: Config = confy::load_path(config_path).unwrap();
assert_eq!(reth_config, loaded_config);
})
}
Expand Down
Loading

0 comments on commit cd05a96

Please sign in to comment.