From 721bfcf88ffd79a552c414755747480c48fb04f8 Mon Sep 17 00:00:00 2001 From: Thomas Knickman Date: Tue, 16 May 2023 18:45:55 -0400 Subject: [PATCH] feat(cli): rework generator api (#4984) --- crates/turborepo-lib/src/cli.rs | 78 +++++++++++++------ crates/turborepo-lib/src/commands/generate.rs | 34 ++++---- 2 files changed, 74 insertions(+), 38 deletions(-) diff --git a/crates/turborepo-lib/src/cli.rs b/crates/turborepo-lib/src/cli.rs index 48b01f95ce7e4..60e36eaae30a3 100644 --- a/crates/turborepo-lib/src/cli.rs +++ b/crates/turborepo-lib/src/cli.rs @@ -265,12 +265,27 @@ pub enum Command { target: LinkTarget, }, /// Generate a new app / package + #[clap(aliases = ["g", "gen"])] Generate { + #[serde(skip)] #[clap(long, default_value_t = String::from("latest"), hide = true)] tag: String, + /// The name of the generator to run + generator_name: Option, + /// Generator configuration file + #[clap(short = 'c', long)] + config: Option, + /// The root of your repository (default: directory with root + /// turbo.json) + #[clap(short = 'r', long)] + root: Option, + /// Answers passed directly to generator + #[clap(short = 'a', long, value_delimiter = ' ', num_args = 1..)] + args: Vec, + #[clap(subcommand)] - #[serde(flatten)] - command: GenerateCommand, + #[serde(skip)] + command: Option, }, /// Login to your Vercel account Login { @@ -309,22 +324,7 @@ pub enum Command { } #[derive(Parser, Clone, Debug, Default, Serialize, PartialEq)] -pub struct GenerateCustomArgs { - /// The name of the generator to run - pub generator_name: Option, - /// Generator configuration file - #[clap(short = 'c', long)] - pub config: Option, - /// The root of your repository (default: directory with root turbo.json) - #[clap(short = 'r', long)] - pub root: Option, - /// Answers passed directly to generator - #[clap(short = 'a', long, value_delimiter = ' ', num_args = 1..)] - pub args: Vec, -} - -#[derive(Parser, Clone, Debug, Default, Serialize, PartialEq)] -pub struct GenerateAddArgs { +pub struct GenerateWorkspaceArgs { /// Name for the new workspace #[clap(short = 'n', long)] pub name: Option, @@ -358,14 +358,29 @@ pub struct GenerateAddArgs { pub show_all_dependencies: bool, } +#[derive(Parser, Clone, Debug, Default, Serialize, PartialEq)] +pub struct GeneratorCustomArgs { + /// The name of the generator to run + generator_name: Option, + /// Generator configuration file + #[clap(short = 'c', long)] + config: Option, + /// The root of your repository (default: directory with root + /// turbo.json) + #[clap(short = 'r', long)] + root: Option, + /// Answers passed directly to generator + #[clap(short = 'a', long, value_delimiter = ' ', num_args = 1..)] + args: Vec, +} + #[derive(Subcommand, Clone, Debug, Serialize, PartialEq)] pub enum GenerateCommand { /// Add a new package or app to your project - #[clap(name = "add", alias = "a")] - Add(GenerateAddArgs), - /// Run custom generators + #[clap(name = "workspace", alias = "w")] + Workspace(GenerateWorkspaceArgs), #[clap(name = "run", alias = "r")] - Custom(GenerateCustomArgs), + Run(GeneratorCustomArgs), } #[derive(Parser, Clone, Debug, Default, Serialize, PartialEq)] @@ -635,8 +650,23 @@ pub async fn run( Ok(Payload::Rust(Ok(0))) } - Command::Generate { command, tag } => { - generate::run(command, tag)?; + Command::Generate { + tag, + generator_name, + config, + root, + args, + command, + } => { + // build GeneratorCustomArgs struct + let args = GeneratorCustomArgs { + generator_name: generator_name.clone(), + config: config.clone(), + root: root.clone(), + args: args.clone(), + }; + + generate::run(tag, command, &args)?; Ok(Payload::Rust(Ok(0))) } Command::Daemon { command, idle_time } => { diff --git a/crates/turborepo-lib/src/commands/generate.rs b/crates/turborepo-lib/src/commands/generate.rs index 88d4313ce4606..b4ab15f45fb46 100644 --- a/crates/turborepo-lib/src/commands/generate.rs +++ b/crates/turborepo-lib/src/commands/generate.rs @@ -2,7 +2,10 @@ use std::process::{Command, Stdio}; use anyhow::Result; -use crate::{child::spawn_child, cli::GenerateCommand}; +use crate::{ + child::spawn_child, + cli::{GenerateCommand, GeneratorCustomArgs}, +}; fn verify_requirements() -> Result<()> { let output = Command::new("npx") @@ -34,25 +37,28 @@ fn call_turbo_gen(command: &str, tag: &String, raw_args: &str) -> Result { Ok(exit_code) } -pub fn run(command: &GenerateCommand, tag: &String) -> Result<()> { +pub fn run( + tag: &String, + command: &Option, + args: &GeneratorCustomArgs, +) -> Result<()> { // ensure npx is available verify_requirements()?; match command { - GenerateCommand::Add(args) => { - let mut add_args = args.clone(); - // example implies copy - if add_args.example.is_some() { - add_args.copy = true; - add_args.empty = false; + // check if a subcommand was passed + Some(command) => { + if let GenerateCommand::Workspace(workspace_args) = command { + let raw_args = serde_json::to_string(&workspace_args)?; + call_turbo_gen("add", tag, &raw_args)?; + } else { + let raw_args = serde_json::to_string(&args)?; + call_turbo_gen("generate", tag, &raw_args)?; } - - // convert args to json - let raw_args = serde_json::to_string(&add_args)?; - call_turbo_gen("add", tag, &raw_args)?; } - GenerateCommand::Custom(args) => { - let raw_args = serde_json::to_string(args)?; + // if no subcommand was passed, run the generate command as default + None => { + let raw_args = serde_json::to_string(&args)?; call_turbo_gen("generate", tag, &raw_args)?; } };