From 0dffdb215058bdab6617e342b0b17525ff6e4cf7 Mon Sep 17 00:00:00 2001 From: Tom Lienard Date: Sat, 25 Mar 2023 09:19:41 +0100 Subject: [PATCH] feat(cli): allow `lagon deploy` & `lagon build` to specify files (#688) --- .changeset/smart-hotels-camp.md | 6 +++++ crates/cli/src/commands/build.rs | 7 +++--- crates/cli/src/commands/deploy.rs | 7 +++--- crates/cli/src/commands/dev.rs | 37 +++-------------------------- crates/cli/src/main.rs | 20 ++++++++-------- crates/cli/src/utils/deployments.rs | 37 +++++++++++++++++++++++++++++ packages/docs/pages/cli.mdx | 6 +++-- 7 files changed, 66 insertions(+), 54 deletions(-) create mode 100644 .changeset/smart-hotels-camp.md diff --git a/.changeset/smart-hotels-camp.md b/.changeset/smart-hotels-camp.md new file mode 100644 index 000000000..60ab1c5a5 --- /dev/null +++ b/.changeset/smart-hotels-camp.md @@ -0,0 +1,6 @@ +--- +'@lagon/cli': patch +'@lagon/docs': patch +--- + +Allow `lagon deploy` & `lagon build` to specify files and folders diff --git a/crates/cli/src/commands/build.rs b/crates/cli/src/commands/build.rs index d8c0338f3..66cdddfe2 100644 --- a/crates/cli/src/commands/build.rs +++ b/crates/cli/src/commands/build.rs @@ -2,15 +2,14 @@ use std::{fs, path::PathBuf}; use anyhow::{anyhow, Result}; -use crate::utils::{bundle_function, debug, get_root, print_progress, success, FunctionConfig}; +use crate::utils::{bundle_function, debug, print_progress, resolve_path, success}; pub fn build( + path: Option, client: Option, public_dir: Option, - directory: Option, ) -> Result<()> { - let root = get_root(directory); - let function_config = FunctionConfig::load(&root, client, public_dir)?; + let (root, function_config) = resolve_path(path, client, public_dir)?; let (index, assets) = bundle_function(&function_config, &root)?; let end_progress = print_progress("Writting index.js..."); diff --git a/crates/cli/src/commands/deploy.rs b/crates/cli/src/commands/deploy.rs index a86360e35..916dc63ee 100644 --- a/crates/cli/src/commands/deploy.rs +++ b/crates/cli/src/commands/deploy.rs @@ -8,7 +8,7 @@ use dialoguer::{Confirm, Input, Select}; use serde::{Deserialize, Serialize}; use crate::utils::{ - create_deployment, debug, get_root, info, print_progress, Config, FunctionConfig, TrpcClient, + create_deployment, debug, info, print_progress, resolve_path, Config, TrpcClient, }; #[derive(Deserialize, Debug)] @@ -53,10 +53,10 @@ impl Display for Function { pub type FunctionsResponse = Vec; pub async fn deploy( + path: Option, client: Option, public_dir: Option, prod: bool, - directory: Option, ) -> Result<()> { let config = Config::new()?; @@ -66,8 +66,7 @@ pub async fn deploy( )); } - let root = get_root(directory); - let mut function_config = FunctionConfig::load(&root, client, public_dir)?; + let (root, mut function_config) = resolve_path(path, client, public_dir)?; if function_config.function_id.is_empty() { println!("{}", debug("No deployment config found...")); diff --git a/crates/cli/src/commands/dev.rs b/crates/cli/src/commands/dev.rs index d0c662d02..934bba247 100644 --- a/crates/cli/src/commands/dev.rs +++ b/crates/cli/src/commands/dev.rs @@ -1,4 +1,4 @@ -use anyhow::{anyhow, Error, Result}; +use anyhow::{Error, Result}; use chrono::offset::Local; use colored::Colorize; use envfile::EnvFile; @@ -16,7 +16,6 @@ use log::{ }; use notify::event::ModifyKind; use notify::{Config, EventKind, RecommendedWatcher, RecursiveMode, Watcher}; -use pathdiff::diff_paths; use std::collections::HashMap; use std::convert::Infallible; use std::path::{Path, PathBuf}; @@ -25,7 +24,7 @@ use std::time::Duration; use tokio::runtime::Handle; use tokio::sync::Mutex; -use crate::utils::{bundle_function, error, info, input, success, warn, Assets, FunctionConfig}; +use crate::utils::{bundle_function, error, info, input, resolve_path, success, warn, Assets}; const LOCAL_REGION: &str = "local"; @@ -178,37 +177,7 @@ pub async fn dev( env: Option, allow_code_generation: bool, ) -> Result<()> { - let path = path.unwrap_or_else(|| PathBuf::from(".")); - - if !path.exists() { - return Err(anyhow!("File or directory not found")); - } - - let (root, function_config) = match path.is_file() { - true => { - let root = PathBuf::from(path.parent().unwrap()); - - let index = diff_paths(&path, &root).unwrap(); - let client = client.map(|client| diff_paths(client, &root).unwrap()); - let assets = public_dir.map(|public_dir| diff_paths(public_dir, &root).unwrap()); - - ( - root, - FunctionConfig { - function_id: String::new(), - organization_id: String::new(), - index, - client, - assets, - }, - ) - } - false => ( - path.clone(), - FunctionConfig::load(&path, client, public_dir)?, - ), - }; - + let (root, function_config) = resolve_path(path, client, public_dir)?; let (index, assets) = bundle_function(&function_config, &root)?; let server_index = index.clone(); diff --git a/crates/cli/src/main.rs b/crates/cli/src/main.rs index f78194bfa..8da285433 100644 --- a/crates/cli/src/main.rs +++ b/crates/cli/src/main.rs @@ -33,6 +33,9 @@ enum Commands { Logout, /// Deploy a new or existing Function Deploy { + /// Path to a file or a directory containing a Function + #[clap(value_parser)] + path: Option, /// Path to a client-side script #[clap(short, long, value_parser)] client: Option, @@ -42,9 +45,6 @@ enum Commands { /// Deploy as a production deployment #[clap(visible_alias = "production", long)] prod: bool, - /// Path to a directory containing a Function - #[clap(value_parser)] - directory: Option, }, /// Delete an existing Function Rm { @@ -78,15 +78,15 @@ enum Commands { }, /// Build a Function without deploying it Build { + /// Path to a file or a directory containing a Function + #[clap(value_parser)] + path: Option, /// Path to a client-side script #[clap(short, long, value_parser)] client: Option, /// Path to a public directory to serve assets from #[clap(short, long, value_parser)] public_dir: Option, - /// Path to a directory containing a Function - #[clap(value_parser)] - directory: Option, }, /// Link a local Function file to an already deployed Function Link { @@ -127,11 +127,11 @@ async fn main() { Commands::Login => commands::login().await, Commands::Logout => commands::logout(), Commands::Deploy { + path, client, public_dir, prod, - directory, - } => commands::deploy(client, public_dir, prod, directory).await, + } => commands::deploy(path, client, public_dir, prod).await, Commands::Rm { directory } => commands::rm(directory).await, Commands::Dev { path, @@ -154,10 +154,10 @@ async fn main() { .await } Commands::Build { + path, client, public_dir, - directory, - } => commands::build(client, public_dir, directory), + } => commands::build(path, client, public_dir), Commands::Link { directory } => commands::link(directory).await, Commands::Ls { directory } => commands::ls(directory).await, Commands::Undeploy { diff --git a/crates/cli/src/utils/deployments.rs b/crates/cli/src/utils/deployments.rs index 7705738db..3f3cb1043 100644 --- a/crates/cli/src/utils/deployments.rs +++ b/crates/cli/src/utils/deployments.rs @@ -167,6 +167,43 @@ impl FunctionConfig { } } +pub fn resolve_path( + path: Option, + client: Option, + public_dir: Option, +) -> Result<(PathBuf, FunctionConfig)> { + let path = path.unwrap_or_else(|| PathBuf::from(".")); + + if !path.exists() { + return Err(anyhow!("File or directory not found")); + } + + match path.is_file() { + true => { + let root = PathBuf::from(path.parent().unwrap()); + + let index = diff_paths(&path, &root).unwrap(); + let client = client.map(|client| diff_paths(client, &root).unwrap()); + let assets = public_dir.map(|public_dir| diff_paths(public_dir, &root).unwrap()); + + Ok(( + root, + FunctionConfig { + function_id: String::new(), + organization_id: String::new(), + index, + client, + assets, + }, + )) + } + false => Ok(( + path.clone(), + FunctionConfig::load(&path, client, public_dir)?, + )), + } +} + pub fn get_root(root: Option) -> PathBuf { match root { Some(path) => path, diff --git a/packages/docs/pages/cli.mdx b/packages/docs/pages/cli.mdx index 08f35891b..a373343eb 100644 --- a/packages/docs/pages/cli.mdx +++ b/packages/docs/pages/cli.mdx @@ -48,7 +48,7 @@ If you then want to trigger a new Deployment, re-run the same command. By defaul This command accepts the following arguments and options: -- `[DIRECTORY]` is an optional path to a directory containing the Function. (Default: `.`) +- `[PATH]` is an optional path to a file or directory containing the Function. (Default: `.`) - `--client, -c ` allows you to specify a path to an additional file to bundle as a client-side script. - `--public, -p <>` allows you to specify a path to a directory containing assets to be served statically. - `--production, --prod` allows you to deploy the Function in production mode. (Default: `false`) @@ -58,6 +58,8 @@ Examples: ```bash # Deploy the current directory to Production lagon deploy --prod +# Deploy the index.ts file +lagon deploy ./index.ts # Deploy the my-project directory and override the public directory lagon deploy ./my-project --public ./my-project/assets ``` @@ -168,7 +170,7 @@ For debugging purposes, you can build a Function and see its output without depl This command accepts the following arguments and options: -- `[DIRECTORY]` is an optional path to a directory containing the Function. (Default: `.`) +- `[PATH]` is an optional path to a file or directory containing the Function. (Default: `.`) - `--client, -c ` allows you to specify a path to an additional file to bundle as a client-side script. - `--public, -p <>` allows you to specify a path to a directory containing assets to be served statically.