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": "ok",
33                "pack_dir": root,
34            }))?
35        );
36    } else {
37        println!("created pack at {}", root.display());
38    }
39
40    Ok(())
41}
42
43fn write_pack_yaml(root: &Path, pack_id: &str) -> Result<()> {
44    let pack_yaml = format!(
45        r#"pack_id: {pack_id}
46version: 0.1.0
47kind: application
48publisher: Greentic
49
50components: []
51
52flows:
53  - id: main
54    file: flows/main.ygtc
55    tags: [default]
56    entrypoints: [default]
57
58dependencies: []
59
60assets: []
61"#
62    );
63    let path = root.join("pack.yaml");
64    fs::write(&path, pack_yaml).with_context(|| format!("failed to write {}", path.display()))
65}
66
67fn write_flow(root: &Path) -> Result<()> {
68    let flows_dir = root.join("flows");
69    fs::create_dir_all(&flows_dir)?;
70    let flow_path = flows_dir.join("main.ygtc");
71    const FLOW: &str = r#"id: main
72type: messaging
73nodes: {}
74"#;
75    fs::write(&flow_path, FLOW).with_context(|| format!("failed to write {}", flow_path.display()))
76}
77
78fn create_components_dir(root: &Path) -> Result<()> {
79    let components_dir = root.join("components");
80    fs::create_dir_all(&components_dir)
81        .with_context(|| format!("failed to create {}", components_dir.display()))
82}