1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
use crate::{util, Config};
use clap::{Arg, ArgMatches};
use duckscript::types::runtime::{Context, StateValue};
use std::path::Path;

pub fn cli() -> clap::Command<'static> {
    clap::Command::new("build").about("Builds a spacetime module.").arg(
        Arg::new("project-path")
            .required(false)
            .default_value(".")
            .help("The path of the project that you would like to build."),
    )
}

pub async fn exec(_: Config, args: &ArgMatches) -> Result<(), anyhow::Error> {
    let project_path_str = args.value_of("project-path").unwrap();
    let project_path = Path::new(project_path_str);

    // Create the project path, or make sure the target project path is empty.
    if project_path.exists() {
        if !project_path.is_dir() {
            return Err(anyhow::anyhow!(
                "Fatal Error: path {} exists but is not a directory.",
                project_path_str
            ));
        }
    } else {
        return Err(anyhow::anyhow!(
            "Fatal Error: path {} does not exist.",
            project_path_str
        ));
    }

    let mut context = Context::new();
    duckscriptsdk::load(&mut context.commands)?;
    context
        .variables
        .insert("PATH".to_string(), std::env::var("PATH").unwrap());
    context
        .variables
        .insert("PROJECT_PATH".to_string(), project_path_str.to_string());

    match util::invoke_duckscript(include_str!("project/build.duck"), context) {
        Ok(ok) => {
            let mut error = false;
            for entry in ok.state {
                if let StateValue::SubState(sub_state) = entry.1 {
                    for entry in sub_state {
                        match entry.1 {
                            StateValue::String(a) => {
                                error = true;
                                println!("{}|{}", entry.0, a)
                            }
                            _ => {}
                        }
                    }
                }
            }

            if !error {
                println!("Build finished successfully.");
            } else {
                println!("Build finished with errors, check the console for more information.");
            }
        }
        Err(e) => {
            println!("Script execution error: {}", e);
        }
    }

    Ok(())
}