Most of the refactor. Need to switch machines.

This commit is contained in:
Olivia Brooks
2026-02-15 09:36:04 -05:00
parent dda863e512
commit e41d4bcd76
61 changed files with 3390 additions and 618 deletions

15
crates/cli/Cargo.toml Normal file
View 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
View 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)
}
}