use crate::HostCallFlags;
use crate::cmds::accounts::get_current_account;
use anyhow::bail;
use clap::Subcommand;
use ordinary_config::{FunctionFfiVersion, FunctionToolchain, OrdinaryConfig};
use std::path::Path;
use tracing::instrument;
#[derive(Subcommand, Debug)]
pub enum Functions {
#[clap(visible_aliases(["create", "new"]))]
Add {
name: String,
#[arg(short, long, default_value = "rust")]
toolchain: FunctionToolchain,
},
Build {
#[arg(short, long)]
name: Option<String>,
#[arg(short, long, default_value_t = false)]
force: bool,
},
Upload {
#[command(flatten)]
host: HostCallFlags,
#[arg(short, long)]
name: Option<String>,
},
}
impl Functions {
#[instrument(skip_all, name = "functions")]
pub async fn handle(&self, project: &str) -> anyhow::Result<()> {
match self {
Self::Add { name, toolchain } => {
ordinary_function::modify::add(Path::new(project), name, toolchain)?;
}
Self::Build { name, force } => {
let env_file = Path::new(project).join(".env");
if env_file.exists() {
dotenvy::from_path(env_file)?;
}
let config = OrdinaryConfig::get("../../../../../..", true)?;
config.validate()?;
if let Some(name) = name {
if let Some(function_config) = config.functions.and_then(|functions| {
functions.iter().find_map(|a| {
if a.name_validated() == name {
Some(a.clone())
} else {
None
}
})
}) {
match function_config.ffi_validated().version {
FunctionFfiVersion::V1 => {
ordinary_function::build::v1::build(
&function_config,
Path::new(project),
*force,
)?;
}
}
} else {
bail!("function with name '{name}' doesn't exist");
}
} else if let Some(function_configs) = &config.functions {
for function_config in function_configs {
match function_config.ffi_validated().version {
FunctionFfiVersion::V1 => {
ordinary_function::build::v1::build(
function_config,
Path::new(project),
*force,
)?;
}
}
}
}
}
Self::Upload { name, host } => {
let account = get_current_account(host.insecure)?;
let client = host.client(&account)?;
if let Some(name) = name {
client.functions_upload(project, name).await?;
} else {
client.functions_upload_all(project).await?;
}
}
}
Ok(())
}
}