feat: allow including other collections

This commit is contained in:
əlemi 2024-10-20 04:19:03 +02:00
parent a44babb509
commit 37e6c48048
Signed by: alemi
GPG key ID: A4895B84D311642C
2 changed files with 38 additions and 7 deletions

View file

@ -2,6 +2,8 @@ mod model;
mod errors; mod errors;
mod ext; mod ext;
use std::{collections::HashMap, str::FromStr};
use clap::{Parser, Subcommand}; use clap::{Parser, Subcommand};
pub use model::PostWomanCollection; pub use model::PostWomanCollection;
@ -15,7 +17,7 @@ pub static APP_USER_AGENT: &str = concat!(env!("CARGO_PKG_NAME"), "/", env!("CAR
struct PostWomanArgs { struct PostWomanArgs {
/// collection file to use /// collection file to use
#[arg(short, long, default_value = "postwoman.toml")] #[arg(short, long, default_value = "postwoman.toml")]
collection: String, collection: std::path::PathBuf,
/// action to run /// action to run
#[clap(subcommand)] #[clap(subcommand)]
@ -59,26 +61,54 @@ const TIMESTAMP_FMT: &str = "%H:%M:%S%.6f";
fn main() -> Result<(), PostWomanError> { fn main() -> Result<(), PostWomanError> {
let args = PostWomanArgs::parse(); let args = PostWomanArgs::parse();
let collection_raw = std::fs::read_to_string(&args.collection)?; // if we got a regex, test it early to avoid wasting work when invalid
let collection: PostWomanCollection = toml::from_str(&collection_raw)?; if let Some(PostWomanActions::Run { ref query, .. }) = args.action {
// note that if you remove this test, there's another .expect() below you need to manage too!
regex::Regex::new(query).expect("error compiling regex");
}
let mut collections = HashMap::new();
load_collections(&mut collections, args.collection.clone());
if args.multi_threaded { if args.multi_threaded {
let task = async move {
for (name, collection) in collections {
run_postwoman(&args, name, collection).await;
}
};
tokio::runtime::Builder::new_multi_thread() tokio::runtime::Builder::new_multi_thread()
.enable_all() .enable_all()
.build() .build()
.expect("failed creating tokio multi-thread runtime") .expect("failed creating tokio multi-thread runtime")
.block_on(async { run_postwoman(args, collection).await }) .block_on(task)
} else { } else {
tokio::runtime::Builder::new_current_thread() tokio::runtime::Builder::new_current_thread()
.enable_all() .enable_all()
.build() .build()
.expect("failed creating tokio current-thread runtime") .expect("failed creating tokio current-thread runtime")
.block_on(async { run_postwoman(args, collection).await }) .block_on(task)
} }
} }
async fn run_postwoman(args: PostWomanArgs, collection: PostWomanCollection) -> Result<(), PostWomanError> { fn load_collections(store: &mut HashMap<String, PostWomanCollection>, mut path: std::path::PathBuf) {
let action = args.action.unwrap_or(PostWomanActions::List { verbose: false }); let collection_raw = std::fs::read_to_string(&path).expect("error loading collection");
let collection: PostWomanCollection = toml::from_str(&collection_raw).expect("error parsing collection");
let name = path.to_string_lossy().to_string();
if let Some(ref includes) = collection.include {
path.pop();
for include in includes {
let mut base = path.clone();
let new = std::path::PathBuf::from_str(include).expect("infallible");
base.push(new);
load_collections(store, base);
}
}
store.insert(name, collection);
}
match action { match action {
PostWomanActions::List { verbose } => { PostWomanActions::List { verbose } => {

View file

@ -10,6 +10,7 @@ pub use extractor::ExtractorConfig;
pub struct PostWomanCollection { pub struct PostWomanCollection {
pub client: ClientConfig, pub client: ClientConfig,
pub env: toml::Table, pub env: toml::Table,
pub include: Option<Vec<String>>,
// it's weird to name it singular but makes more sense in config // it's weird to name it singular but makes more sense in config
pub route: indexmap::IndexMap<String, EndpointConfig>, pub route: indexmap::IndexMap<String, EndpointConfig>,
} }