Skip to content

Commit 83eeb3e

Browse files
committed
rework config management to allow better updates
1 parent 3cd6a1f commit 83eeb3e

9 files changed

Lines changed: 357 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::{Args, 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
cscs::api_client::client::{EdfSpec as EdfSpecEnum, ScriptSpec as ScriptSpecEnum},
910
util::types::DockerImageUrl,
1011
};
@@ -27,8 +28,37 @@ pub enum CliCommands {
2728
},
2829
#[clap(about = "Create a new project configuration file")]
2930
Init {
30-
#[clap(help = "Destination folder to create config in (default = current directory)")]
31+
#[clap(help = "destination folder to create config in (default = current directory)")]
3132
destination: Option<PathBuf>,
33+
#[clap(help = "project name to use")]
34+
name: Option<String>,
35+
},
36+
#[clap(about = "Manage configuration")]
37+
Config {
38+
#[command(subcommand)]
39+
command: ConfigCommands,
40+
},
41+
}
42+
43+
#[derive(Subcommand, Debug)]
44+
pub enum ConfigCommands {
45+
#[clap(about = "Set config values")]
46+
Set {
47+
#[clap(
48+
short,
49+
long,
50+
action,
51+
help = "whether to change the global config or the project local one"
52+
)]
53+
global: bool,
54+
#[clap(help = "Config key path, e.g. `cscs.current_system`")]
55+
key_path: String,
56+
#[clap(help = "Value to set", value_parser = parse_toml_value)]
57+
value: toml_edit::Value,
58+
},
59+
Get {
60+
#[clap(help = "Config key path, e.g. `cscs.current_system`")]
61+
key_path: String,
3262
},
3363
}
3464

@@ -251,6 +281,17 @@ Data directory: {data_dir_path}"
251281
)
252282
}
253283

284+
pub fn set_config<V: Into<toml_edit::Value>>(key_path: String, value: V, global: bool) -> Result<()> {
285+
let mut config = Config::new()?;
286+
config.set(&key_path, value, global)?;
287+
Ok(())
288+
}
289+
290+
pub fn get_config(key_path: String) -> Result<String> {
291+
let config = Config::new()?;
292+
config.get(&key_path)
293+
}
294+
254295
fn parse_key_val<T, U>(s: &str) -> Result<(T, U), Box<dyn Error + Send + Sync + 'static>>
255296
where
256297
T: std::str::FromStr,
@@ -275,3 +316,22 @@ where
275316
.ok_or_else(|| format!("invalid KEY:value: no `:` found in `{s}`"))?;
276317
Ok((s[..pos].parse()?, s[pos + 1..].parse()?))
277318
}
319+
320+
pub fn parse_toml_value(value_str: &str) -> Result<toml_edit::Value, toml_edit::TomlError> {
321+
match value_str.parse() {
322+
Ok(value) => Ok(value),
323+
Err(_) if is_bare_string(value_str) => Ok(value_str.into()),
324+
Err(err) => Err(err),
325+
}
326+
}
327+
fn is_bare_string(value_str: &str) -> bool {
328+
// leading whitespace isn't ignored when parsing TOML value expression, but
329+
// "\n[]" doesn't look like a bare string.
330+
let trimmed = value_str.trim_ascii().as_bytes();
331+
if let (Some(&first), Some(&last)) = (trimmed.first(), trimmed.last()) {
332+
// string, array, or table constructs?
333+
!matches!(first, b'"' | b'\'' | b'[' | b'{') && !matches!(last, b'"' | b'\'' | b']' | b'}')
334+
} else {
335+
true // empty or whitespace only
336+
}
337+
}

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)