mirror of
https://github.com/rust-lang/rustlings.git
synced 2026-01-09 20:29:18 +00:00
Replace argh with bpaf
This commit is contained in:
parent
464cb5566d
commit
50f36066e6
159
Cargo.lock
generated
159
Cargo.lock
generated
@ -11,34 +11,6 @@ dependencies = [
|
||||
"memchr",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "argh"
|
||||
version = "0.1.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ab257697eb9496bf75526f0217b5ed64636a9cfafa78b8365c71bd283fcef93e"
|
||||
dependencies = [
|
||||
"argh_derive",
|
||||
"argh_shared",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "argh_derive"
|
||||
version = "0.1.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b382dbd3288e053331f03399e1db106c9fb0d8562ad62cb04859ae926f324fa6"
|
||||
dependencies = [
|
||||
"argh_shared",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 1.0.109",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "argh_shared"
|
||||
version = "0.1.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "64cb94155d965e3d37ffbbe7cc5b82c3dd79dd33bd48e536f73d2cfb8d85506f"
|
||||
|
||||
[[package]]
|
||||
name = "assert_cmd"
|
||||
version = "0.11.1"
|
||||
@ -63,6 +35,43 @@ version = "1.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
|
||||
|
||||
[[package]]
|
||||
name = "bitflags"
|
||||
version = "2.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b4682ae6287fcf752ecaabbfcc7b6f9b72aa33933dc23a554d853aea8eea8635"
|
||||
|
||||
[[package]]
|
||||
name = "bpaf"
|
||||
version = "0.9.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1dc3b1bd654a8d16eea03586c3eee8ffd25c7f242b9eae9730cc442834fe56d9"
|
||||
dependencies = [
|
||||
"bpaf_derive",
|
||||
"owo-colors",
|
||||
"supports-color",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bpaf_derive"
|
||||
version = "0.5.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "22cbaba260bbcbb69b0d54e9f0d83038a4568f3a5d1c95591fed5e8fee964539"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cc"
|
||||
version = "1.0.83"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
version = "0.1.10"
|
||||
@ -100,6 +109,27 @@ version = "0.3.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f"
|
||||
|
||||
[[package]]
|
||||
name = "errno"
|
||||
version = "0.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6b30f669a7961ef1631673d2766cc92f52d64f7ef354d4fe0ddfd30ed52f0f4f"
|
||||
dependencies = [
|
||||
"errno-dragonfly",
|
||||
"libc",
|
||||
"windows-sys 0.48.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "errno-dragonfly"
|
||||
version = "0.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "aa68f1b12764fab894d2755d2518754e71b4fd80ecfb822714a1206c2aab39bf"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "escargot"
|
||||
version = "0.4.0"
|
||||
@ -139,7 +169,7 @@ version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5ab7d1bd1bd33cc98b0889831b72da23c0aa4df9cec7e0702f46ecea04b35db6"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"bitflags 1.3.2",
|
||||
"fsevent-sys",
|
||||
]
|
||||
|
||||
@ -158,7 +188,7 @@ version = "0.3.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2e9763c69ebaae630ba35f74888db465e49e259ba1bc0eda7d06f4a067615d82"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"bitflags 1.3.2",
|
||||
"fuchsia-zircon-sys",
|
||||
]
|
||||
|
||||
@ -174,6 +204,12 @@ version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b"
|
||||
|
||||
[[package]]
|
||||
name = "hermit-abi"
|
||||
version = "0.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "443144c8cdadd93ebf52ddb4056d257f5b52c04d3c804e657d19eb73fc33668b"
|
||||
|
||||
[[package]]
|
||||
name = "home"
|
||||
version = "0.5.5"
|
||||
@ -201,7 +237,7 @@ version = "0.7.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4816c66d2c8ae673df83366c18341538f234a26d65a9ecea5c348b453ac1d02f"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"bitflags 1.3.2",
|
||||
"inotify-sys",
|
||||
"libc",
|
||||
]
|
||||
@ -224,6 +260,23 @@ dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "is-terminal"
|
||||
version = "0.4.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cb0889898416213fab133e1d33a0e5858a48177452750691bde3666d0fdbaf8b"
|
||||
dependencies = [
|
||||
"hermit-abi",
|
||||
"rustix",
|
||||
"windows-sys 0.48.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "is_ci"
|
||||
version = "1.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "616cde7c720bb2bb5824a224687d8f77bfd38922027f01d825cd7453be5099fb"
|
||||
|
||||
[[package]]
|
||||
name = "itoa"
|
||||
version = "1.0.8"
|
||||
@ -258,6 +311,12 @@ version = "0.2.147"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b4668fb0ea861c1df094127ac5f1da3409a82116a4ba74fca2e58ef927159bb3"
|
||||
|
||||
[[package]]
|
||||
name = "linux-raw-sys"
|
||||
version = "0.4.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "57bcfdad1b858c2db7c38303a6d2ad4dfaf5eb53dfeb0910128b2c26d6158503"
|
||||
|
||||
[[package]]
|
||||
name = "log"
|
||||
version = "0.4.19"
|
||||
@ -336,7 +395,7 @@ version = "4.0.17"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ae03c8c853dba7bfd23e571ff0cff7bc9dceb40a4cd684cd1681824183f45257"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"bitflags 1.3.2",
|
||||
"filetime",
|
||||
"fsevent",
|
||||
"fsevent-sys",
|
||||
@ -363,6 +422,12 @@ version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "830b246a0e5f20af87141b25c173cd1b609bd7779a4617d6ec582abaf90870f3"
|
||||
|
||||
[[package]]
|
||||
name = "owo-colors"
|
||||
version = "3.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c1b04fb49957986fdce4d6ee7a65027d55d4b6d2265e5848bbb507b58ccfdb6f"
|
||||
|
||||
[[package]]
|
||||
name = "predicates"
|
||||
version = "1.0.8"
|
||||
@ -416,7 +481,7 @@ version = "0.2.16"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"bitflags 1.3.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -448,12 +513,25 @@ version = "0.7.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e5ea92a5b6195c6ef2a0295ea818b312502c6fc94dde986c5553242e18fd4ce2"
|
||||
|
||||
[[package]]
|
||||
name = "rustix"
|
||||
version = "0.38.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "19ed4fa021d81c8392ce04db050a3da9a60299050b7ae1cf482d862b54a7218f"
|
||||
dependencies = [
|
||||
"bitflags 2.4.0",
|
||||
"errno",
|
||||
"libc",
|
||||
"linux-raw-sys",
|
||||
"windows-sys 0.48.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustlings"
|
||||
version = "5.5.1"
|
||||
dependencies = [
|
||||
"argh",
|
||||
"assert_cmd",
|
||||
"bpaf",
|
||||
"console",
|
||||
"glob",
|
||||
"home",
|
||||
@ -498,7 +576,7 @@ checksum = "389894603bd18c46fa56231694f8d827779c0951a667087194cf9de94ed24682"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.25",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -522,14 +600,13 @@ dependencies = [
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "1.0.109"
|
||||
name = "supports-color"
|
||||
version = "2.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237"
|
||||
checksum = "4950e7174bffabe99455511c39707310e7e9b440364a2fcb1cc21521be57b354"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"unicode-ident",
|
||||
"is-terminal",
|
||||
"is_ci",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
||||
@ -9,7 +9,6 @@ authors = [
|
||||
edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
argh = "0.1"
|
||||
indicatif = "0.16"
|
||||
console = "0.15"
|
||||
notify = "4.0"
|
||||
@ -19,6 +18,7 @@ serde = { version = "1.0", features = ["derive"] }
|
||||
serde_json = "1.0.81"
|
||||
home = "0.5.3"
|
||||
glob = "0.3.0"
|
||||
bpaf = { version = "0.9.5", features = ["derive", "bright-color"] }
|
||||
|
||||
[[bin]]
|
||||
name = "rustlings"
|
||||
|
||||
189
src/main.rs
189
src/main.rs
@ -2,7 +2,7 @@ use crate::exercise::{Exercise, ExerciseList};
|
||||
use crate::project::RustAnalyzerProject;
|
||||
use crate::run::{reset, run};
|
||||
use crate::verify::verify;
|
||||
use argh::FromArgs;
|
||||
use bpaf::Bpaf;
|
||||
use console::Emoji;
|
||||
use notify::DebouncedEvent;
|
||||
use notify::{RecommendedWatcher, RecursiveMode, Watcher};
|
||||
@ -25,111 +25,77 @@ mod project;
|
||||
mod run;
|
||||
mod verify;
|
||||
|
||||
// In sync with crate version
|
||||
const VERSION: &str = "5.5.1";
|
||||
|
||||
#[derive(FromArgs, PartialEq, Debug)]
|
||||
/// Rustlings is a collection of small exercises to get you used to writing and reading Rust code
|
||||
#[derive(Bpaf)]
|
||||
#[bpaf(options, version)]
|
||||
struct Args {
|
||||
/// show outputs from the test exercises
|
||||
#[argh(switch)]
|
||||
/// Show outputs from the test exercises
|
||||
nocapture: bool,
|
||||
/// show the executable version
|
||||
#[argh(switch, short = 'v')]
|
||||
version: bool,
|
||||
#[argh(subcommand)]
|
||||
nested: Option<Subcommands>,
|
||||
#[bpaf(external, optional)]
|
||||
subcommand: Option<Subcommand>,
|
||||
}
|
||||
|
||||
#[derive(FromArgs, PartialEq, Debug)]
|
||||
#[argh(subcommand)]
|
||||
enum Subcommands {
|
||||
Verify(VerifyArgs),
|
||||
Watch(WatchArgs),
|
||||
Run(RunArgs),
|
||||
Reset(ResetArgs),
|
||||
Hint(HintArgs),
|
||||
List(ListArgs),
|
||||
Lsp(LspArgs),
|
||||
}
|
||||
|
||||
#[derive(FromArgs, PartialEq, Debug)]
|
||||
#[argh(subcommand, name = "verify")]
|
||||
/// Verifies all exercises according to the recommended order
|
||||
struct VerifyArgs {}
|
||||
|
||||
#[derive(FromArgs, PartialEq, Debug)]
|
||||
#[argh(subcommand, name = "watch")]
|
||||
/// Reruns `verify` when files were edited
|
||||
struct WatchArgs {
|
||||
/// show hints on success
|
||||
#[argh(switch)]
|
||||
#[derive(Bpaf, Clone)]
|
||||
enum Subcommand {
|
||||
/// Verify all exercises according to the recommended order
|
||||
#[bpaf(command)]
|
||||
Verify,
|
||||
/// Rerun `verify` when files were edited
|
||||
#[bpaf(command)]
|
||||
Watch {
|
||||
/// Show hints on success
|
||||
success_hints: bool,
|
||||
}
|
||||
|
||||
#[derive(FromArgs, PartialEq, Debug)]
|
||||
#[argh(subcommand, name = "run")]
|
||||
/// Runs/Tests a single exercise
|
||||
struct RunArgs {
|
||||
#[argh(positional)]
|
||||
/// the name of the exercise
|
||||
},
|
||||
/// Run/Test a single exercise
|
||||
#[bpaf(command)]
|
||||
Run {
|
||||
/// The name of the exercise
|
||||
#[bpaf(positional("NAME"))]
|
||||
name: String,
|
||||
}
|
||||
|
||||
#[derive(FromArgs, PartialEq, Debug)]
|
||||
#[argh(subcommand, name = "reset")]
|
||||
/// Resets a single exercise using "git stash -- <filename>"
|
||||
struct ResetArgs {
|
||||
#[argh(positional)]
|
||||
/// the name of the exercise
|
||||
},
|
||||
/// Reset a single exercise using "git stash -- <filename>"
|
||||
#[bpaf(command)]
|
||||
Reset {
|
||||
/// The name of the exercise
|
||||
#[bpaf(positional("NAME"))]
|
||||
name: String,
|
||||
}
|
||||
|
||||
#[derive(FromArgs, PartialEq, Debug)]
|
||||
#[argh(subcommand, name = "hint")]
|
||||
/// Returns a hint for the given exercise
|
||||
struct HintArgs {
|
||||
#[argh(positional)]
|
||||
/// the name of the exercise
|
||||
},
|
||||
/// Return a hint for the given exercise
|
||||
#[bpaf(command)]
|
||||
Hint {
|
||||
/// The name of the exercise
|
||||
#[bpaf(positional("NAME"))]
|
||||
name: String,
|
||||
}
|
||||
|
||||
#[derive(FromArgs, PartialEq, Debug)]
|
||||
#[argh(subcommand, name = "lsp")]
|
||||
/// Enable rust-analyzer for exercises
|
||||
struct LspArgs {}
|
||||
|
||||
#[derive(FromArgs, PartialEq, Debug)]
|
||||
#[argh(subcommand, name = "list")]
|
||||
/// Lists the exercises available in Rustlings
|
||||
struct ListArgs {
|
||||
#[argh(switch, short = 'p')]
|
||||
/// show only the paths of the exercises
|
||||
},
|
||||
/// List the exercises available in Rustlings
|
||||
#[bpaf(command)]
|
||||
List {
|
||||
/// Show only the paths of the exercises
|
||||
#[bpaf(short, long)]
|
||||
paths: bool,
|
||||
#[argh(switch, short = 'n')]
|
||||
/// show only the names of the exercises
|
||||
/// Show only the names of the exercises
|
||||
#[bpaf(short, long)]
|
||||
names: bool,
|
||||
#[argh(option, short = 'f')]
|
||||
/// provide a string to match exercise names
|
||||
/// comma separated patterns are acceptable
|
||||
/// Provide a string to match exercise names.
|
||||
/// Comma separated patterns are accepted
|
||||
#[bpaf(short, long)]
|
||||
filter: Option<String>,
|
||||
#[argh(switch, short = 'u')]
|
||||
/// display only exercises not yet solved
|
||||
/// Display only exercises not yet solved
|
||||
#[bpaf(short, long)]
|
||||
unsolved: bool,
|
||||
#[argh(switch, short = 's')]
|
||||
/// display only exercises that have been solved
|
||||
/// Display only exercises that have been solved
|
||||
#[bpaf(short, long)]
|
||||
solved: bool,
|
||||
},
|
||||
/// Enable rust-analyzer for exercises
|
||||
#[bpaf(command)]
|
||||
Lsp,
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let args: Args = argh::from_env();
|
||||
let args = args().run();
|
||||
|
||||
if args.version {
|
||||
println!("v{VERSION}");
|
||||
std::process::exit(0);
|
||||
}
|
||||
|
||||
if args.nested.is_none() {
|
||||
if args.subcommand.is_none() {
|
||||
println!("\n{WELCOME}\n");
|
||||
}
|
||||
|
||||
@ -153,17 +119,24 @@ fn main() {
|
||||
let exercises = toml::from_str::<ExerciseList>(toml_str).unwrap().exercises;
|
||||
let verbose = args.nocapture;
|
||||
|
||||
let command = args.nested.unwrap_or_else(|| {
|
||||
let subcommand = args.subcommand.unwrap_or_else(|| {
|
||||
println!("{DEFAULT_OUT}\n");
|
||||
std::process::exit(0);
|
||||
});
|
||||
match command {
|
||||
Subcommands::List(subargs) => {
|
||||
if !subargs.paths && !subargs.names {
|
||||
|
||||
match subcommand {
|
||||
Subcommand::List {
|
||||
paths,
|
||||
names,
|
||||
filter,
|
||||
unsolved,
|
||||
solved,
|
||||
} => {
|
||||
if !paths && !names {
|
||||
println!("{:<17}\t{:<46}\t{:<7}", "Name", "Path", "Status");
|
||||
}
|
||||
let mut exercises_done: u16 = 0;
|
||||
let filters = subargs.filter.clone().unwrap_or_default().to_lowercase();
|
||||
let filters = filter.clone().unwrap_or_default().to_lowercase();
|
||||
exercises.iter().for_each(|e| {
|
||||
let fname = format!("{}", e.path.display());
|
||||
let filter_cond = filters
|
||||
@ -177,14 +150,14 @@ fn main() {
|
||||
"Pending"
|
||||
};
|
||||
let solve_cond = {
|
||||
(e.looks_done() && subargs.solved)
|
||||
|| (!e.looks_done() && subargs.unsolved)
|
||||
|| (!subargs.solved && !subargs.unsolved)
|
||||
(e.looks_done() && solved)
|
||||
|| (!e.looks_done() && unsolved)
|
||||
|| (!solved && !unsolved)
|
||||
};
|
||||
if solve_cond && (filter_cond || subargs.filter.is_none()) {
|
||||
let line = if subargs.paths {
|
||||
if solve_cond && (filter_cond || filter.is_none()) {
|
||||
let line = if paths {
|
||||
format!("{fname}\n")
|
||||
} else if subargs.names {
|
||||
} else if names {
|
||||
format!("{}\n", e.name)
|
||||
} else {
|
||||
format!("{:<17}\t{fname:<46}\t{status:<7}\n", e.name)
|
||||
@ -214,30 +187,30 @@ fn main() {
|
||||
std::process::exit(0);
|
||||
}
|
||||
|
||||
Subcommands::Run(subargs) => {
|
||||
let exercise = find_exercise(&subargs.name, &exercises);
|
||||
Subcommand::Run { name } => {
|
||||
let exercise = find_exercise(&name, &exercises);
|
||||
|
||||
run(exercise, verbose).unwrap_or_else(|_| std::process::exit(1));
|
||||
}
|
||||
|
||||
Subcommands::Reset(subargs) => {
|
||||
let exercise = find_exercise(&subargs.name, &exercises);
|
||||
Subcommand::Reset { name } => {
|
||||
let exercise = find_exercise(&name, &exercises);
|
||||
|
||||
reset(exercise).unwrap_or_else(|_| std::process::exit(1));
|
||||
}
|
||||
|
||||
Subcommands::Hint(subargs) => {
|
||||
let exercise = find_exercise(&subargs.name, &exercises);
|
||||
Subcommand::Hint { name } => {
|
||||
let exercise = find_exercise(&name, &exercises);
|
||||
|
||||
println!("{}", exercise.hint);
|
||||
}
|
||||
|
||||
Subcommands::Verify(_subargs) => {
|
||||
Subcommand::Verify => {
|
||||
verify(&exercises, (0, exercises.len()), verbose, false)
|
||||
.unwrap_or_else(|_| std::process::exit(1));
|
||||
}
|
||||
|
||||
Subcommands::Lsp(_subargs) => {
|
||||
Subcommand::Lsp => {
|
||||
let mut project = RustAnalyzerProject::new();
|
||||
project
|
||||
.get_sysroot_src()
|
||||
@ -256,7 +229,7 @@ fn main() {
|
||||
}
|
||||
}
|
||||
|
||||
Subcommands::Watch(_subargs) => match watch(&exercises, verbose, _subargs.success_hints) {
|
||||
Subcommand::Watch { success_hints } => match watch(&exercises, verbose, success_hints) {
|
||||
Err(e) => {
|
||||
println!(
|
||||
"Error: Could not watch your progress. Error message was {:?}.",
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user