update a bunch of dependencies, including clap3

This commit is contained in:
Marcel Märtens 2022-04-02 23:29:22 +02:00
parent a0a0e36246
commit affdf3131f
17 changed files with 1210 additions and 853 deletions

1912
Cargo.lock generated

File diff suppressed because it is too large Load Diff

View File

@ -39,7 +39,7 @@ async-channel = { version = "1.6", optional = true }
common-ecs = { package = "veloren-common-ecs", path = "../common/ecs", optional = true } common-ecs = { package = "veloren-common-ecs", path = "../common/ecs", optional = true }
serde = { version = "1.0", features = [ "rc", "derive" ], optional = true } serde = { version = "1.0", features = [ "rc", "derive" ], optional = true }
ron = { version = "0.7", default-features = false, optional = true } ron = { version = "0.7", default-features = false, optional = true }
clap = { version = "2.33", optional = true } clap = { version = "3.1.8", optional = true, features = ["color", "std"] }
structopt = { version = "0.3.13", optional = true } structopt = { version = "0.3.13", optional = true }
rustyline = { version = "9.0.0", optional = true } rustyline = { version = "9.0.0", optional = true }
## logging ## logging

View File

@ -1,4 +1,4 @@
use clap::{App, AppSettings, Arg, SubCommand}; use clap::{Arg, Command};
use std::{thread, time::Duration}; use std::{thread, time::Duration};
use tracing::error; use tracing::error;
@ -40,46 +40,46 @@ impl Tui {
} }
pub fn process_command(cmd: &str, command_s: &mut async_channel::Sender<Cmd>) -> bool { pub fn process_command(cmd: &str, command_s: &mut async_channel::Sender<Cmd>) -> bool {
let matches = App::new("veloren-botclient") let matches = Command::new("veloren-botclient")
.version(common::util::DISPLAY_VERSION_LONG.as_str()) .version(common::util::DISPLAY_VERSION_LONG.as_str())
.author("The veloren devs <https://gitlab.com/veloren/veloren>") .author("The veloren devs <https://gitlab.com/veloren/veloren>")
.about("The veloren bot client allows logging in as a horde of bots for load-testing") .about("The veloren bot client allows logging in as a horde of bots for load-testing")
.setting(AppSettings::NoBinaryName) .no_binary_name(true)
.subcommand( .subcommand(
SubCommand::with_name("register") Command::new("register")
.about("Register more bots with the auth server") .about("Register more bots with the auth server")
.args(&[ .args(&[
Arg::with_name("prefix").required(true), Arg::new("prefix").required(true),
Arg::with_name("password").required(true), Arg::new("password").required(true),
Arg::with_name("count"), Arg::new("count"),
]), ]),
) )
.subcommand( .subcommand(
SubCommand::with_name("login") Command::new("login")
.about("Login all registered bots whose username starts with a prefix") .about("Login all registered bots whose username starts with a prefix")
.args(&[Arg::with_name("prefix").required(true)]), .args(&[Arg::new("prefix").required(true)]),
) )
.subcommand( .subcommand(
SubCommand::with_name("ingame") Command::new("ingame")
.about("Join the world with some random character") .about("Join the world with some random character")
.args(&[Arg::with_name("prefix").required(true)]), .args(&[Arg::new("prefix").required(true)]),
) )
.get_matches_from_safe(cmd.split(' ')); .try_get_matches_from(cmd.split(' '));
use clap::ErrorKind::*; use clap::ErrorKind::*;
match matches { match matches {
Ok(matches) => { Ok(matches) => {
if match matches.subcommand() { if match matches.subcommand() {
("register", Some(matches)) => command_s.try_send(Cmd::Register { Some(("register", matches)) => command_s.try_send(Cmd::Register {
prefix: matches.value_of("prefix").unwrap().to_string(), prefix: matches.value_of("prefix").unwrap().to_string(),
password: matches.value_of("password").unwrap().to_string(), password: matches.value_of("password").unwrap().to_string(),
count: matches count: matches
.value_of("count") .value_of("count")
.and_then(|x| x.parse::<usize>().ok()), .and_then(|x| x.parse::<usize>().ok()),
}), }),
("login", Some(matches)) => command_s.try_send(Cmd::Login { Some(("login", matches)) => command_s.try_send(Cmd::Login {
prefix: matches.value_of("prefix").unwrap().to_string(), prefix: matches.value_of("prefix").unwrap().to_string(),
}), }),
("ingame", Some(matches)) => command_s.try_send(Cmd::InGame { Some(("ingame", matches)) => command_s.try_send(Cmd::InGame {
prefix: matches.value_of("prefix").unwrap().to_string(), prefix: matches.value_of("prefix").unwrap().to_string(),
}), }),
_ => Ok(()), _ => Ok(()),
@ -90,9 +90,9 @@ impl Tui {
} }
}, },
Err(e) Err(e)
if [HelpDisplayed, MissingRequiredArgument, UnknownArgument].contains(&e.kind) => if [DisplayHelp, MissingRequiredArgument, UnknownArgument].contains(&e.kind()) =>
{ {
println!("{}", e.message); let _ = e.print();
}, },
Err(e) => { Err(e) => {
error!("{:?}", e); error!("{:?}", e);

View File

@ -30,7 +30,7 @@ enum-iterator = "0.7"
vek = { version = "=0.14.1", features = ["serde"] } vek = { version = "=0.14.1", features = ["serde"] }
chrono = "0.4" chrono = "0.4"
chrono-tz = "0.6" chrono-tz = "0.6"
sha2 = "0.9.8" sha2 = "0.10"
serde_json = "1.0.50" serde_json = "1.0.50"
# Strum # Strum
@ -69,7 +69,7 @@ ron = { version = "0.7", default-features = false, optional = true }
csv = { version = "1.1.3", optional = true } csv = { version = "1.1.3", optional = true }
structopt = { version = "0.3.13", optional = true } structopt = { version = "0.3.13", optional = true }
# graphviz exporters # graphviz exporters
petgraph = { version = "0.5.1", optional = true } petgraph = { version = "0.6", optional = true }
# K-d trees used for RRT pathfinding # K-d trees used for RRT pathfinding
kiddo = { version = "0.1", optional = true } kiddo = { version = "0.1", optional = true }
@ -89,7 +89,7 @@ criterion = "0.3"
#test #test
tracing-subscriber = { version = "0.3.7", default-features = false, features = ["fmt", "time", "ansi", "smallvec", "env-filter"] } tracing-subscriber = { version = "0.3.7", default-features = false, features = ["fmt", "time", "ansi", "smallvec", "env-filter"] }
petgraph = "0.5.1" petgraph = "0.6.0"
[[bench]] [[bench]]
name = "chonk_benchmark" name = "chonk_benchmark"

View File

@ -52,7 +52,7 @@ hashbrown = { version = ">=0.9, <0.13" }
tracing-subscriber = { version = "0.3.7", default-features = false, features = ["env-filter", "fmt", "time", "ansi", "smallvec"] } tracing-subscriber = { version = "0.3.7", default-features = false, features = ["env-filter", "fmt", "time", "ansi", "smallvec"] }
tokio = { version = "1.14", default-features = false, features = ["io-std", "fs", "rt-multi-thread"] } tokio = { version = "1.14", default-features = false, features = ["io-std", "fs", "rt-multi-thread"] }
futures-util = { version = "0.3.7", default-features = false, features = ["sink", "std"] } futures-util = { version = "0.3.7", default-features = false, features = ["sink", "std"] }
clap = { version = "3.1.8", default-features = false, features = ["std", "color"] } clap = { version = "3.1.8", default-features = false, features = ["std", "color", "suggestions"] }
shellexpand = "2.0.0" shellexpand = "2.0.0"
serde = { version = "1.0", features = ["derive"] } serde = { version = "1.0", features = ["derive"] }
prometheus-hyper = "0.1.2" prometheus-hyper = "0.1.2"

View File

@ -3,7 +3,7 @@
//! RUST_BACKTRACE=1 cargo run --example chat -- --trace=info --port 15006 //! RUST_BACKTRACE=1 cargo run --example chat -- --trace=info --port 15006
//! RUST_BACKTRACE=1 cargo run --example chat -- --trace=info --port 15006 --mode=client //! RUST_BACKTRACE=1 cargo run --example chat -- --trace=info --port 15006 --mode=client
//! ``` //! ```
use clap::{Command, Arg}; use clap::{Arg, Command};
use std::{sync::Arc, thread, time::Duration}; use std::{sync::Arc, thread, time::Duration};
use tokio::{io, io::AsyncBufReadExt, runtime::Runtime, sync::RwLock}; use tokio::{io, io::AsyncBufReadExt, runtime::Runtime, sync::RwLock};
use tracing::*; use tracing::*;

View File

@ -4,7 +4,7 @@
//! --profile=release -Z unstable-options -- --trace=info --port 15006) //! --profile=release -Z unstable-options -- --trace=info --port 15006)
//! (cd network/examples/fileshare && RUST_BACKTRACE=1 cargo run //! (cd network/examples/fileshare && RUST_BACKTRACE=1 cargo run
//! --profile=release -Z unstable-options -- --trace=info --port 15007) ``` //! --profile=release -Z unstable-options -- --trace=info --port 15007) ```
use clap::{Command, Arg}; use clap::{Arg, Command};
use std::{path::PathBuf, sync::Arc, thread, time::Duration}; use std::{path::PathBuf, sync::Arc, thread, time::Duration};
use tokio::{io, io::AsyncBufReadExt, runtime::Runtime, sync::mpsc}; use tokio::{io, io::AsyncBufReadExt, runtime::Runtime, sync::mpsc};
use tracing::*; use tracing::*;

View File

@ -3,7 +3,7 @@
/// (cd network/examples/network-speed && RUST_BACKTRACE=1 cargo run --profile=debuginfo -Z unstable-options -- --trace=error --protocol=tcp --mode=server) /// (cd network/examples/network-speed && RUST_BACKTRACE=1 cargo run --profile=debuginfo -Z unstable-options -- --trace=error --protocol=tcp --mode=server)
/// (cd network/examples/network-speed && RUST_BACKTRACE=1 cargo run --profile=debuginfo -Z unstable-options -- --trace=error --protocol=tcp --mode=client) /// (cd network/examples/network-speed && RUST_BACKTRACE=1 cargo run --profile=debuginfo -Z unstable-options -- --trace=error --protocol=tcp --mode=client)
/// ``` /// ```
use clap::{Command, Arg}; use clap::{Arg, Command};
use prometheus::Registry; use prometheus::Registry;
use prometheus_hyper::Server; use prometheus_hyper::Server;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};

View File

@ -34,8 +34,7 @@ common-frontend = { package = "veloren-common-frontend", path = "../common/front
tokio = { version = "1.14", default-features = false, features = ["rt-multi-thread"] } tokio = { version = "1.14", default-features = false, features = ["rt-multi-thread"] }
num_cpus = "1.0" num_cpus = "1.0"
ansi-parser = "0.8" ansi-parser = "0.8"
clap = "2.33" clap = { version = "3.1.8", features = ["derive"] }
structopt = "0.3.13"
crossterm = "0.22" crossterm = "0.22"
lazy_static = "1" lazy_static = "1"
signal-hook = "0.3.6" signal-hook = "0.3.6"

View File

@ -1,7 +1,7 @@
use clap::StructOpt;
use common::comp; use common::comp;
use server::persistence::SqlLogMode; use server::persistence::SqlLogMode;
use std::sync::mpsc::Sender; use std::sync::mpsc::Sender;
use structopt::StructOpt;
use tracing::error; use tracing::error;
#[derive(Clone, Debug, StructOpt)] #[derive(Clone, Debug, StructOpt)]
@ -11,7 +11,7 @@ pub enum Admin {
/// Name of the admin to whom to assign a role /// Name of the admin to whom to assign a role
username: String, username: String,
/// role to assign to the admin /// role to assign to the admin
#[structopt(possible_values = &comp::AdminRole::variants(), case_insensitive = true)] #[structopt(possible_values = comp::AdminRole::variants(), ignore_case = true)]
role: comp::AdminRole, role: comp::AdminRole,
}, },
Remove { Remove {
@ -62,7 +62,7 @@ pub enum Message {
}, },
/// Enable or disable sql logging /// Enable or disable sql logging
SqlLogMode { SqlLogMode {
#[structopt(default_value, possible_values = &SqlLogMode::variants())] #[structopt(default_value_t, possible_values = SqlLogMode::variants())]
mode: SqlLogMode, mode: SqlLogMode,
}, },
/// Disconnects all connected clients /// Disconnects all connected clients
@ -75,8 +75,8 @@ pub enum Message {
version = common::util::DISPLAY_VERSION_LONG.as_str(), version = common::util::DISPLAY_VERSION_LONG.as_str(),
about = "The veloren server tui allows sending commands directly to the running server.", about = "The veloren server tui allows sending commands directly to the running server.",
author = "The veloren devs <https://gitlab.com/veloren/veloren>", author = "The veloren devs <https://gitlab.com/veloren/veloren>",
setting = clap::AppSettings::NoBinaryName,
)] )]
#[clap(no_binary_name = true)]
pub struct TuiApp { pub struct TuiApp {
#[structopt(subcommand)] #[structopt(subcommand)]
command: Message, command: Message,
@ -109,7 +109,7 @@ pub struct ArgvApp {
#[structopt(long)] #[structopt(long)]
/// Run without auth enabled /// Run without auth enabled
pub no_auth: bool, pub no_auth: bool,
#[structopt(default_value, long, short, possible_values = &SqlLogMode::variants())] #[structopt(default_value_t, long, short, possible_values = SqlLogMode::variants())]
/// Enables SQL logging /// Enables SQL logging
pub sql_log_mode: SqlLogMode, pub sql_log_mode: SqlLogMode,
#[structopt(subcommand)] #[structopt(subcommand)]
@ -117,12 +117,12 @@ pub struct ArgvApp {
} }
pub fn parse_command(input: &str, msg_s: &mut Sender<Message>) { pub fn parse_command(input: &str, msg_s: &mut Sender<Message>) {
match TuiApp::from_iter_safe(shell_words::split(input).unwrap_or_default()) { match TuiApp::try_parse_from(shell_words::split(input).unwrap_or_default()) {
Ok(message) => { Ok(message) => {
msg_s msg_s
.send(message.command) .send(message.command)
.unwrap_or_else(|err| error!("Failed to send CLI message, err: {:?}", err)); .unwrap_or_else(|e| error!(?e, "Failed to send CLI message"));
}, },
Err(err) => error!("{}", err.message), Err(e) => error!("{}", e),
} }
} }

View File

@ -24,7 +24,6 @@ use std::{
sync::{atomic::AtomicBool, mpsc, Arc}, sync::{atomic::AtomicBool, mpsc, Arc},
time::Duration, time::Duration,
}; };
use structopt::StructOpt;
use tracing::{info, trace}; use tracing::{info, trace};
lazy_static::lazy_static! { lazy_static::lazy_static! {
@ -33,7 +32,8 @@ lazy_static::lazy_static! {
const TPS: u64 = 30; const TPS: u64 = 30;
fn main() -> io::Result<()> { fn main() -> io::Result<()> {
let app = ArgvApp::from_args(); use clap::Parser;
let app = ArgvApp::parse();
let basic = !app.tui || app.command.is_some(); let basic = !app.tui || app.command.is_some();
let noninteractive = app.non_interactive; let noninteractive = app.non_interactive;

View File

@ -35,10 +35,10 @@ tracing = "0.1"
vek = { version = "0.14.1", features = ["serde"] } vek = { version = "0.14.1", features = ["serde"] }
futures-util = "0.3.7" futures-util = "0.3.7"
tokio = { version = "1.14", default-features = false, features = ["rt"] } tokio = { version = "1.14", default-features = false, features = ["rt"] }
prometheus-hyper = "0.1.2" prometheus-hyper = "0.1.4"
quinn = "0.8" quinn = "0.8"
rustls = { version = "0.20", default-features = false } rustls = { version = "0.20", default-features = false }
rustls-pemfile = { version = "0.2.1", default-features = false } rustls-pemfile = { version = "0.3", default-features = false }
atomicwrites = "0.3.0" atomicwrites = "0.3.0"
chrono = { version = "0.4.19", features = ["serde"] } chrono = { version = "0.4.19", features = ["serde"] }
chrono-tz = { version = "0.6", features = ["serde"] } chrono-tz = { version = "0.6", features = ["serde"] }
@ -52,7 +52,7 @@ rand = { version = "0.8", features = ["small_rng"] }
hashbrown = { version = "0.11", features = ["rayon", "serde", "nightly"] } hashbrown = { version = "0.11", features = ["rayon", "serde", "nightly"] }
rayon = "1.5" rayon = "1.5"
crossbeam-channel = "0.5" crossbeam-channel = "0.5"
prometheus = { version = "0.12", default-features = false} prometheus = { version = "0.13", default-features = false}
portpicker = { git = "https://github.com/xMAC94x/portpicker-rs", rev = "df6b37872f3586ac3b21d08b56c8ec7cd92fb172" } portpicker = { git = "https://github.com/xMAC94x/portpicker-rs", rev = "df6b37872f3586ac3b21d08b56c8ec7cd92fb172" }
authc = { git = "https://gitlab.com/veloren/auth.git", rev = "fb3dcbc4962b367253f8f2f92760ef44d2679c9a" } authc = { git = "https://gitlab.com/veloren/auth.git", rev = "fb3dcbc4962b367253f8f2f92760ef44d2679c9a" }
slab = "0.4" slab = "0.4"

View File

@ -496,7 +496,9 @@ impl Server {
.into_iter() .into_iter()
.find_map(|item| match item { .find_map(|item| match item {
Item::RSAKey(v) | Item::PKCS8Key(v) => Some(v), Item::RSAKey(v) | Item::PKCS8Key(v) => Some(v),
Item::ECKey(_) => None,
Item::X509Certificate(_) => None, Item::X509Certificate(_) => None,
_ => None,
}) })
.ok_or("No valid pem key in file")?; .ok_or("No valid pem key in file")?;
rustls::PrivateKey(key) rustls::PrivateKey(key)

View File

@ -94,7 +94,7 @@ assets_manager = {version = "0.7", features = ["ab_glyph"]}
backtrace = "0.3.40" backtrace = "0.3.40"
bincode = "1.3.1" bincode = "1.3.1"
chrono = { version = "0.4.19", features = ["serde"] } chrono = { version = "0.4.19", features = ["serde"] }
chumsky = "0.3.2" chumsky = "0.8"
cpal = "0.13" cpal = "0.13"
copy_dir = "0.1.2" copy_dir = "0.1.2"
crossbeam-utils = "0.8.1" crossbeam-utils = "0.8.1"
@ -107,13 +107,13 @@ guillotiere = "0.6"
hashbrown = {version = "0.11", features = ["rayon", "serde", "nightly"]} hashbrown = {version = "0.11", features = ["rayon", "serde", "nightly"]}
image = {version = "0.23.12", default-features = false, features = ["ico", "png"]} image = {version = "0.23.12", default-features = false, features = ["ico", "png"]}
lazy_static = "1.4.0" lazy_static = "1.4.0"
native-dialog = { version = "0.5.2", optional = true } native-dialog = { version = "0.6.3", optional = true }
num = "0.4" num = "0.4"
ordered-float = { version = "2.0.1", default-features = false } ordered-float = { version = "2.0.1", default-features = false }
rand = "0.8" rand = "0.8"
rand_chacha = "0.3" rand_chacha = "0.3"
rayon = "1.5" rayon = "1.5"
rodio = {version = "0.14", default-features = false, features = ["vorbis"]} rodio = {version = "0.15", default-features = false, features = ["vorbis"]}
ron = {version = "0.7", default-features = false} ron = {version = "0.7", default-features = false}
serde = {version = "1.0", features = [ "rc", "derive" ]} serde = {version = "1.0", features = [ "rc", "derive" ]}
slab = "0.4.2" slab = "0.4.2"

View File

@ -821,7 +821,7 @@ fn get_chat_template_key(chat_type: &ChatType<String>) -> Option<&str> {
fn parse_cmd(msg: &str) -> Result<(String, Vec<String>), String> { fn parse_cmd(msg: &str) -> Result<(String, Vec<String>), String> {
use chumsky::prelude::*; use chumsky::prelude::*;
let escape = just::<_, Simple<char>>('\\').padding_for( let escape = just::<_, _, Simple<char>>('\\').ignore_then(
just('\\') just('\\')
.or(just('/')) .or(just('/'))
.or(just('"')) .or(just('"'))
@ -833,20 +833,20 @@ fn parse_cmd(msg: &str) -> Result<(String, Vec<String>), String> {
); );
let string = just('"') let string = just('"')
.padding_for(filter(|c| *c != '\\' && *c != '"').or(escape).repeated()) .ignore_then(filter(|c| *c != '\\' && *c != '"').or(escape).repeated())
.padded_by(just('"')) .then_ignore(just('"'))
.labelled("quoted argument"); .labelled("quoted argument");
let arg = string let arg = string
.or(filter(|c: &char| !c.is_whitespace() && *c != '"') .or(filter(|c: &char| !c.is_whitespace() && *c != '"')
.repeated_at_least(1) .repeated()
.at_least(1)
.labelled("argument")) .labelled("argument"))
.collect::<String>(); .collect::<String>();
let cmd = text::ident() let cmd = text::ident()
.collect::<String>()
.then(arg.padded().repeated()) .then(arg.padded().repeated())
.padded_by(end()); .then_ignore(end());
cmd.parse(msg).map_err(|errs| { cmd.parse(msg).map_err(|errs| {
errs.into_iter() errs.into_iter()
@ -855,3 +855,31 @@ fn parse_cmd(msg: &str) -> Result<(String, Vec<String>), String> {
.join(", ") .join(", ")
}) })
} }
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn parse_cmds() {
let expected: Result<(String, Vec<String>), String> = Ok(("help".to_string(), vec![]));
assert_eq!(parse_cmd(r#"help"#), expected);
let expected: Result<(String, Vec<String>), String> = Ok(("say".to_string(), vec![
"foo".to_string(),
"bar".to_string(),
]));
assert_eq!(parse_cmd(r#"say foo bar"#), expected);
assert_eq!(parse_cmd(r#"say "foo" "bar""#), expected);
let expected: Result<(String, Vec<String>), String> =
Ok(("say".to_string(), vec!["Hello World".to_string()]));
assert_eq!(parse_cmd(r#"say "Hello World""#), expected);
// Note: \n in the exptected gets expanded by rust to a newline character, thats
// why we must not use a raw string in the expected
let expected: Result<(String, Vec<String>), String> =
Ok(("say".to_string(), vec!["Hello\nWorld".to_string()]));
assert_eq!(parse_cmd(r#"say "Hello\nWorld""#), expected);
}
}

View File

@ -45,7 +45,7 @@ flate2 = { version = "1.0.20", optional = true }
num-traits = { version = "0.2", optional = true } num-traits = { version = "0.2", optional = true }
fallible-iterator = { version = "0.2.0", optional = true } fallible-iterator = { version = "0.2.0", optional = true }
rstar = { version = "0.9", optional = true } rstar = { version = "0.9", optional = true }
clap = { version = "2.33.3", optional = true } clap = { version = "3.1.8", optional = true }
[dev-dependencies] [dev-dependencies]
@ -53,7 +53,7 @@ common-frontend = { package = "veloren-common-frontend", path = "../common/front
criterion = "0.3" criterion = "0.3"
csv = "1.1.3" csv = "1.1.3"
tracing-subscriber = { version = "0.3.7", default-features = false, features = ["fmt", "time", "ansi", "smallvec", "env-filter"] } tracing-subscriber = { version = "0.3.7", default-features = false, features = ["fmt", "time", "ansi", "smallvec", "env-filter"] }
minifb = "0.19.1" minifb = "0.22"
rusqlite = { version = "0.24.2", features = ["array", "vtab", "bundled", "trace"] } rusqlite = { version = "0.24.2", features = ["array", "vtab", "bundled", "trace"] }
svg_fmt = "0.4" svg_fmt = "0.4"
structopt = "0.3" structopt = "0.3"

View File

@ -1,4 +1,4 @@
use clap::{App, Arg, SubCommand}; use clap::{Arg, Command};
use common::{ use common::{
terrain::{BlockKind, TerrainChunkSize}, terrain::{BlockKind, TerrainChunkSize},
vol::{IntoVolIterator, RectVolSize}, vol::{IntoVolIterator, RectVolSize},
@ -243,36 +243,36 @@ fn palette(conn: Connection) -> Result<(), Box<dyn Error>> {
} }
fn main() -> Result<(), Box<dyn Error>> { fn main() -> Result<(), Box<dyn Error>> {
let mut app = App::new("world_block_statistics") let mut app = Command::new("world_block_statistics")
.version(common::util::DISPLAY_VERSION_LONG.as_str()) .version(common::util::DISPLAY_VERSION_LONG.as_str())
.author("The veloren devs <https://gitlab.com/veloren/veloren>") .author("The veloren devs <https://gitlab.com/veloren/veloren>")
.about("Compute and process block statistics on generated chunks") .about("Compute and process block statistics on generated chunks")
.subcommand( .subcommand(
SubCommand::with_name("generate") Command::new("generate")
.about("Generate block statistics") .about("Generate block statistics")
.args(&[ .args(&[
Arg::with_name("database") Arg::new("database")
.required(true) .required(true)
.help("File to generate/resume generation"), .help("File to generate/resume generation"),
Arg::with_name("ymin").long("ymin").takes_value(true), Arg::new("ymin").long("ymin").takes_value(true),
Arg::with_name("ymax").long("ymax").takes_value(true), Arg::new("ymax").long("ymax").takes_value(true),
]), ]),
) )
.subcommand( .subcommand(
SubCommand::with_name("palette") Command::new("palette")
.about("Compute a palette from previously gathered statistics") .about("Compute a palette from previously gathered statistics")
.args(&[Arg::with_name("database").required(true)]), .args(&[Arg::new("database").required(true)]),
); );
let matches = app.clone().get_matches(); let matches = app.clone().get_matches();
match matches.subcommand() { match matches.subcommand() {
("generate", Some(matches)) => { Some(("generate", matches)) => {
let db_path = matches.value_of("database").expect("database is required"); let db_path = matches.value_of("database").expect("database is required");
let ymin = matches.value_of("ymin").and_then(|x| i32::from_str(x).ok()); let ymin = matches.value_of("ymin").and_then(|x| i32::from_str(x).ok());
let ymax = matches.value_of("ymax").and_then(|x| i32::from_str(x).ok()); let ymax = matches.value_of("ymax").and_then(|x| i32::from_str(x).ok());
generate(db_path, ymin, ymax)?; generate(db_path, ymin, ymax)?;
}, },
("palette", Some(matches)) => { Some(("palette", matches)) => {
let conn = let conn =
Connection::open(&matches.value_of("database").expect("database is required"))?; Connection::open(&matches.value_of("database").expect("database is required"))?;
palette(conn)?; palette(conn)?;