Upgrade to newer version of config crate.

This commit is contained in:
Nick Mathewson 2022-02-25 09:17:37 -05:00
parent 55416937cc
commit a3bc59918d
8 changed files with 82 additions and 59 deletions

47
Cargo.lock generated
View File

@ -62,12 +62,6 @@ version = "0.3.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a4c527152e37cf757a3f78aae5a06fbeefdb07ccc535c980a3208ee3060dd544"
[[package]]
name = "arrayvec"
version = "0.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "23b62fc65de8e4e7f52534fb52b0f3ed04746ae267519eef2a83941e8085068b"
[[package]]
name = "arti"
version = "0.0.4"
@ -628,12 +622,14 @@ dependencies = [
[[package]]
name = "config"
version = "0.11.0"
version = "0.12.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1b1b9d958c2b1368a663f05538fc1b5975adce1e19f435acceae987aceeeb369"
checksum = "54ad70579325f1a38ea4c13412b82241c5900700a69785d73e2736bd65a33f86"
dependencies = [
"async-trait",
"lazy_static",
"nom",
"pathdiff",
"serde",
"toml",
]
@ -1561,19 +1557,6 @@ version = "1.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55"
[[package]]
name = "lexical-core"
version = "0.7.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6607c62aa161d23d17a9072cc5da0be67cdfc89d3afb1e8d9c842bebc2525ffe"
dependencies = [
"arrayvec",
"bitflags",
"cfg-if 1.0.0",
"ryu",
"static_assertions",
]
[[package]]
name = "libc"
version = "0.2.115"
@ -1678,6 +1661,12 @@ dependencies = [
"zeroize",
]
[[package]]
name = "minimal-lexical"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a"
[[package]]
name = "miniz_oxide"
version = "0.4.4"
@ -1797,12 +1786,12 @@ dependencies = [
[[package]]
name = "nom"
version = "5.1.2"
version = "7.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ffb4262d26ed83a1c0a33a38fe2bb15797329c85770da05e6b828ddb782627af"
checksum = "1b1d11e1ef389c76fe5b81bcaf2ea32cf88b62bc494e19f493d0b30e7a930109"
dependencies = [
"lexical-core",
"memchr",
"minimal-lexical",
"version_check",
]
@ -2007,6 +1996,12 @@ dependencies = [
"winapi 0.3.9",
]
[[package]]
name = "pathdiff"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8835116a5c179084a830efb3adc117ab007512b535bc1a21c991d3b32a6b44dd"
[[package]]
name = "pem-rfc7468"
version = "0.2.4"
@ -2868,9 +2863,9 @@ dependencies = [
[[package]]
name = "tokio-util"
version = "0.6.9"
version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9e99e1983e5d376cd8eb4b66604d2e99e79f5bd988c3055891dcd8c9e2604cc0"
checksum = "64910e1b9c1901aaf5375561e35b9c057d95ff41a44ede043a03e09279eabaf1"
dependencies = [
"bytes",
"futures-core",

View File

@ -46,6 +46,7 @@ use rand::distributions::Standard;
use rand::Rng;
use serde::{Deserialize, Serialize};
use std::collections::HashMap;
use std::convert::TryInto;
use std::fmt;
use std::fmt::Formatter;
use std::future::Future;

View File

@ -14,7 +14,7 @@ repository="https://gitlab.torproject.org/tpo/core/arti.git/"
arti-client = { package="arti-client", path = "../arti-client", version = "0.0.4"}
tor-circmgr = { package="tor-circmgr", path="../tor-circmgr", version = "0.0.4"}
tor-config = { package="tor-config", path = "../tor-config", version = "0.0.4", features = ["expand-paths"]}
config = { version = "0.11.0", default-features = false, features = ["toml"] }
config = { version = "0.12.0", default-features = false, features = ["toml"] }
once_cell = "1"
serde = { version = "1.0.103", features = ["derive"] }
toml = "0.5"

View File

@ -51,6 +51,11 @@ pub use options::{
};
use tor_config::CfgPath;
/// The synchronous configuration builder type we use.
///
/// (This is a type alias that config should really provide.)
type ConfigBuilder = config::builder::ConfigBuilder<config::builder::DefaultState>;
use std::path::{Path, PathBuf};
/// A description of where to find our configuration options.
@ -116,38 +121,41 @@ impl ConfigurationSources {
/// Load the configuration into a new [`config::Config`].
pub fn load(&self) -> Result<config::Config, config::ConfigError> {
let mut config = config::Config::new();
config.merge(config::File::from_str(
let mut builder = config::Config::builder();
builder = builder.add_source(config::File::from_str(
options::ARTI_DEFAULTS,
config::FileFormat::Toml,
))?;
load_mut(&mut config, &self.files, &self.options)?;
Ok(config)
));
builder = add_sources(builder, &self.files, &self.options);
builder.build()
}
}
/// As [`ConfigurationSources::load()`], but load into a mutable `Config`
/// object.
fn load_mut<P: AsRef<Path>>(
cfg: &mut config::Config,
/// Add every file and commandline source to `builder`, returning a new
/// builder.
fn add_sources<P>(
mut builder: ConfigBuilder,
files: &[(P, MustRead)],
opts: &[String],
) -> Result<(), config::ConfigError> {
) -> ConfigBuilder
where
P: AsRef<Path>,
{
for (path, must_read) in files {
// Not going to use File::with_name here, since it doesn't
// quite do what we want.
let f: config::File<_> = path.as_ref().into();
let f: config::File<_, _> = path.as_ref().into();
let required = must_read == &MustRead::MustRead;
cfg.merge(f.format(config::FileFormat::Toml).required(required))?;
builder = builder.add_source(f.format(config::FileFormat::Toml).required(required));
}
let mut cmdline = CmdLine::new();
for opt in opts {
cmdline.push_toml_line(opt.clone());
}
cfg.merge(cmdline)?;
builder = builder.add_source(cmdline);
Ok(())
builder
}
/// Return a filename for the default user configuration file.
@ -167,13 +175,21 @@ world = \"stuff\"
friends = 4242
";
/// Load from a set of files and option strings, without taking
/// the arti defaults into account.
fn load_nodefaults<P: AsRef<Path>>(
files: &[(P, MustRead)],
opts: &[String],
) -> Result<config::Config, config::ConfigError> {
add_sources(config::Config::builder(), files, opts).build()
}
#[test]
fn non_required_file() {
let td = tempdir().unwrap();
let dflt = td.path().join("a_file");
let files = vec![(dflt, MustRead::TolerateAbsence)];
let mut c = config::Config::new();
load_mut(&mut c, &files, Default::default()).unwrap();
load_nodefaults(&files, Default::default()).unwrap();
}
static EX2_TOML: &str = "
@ -186,13 +202,12 @@ world = \"nonsense\"
let td = tempdir().unwrap();
let dflt = td.path().join("a_file");
let cf = td.path().join("other_file");
let mut c = config::Config::new();
std::fs::write(&cf, EX2_TOML).unwrap();
let files = vec![(dflt, MustRead::TolerateAbsence), (cf, MustRead::MustRead)];
load_mut(&mut c, &files, Default::default()).unwrap();
let c = load_nodefaults(&files, Default::default()).unwrap();
assert!(c.get_str("hello.friends").is_err());
assert_eq!(c.get_str("hello.world").unwrap(), "nonsense".to_string());
assert!(c.get_string("hello.friends").is_err());
assert_eq!(c.get_string("hello.world").unwrap(), "nonsense".to_string());
}
#[test]
@ -200,16 +215,15 @@ world = \"nonsense\"
let td = tempdir().unwrap();
let cf1 = td.path().join("a_file");
let cf2 = td.path().join("other_file");
let mut c = config::Config::new();
std::fs::write(&cf1, EX_TOML).unwrap();
std::fs::write(&cf2, EX2_TOML).unwrap();
let v = vec![(cf1, MustRead::TolerateAbsence), (cf2, MustRead::MustRead)];
let v2 = vec!["other.var=present".to_string()];
load_mut(&mut c, &v, &v2).unwrap();
let c = load_nodefaults(&v, &v2).unwrap();
assert_eq!(c.get_str("hello.friends").unwrap(), "4242".to_string());
assert_eq!(c.get_str("hello.world").unwrap(), "nonsense".to_string());
assert_eq!(c.get_str("other.var").unwrap(), "present".to_string());
assert_eq!(c.get_string("hello.friends").unwrap(), "4242".to_string());
assert_eq!(c.get_string("hello.world").unwrap(), "nonsense".to_string());
assert_eq!(c.get_string("other.var").unwrap(), "present".to_string());
}
#[test]

View File

@ -10,6 +10,7 @@ use arti_client::config::{
use derive_builder::Builder;
use serde::Deserialize;
use std::collections::HashMap;
use std::convert::TryFrom;
use tor_config::{CfgPath, ConfigBuildError};
/// Default options to use for our configuration.
@ -288,6 +289,13 @@ pub struct ArtiConfig {
system: SystemConfig,
}
impl TryFrom<config::Config> for ArtiConfig {
type Error = config::ConfigError;
fn try_from(cfg: config::Config) -> Result<ArtiConfig, Self::Error> {
cfg.try_deserialize()
}
}
impl From<ArtiConfig> for TorClientConfigBuilder {
fn from(cfg: ArtiConfig) -> TorClientConfigBuilder {
let mut builder = TorClientConfig::builder();
@ -570,6 +578,7 @@ impl From<ArtiConfig> for ArtiConfigBuilder {
mod test {
#![allow(clippy::unwrap_used)]
use std::convert::TryInto;
use std::time::Duration;
use super::*;
@ -577,12 +586,13 @@ mod test {
#[test]
fn default_config() {
// TODO: this is duplicate code.
let mut cfg = config::Config::new();
cfg.merge(config::File::from_str(
ARTI_DEFAULTS,
config::FileFormat::Toml,
))
.unwrap();
let cfg = config::Config::builder()
.add_source(config::File::from_str(
ARTI_DEFAULTS,
config::FileFormat::Toml,
))
.build()
.unwrap();
let parsed: ArtiConfig = cfg.try_into().unwrap();
let default = ArtiConfig::default();

View File

@ -28,7 +28,7 @@ arti-config = { path="../arti-config", version = "0.0.4"}
anyhow = "1.0.23"
async-ctrlc = { version = "1.2.0", optional = true }
config = { version = "0.11.0", default-features = false }
config = { version = "0.12.0", default-features = false }
cfg-if = "1.0.0"
futures = "0.3.14"
tracing = "0.1.18"

View File

@ -101,6 +101,8 @@ use anyhow::{Context, Result};
use clap::{App, AppSettings, Arg, SubCommand};
use tracing::{info, warn};
use std::convert::TryInto;
/// Run the main loop of the proxy.
async fn run<R: Runtime>(
runtime: R,

View File

@ -1,6 +1,7 @@
//! Code to watch configuration files for any changes.
use std::collections::HashSet;
use std::convert::TryInto;
use std::path::{Path, PathBuf};
use std::sync::mpsc::channel as std_channel;
use std::time::Duration;