Skip to content

Commit

Permalink
feat(turbo): g
Browse files Browse the repository at this point in the history
update args

fix debug
  • Loading branch information
tknickman committed May 11, 2023
1 parent 1e5493f commit ecfb235
Show file tree
Hide file tree
Showing 3 changed files with 139 additions and 1 deletion.
79 changes: 78 additions & 1 deletion crates/turborepo-lib/src/cli.rs
Expand Up @@ -14,7 +14,7 @@ use tracing::{debug, error};
use turbopath::AbsoluteSystemPathBuf;

use crate::{
commands::{bin, daemon, link, login, logout, unlink, CommandBase},
commands::{bin, daemon, generate, link, login, logout, unlink, CommandBase},
get_version,
shim::{RepoMode, RepoState},
tracing::TurboSubscriber,
Expand Down Expand Up @@ -264,6 +264,14 @@ pub enum Command {
#[clap(long, value_enum, default_value_t = LinkTarget::RemoteCache)]
target: LinkTarget,
},
/// Generate a new app / package
G {
#[clap(long, default_value_t = String::from("latest"), hide = true)]
tag: String,
#[clap(subcommand)]
#[serde(flatten)]
command: GenerateCommand,
},
/// Login to your Vercel account
Login {
#[clap(long = "sso-team")]
Expand Down Expand Up @@ -300,6 +308,71 @@ pub enum Command {
},
}

#[derive(Parser, Clone, Debug, Default, Serialize, PartialEq)]
pub struct GenerateArgs {
/// The name of the generator to run
pub generator_name: Option<String>,
/// Generator configuration file
#[clap(short = 'c', long)]
pub config: Option<String>,
/// The root of your repository (default: directory with root turbo.json)
#[clap(short = 'r', long)]
pub root: Option<String>,
/// Answers passed directly to generator
#[clap(short = 'a', long, value_delimiter = ' ', num_args = 1..)]
pub args: Vec<String>,
}

#[derive(Parser, Clone, Debug, Default, Serialize, PartialEq)]
pub struct GenerateAddArgs {
/// Name for the new workspace
#[clap(short = 'n', long)]
pub name: Option<String>,
/// Generate an empty workspace
#[clap(
short = 'b',
long,
conflicts_with = "copy",
default_missing_value = "true"
)]
pub empty: bool,
/// Generate a workspace using an existing workspace as a template
#[clap(short = 'c', long, conflicts_with = "empty")]
pub copy: bool,
/// Where the new workspace should be created
#[clap(short = 'd', long)]
pub destination: Option<String>,
/// The type of workspace to create
#[clap(short = 'w', long)]
pub what: Option<String>,
/// The root of your repository (default: directory with root turbo.json)
#[clap(short = 'r', long)]
pub root: Option<String>,
/// An example package to add. You can use a GitHub URL with any branch
/// and/or subdirectory.
#[clap(short = 'e', long)]
pub example: Option<String>,
/// In a rare case, your GitHub URL might contain a branch name with a slash
/// (e.g. bug/fix-1) and the path to the example (e.g. foo/bar). In this
/// case, you must specify the path to the example separately:
/// --example-path foo/bar
#[clap(short = 'p', long)]
pub example_path: Option<String>,
/// Do not filter available dependencies by the workspace type
#[clap(long)]
pub show_all_dependencies: bool,
}

#[derive(Subcommand, Clone, Debug, Serialize, PartialEq)]
pub enum GenerateCommand {
/// Add a new package or app to your project
#[clap(name = "add", aliases = &["a"])]
Add(GenerateAddArgs),
/// Run custom generators
#[clap(name = "generate", aliases = &["g", "gen"])]
Gen(GenerateArgs),
}

#[derive(Parser, Clone, Debug, Default, Serialize, PartialEq)]
pub struct RunArgs {
/// Override the filesystem cache directory.
Expand Down Expand Up @@ -567,6 +640,10 @@ pub async fn run(

Ok(Payload::Rust(Ok(0)))
}
Command::G { command, tag } => {
generate::run(command, tag)?;
Ok(Payload::Rust(Ok(0)))
}
Command::Daemon { command, idle_time } => {
let base = CommandBase::new(cli_args.clone(), repo_root, version, ui)?;

Expand Down
60 changes: 60 additions & 0 deletions crates/turborepo-lib/src/commands/generate.rs
@@ -0,0 +1,60 @@
use std::process::{Command, Stdio};

use anyhow::Result;

use crate::{child::spawn_child, cli::GenerateCommand};

fn verify_requirements() -> Result<()> {
let output = Command::new("npx")
.arg("--version")
.stdout(Stdio::null())
.stderr(Stdio::null())
.status();

const ERROR_MSG: &str = "Unable to run generate - missing requirements (npx)";
match output {
Ok(result) => {
if result.success() {
return Ok(());
}
return Err(anyhow::anyhow!(ERROR_MSG));
}
Err(_) => {
return Err(anyhow::anyhow!(ERROR_MSG));
}
}
}

fn call_turbo_gen(command: &str, tag: &String, raw_args: &str) -> Result<i32> {
let mut npx = Command::new("npx");
npx.arg("--yes")
.arg(format!("@turbo/gen@{}", tag))
.arg("raw")
.arg(command)
.args(["--json", raw_args])
.stdout(Stdio::inherit())
.stderr(Stdio::inherit());

let child = spawn_child(npx)?;
let exit_code = child.wait()?.code().unwrap_or(2);
Ok(exit_code)
}

pub fn run(command: &GenerateCommand, tag: &String) -> Result<()> {
// ensure npx is available
verify_requirements()?;

match command {
GenerateCommand::Add(args) => {
// convert args to json
let raw_args = serde_json::to_string(args)?;
call_turbo_gen("add", tag, &raw_args)?;
}
GenerateCommand::Gen(args) => {
let raw_args = serde_json::to_string(args)?;
call_turbo_gen("generate", tag, &raw_args)?;
}
};

Ok(())
}
1 change: 1 addition & 0 deletions crates/turborepo-lib/src/commands/mod.rs
Expand Up @@ -15,6 +15,7 @@ use crate::{

pub(crate) mod bin;
pub(crate) mod daemon;
pub(crate) mod generate;
pub(crate) mod link;
pub(crate) mod login;
pub(crate) mod logout;
Expand Down

0 comments on commit ecfb235

Please sign in to comment.