Skip to content

Commit

Permalink
feat: Some CLI improvements (#54)
Browse files Browse the repository at this point in the history
* fixes
- default arg values don't overwrite config values
- now we can supply all args after subcommand
- you can set `time_crate = true` to set `time` as default crate
- clorind live url can be set by env `DATABASE_URL`

* update

* remove enforcing chrono or time feature

* remove time_crate config

* address comment
  • Loading branch information
PoOnesNerfect authored Feb 16, 2025
1 parent b8b542c commit c127f05
Show file tree
Hide file tree
Showing 2 changed files with 57 additions and 36 deletions.
2 changes: 1 addition & 1 deletion clorinde/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ miette = { version = "7.4.0", features = ["fancy"] }
chumsky = "0.9.3"

# CLI handling
clap = { version = "4.5.24", features = ["derive"] }
clap = { version = "4.5.24", features = ["derive", "env"] }

# Word case
heck = "0.5.0"
Expand Down
91 changes: 56 additions & 35 deletions clorinde/src/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,70 +10,91 @@ use crate::{config::Config, conn, container, error::Error, gen_live, gen_managed
struct Args {
#[clap(subcommand)]
action: Action,

/// Config file path
#[clap(short, long, default_value = "clorinde.toml")]
config: PathBuf,

/// Use `podman` instead of `docker`
#[clap(short, long)]
podman: bool,
/// Folder containing the queries
#[clap(short, long, default_value = "queries/")]
queries_path: PathBuf,
/// Destination folder for generated modules
#[clap(short, long, default_value = "clorinde")]
destination: PathBuf,
/// Generate synchronous rust code
#[clap(long)]
sync: bool,
/// Generate asynchronous rust code
#[clap(long)]
r#async: bool,
/// Derive serde's `Serialize` trait for generated types.
#[clap(long)]
serialize: bool,
}

#[derive(Debug, Subcommand)]
enum Action {
/// Generate your modules against your own db
Live {
#[clap(env = "DATABASE_URL")]
/// Postgres url to the database
url: String,

#[clap(flatten)]
args: CommonArgs,
},
/// Generate your modules against schema files
Schema {
/// SQL files containing the database schema
schema_files: Vec<PathBuf>,

#[clap(flatten)]
args: CommonArgs,
},
}

impl Action {
fn args(&self) -> CommonArgs {
match self {
Self::Live { args, .. } => args,
Self::Schema { args, .. } => args,
}
.clone()
}
}

#[derive(Parser, Debug, Clone)]
struct CommonArgs {
/// Config file path
#[clap(short, long, default_value = "clorinde.toml")]
config: PathBuf,
/// Use `podman` instead of `docker`
#[clap(short, long)]
podman: Option<bool>,
/// Folder containing the queries
#[clap(short, long)]
queries_path: Option<PathBuf>,
/// Destination folder for generated modules
#[clap(short, long)]
destination: Option<PathBuf>,
/// Generate synchronous rust code
#[clap(long)]
sync: Option<bool>,
/// Generate asynchronous rust code
#[clap(long)]
r#async: Option<bool>,
/// Derive serde's `Serialize` trait for generated types.
#[clap(long)]
serialize: Option<bool>,
}

#[allow(clippy::result_large_err)]
// Main entrypoint of the CLI. Parses the args and calls the appropriate routines.
pub fn run() -> Result<(), Error> {
let Args {
let Args { action } = Args::parse();
let CommonArgs {
config,
podman,
queries_path,
destination,
action,
sync,
r#async,
serialize,
config,
} = Args::parse();
} = action.args();

let mut cfg = match config.is_file() {
true => Config::from_file(config)?,
false => Config::default(),
};

cfg.podman = podman;
cfg.queries = queries_path;
cfg.destination = destination;
cfg.sync = sync;
cfg.r#async = r#async || !sync;
cfg.serialize = serialize;
cfg.podman = podman.unwrap_or(cfg.podman);
cfg.queries = queries_path.unwrap_or(cfg.queries);
cfg.destination = destination.unwrap_or(cfg.destination);
cfg.sync = sync.unwrap_or(cfg.sync);
cfg.r#async = r#async.map_or(cfg.r#async, |a| a || !cfg.sync);
cfg.serialize = serialize.unwrap_or(cfg.serialize);

let podman = cfg.podman;

// Prevent wrong directory being accidentally deleted
if !cfg.destination.ends_with("clorinde")
Expand All @@ -98,11 +119,11 @@ pub fn run() -> Result<(), Error> {
}

match action {
Action::Live { url } => {
Action::Live { url, .. } => {
let mut client = conn::from_url(&url)?;
gen_live(&mut client, cfg)?;
}
Action::Schema { schema_files } => {
Action::Schema { schema_files, .. } => {
// Run the generate command. If the command is unsuccessful, cleanup Clorinde's container
if let Err(e) = gen_managed(&schema_files, cfg) {
container::cleanup(podman).ok();
Expand Down

0 comments on commit c127f05

Please sign in to comment.