use anyhow::Result;
use clap::{Args, Parser, Subcommand};
use inquire::validator::Validation;
use inquire::{required, Select, Text};
use manatsu::dev::scaffold::{component, composable};
use manatsu::dev::{self, package};
use manatsu::project::{self, Project, Template};
#[derive(Debug, Parser)]
#[command(name = "manatsu")]
#[command(version, about, long_about = None)]
struct ManatsuCli {
#[command(subcommand)]
command: Command,
}
#[derive(Debug, Subcommand)]
enum Command {
Create(CreateCommand),
#[command(subcommand)]
Dev(DevCommand),
}
trait ManatsuCommand {
fn execute(&self) -> Result<()>;
}
#[derive(Debug, Args)]
struct CreateCommand {
#[arg(short = 'f', long)]
force: bool,
}
impl ManatsuCommand for CreateCommand {
fn execute(&self) -> Result<()> {
let validator = |name: &str| {
if project::is_valid(name)? {
Ok(Validation::Valid)
} else {
Ok(Validation::Invalid("Invalid component name".into()))
}
};
let project_name = Text::new("Project name")
.with_validator(required!("Project name is required"))
.with_validator(validator)
.prompt()?;
let description = Text::new("Description").prompt_skippable()?;
let options = vec![Template::Tauri, Template::Vue];
let template = Select::new("Select a template", options).prompt()?;
let project = Project {
name: project_name,
description,
force: self.force,
template,
};
project.create()
}
}
#[derive(Debug, Subcommand)]
enum DevCommand {
Build {
packages: Option<Vec<String>>,
},
Component,
Composable,
Readme,
Release,
}
impl ManatsuCommand for DevCommand {
fn execute(&self) -> Result<()> {
match self {
DevCommand::Build { packages } => {
let packages = packages.as_deref();
match packages {
Some(p) if !p.is_empty() => dev::build(p),
_ => dev::build(package::PUBLIC_PACKAGES),
}
}
DevCommand::Component => {
let validator = |name: &str| {
if component::is_valid(name)? {
Ok(Validation::Valid)
} else {
Ok(Validation::Invalid("Invalid component name".into()))
}
};
let name = Text::new("Component name")
.with_validator(required!("Component name is required"))
.with_validator(validator)
.prompt()?;
component::create(name)
}
DevCommand::Composable => {
let validator = |name: &str| {
if composable::is_valid(name)? {
Ok(Validation::Valid)
} else {
Ok(Validation::Invalid("Invalid composable name".into()))
}
};
let name = Text::new("Composable name")
.with_validator(required!("Composable name is required"))
.with_validator(validator)
.prompt()?;
composable::create(name)
}
DevCommand::Readme => dev::readme(),
DevCommand::Release => dev::release(),
}
}
}
fn main() -> Result<()> {
let cli = ManatsuCli::parse();
match cli.command {
Command::Create(cmd) => cmd.execute(),
Command::Dev(cmd) => cmd.execute(),
}
}