use std::path::{Path, PathBuf};
use snapbox::cmd::{Command, OutputAssert};
mod project;
use project::Project;
pub use project::{CargoPathExt, paths::init_root, project};
pub struct LambdaProject {
pub name: String,
template: PathBuf,
root: PathBuf,
cwd: PathBuf,
}
impl LambdaProject {
pub fn zip_name(&self) -> String {
format!("{}.zip", &self.name)
}
pub fn extension_path(&self) -> String {
format!("extensions/{}", &self.name)
}
pub fn new_cmd(&self) -> Command {
Command::cargo_lambda()
.arg("lambda")
.arg("new")
.arg("--template")
.arg(self.template_path().as_os_str())
.current_dir(&self.cwd)
}
pub fn init_cmd(&self) -> Command {
Command::cargo_lambda()
.arg("lambda")
.arg("init")
.arg("--template")
.arg(self.template_path().as_os_str())
.arg("--name")
.arg(&self.name)
.current_dir(&self.cwd)
}
pub fn root(&self) -> &PathBuf {
&self.root
}
pub fn test_project(&self) -> Project {
test_project(&self.root)
}
fn template_path(&self) -> PathBuf {
let path = Path::new("..")
.join("..")
.join("tests")
.join("templates")
.join(&self.template);
dunce::realpath(path).expect("failed to create real template path")
}
}
pub fn test_project<P: AsRef<Path>>(path: P) -> Project {
let project = Project::from_template(path);
let metadata = project.read_file("Cargo.toml");
let metadata = format!("{metadata}\n\n[workspace]\n");
project.change_file("Cargo.toml", &metadata);
project
}
pub fn cargo_lambda_new<P: AsRef<Path>>(project_name: &str, template: P) -> LambdaProject {
let project = project::project().build();
cargo_lambda_new_in_root(project_name, template, project.root())
}
pub fn cargo_lambda_new_in_root<P: AsRef<Path>, R: AsRef<Path>>(
project_name: &str,
template: P,
root: R,
) -> LambdaProject {
let root = root.as_ref();
let cwd = dunce::canonicalize(root).expect("failed to create canonical path");
let name = format!("{}-{}", project_name, uuid::Uuid::new_v4());
let root = root.join(&name);
LambdaProject {
name,
template: template.as_ref().to_path_buf(),
root: root.to_path_buf(),
cwd,
}
}
pub fn cargo_lambda_init<P: AsRef<Path>>(project_name: &str, template: P) -> LambdaProject {
let project = project::project().build();
let cwd = dunce::canonicalize(project.root()).expect("failed to create canonical path");
cwd.mkdir_p();
let name = format!("{}-{}", project_name, uuid::Uuid::new_v4());
LambdaProject {
name,
template: template.as_ref().to_path_buf(),
root: project.root(),
cwd,
}
}
pub fn cargo_lambda_build<P: AsRef<Path>>(path: P) -> Command {
let path = path.as_ref();
let lambda_dir = path.join("target").join("lambda");
Command::cargo_lambda()
.arg("lambda")
.arg("build")
.arg("-vv")
.arg("--lambda-dir")
.arg(lambda_dir.as_os_str())
.env("RUST_BACKTRACE", "full")
.env("CARGO_ZIGBUILD_CACHE_DIR", path.as_os_str())
.current_dir(path)
}
pub fn cargo_lambda_dry_deploy<P: AsRef<Path>>(path: P) -> Command {
let path = path.as_ref();
let lambda_dir = path.join("target").join("lambda");
Command::cargo_lambda()
.arg("lambda")
.arg("deploy")
.arg("--dry")
.arg("--output-format")
.arg("json")
.arg("--lambda-dir")
.arg(lambda_dir.as_os_str())
.current_dir(path)
}
fn cargo_exe() -> std::path::PathBuf {
snapbox::cmd::cargo_bin!("cargo-lambda").to_path_buf()
}
pub trait LambdaCommandExt {
fn cargo_lambda() -> Self;
}
impl LambdaCommandExt for Command {
fn cargo_lambda() -> Self {
Self::new(cargo_exe()).with_assert(project::assert_ui())
}
}
pub fn deploy_output_json(output: &OutputAssert) -> Result<serde_json::Value, serde_json::Error> {
let output = output.get_output();
let stdout = String::from_utf8_lossy(&output.stdout);
let (_log, json) = stdout.split_once("loading binary data").unwrap();
serde_json::from_str(json)
}