-
Notifications
You must be signed in to change notification settings - Fork 216
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
switch cli parsing from clap to docopt
- Loading branch information
Showing
12 changed files
with
688 additions
and
449 deletions.
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
use docopt::{self, Docopt}; | ||
use notion_core::{global, die}; | ||
use notion_core::version::Version; | ||
use std::process::exit; | ||
|
||
pub const USAGE: &'static str = " | ||
Activate a particular toolchain version | ||
Usage: | ||
notion use [options] <version> | ||
notion use -h | --help | ||
Options: | ||
-h, --help Display this message | ||
-g, --global Activate the toolchain globally | ||
"; | ||
|
||
#[derive(Debug, Deserialize)] | ||
struct Args { | ||
arg_version: Option<String>, | ||
flag_global: bool | ||
} | ||
|
||
pub fn run(mut args: Vec<String>, _verbose: bool) -> Result<(), docopt::Error> { | ||
let mut argv = vec![String::from("notion"), String::from("use")]; | ||
argv.append(&mut args); | ||
|
||
let args: Args = Docopt::new(USAGE) | ||
.and_then(|d| d.argv(argv).deserialize())?; | ||
|
||
if args.flag_global { | ||
// FIXME: compute the default | ||
let version = args.arg_version.unwrap(); | ||
match global::set(Version::Public(version)) { | ||
Ok(_) => { } | ||
Err(err) => { die(err); } | ||
} | ||
} else { | ||
println!("not yet implemented; in the meantime you can modify your package.json."); | ||
exit(1); | ||
} | ||
|
||
Ok(()) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
use docopt::{self, Docopt}; | ||
use std::process::exit; | ||
use notion_core::{current, die}; | ||
|
||
pub const USAGE: &'static str = " | ||
Display the currently activated toolchain | ||
Usage: | ||
notion current [options] | ||
Options: | ||
-h, --help Display this message | ||
-l, --local Display local toolchain | ||
-g, --global Display global toolchain | ||
"; | ||
|
||
#[derive(Debug, Deserialize)] | ||
struct Args { | ||
flag_local: bool, | ||
flag_global: bool | ||
} | ||
|
||
pub fn run(mut args: Vec<String>) -> Result<(), docopt::Error> { | ||
let mut argv = vec![String::from("notion"), String::from("current")]; | ||
argv.append(&mut args); | ||
|
||
let args: Args = Docopt::new(USAGE) | ||
.and_then(|d| d.argv(argv).deserialize())?; | ||
|
||
if args.flag_local && !args.flag_global { | ||
match current::local() { | ||
Ok(Some(version)) => { println!("v{}", version); } | ||
Ok(None) => { exit(1); } | ||
Err(err) => { die(err); } | ||
} | ||
} else if args.flag_global && !args.flag_local { | ||
match current::global() { | ||
Ok(Some(version)) => { println!("v{}", version); } | ||
Ok(None) => { exit(1); } | ||
Err(err) => { die(err); } | ||
} | ||
} else { | ||
match current::both() { | ||
Ok((local, global)) => { | ||
let global_active = local.is_none() && global.is_some(); | ||
let none = local.is_none() && global.is_none(); | ||
// FIXME: abstract this | ||
for version in local { | ||
println!("local: v{} (active)", version); | ||
} | ||
for version in global { | ||
println!("global: v{}{}", version, if global_active { " (active)" } else { "" }); | ||
} | ||
if none { | ||
exit(1); | ||
} | ||
} | ||
Err(err) => { die(err); } | ||
} | ||
} | ||
|
||
Ok(()) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
use docopt::{self, Docopt}; | ||
use std::process::exit; | ||
use console::style; | ||
|
||
const USAGE: &'static str = " | ||
Get some help with a notion command | ||
Usage: | ||
notion help [<command>] | ||
notion help -h | --help | ||
Options: | ||
-h, --help Display this message | ||
"; | ||
|
||
#[derive(Debug, Deserialize)] | ||
struct Args { | ||
arg_command: Option<String> | ||
} | ||
|
||
pub fn run(mut args: Vec<String>) -> Result<(), docopt::Error> { | ||
let mut argv = vec![String::from("notion"), String::from("help")]; | ||
argv.append(&mut args); | ||
|
||
let args: Args = Docopt::new(USAGE) | ||
.and_then(|d| d.argv(argv).deserialize())?; | ||
|
||
let command = match args.arg_command { | ||
Some(command) => command, | ||
None => { | ||
super::throw_help(super::USAGE)?; | ||
panic!("can't happen") | ||
} | ||
}; | ||
|
||
match &command[..] { | ||
"use" => { | ||
super::throw_help(super::activate::USAGE)?; | ||
} | ||
"current" => { | ||
super::throw_help(super::current::USAGE)?; | ||
} | ||
"help" => { | ||
super::throw_help(USAGE)?; | ||
} | ||
"version" => { | ||
super::throw_help(super::version::USAGE)?; | ||
} | ||
"install" => { | ||
super::throw_help(super::install::USAGE)?; | ||
} | ||
"uninstall" => { | ||
super::throw_help(super::uninstall::USAGE)?; | ||
} | ||
_ => { | ||
eprintln!("{} Unknown subcommand: '{}'", style("error:").red().bold(), command); | ||
exit(1); | ||
} | ||
} | ||
|
||
Ok(()) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
use docopt::{self, Docopt}; | ||
use std::process::exit; | ||
use notion_core; | ||
|
||
pub const USAGE: &'static str = " | ||
Install a toolchain to the local machine | ||
Usage: | ||
notion install <version> | ||
notion install -h | --help | ||
Options: | ||
-h, --help Display this message | ||
"; | ||
|
||
#[derive(Debug, Deserialize)] | ||
struct Args { | ||
arg_version: String | ||
} | ||
|
||
pub fn run(mut args: Vec<String>, _verbose: bool) -> Result<(), docopt::Error> { | ||
let mut argv = vec![String::from("notion"), String::from("install")]; | ||
argv.append(&mut args); | ||
|
||
let args: Args = Docopt::new(USAGE) | ||
.and_then(|d| d.argv(argv).deserialize())?; | ||
|
||
if let Err(err) = notion_core::install::by_version(&args.arg_version) { | ||
notion_core::display_error(err); | ||
exit(1); | ||
} | ||
|
||
Ok(()) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,122 @@ | ||
pub mod install; | ||
pub mod uninstall; | ||
pub mod current; | ||
pub mod activate; | ||
pub mod help; | ||
pub mod version; | ||
|
||
use docopt::{self, Docopt}; | ||
use console::style; | ||
use std::process::exit; | ||
|
||
pub const VERSION: &'static str = env!("CARGO_PKG_VERSION"); | ||
|
||
pub const USAGE: &'static str = " | ||
Notion: the hassle-free Node.js manager | ||
Usage: | ||
notion [-v | --verbose] <command> [<args> ...] | ||
notion -h | --help | ||
notion -V | --version | ||
Options: | ||
-h, --help Display this message | ||
-V, --version Print version info and exit | ||
-v, --verbose Use verbose output | ||
Some common notion commands are: | ||
install Install a toolchain to the local machine | ||
uninstall Uninstall a toolchain from the local machine | ||
use Activate a particular toolchain version | ||
current Display the currently activated toolchain version | ||
help Display this message | ||
version Print version info and exit | ||
See 'notion help <command>' for more information on a specific command. | ||
"; | ||
|
||
#[derive(Debug, Deserialize)] | ||
struct Args { | ||
arg_command: Option<Command>, | ||
arg_args: Vec<String>, | ||
flag_version: bool, | ||
flag_verbose: bool | ||
} | ||
|
||
#[derive(Debug, Deserialize)] | ||
enum Command { | ||
Install, | ||
Uninstall, | ||
Use, | ||
Current, | ||
Help, | ||
Version | ||
} | ||
|
||
fn docopt_help_error(e: &docopt::Error) -> Option<&str> { | ||
match e { | ||
&docopt::Error::WithProgramUsage(ref err, ref usage) => { | ||
if let &docopt::Error::Help = &**err { | ||
Some(usage) | ||
} else { | ||
None | ||
} | ||
} | ||
&docopt::Error::Help => { | ||
Some(USAGE) | ||
} | ||
_ => None | ||
} | ||
} | ||
|
||
fn exit_with(e: docopt::Error) -> ! { | ||
// Docopt prints help messages to stdout but stderr is more traditional. | ||
if let Some(usage) = docopt_help_error(&e) { | ||
eprintln!("{}", usage); | ||
exit(0); | ||
} | ||
|
||
// Prefix fatal errors with a red, bold "error: " prefix. | ||
if e.fatal() { | ||
eprint!("{} ", style("error:").red().bold()); | ||
} | ||
|
||
// Now let docopt do the rest. | ||
e.exit() | ||
} | ||
|
||
pub fn throw_help(usage: &str) -> Result<(), docopt::Error> { | ||
Err(docopt::Error::WithProgramUsage(Box::new(docopt::Error::Help), String::from(usage.trim()))) | ||
} | ||
|
||
pub fn run() { | ||
Docopt::new(USAGE) | ||
.and_then(|d| d.options_first(true).version(Some(String::from(VERSION))).deserialize()) | ||
.and_then(|args: Args| { | ||
match args.arg_command { | ||
None => { | ||
throw_help(USAGE) | ||
} | ||
Some(Command::Install) => { | ||
install::run(args.arg_args, args.flag_verbose) | ||
} | ||
Some(Command::Uninstall) => { | ||
uninstall::run(args.arg_args, args.flag_verbose) | ||
} | ||
Some(Command::Use) => { | ||
activate::run(args.arg_args, args.flag_verbose) | ||
} | ||
Some(Command::Current) => { | ||
current::run(args.arg_args) | ||
} | ||
Some(Command::Help) => { | ||
help::run(args.arg_args) | ||
} | ||
Some(Command::Version) => { | ||
version::run(args.arg_args) | ||
} | ||
} | ||
}) | ||
.unwrap_or_else(|e| exit_with(e)); | ||
|
||
} |
Oops, something went wrong.