#![forbid(unsafe_code)]
use anyhow::{Context, Result};
use clap::Parser;
use std::fs;
use std::path::{Path, PathBuf};
use crate::runtime::RuntimeContext;
#[derive(Debug, Parser)]
pub struct NewArgs {
#[arg(long = "dir", value_name = "DIR")]
pub dir: PathBuf,
#[arg(value_name = "PACK_ID")]
pub pack_id: String,
}
pub async fn handle(args: NewArgs, json: bool, _runtime: &RuntimeContext) -> Result<()> {
let root = args.dir.canonicalize().unwrap_or_else(|_| args.dir.clone());
fs::create_dir_all(&root)?;
write_pack_yaml(&root, &args.pack_id)?;
write_flow(&root)?;
create_components_dir(&root)?;
if json {
println!(
"{}",
serde_json::to_string_pretty(&serde_json::json!({
"status": crate::cli_i18n::t("cli.status.ok"),
"pack_dir": root,
}))?
);
} else {
println!(
"{}",
crate::cli_i18n::tf("cli.new.created_pack_at", &[&root.display().to_string()])
);
}
Ok(())
}
fn write_pack_yaml(root: &Path, pack_id: &str) -> Result<()> {
let pack_yaml = format!(
r#"pack_id: {pack_id}
version: 0.1.0
kind: application
publisher: Greentic
components: []
flows:
- id: main
file: flows/main.ygtc
tags: [default]
entrypoints: [default]
dependencies: []
assets: []
"#
);
let path = root.join("pack.yaml");
fs::write(&path, pack_yaml).with_context(|| format!("failed to write {}", path.display()))
}
fn write_flow(root: &Path) -> Result<()> {
let flows_dir = root.join("flows");
fs::create_dir_all(&flows_dir)?;
let flow_path = flows_dir.join("main.ygtc");
const FLOW: &str = r#"id: main
type: messaging
nodes: {}
"#;
fs::write(&flow_path, FLOW).with_context(|| format!("failed to write {}", flow_path.display()))
}
fn create_components_dir(root: &Path) -> Result<()> {
let components_dir = root.join("components");
fs::create_dir_all(&components_dir)
.with_context(|| format!("failed to create {}", components_dir.display()))
}