From eed91b1246a788bd2dce237b5584e6c858dec069 Mon Sep 17 00:00:00 2001 From: Kjetil Orbekk Date: Wed, 26 Feb 2020 21:21:48 -0500 Subject: Use StructOpt instead of directly using clap --- Cargo.lock | 73 +++++++++++++++++++++ Cargo.toml | 1 + README.md | 4 +- src/main.rs | 212 ++++++++++++++++++++++++++---------------------------------- 4 files changed, 167 insertions(+), 123 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 3f7551e..e7ecd42 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1097,6 +1097,7 @@ dependencies = [ "rocket_contrib 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 1.0.45 (registry+https://github.com/rust-lang/crates.io-index)", + "structopt 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", "threadpool 1.7.1 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1118,6 +1119,30 @@ dependencies = [ "vcpkg 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "proc-macro-error" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "proc-macro-error-attr 0.4.9 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "rustversion 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.14 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "proc-macro-error-attr" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "proc-macro2 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "rustversion 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.14 (registry+https://github.com/rust-lang/crates.io-index)", + "syn-mid 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "proc-macro2" version = "0.4.30" @@ -1374,6 +1399,16 @@ dependencies = [ "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "rustversion" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "proc-macro2 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.14 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "ryu" version = "1.0.2" @@ -1516,6 +1551,28 @@ name = "strsim" version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "structopt" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "clap 2.33.0 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "structopt-derive 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "structopt-derive" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "heck 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro-error 0.4.9 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.14 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "syn" version = "0.15.44" @@ -1536,6 +1593,16 @@ dependencies = [ "unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "syn-mid" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "proc-macro2 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.14 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "tempfile" version = "3.1.0" @@ -2096,6 +2163,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum pkg-config 0.3.17 (registry+https://github.com/rust-lang/crates.io-index)" = "05da548ad6865900e60eaba7f589cc0783590a92e940c26953ff81ddbab2d677" "checksum ppv-lite86 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "74490b50b9fbe561ac330df47c08f3f33073d2d00c150f719147d7c54522fa1b" "checksum pq-sys 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "6ac25eee5a0582f45a67e837e350d784e7003bd29a5f460796772061ca49ffda" +"checksum proc-macro-error 0.4.9 (registry+https://github.com/rust-lang/crates.io-index)" = "052b3c9af39c7e5e94245f820530487d19eb285faedcb40e0c3275132293f242" +"checksum proc-macro-error-attr 0.4.9 (registry+https://github.com/rust-lang/crates.io-index)" = "d175bef481c7902e63e3165627123fff3502f06ac043d3ef42d08c1246da9253" "checksum proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)" = "cf3d2011ab5c909338f7887f4fc896d35932e29146c12c8d01da6b22a80ba759" "checksum proc-macro2 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)" = "3acb317c6ff86a4e579dfa00fc5e6cca91ecbb4e7eb2df0468805b674eb88548" "checksum quick-error 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0" @@ -2119,6 +2188,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum rocket_contrib 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e0fa5c1392135adc0f96a02ba150ac4c765e27c58dbfd32aa40678e948f6e56f" "checksum rocket_contrib_codegen 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "343da6694fc3cfd901242fd6efafc823e7a3a7f4948017a7dda7311775055092" "checksum rocket_http 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "b1391457ee4e80b40d4b57fa5765c0f2836b20d73bcbee4e3f35d93cf3b80817" +"checksum rustversion 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "b3bba175698996010c4f6dce5e7f173b6eb781fce25d2cfc45e27091ce0b79f6" "checksum ryu 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "bfa8506c1de11c9c4e4c38863ccbe02a305c8188e85a05a784c9e11e1c3910c8" "checksum safemem 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ef703b7cb59335eae2eb93ceb664c0eb7ea6bf567079d843e09420219668e072" "checksum same-file 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" @@ -2138,8 +2208,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum sourcefile 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "4bf77cb82ba8453b42b6ae1d692e4cdc92f9a47beaf89a847c8be83f4e328ad3" "checksum state 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7345c971d1ef21ffdbd103a75990a15eb03604fc8b8852ca8cb418ee1a099028" "checksum strsim 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a" +"checksum structopt 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "a1bcbed7d48956fcbb5d80c6b95aedb553513de0a1b451ea92679d999c010e98" +"checksum structopt-derive 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "095064aa1f5b94d14e635d0a5684cf140c43ae40a0fd990708d38f5d669e5f64" "checksum syn 0.15.44 (registry+https://github.com/rust-lang/crates.io-index)" = "9ca4b3b69a77cbe1ffc9e198781b7acb0c7365a883670e8f1c1bc66fba79a5c5" "checksum syn 1.0.14 (registry+https://github.com/rust-lang/crates.io-index)" = "af6f3550d8dff9ef7dc34d384ac6f107e5d31c8f57d9f28e0081503f547ac8f5" +"checksum syn-mid 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7be3539f6c128a931cf19dcee741c1af532c7fd387baa739c03dd2e96479338a" "checksum tempfile 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6e24d9338a0a5be79593e2fa15a648add6138caa803e2d5bc782c371732ca9" "checksum textwrap 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060" "checksum thread_local 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c6b53e329000edc2b34dbe8545fd20e55a333362d0a321909685a19bd28c3f1b" diff --git a/Cargo.toml b/Cargo.toml index ca735f4..09c75bd 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -9,6 +9,7 @@ serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" reqwest = { version = "0.10.1", features = ["blocking", "json"] } clap = "2" +structopt = "0.3" rocket = "0.4.2" rocket_contrib = { version = "0.4.2", default-features = false, features = ["handlebars_templates", "diesel_postgres_pool", "serve"] } diesel = { version = "1.0.0", features = ["postgres", "chrono", "extras"] } diff --git a/README.md b/README.md index 50a4781..b327372 100644 --- a/README.md +++ b/README.md @@ -22,6 +22,6 @@ ROCKET_SECRET_KEY=openssl rand -base64 32 cargo run -- --database_url $DB_URL \ init --rocket_secret_key $ROCKET_SECRET_KEY \ - --strava_client_id - --strava_client_secret + --strava-client-id + --strava-client-secret ``` diff --git a/src/main.rs b/src/main.rs index 5fc638b..7afba14 100644 --- a/src/main.rs +++ b/src/main.rs @@ -2,14 +2,11 @@ extern crate fern; #[macro_use] extern crate log; -extern crate clap; #[macro_use] extern crate diesel_migrations; use chrono::Utc; -use clap::App; -use clap::Arg; -use clap::SubCommand; +use structopt::StructOpt; use diesel::connection::Connection; use diesel::pg::PgConnection; use pjournal::db; @@ -19,6 +16,55 @@ use serde_json::to_value; embed_migrations!(); +/// Practice Journal +#[derive(Debug, StructOpt)] +struct Opt { + /// URL to postgresql database + #[structopt(long)] + database_url: String, + + /// Endpoint for this web server + #[structopt(long, default_value = "http://localhost:8080/")] + base_url: String, + + /// Path to directory containing templates + #[structopt(long, default_value = "./templates")] + template_path: String, + + /// Path to directory containing static files + #[structopt(long, default_value = "./static")] + static_path: String, + + /// Port on which to server HTTP requests + #[structopt(long, default_value = "8000")] + port: u16, + + #[structopt(subcommand)] + cmd: Option, +} + +#[derive(Debug, StructOpt)] +enum Command { + /// Initialize config table in the database + Init { + /// Secret passed to rocket for encrypting cookies + rocket_secret_key: String, + + /// Client secret for strava authentication + strava_client_secret: String, + + /// Client id for strava authentication + strava_client_id: String, + }, + /// Add a user account + AddUser { + username: String, + password: String, + }, + /// Create a ProcessAllRawData task + ProcessAllData, +} + fn setup_logger() -> Result<(), fern::InitError> { use fern::colors::{Color, ColoredLevelConfig}; let colors = ColoredLevelConfig::new(); @@ -71,127 +117,51 @@ fn setup_logger() -> Result<(), fern::InitError> { } fn main() { - let matches = App::new("pjournal") - .version("0.1") - .author("KJ Ørbekk ") - .about("Practice Journaling") - .arg( - Arg::with_name("database_url") - .long("database_url") - .required(true) - .takes_value(true) - .help("URL to postgresql database"), - ) - .arg( - Arg::with_name("base_url") - .long("base_url") - .takes_value(true) - .help("Endpoint for this web server"), - ) - .arg( - Arg::with_name("template_path") - .long("template_path") - .takes_value(true) - .help("Path to directory containing templates"), - ) - .arg( - Arg::with_name("static_path") - .long("static_path") - .takes_value(true) - .help("Directory containing static files"), - ) - .arg( - Arg::with_name("port") - .long("port") - .takes_value(true) - .help("Port to serve http user requests"), - ) - .subcommand( - SubCommand::with_name("init") - .about("initialize database config") - .arg( - Arg::with_name("rocket_secret_key") - .long("rocket_secret_key") - .takes_value(true) - .required(true) - .help("Secret passed to rocket for encrypted cookies"), - ) - .arg( - Arg::with_name("strava_client_secret") - .long("strava_client_secret") - .takes_value(true) - .required(true) - .help("Client secret for strava authentication"), - ) - .arg( - Arg::with_name("strava_client_id") - .long("strava_client_id") - .takes_value(true) - .required(true) - .help("Client id for strava authentication"), - ), - ) - .subcommand( - SubCommand::with_name("adduser") - .about("add a user account") - .arg(Arg::with_name("USERNAME").required(true).index(1)) - .arg(Arg::with_name("PASSWORD").required(true).index(2)), - ) - .subcommand( - SubCommand::with_name("process_all_data").about("create a ProcessAllRawData task"), - ) - .get_matches(); - setup_logger().expect("logger"); + let opt = Opt::from_args(); - let static_path = matches.value_of("static_path").unwrap_or("./static"); - let port: u16 = matches.value_of("port").unwrap_or("8000").parse().unwrap(); - - let default_base_url = format!("http://localhost:{}", port); - let base_url = matches - .value_of("base_url") - .unwrap_or(&default_base_url); - - let template_path = matches - .value_of("template_path") - .unwrap_or("./templates/"); - - let db_url = matches.value_of("database_url").unwrap(); - let conn = PgConnection::establish(db_url).unwrap(); - + let conn = PgConnection::establish(&opt.database_url).unwrap(); embedded_migrations::run(&conn).unwrap(); - if let Some(matches) = matches.subcommand_matches("init") { - let config = models::Config { - strava_client_id: matches.value_of("strava_client_id").unwrap().to_string(), - strava_client_secret: matches - .value_of("strava_client_secret") - .unwrap() - .to_string(), - rocket_secret_key: matches.value_of("rocket_secret_key").unwrap().to_string(), - singleton: true, - }; - - db::create_config(&conn, &config).unwrap(); - } else if let Some(matches) = matches.subcommand_matches("adduser") { - let user = matches.value_of("USERNAME").unwrap(); - let password = matches.value_of("PASSWORD").unwrap(); - db::adduser(&conn, user, password).unwrap(); - } else if let Some(_matches) = matches.subcommand_matches("process_all_data") { - let command = importer::Command::ProcessAllRawData; - db::insert_task( - &conn, - &models::NewTask { - start_at: Utc::now(), - state: models::TaskState::NEW, - username: "system", - payload: &to_value(command).unwrap(), - }, - ) - .expect("insert"); - } else { - info!("Start server"); - pjournal::server::start(conn, db_url, base_url, static_path, port, template_path); + match opt.cmd { + Some(Command::Init { rocket_secret_key, strava_client_secret, strava_client_id }) => { + let config = models::Config { + strava_client_id, + strava_client_secret, + rocket_secret_key, + singleton: true, + }; + + db::create_config(&conn, &config).unwrap(); + info!("config created"); + }, + Some(Command::AddUser { username, password }) => { + db::adduser(&conn, &username, &password).unwrap(); + info!("added user {}", username); + }, + Some(Command::ProcessAllData) => { + let command = importer::Command::ProcessAllRawData; + db::insert_task( + &conn, + &models::NewTask { + start_at: Utc::now(), + state: models::TaskState::NEW, + username: "system", + payload: &to_value(command).unwrap(), + }, + ) + .expect("insert"); + info!("ProcessAllRawData: task inserted"); + }, + None => { + info!("starting server with options {:?}", opt); + pjournal::server::start(conn, + &opt.database_url, + &opt.base_url, + &opt.static_path, + opt.port, + &opt.template_path); + } } } -- cgit v1.2.3