chore, refactor: update clap, use derive

feat/type-attributes
Tomáš Mládek 2023-04-24 23:00:21 +02:00
parent ff69c0a80f
commit a724d4c07b
3 changed files with 100 additions and 211 deletions

73
Cargo.lock generated
View File

@ -428,15 +428,6 @@ dependencies = [
"libc",
]
[[package]]
name = "ansi_term"
version = "0.12.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d52a9bb7ec0cf484c551830a7ce27bd20d67eac647e1befb56b0be4ee39a55d2"
dependencies = [
"winapi 0.3.9",
]
[[package]]
name = "anstream"
version = "0.3.0"
@ -503,17 +494,6 @@ dependencies = [
"syn 2.0.15",
]
[[package]]
name = "atty"
version = "0.2.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8"
dependencies = [
"hermit-abi 0.1.19",
"libc",
"winapi 0.3.9",
]
[[package]]
name = "autocfg"
version = "1.1.0"
@ -716,21 +696,6 @@ dependencies = [
"winapi 0.3.9",
]
[[package]]
name = "clap"
version = "2.34.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a0610544180c38b88101fecf2dd634b174a62eef6946f84dfc6a7127512b381c"
dependencies = [
"ansi_term",
"atty",
"bitflags 1.3.2",
"strsim 0.8.0",
"textwrap",
"unicode-width",
"vec_map",
]
[[package]]
name = "clap"
version = "4.2.4"
@ -752,7 +717,7 @@ dependencies = [
"anstyle",
"bitflags 1.3.2",
"clap_lex",
"strsim 0.10.0",
"strsim",
]
[[package]]
@ -1503,15 +1468,6 @@ version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8"
[[package]]
name = "hermit-abi"
version = "0.1.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33"
dependencies = [
"libc",
]
[[package]]
name = "hermit-abi"
version = "0.2.6"
@ -3374,12 +3330,6 @@ dependencies = [
"quote",
]
[[package]]
name = "strsim"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a"
[[package]]
name = "strsim"
version = "0.10.0"
@ -3453,15 +3403,6 @@ dependencies = [
"winapi-util",
]
[[package]]
name = "textwrap"
version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060"
dependencies = [
"unicode-width",
]
[[package]]
name = "thiserror"
version = "1.0.40"
@ -3963,7 +3904,7 @@ dependencies = [
]
[[package]]
name = "upend-server"
name = "upend-cli"
version = "0.1.0"
dependencies = [
"actix",
@ -3975,7 +3916,7 @@ dependencies = [
"actix_derive",
"anyhow",
"chrono",
"clap 2.34.0",
"clap",
"diesel",
"diesel_migrations",
"filebuffer",
@ -4022,7 +3963,7 @@ name = "upend_cli"
version = "0.1.0"
dependencies = [
"anyhow",
"clap 4.2.4",
"clap",
"env_logger",
"filebuffer",
"log",
@ -4127,12 +4068,6 @@ version = "0.2.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426"
[[package]]
name = "vec_map"
version = "0.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191"
[[package]]
name = "version_check"
version = "0.1.5"

View File

@ -1,11 +1,12 @@
[package]
name = "upend-server"
name = "upend-cli"
authors = ["Tomáš Mládek <t@mldk.cz>"]
version = "0.1.0"
edition = "2021"
[dependencies]
upend = { path = "../" }
clap = "2.33.0"
clap = { version = "4.2.4", features = ["derive", "env", "color"] }
log = "0.4"
tracing = "0.1"

View File

@ -7,7 +7,7 @@ use std::path::PathBuf;
use actix_cors::Cors;
use actix_web::{middleware, App, HttpServer};
use anyhow::Result;
use clap::{App as ClapApp, Arg};
use clap::Parser;
use rand::{thread_rng, Rng};
use std::sync::Arc;
use tracing::{debug, info, warn};
@ -31,7 +31,69 @@ mod util;
mod extractors;
mod previews;
#[derive(Parser, Debug)]
#[command(name="upend", author, version)]
struct Args {
/// Directory to serve a vault from.
#[arg()]
directory: PathBuf,
/// Address and port to bind the Web interface on.
#[arg(long, default_value = "127.0.0.1:8093")]
bind: String,
/// Path to blob store ($VAULT_PATH by default).
#[arg(long)]
store_path: Option<PathBuf>,
/// Do not open a web browser with the UI.
#[arg(long)]
no_browser: bool,
/// Disable desktop features (web browser, native file opening).
#[arg(long)]
no_desktop: bool,
/// Trust the vault, and open local executable files.
#[arg(long)]
trust_executables: bool,
/// Do not serve the web UI.
#[arg(long)]
no_ui: bool,
/// Do not run a database update on start.
#[arg(long)]
no_initial_update: bool,
/// Clean up temporary files (e.g. previews) on start.
#[arg(long)]
clean: bool,
/// Delete and initialize database, if it exists already.
#[arg(long)]
reinitialize: bool,
/// Name of the vault.
#[arg(long)]
vault_name: Option<String>,
/// Secret to use for authentication.
#[arg(long, env = "UPEND_SECRET")]
secret: Option<String>,
/// Authentication key users must supply.
#[arg(long, env = "UPEND_KEY")]
key: Option<String>,
/// Allowed host/domain name the API can serve.
#[arg(long)]
allow_host: Vec<String>,
}
fn main() -> Result<()> {
let args = Args::parse();
tracing_subscriber::fmt()
.with_env_filter(
EnvFilter::builder()
@ -40,108 +102,19 @@ fn main() -> Result<()> {
)
.init();
let app = ClapApp::new("upend")
.version(build::PKG_VERSION)
.author("Tomáš Mládek <t@mldk.cz>")
.arg(Arg::with_name("DIRECTORY").required(true).index(1))
.arg(
Arg::with_name("BIND")
.long("bind")
.default_value("127.0.0.1:8093")
.help("address and port to bind the Web interface on")
.required(true),
)
.arg(
Arg::with_name("STORE_PATH")
.long("store")
.takes_value(true)
.help(r#"path to store ($VAULT_PATH by default)"#),
)
.arg(
Arg::with_name("NO_BROWSER")
.long("no-browser")
.help("Do not open web browser with the UI."),
)
.arg(
Arg::with_name("NO_DESKTOP")
.long("no-desktop")
.help("Disable desktop features (webbrowser, native file opening)"),
)
.arg(
Arg::with_name("TRUST_EXECUTABLES")
.long("trust-executables")
.help("Trust the vault and open local executable files."),
)
.arg(
Arg::with_name("NO_UI")
.long("no-ui")
.help("Do not serve the web UI."),
)
.arg(
Arg::with_name("NO_INITIAL_UPDATE")
.long("no-initial-update")
.help("Don't run a database update on start."),
)
.arg(
Arg::with_name("CLEAN")
.long("clean")
.help("Clean up temporary files (e.g. previews) on start."),
)
.arg(
Arg::with_name("REINITIALIZE")
.long("reinitialize")
.help("Delete and initialize database, if it exists already."),
)
.arg(
Arg::with_name("VAULT_NAME")
.takes_value(true)
.long("name")
.help("Name of the vault."),
)
.arg(
Arg::with_name("SECRET")
.takes_value(true)
.long("secret")
.env("UPEND_SECRET")
.help("Secret to use for authentication."),
)
.arg(
Arg::with_name("KEY")
.takes_value(true)
.long("key")
.env("UPEND_KEY")
.help("Authentication key users must supply."),
)
.arg(
Arg::with_name("ALLOW_HOST")
.takes_value(true)
.multiple(true)
.number_of_values(1)
.long("allow-host")
.help("Allowed host/domain name the API can serve."),
);
let matches = app.get_matches();
info!("Starting UpEnd {}...", build::PKG_VERSION);
let sys = actix::System::new("upend");
let job_container = JobContainer::new();
let vault_path = PathBuf::from(matches.value_of("DIRECTORY").unwrap());
let vault_path = args.directory;
let open_result = UpEndDatabase::open(&vault_path, matches.is_present("REINITIALIZE"))
.expect("failed to open database!");
let open_result =
UpEndDatabase::open(&vault_path, args.reinitialize).expect("failed to open database!");
let upend = Arc::new(open_result.db);
let store = Arc::new(Box::new(
FsStore::from_path(
matches
.value_of("STORE_PATH")
.map(PathBuf::from)
.unwrap_or_else(|| vault_path.clone()),
)
.unwrap(),
FsStore::from_path(args.store_path.unwrap_or_else(|| vault_path.clone())).unwrap(),
) as Box<dyn UpStore + Send + Sync>);
let ui_path = get_static_dir("webui");
@ -151,10 +124,9 @@ fn main() -> Result<()> {
ui_path
);
}
let desktop_enabled = !matches.is_present("NO_DESKTOP");
let trust_executables = matches.is_present("TRUST_EXECUTABLES");
let ui_enabled = ui_path.is_ok() && !matches.is_present("NO_UI");
let browser_enabled = desktop_enabled && ui_enabled && !matches.is_present("NO_BROWSER");
let ui_enabled = ui_path.is_ok() && !args.no_ui;
let browser_enabled = !args.no_desktop && ui_enabled && !args.no_browser;
let preview_path = upend.path.join("previews");
#[cfg(feature = "previews")]
@ -170,7 +142,7 @@ fn main() -> Result<()> {
.unwrap(),
));
if matches.is_present("CLEAN") {
if args.clean {
info!("Cleaning temporary directories...");
if preview_path.exists() {
std::fs::remove_dir_all(&preview_path).unwrap();
@ -185,26 +157,17 @@ fn main() -> Result<()> {
#[cfg(not(feature = "previews"))]
let preview_pool = None;
let mut bind: SocketAddr = matches
.value_of("BIND")
.unwrap()
.parse()
.expect("Incorrect bind format.");
let mut bind: SocketAddr = args.bind.parse().expect("Incorrect bind format.");
let secret = matches
.value_of("SECRET")
.map(String::from)
.unwrap_or_else(|| {
warn!("No secret supplied, generating one at random.");
let secret = args.secret.unwrap_or_else(|| {
warn!("No secret supplied, generating one at random.");
thread_rng()
.sample_iter(&rand::distributions::Alphanumeric)
.take(32)
.map(char::from)
.collect()
});
let key = matches.value_of("KEY").map(String::from);
thread_rng()
.sample_iter(&rand::distributions::Alphanumeric)
.take(32)
.map(char::from)
.collect()
});
let state = routes::State {
upend: upend.clone(),
@ -213,23 +176,18 @@ fn main() -> Result<()> {
preview_store,
preview_pool,
config: UpEndConfig {
vault_name: Some(
matches
.value_of("VAULT_NAME")
.map(|s| s.to_string())
.unwrap_or_else(|| {
vault_path
.iter()
.last()
.unwrap()
.to_string_lossy()
.into_owned()
}),
),
desktop_enabled,
trust_executables,
vault_name: Some(args.vault_name.unwrap_or_else(|| {
vault_path
.iter()
.last()
.unwrap()
.to_string_lossy()
.into_owned()
})),
desktop_enabled: !args.no_desktop,
trust_executables: args.trust_executables,
key: args.key,
secret,
key,
},
};
@ -237,15 +195,10 @@ fn main() -> Result<()> {
let mut cnt = 0;
let ui_path = ui_path.ok();
let allowed_origins: Vec<_> = if let Some(matches) = matches.values_of("ALLOW_HOST") {
matches.map(String::from).collect()
} else {
vec![]
};
let server = loop {
let state = state.clone();
let ui_path = ui_path.clone();
let allowed_origins = allowed_origins.clone();
let allowed_origins = args.allow_host.clone();
let server = HttpServer::new(move || {
let allowed_origins = allowed_origins.clone();
@ -313,7 +266,7 @@ fn main() -> Result<()> {
info!("Starting server at: {}", &bind);
server.run();
if !matches.is_present("NO_INITIAL_UPDATE") {
if !args.no_initial_update {
info!("Running initial update...");
let initial = open_result.new;
block_background::<_, _, anyhow::Error>(move || {