Skip to main content

packc/
new.rs

1#![forbid(unsafe_code)]
2
3use anyhow::{Context, Result};
4use clap::Parser;
5use std::fs;
6use std::path::{Path, PathBuf};
7
8use crate::runtime::RuntimeContext;
9
10#[derive(Debug, Parser)]
11pub struct NewArgs {
12    /// Directory to create the pack in
13    #[arg(long = "dir", value_name = "DIR")]
14    pub dir: PathBuf,
15    /// Pack id to use
16    #[arg(value_name = "PACK_ID")]
17    pub pack_id: String,
18}
19
20pub async fn handle(args: NewArgs, json: bool, _runtime: &RuntimeContext) -> Result<()> {
21    let root = args.dir.canonicalize().unwrap_or_else(|_| args.dir.clone());
22    fs::create_dir_all(&root)?;
23
24    write_pack_yaml(&root, &args.pack_id)?;
25    write_flow(&root)?;
26    create_components_dir(&root)?;
27
28    if json {
29        println!(
30            "{}",
31            serde_json::to_string_pretty(&serde_json::json!({
32                "status": crate::cli_i18n::t("cli.status.ok"),
33                "pack_dir": root,
34            }))?
35        );
36    } else {
37        println!(
38            "{}",
39            crate::cli_i18n::tf("cli.new.created_pack_at", &[&root.display().to_string()])
40        );
41    }
42
43    Ok(())
44}
45
46fn write_pack_yaml(root: &Path, pack_id: &str) -> Result<()> {
47    let pack_yaml = format!(
48        r#"pack_id: {pack_id}
49version: 0.1.0
50kind: application
51publisher: Greentic
52
53components: []
54
55flows:
56  - id: main
57    file: flows/main.ygtc
58    tags: [default]
59    entrypoints: [default]
60
61dependencies: []
62
63assets: []
64"#
65    );
66    let path = root.join("pack.yaml");
67    fs::write(&path, pack_yaml).with_context(|| format!("failed to write {}", path.display()))
68}
69
70fn write_flow(root: &Path) -> Result<()> {
71    let flows_dir = root.join("flows");
72    fs::create_dir_all(&flows_dir)?;
73    let flow_path = flows_dir.join("main.ygtc");
74    const FLOW: &str = r#"id: main
75type: messaging
76nodes: {}
77"#;
78    fs::write(&flow_path, FLOW).with_context(|| format!("failed to write {}", flow_path.display()))
79}
80
81fn create_components_dir(root: &Path) -> Result<()> {
82    let components_dir = root.join("components");
83    fs::create_dir_all(&components_dir)
84        .with_context(|| format!("failed to create {}", components_dir.display()))
85}