Use Clap v3.0.0-beta

This commit is contained in:
Arne Beer 2020-10-30 18:33:50 +01:00
parent b469170f35
commit 7d64747148
6 changed files with 178 additions and 124 deletions

138
Cargo.lock generated
View file

@ -6,15 +6,6 @@ version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "aae1277d39aeec15cb388266ecc24b11c80469deae6067e17a1a7aa9e5c1f234"
[[package]]
name = "ansi_term"
version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b"
dependencies = [
"winapi",
]
[[package]]
name = "anyhow"
version = "1.0.33"
@ -76,9 +67,9 @@ dependencies = [
[[package]]
name = "async-global-executor"
version = "1.4.2"
version = "1.4.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "124ac8c265e407641c3362b8f4d39cdb4e243885b71eef087be27199790f5a3a"
checksum = "73079b49cd26b8fd5a15f68fc7707fc78698dc2a3d61430f2a7a9430230dfa04"
dependencies = [
"async-executor",
"async-io",
@ -342,19 +333,45 @@ dependencies = [
[[package]]
name = "clap"
version = "2.33.3"
version = "3.0.0-beta.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "37e58ac78573c40708d45522f0d80fa2f01cc4f9b4e2bf749807255454312002"
checksum = "4bd1061998a501ee7d4b6d449020df3266ca3124b941ec56cf2005c3779ca142"
dependencies = [
"ansi_term",
"atty",
"bitflags",
"clap_derive",
"indexmap",
"lazy_static",
"os_str_bytes",
"strsim",
"termcolor",
"textwrap",
"unicode-width",
"vec_map",
]
[[package]]
name = "clap_derive"
version = "3.0.0-beta.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "370f715b81112975b1b69db93e0b56ea4cd4e5002ac43b2da8474106a54096a1"
dependencies = [
"heck",
"proc-macro-error",
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "clap_generate"
version = "3.0.0-beta.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "adf420f8b687b628d2915ccfd43a660c437a170432e3fbcb66944e8717a0d68f"
dependencies = [
"clap",
]
[[package]]
name = "cloudabi"
version = "0.1.0"
@ -424,9 +441,9 @@ dependencies = [
[[package]]
name = "crossterm"
version = "0.18.1"
version = "0.18.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cef9149b29071d44c9fb98fd9c27fcf74405bbdb761889ad6a03f36be93b0b15"
checksum = "4e86d73f2a0b407b5768d10a8c720cf5d2df49a9efc10ca09176d201ead4b7fb"
dependencies = [
"bitflags",
"crossterm_winapi",
@ -639,6 +656,12 @@ dependencies = [
"serde_json",
]
[[package]]
name = "hashbrown"
version = "0.9.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d7afe4a420e3fe79967a00898cc1f4db7c8a49a9333a29f8a4bd76a253d5cd04"
[[package]]
name = "heck"
version = "0.3.1"
@ -663,6 +686,16 @@ version = "0.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "644f9158b2f133fd50f5fb3242878846d9eb792e445c893805ff0e3824006e35"
[[package]]
name = "indexmap"
version = "1.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "55e2e4c765aa53a0424761bf9f41aa7a6ac1efa87238f59560640e27fca028f2"
dependencies = [
"autocfg",
"hashbrown",
]
[[package]]
name = "instant"
version = "0.1.8"
@ -780,9 +813,9 @@ checksum = "3e2e65a1a2e43cfcb47a895c4c8b10d1f4a61097f9f254f183aee60cad9c651d"
[[package]]
name = "memchr"
version = "2.3.3"
version = "2.3.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3728d817d99e5ac407411fa471ff9800a778d88a24685968b36824eaf4bee400"
checksum = "0ee1c47aaa256ecabcaea351eae4a9b01ef39ed810004e298d2511ed284b1525"
[[package]]
name = "mio"
@ -876,9 +909,9 @@ dependencies = [
[[package]]
name = "num-integer"
version = "0.1.43"
version = "0.1.44"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8d59457e662d541ba17869cf51cf177c0b5f0cbf476c66bdc90bf1edac4f875b"
checksum = "d2cc698a63b549a70bc047073d2949cce27cd1c7b0a4a862d08a8031bc2801db"
dependencies = [
"autocfg",
"num-traits",
@ -886,9 +919,9 @@ dependencies = [
[[package]]
name = "num-traits"
version = "0.2.12"
version = "0.2.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ac267bcc07f48ee5f8935ab0d24f316fb722d7a1292e2913f0cc196b29ffd611"
checksum = "9a64b1ec5cda2586e284722486d802acf1f7dbdc623e2bfc57e65ca1cd099290"
dependencies = [
"autocfg",
]
@ -915,6 +948,12 @@ version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2839e79665f131bdb5782e51f2c6c9599c133c6098982a54c794358bf432529c"
[[package]]
name = "os_str_bytes"
version = "2.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2ac6fe3538f701e339953a3ebbe4f39941aababa8a3f6964635b24ab526daeac"
[[package]]
name = "parking"
version = "2.0.0"
@ -1125,6 +1164,8 @@ dependencies = [
"bytes",
"chrono",
"chrono-english",
"clap",
"clap_generate",
"comfy-table",
"config",
"crossterm",
@ -1143,7 +1184,6 @@ dependencies = [
"serde_yaml",
"simplelog",
"snap",
"structopt",
"strum",
"strum_macros",
"tempfile",
@ -1423,33 +1463,9 @@ checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f"
[[package]]
name = "strsim"
version = "0.8.0"
version = "0.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a"
[[package]]
name = "structopt"
version = "0.3.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "126d630294ec449fae0b16f964e35bf3c74f940da9dca17ee9b905f7b3112eb8"
dependencies = [
"clap",
"lazy_static",
"structopt-derive",
]
[[package]]
name = "structopt-derive"
version = "0.4.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "65e51c492f9e23a220534971ff5afc14037289de430e3c83f9daf6a1b6ae91e8"
dependencies = [
"heck",
"proc-macro-error",
"proc-macro2",
"quote",
"syn",
]
checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623"
[[package]]
name = "strum"
@ -1495,10 +1511,19 @@ dependencies = [
]
[[package]]
name = "textwrap"
version = "0.11.0"
name = "termcolor"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060"
checksum = "bb6bfa289a4d7c5766392812c0a1f4c1ba45afa1ad47803c11e1f407d846d75f"
dependencies = [
"winapi-util",
]
[[package]]
name = "textwrap"
version = "0.12.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "203008d98caf094106cfaba70acfed15e18ed3ddb7d94e49baec153a2b462789"
dependencies = [
"unicode-width",
]
@ -1732,6 +1757,15 @@ version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
[[package]]
name = "winapi-util"
version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178"
dependencies = [
"winapi",
]
[[package]]
name = "winapi-x86_64-pc-windows-gnu"
version = "0.4.0"

View file

@ -51,7 +51,8 @@ serde_derive = "^1.0"
log = "0.4"
config = { version = "^0.10", default-features = false, features = ["yaml"] }
simplelog = { version = "0.8", default-features = false }
structopt = "0.3"
clap = "3.0.0-beta.2"
clap_generate = "3.0.0-beta.2"
crossterm = "^0.18"
comfy-table= "^1"
tempfile = "^3"

View file

@ -3,46 +3,45 @@ use std::path::PathBuf;
use chrono::prelude::*;
use chrono::Duration;
use chrono_english::*;
use structopt::clap::Shell;
use structopt::StructOpt;
use clap::Clap;
#[derive(StructOpt, Debug)]
#[derive(Clap, Debug)]
pub enum SubCommand {
/// Enqueue a task for execution.
Add {
/// The command that should be added.
#[structopt(required = true)]
#[clap(required = true)]
command: Vec<String>,
/// Start the task immediately.
#[structopt(name = "immediate", short, long, conflicts_with = "stashed")]
#[clap(name = "immediate", short, long, conflicts_with = "stashed")]
start_immediately: bool,
/// Create the task in stashed state.
/// Useful to avoid immediate execution if the queue is empty.
#[structopt(name = "stashed", short, long, conflicts_with = "immediate")]
#[clap(name = "stashed", short, long, conflicts_with = "immediate")]
stashed: bool,
/// Delays enqueueing the task until <delay> elapses. See "enqueue" for accepted formats.
#[structopt(name = "delay", short, long, conflicts_with = "immediate", parse(try_from_str=parse_delay_until))]
#[clap(name = "delay", short, long, conflicts_with = "immediate", parse(try_from_str=parse_delay_until))]
delay_until: Option<DateTime<Local>>,
/// Assign the task to a group. Groups kind of act as separate queues.
/// I.e. all groups run in parallel and you can specify the amount of parallel tasks for each group.
/// If no group is specified, the default group will be used.
#[structopt(name = "group", short, long)]
#[clap(name = "group", short, long)]
group: Option<String>,
/// Start the task once all specified tasks have successfully finished.
/// As soon as one of the dependencies fails, this task will fail as well.
#[structopt(name = "after", short, long)]
#[clap(name = "after", short, long)]
dependencies: Vec<usize>,
},
/// Remove tasks from the list.
/// Running or paused tasks need to be killed first.
Remove {
/// The task ids to be removed.
#[structopt(required = true)]
#[clap(required = true)]
task_ids: Vec<usize>,
},
/// Switches the queue position of two commands. Only works on queued and stashed commands.
@ -56,11 +55,11 @@ pub enum SubCommand {
/// Either enqueue them, to be normally handled or explicitly start them.
Stash {
/// The id(s) of the tasks you want to stash.
#[structopt(required = true)]
#[clap(required = true)]
task_ids: Vec<usize>,
},
/// Enqueue stashed tasks. They'll be handled normally afterwards.
#[structopt(after_help = "DELAY FORMAT:
#[clap(after_help = "DELAY FORMAT:
The --delay argument must be either a number of seconds or a \"date expression\" similar to GNU \
`date -d` with some extensions. It does not attempt to parse all natural language, but is \
@ -87,31 +86,31 @@ pub enum SubCommand {
task_ids: Vec<usize>,
/// Delay enqueuing the tasks until <delay> elapses. See DELAY FORMAT below.
#[structopt(name = "delay", short, long, parse(try_from_str=parse_delay_until))]
#[clap(name = "delay", short, long, parse(try_from_str=parse_delay_until))]
delay_until: Option<DateTime<Local>>,
},
/// Resume operation of specific tasks or groups of tasks.
/// By default, this resumes the default queue and all its tasks.
/// Can also be used force-start specific tasks.
#[structopt(verbatim_doc_comment)]
#[clap(verbatim_doc_comment)]
Start {
/// Enforce starting these tasks. Paused tasks will be started again.
/// This does not affect anything other than these tasks.
task_ids: Vec<usize>,
/// Start a specific group and all paused tasks in it.
#[structopt(short, long, group("start"))]
#[clap(short, long, group("start"))]
group: Option<String>,
/// Start a everything (Default queue and all groups)!
/// All groups will be set to `running` and all paused tasks will be resumed.
#[structopt(short, long, group("start"))]
#[clap(short, long, group("start"))]
all: bool,
/// Also resume direct child processes of your paused tasks.
/// By default only the main process will get a SIGSTART.
#[structopt(short, long, group("start"))]
#[clap(short, long, group("start"))]
children: bool,
},
@ -119,54 +118,54 @@ pub enum SubCommand {
/// Identical tasks will be created and by default enqueued.
Restart {
/// The tasks you want to restart.
#[structopt(required = true)]
#[clap(required = true)]
task_ids: Vec<usize>,
/// Immediately start the task(s).
#[structopt(name = "immediate", short, long)]
#[clap(name = "immediate", short, long)]
start_immediately: bool,
/// Create the task in stashed state.
/// Useful to avoid immediate execution.
#[structopt(short, long, conflicts_with = "immediate")]
#[clap(short, long, conflicts_with = "immediate")]
stashed: bool,
/// Edit the command of the task before restarting
#[structopt(short, long)]
#[clap(short, long)]
edit: bool,
/// Edit the path of the task before restarting
#[structopt(short, long)]
#[clap(short, long)]
path: bool,
},
/// Pause either running tasks or specific groups of tasks.
/// By default, pauses the default queue and all its tasks.
/// A paused queue (group) won't start any new tasks.
#[structopt(verbatim_doc_comment)]
#[clap(verbatim_doc_comment)]
Pause {
/// Pause these specific tasks.
/// Does not affect the default queue, groups or any other tasks.
task_ids: Vec<usize>,
/// Pause a specific group.
#[structopt(short, long, group("pause"))]
#[clap(short, long, group("pause"))]
group: Option<String>,
/// Pause everything (Default queue and all groups)!
#[structopt(short, long, group("pause"))]
#[clap(short, long, group("pause"))]
all: bool,
/// Don not pause already running tasks and let them finish by themselves,
/// when pausing with `default`, `all` or `group`.
#[structopt(short, long, group("pause"))]
#[clap(short, long, group("pause"))]
wait: bool,
/// Also pause direct child processes of a task's main process.
/// By default only the main process will get a SIGSTOP.
/// This is useful when calling bash scripts, which start other processes themselves.
/// This operation is not recursive!
#[structopt(short, long, group("pause"))]
#[clap(short, long, group("pause"))]
children: bool,
},
@ -176,20 +175,20 @@ pub enum SubCommand {
task_ids: Vec<usize>,
/// Kill all running tasks in the default queue. Pause the default queue.
#[structopt(short, long, group("kill"))]
#[clap(short, long, group("kill"))]
default: bool,
/// Kill all running in a group. Pauses the group.
#[structopt(short, long, group("kill"))]
#[clap(short, long, group("kill"))]
group: Option<String>,
/// Kill ALL running tasks. This also pauses everything
#[structopt(short, long, group("kill"))]
#[clap(short, long, group("kill"))]
all: bool,
/// Send the SIGTERM signal to all children as well.
/// Useful when working with shell scripts.
#[structopt(short, long, group("kill"))]
#[clap(short, long, group("kill"))]
children: bool,
},
@ -204,13 +203,13 @@ pub enum SubCommand {
/// Edit the command or path of a stashed or queued task.
/// This edits the command of the task by default.
#[structopt(verbatim_doc_comment)]
#[clap(verbatim_doc_comment)]
Edit {
/// The id of the task.
task_id: usize,
/// Edit the path of the task.
#[structopt(short, long)]
#[clap(short, long)]
path: bool,
},
@ -218,12 +217,12 @@ pub enum SubCommand {
/// By default, this will simply display all known groups.
Group {
/// Add a group
#[structopt(short, long)]
#[clap(short, long)]
add: Option<String>,
/// Remove a group.
/// This will move all tasks in this group to the default group!
#[structopt(short, long)]
#[clap(short, long)]
remove: Option<String>,
},
@ -232,10 +231,10 @@ pub enum SubCommand {
/// Print the current state as json to stdout.
/// This does not include stdout/stderr of tasks.
/// Use `log -j` if you want everything.
#[structopt(short, long)]
#[clap(short, long)]
json: bool,
#[structopt(short, long)]
#[clap(short, long)]
/// Only show tasks of a specific group
group: Option<String>,
},
@ -247,7 +246,7 @@ pub enum SubCommand {
task_ids: Vec<usize>,
/// Print the current state as json.
/// Includes EVERYTHING.
#[structopt(short, long)]
#[clap(short, long)]
json: bool,
},
@ -260,7 +259,7 @@ pub enum SubCommand {
task_id: Option<usize>,
/// Show stderr instead of stdout.
#[structopt(short, long)]
#[clap(short, long)]
err: bool,
},
@ -271,7 +270,7 @@ pub enum SubCommand {
Reset {
/// Send the SIGTERM signal to all children as well.
/// Useful when working with shell scripts.
#[structopt(short, long)]
#[clap(short, long)]
children: bool,
},
@ -281,11 +280,11 @@ pub enum SubCommand {
/// Set the amount of allowed parallel tasks.
Parallel {
/// The amount of allowed parallel tasks.
#[structopt(validator=min_one)]
#[clap(validator=min_one)]
parallel_tasks: usize,
/// Specify the amount of parallel tasks for a group.
#[structopt(name = "group", short, long)]
#[clap(name = "group", short, long)]
group: Option<String>,
},
@ -293,40 +292,50 @@ pub enum SubCommand {
/// This can be ignored during normal operations.
Completions {
/// The target shell. Can be `bash`, `fish`, `powershell`, `elvish` and `zsh`.
#[clap(arg_enum)]
shell: Shell,
/// The output directory to which the file should be written.
output_directory: PathBuf,
},
}
#[derive(StructOpt, Debug)]
#[structopt(
#[derive(Clap, Debug, PartialEq)]
pub enum Shell {
Bash,
Elvish,
Fish,
PowerShell,
Zsh,
}
#[derive(Clap, Debug)]
#[clap(
name = "Pueue client",
about = "Interact with the Pueue daemon",
author = "Arne Beer <contact@arne.beer>"
)]
pub struct Opt {
/// Verbose mode (-v, -vv, -vvv)
#[structopt(short, long, parse(from_occurrences))]
#[clap(short, long, parse(from_occurrences))]
pub verbose: u8,
/// The port for the daemon. Overwrites the port in the config file.
/// Will force TCP mode.
#[structopt(short, long)]
#[clap(short, long)]
pub port: Option<String>,
/// The path to the unix socket.
/// Overwrites the path in the config file.
/// Will force Unix-socket mode.
#[structopt(short, long, conflicts_with = "port")]
#[clap(short, long, conflicts_with = "port")]
pub unix_socket_path: Option<String>,
/// Path to a specific pueue config daemon, that should be used.
/// This ignores all other config files.
#[structopt(short, long)]
#[clap(short, long)]
pub config: Option<PathBuf>,
#[structopt(subcommand)]
#[clap(subcommand)]
pub cmd: SubCommand,
}
@ -346,7 +355,7 @@ fn parse_delay_until(src: &str) -> Result<DateTime<Local>, String> {
}
/// Validator function. The input string has to be parsable as int and bigger than 0
fn min_one(value: String) -> Result<(), String> {
fn min_one(value: &str) -> Result<(), String> {
match value.parse::<usize>() {
Ok(value) => {
if value < 1 {

View file

@ -1,6 +1,8 @@
use anyhow::Result;
use clap::{Clap, IntoApp};
use clap_generate::generate_to;
use clap_generate::generators::*;
use simplelog::{Config, LevelFilter, SimpleLogger};
use structopt::StructOpt;
use pueue::settings::Settings;
@ -10,23 +12,31 @@ pub mod commands;
pub mod output;
pub mod output_helper;
use crate::cli::{Opt, SubCommand};
use crate::cli::{Opt, Shell, SubCommand};
use crate::client::Client;
#[async_std::main]
async fn main() -> Result<()> {
// Parse commandline options.
let opt = Opt::from_args();
let opt = Opt::parse();
if let SubCommand::Completions {
shell,
output_directory,
} = &opt.cmd
{
let mut clap = Opt::clap();
clap.gen_completions("pueue", *shell, output_directory);
return Ok(());
}
//if let SubCommand::Completions {
// shell,
// output_directory,
//} = &opt.cmd
//{
// let app = Opt::clap();
// match shell {
// Shell::Bash => generate_to::<Bash, _, _>(&mut app, "pueue", output_directory),
// Shell::Elvish => generate_to::<Elvish, _, _>(&mut app, "pueue", output_directory),
// Shell::Fish => generate_to::<Fish, _, _>(&mut app, "pueue", output_directory),
// Shell::PowerShell => {
// generate_to::<PowerShell, _, _>(&mut app, "pueue", output_directory)
// }
// Shell::Zsh => generate_to::<Zsh, _, _>(&mut app, "pueue", output_directory),
// };
// return Ok(());
//}
// Set the verbosity level of the logger.
let level = match opt.verbose {

View file

@ -1,30 +1,30 @@
use std::path::PathBuf;
use structopt::StructOpt;
use clap::Clap;
#[derive(StructOpt, Debug)]
#[structopt(
#[derive(Clap, Debug)]
#[clap(
name = "Pueue daemon",
about = "Start the daemon for pueue",
author = "Arne Beer <contact@arne.beer>"
)]
pub struct Opt {
/// Verbose mode (-v, -vv, -vvv)
#[structopt(short, long, parse(from_occurrences))]
#[clap(short, long, parse(from_occurrences))]
pub verbose: u8,
/// If this flag is set, the daemon will start and fork itself into the background.
/// Closing the terminal won't kill the daemon any longer.
/// This should be avoided and rather be properly done using a service manager.
#[structopt(short, long)]
#[clap(short, long)]
pub daemonize: bool,
/// The port the daemon listens on. Overwrites the port in the config file.
#[structopt(short, long)]
#[clap(short, long)]
pub port: Option<String>,
/// Path to a specific pueue config daemon, that should be used.
/// This ignores all other config files.
#[structopt(short, long)]
#[clap(short, long)]
pub config: Option<PathBuf>,
}

View file

@ -5,8 +5,8 @@ use std::sync::mpsc::channel;
use std::sync::{Arc, Mutex};
use anyhow::Result;
use clap::Clap;
use simplelog::{Config, LevelFilter, SimpleLogger};
use structopt::StructOpt;
use pueue::message::Message;
use pueue::settings::Settings;
@ -28,7 +28,7 @@ mod task_handler;
#[async_std::main]
async fn main() -> Result<()> {
// Parse commandline options.
let opt = Opt::from_args();
let opt = Opt::parse();
if opt.daemonize {
fork_daemon(&opt)?;