Skip to content

Commit 2fadb38

Browse files
committed
rework config management to allow better updates
1 parent 90b1239 commit 2fadb38

9 files changed

Lines changed: 354 additions & 122 deletions

File tree

Cargo.lock

Lines changed: 13 additions & 11 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

coman/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ chrono = "0.4.42"
7272
openssl = { version = "0.10.75", features = ["vendored"] }
7373
tui-realm-treeview = "3.0.0"
7474
aws-sdk-s3 = "1.115.0"
75+
toml_edit = "0.23.9"
7576

7677
[build-dependencies]
7778
anyhow = "1.0.90"

coman/src/cli.rs

Lines changed: 62 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
use std::{error::Error, path::PathBuf};
22

33
use clap::{Parser, Subcommand, builder::TypedValueParser};
4+
use color_eyre::Result;
45
use strum::VariantNames;
56

67
use crate::{
7-
config::{ComputePlatform, get_config_dir, get_data_dir, get_project_local_config_file},
8+
config::{ComputePlatform, Config, get_config_dir, get_data_dir, get_project_local_config_file},
89
util::types::DockerImageUrl,
910
};
1011

@@ -26,8 +27,37 @@ pub enum CliCommands {
2627
},
2728
#[clap(about = "Create a new project configuration file")]
2829
Init {
29-
#[clap(help = "Destination folder to create config in (default = current directory)")]
30+
#[clap(help = "destination folder to create config in (default = current directory)")]
3031
destination: Option<PathBuf>,
32+
#[clap(help = "project name to use")]
33+
name: Option<String>,
34+
},
35+
#[clap(about = "Manage configuration")]
36+
Config {
37+
#[command(subcommand)]
38+
command: ConfigCommands,
39+
},
40+
}
41+
42+
#[derive(Subcommand, Debug)]
43+
pub enum ConfigCommands {
44+
#[clap(about = "Set config values")]
45+
Set {
46+
#[clap(
47+
short,
48+
long,
49+
action,
50+
help = "whether to change the global config or the project local one"
51+
)]
52+
global: bool,
53+
#[clap(help = "Config key path, e.g. `cscs.current_system`")]
54+
key_path: String,
55+
#[clap(help = "Value to set", value_parser = parse_toml_value)]
56+
value: toml_edit::Value,
57+
},
58+
Get {
59+
#[clap(help = "Config key path, e.g. `cscs.current_system`")]
60+
key_path: String,
3161
},
3262
}
3363

@@ -177,6 +207,17 @@ Data directory: {data_dir_path}"
177207
)
178208
}
179209

210+
pub fn set_config<V: Into<toml_edit::Value>>(key_path: String, value: V, global: bool) -> Result<()> {
211+
let mut config = Config::new()?;
212+
config.set(&key_path, value, global)?;
213+
Ok(())
214+
}
215+
216+
pub fn get_config(key_path: String) -> Result<String> {
217+
let config = Config::new()?;
218+
config.get(&key_path)
219+
}
220+
180221
fn parse_key_val<T, U>(s: &str) -> Result<(T, U), Box<dyn Error + Send + Sync + 'static>>
181222
where
182223
T: std::str::FromStr,
@@ -201,3 +242,22 @@ where
201242
.ok_or_else(|| format!("invalid KEY:value: no `:` found in `{s}`"))?;
202243
Ok((s[..pos].parse()?, s[pos + 1..].parse()?))
203244
}
245+
246+
pub fn parse_toml_value(value_str: &str) -> Result<toml_edit::Value, toml_edit::TomlError> {
247+
match value_str.parse() {
248+
Ok(value) => Ok(value),
249+
Err(_) if is_bare_string(value_str) => Ok(value_str.into()),
250+
Err(err) => Err(err),
251+
}
252+
}
253+
fn is_bare_string(value_str: &str) -> bool {
254+
// leading whitespace isn't ignored when parsing TOML value expression, but
255+
// "\n[]" doesn't look like a bare string.
256+
let trimmed = value_str.trim_ascii().as_bytes();
257+
if let (Some(&first), Some(&last)) = (trimmed.first(), trimmed.last()) {
258+
// string, array, or table constructs?
259+
!matches!(first, b'"' | b'\'' | b'[' | b'{') && !matches!(last, b'"' | b'\'' | b']' | b'}')
260+
} else {
261+
true // empty or whitespace only
262+
}
263+
}

coman/src/components/status_bar.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,8 +42,8 @@ impl StatusBar {
4242
last_updated: Instant::now(),
4343
current_status: None,
4444
status_clear_time: Duration::from_secs(10),
45-
current_platform: config.cscs.current_platform.to_string(),
46-
current_system: config.cscs.current_system,
45+
current_platform: config.values.cscs.current_platform.to_string(),
46+
current_system: config.values.cscs.current_system,
4747
}
4848
}
4949
}

0 commit comments

Comments
 (0)