Skip to content

Commit 4f49f8c

Browse files
committed
Basic .csmrc parsing
We rely here on `serde_yaml_ng`, which is a fork of `serde_yaml` that seems at least somewhat actively maintained and used. The benefit here is that we get easy deserialization into Rust types (which we wouldn't get with something like `yaml_rust2` which just gives an AST). The disadvantage is that we're depending on a library that I wish had more community backing like the original `serde_yaml` did. The alternative here would probably be foregoing YAML entirely and using TOML instead, but it seems the rest of the Robotmk ecosystem uses YAML, so it is probably best to remain consistent here.
1 parent 5a67b8f commit 4f49f8c

7 files changed

Lines changed: 129 additions & 6 deletions

File tree

Cargo.lock

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

Cargo.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,5 @@ edition = "2024"
77
clap = { version = "4.5.50", features = ["derive", "wrap_help"] }
88
env_logger = "0.11.8"
99
log = "0.4.28"
10+
serde = { version = "1.0.228", features = ["derive"] }
11+
serde_yaml_ng = "0.10.0"

README.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
# csm - Checkmk synthetic monitoring
2+
3+
(Under active development, not yet usable.)
4+
5+
## Configuration: `~/.csmrc`
6+
7+
You can optionally create a file, `~/.csmrc` (`%UserProfile%\.csmrc` on Windows)
8+
to override certain defaults. This is a YAML file with the following keys
9+
available:
10+
11+
* `mamba_root_prefix` - A string which sets where the Mamba environment(s) will
12+
be created on disk. By default, this is left up to `micromamba` and its
13+
default root prefix is used.

src/csmrc.rs

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
/// Module for reading a user's ~/.csmrc, if it exists.
2+
use log::debug;
3+
use serde::Deserialize;
4+
use std::default::Default;
5+
use std::io::{Error, ErrorKind};
6+
use std::path::PathBuf;
7+
8+
#[derive(Debug, Default, Deserialize)]
9+
pub struct Config {
10+
/// Override the $MAMBA_ROOT_PREFIX when shelling out to micromamba.
11+
#[serde(default)]
12+
#[allow(dead_code)]
13+
pub mamba_root_prefix: Option<String>,
14+
}
15+
16+
impl Config {
17+
/// Read the user's ~/.csmrc if it exists, merging with the Default instance for
18+
/// Config.
19+
pub fn from_csmrc() -> Result<Self, std::io::Error> {
20+
let home = match std::env::var("HOME") {
21+
Ok(home) => home,
22+
Err(_) => match std::env::var("USERPROFILE") {
23+
Ok(home) => home,
24+
Err(_) => return Ok(Config::default()),
25+
},
26+
};
27+
28+
let csmrc_path = PathBuf::from(home).join(".csmrc");
29+
let Ok(csmrc_data) = std::fs::read_to_string(csmrc_path) else {
30+
debug!("No .csmrc found, using defaults");
31+
return Ok(Config::default());
32+
};
33+
let config = serde_yaml_ng::from_str(&csmrc_data).map_err(|e| Error::new(ErrorKind::InvalidData, e));
34+
debug!("config: {:?}", config);
35+
config
36+
}
37+
}

src/env.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
use crate::csmrc::Config;
2+
13
#[derive(Debug, clap::Subcommand)]
24
pub enum Subcommand {
35
/// Create an environment
@@ -27,6 +29,7 @@ pub struct CreateArgs {
2729
name: Option<String>,
2830
}
2931

30-
pub fn run(subcommand: Subcommand) {
32+
pub fn run(config: Config, subcommand: Subcommand) {
33+
println!("{:?}", config);
3134
println!("{:?}", subcommand);
3235
}

src/main.rs

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
1+
mod csmrc;
12
mod env;
23
mod robot;
34

45
use clap::{Parser, Subcommand};
5-
use log::{LevelFilter, debug};
6+
use log::{LevelFilter, debug, error};
67
use std::fs::File;
78
use std::io::Write;
89
use std::path::PathBuf;
@@ -29,7 +30,7 @@ enum Command {
2930
Robot(robot::Subcommand),
3031
}
3132

32-
fn main() {
33+
fn main() -> Result<(), std::io::Error> {
3334
let cli = Cli::parse();
3435

3536
// Set up logging
@@ -41,12 +42,20 @@ fn main() {
4142
let mut env_logger_builder = env_logger::Builder::new();
4243
env_logger_builder.filter_level(default_verbosity);
4344
env_logger_builder.parse_default_env();
45+
env_logger_builder.format_timestamp(None);
4446
env_logger_builder.init();
4547

4648
let _ = create_mambarc();
49+
let config = match csmrc::Config::from_csmrc() {
50+
Ok(config) => config,
51+
Err(err) => {
52+
error!("Failed to parse .csmrc: {}", err);
53+
panic!("Failed to parse .csmrc as valid YAML");
54+
}
55+
};
4756
match cli.command {
48-
Command::Env(sub) => env::run(sub),
49-
Command::Robot(sub) => robot::run(sub),
57+
Command::Env(sub) => Ok(env::run(config, sub)),
58+
Command::Robot(sub) => Ok(robot::run(config, sub)),
5059
}
5160
}
5261

src/robot.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
use crate::csmrc::Config;
2+
13
#[derive(Debug, clap::Subcommand)]
24
pub enum Subcommand {
35
/// Create a Robotmk robot
@@ -13,6 +15,7 @@ pub struct CreateArgs {
1315
path: String,
1416
}
1517

16-
pub fn run(subcommand: Subcommand) {
18+
pub fn run(config: Config, subcommand: Subcommand) {
19+
println!("{:?}", config);
1720
println!("{:?}", subcommand);
1821
}

0 commit comments

Comments
 (0)