greentic-pack-dev 1.1.26495471727

Greentic pack builder CLI
Documentation
#![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 {
    /// Directory to create the pack in
    #[arg(long = "dir", value_name = "DIR")]
    pub dir: PathBuf,
    /// Pack id to use
    #[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()))
}