Most of the refactor. Need to switch machines.
This commit is contained in:
15
crates/cli/Cargo.toml
Normal file
15
crates/cli/Cargo.toml
Normal file
@@ -0,0 +1,15 @@
|
||||
[package]
|
||||
name = "cli"
|
||||
version = "0.1.0"
|
||||
edition.workspace = true
|
||||
license.workspace = true
|
||||
|
||||
description = "Raven's CLI"
|
||||
repository.workspace = true
|
||||
|
||||
publish.workspace = true
|
||||
test.workspace = true
|
||||
|
||||
[dependencies.clap]
|
||||
version = "4.5"
|
||||
features = ["cargo", "derive"]
|
||||
153
crates/cli/src/lib.rs
Normal file
153
crates/cli/src/lib.rs
Normal file
@@ -0,0 +1,153 @@
|
||||
use std::sync::LazyLock;
|
||||
use std::{fmt::Display, path::PathBuf};
|
||||
|
||||
use clap::{ArgAction, Args, Parser, Subcommand, ValueEnum};
|
||||
|
||||
pub static CLI_ARGS: LazyLock<CliArgs> = LazyLock::new(|| CliArgs::parse());
|
||||
|
||||
#[derive(Debug, Parser)]
|
||||
#[clap(author, version)]
|
||||
#[command(help_template = "{author-section}\n{usage-heading} {usage}\n\n{all-args}")]
|
||||
pub struct CliArgs {
|
||||
#[command(subcommand)]
|
||||
pub command: Command,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Subcommand)]
|
||||
pub enum Command {
|
||||
/// Create a new raven project
|
||||
New {
|
||||
#[clap(flatten)]
|
||||
type_: ProjectFlag,
|
||||
name: String,
|
||||
},
|
||||
/// Create a new raven project in an existing directory
|
||||
Init,
|
||||
/// Compile the current project
|
||||
Build,
|
||||
/// Run the current project
|
||||
Run {
|
||||
#[clap(value_hint = clap::ValueHint::DirPath)]
|
||||
entry_point: Option<PathBuf>,
|
||||
|
||||
#[clap(flatten)]
|
||||
assertions: Assertions,
|
||||
},
|
||||
/// !!! BORKED !!! Run the tests
|
||||
Test {
|
||||
#[clap(flatten)]
|
||||
assertions: Assertions,
|
||||
},
|
||||
/// Remove the target directory and caching
|
||||
Clean,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Args)]
|
||||
pub struct Assertions {
|
||||
/// Disable assertions.
|
||||
#[arg(short, long = "no-assert", action = ArgAction::SetFalse)]
|
||||
assertions: bool,
|
||||
}
|
||||
|
||||
impl Into<bool> for Assertions {
|
||||
fn into(self) -> bool {
|
||||
self.assertions
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, Args)]
|
||||
#[group(multiple = false)]
|
||||
pub struct ProjectFlag {
|
||||
#[arg(long, action = ArgAction::SetTrue)]
|
||||
_nest: (),
|
||||
#[arg(long, action = ArgAction::SetTrue)]
|
||||
_package: (),
|
||||
|
||||
#[arg(
|
||||
hide = true,
|
||||
required = false,
|
||||
short,
|
||||
long,
|
||||
default_value_ifs = [
|
||||
("_nest", "true", "nest"),
|
||||
("_package", "true", "package"),
|
||||
("_nest", "false", "nest"),
|
||||
],
|
||||
)]
|
||||
pub project_type: ProjectType,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, ValueEnum)]
|
||||
#[value(rename_all = "kebab-case")]
|
||||
pub enum ProjectType {
|
||||
#[default]
|
||||
Nest,
|
||||
Package,
|
||||
}
|
||||
|
||||
impl Display for ProjectType {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
write!(f, "{}", Self::to_string(&self))
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn args_new_w_arg() {
|
||||
let args: CliArgs = Parser::try_parse_from(["raven", "new", "demo"]).unwrap();
|
||||
let type_ = match args.command {
|
||||
Command::New { type_, .. } => type_,
|
||||
_ => unreachable!(),
|
||||
};
|
||||
|
||||
assert!(type_.project_type == ProjectType::Nest);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn args_new_nest() {
|
||||
let args: CliArgs = Parser::try_parse_from(["raven", "new", "--nest", "demo"]).unwrap();
|
||||
let type_ = match args.command {
|
||||
Command::New { type_, .. } => type_,
|
||||
_ => unreachable!(),
|
||||
};
|
||||
|
||||
assert!(type_.project_type == ProjectType::Nest);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn args_new_package() {
|
||||
let args: CliArgs = Parser::try_parse_from(["raven", "new", "--package", "demo"]).unwrap();
|
||||
let type_ = match args.command {
|
||||
Command::New { type_, .. } => type_,
|
||||
_ => unreachable!(),
|
||||
};
|
||||
|
||||
assert!(type_.project_type == ProjectType::Package);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn args_run_assert() {
|
||||
let args: CliArgs = Parser::try_parse_from(["raven", "run", "Main"]).unwrap();
|
||||
let assertions: bool = match args.command {
|
||||
Command::Run { assertions, .. } => assertions.assertions,
|
||||
_ => unreachable!(),
|
||||
};
|
||||
|
||||
assert!(assertions == true)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn args_run_no_assert() {
|
||||
let args: CliArgs =
|
||||
Parser::try_parse_from(["raven", "run", "--no-assert", "Main"]).unwrap();
|
||||
let assertions: bool = match args.command {
|
||||
Command::Run { assertions, .. } => assertions.assertions,
|
||||
_ => unreachable!(),
|
||||
};
|
||||
|
||||
assert!(assertions == false)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user