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
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
//! # duck_script
//!
//! Compiles and runs duckscript code.
//!

#[cfg(test)]
#[path = "mod_test.rs"]
mod mod_test;

mod sdk;

use crate::environment;
use crate::types::{FlowInfo, FlowState};
use duckscript::runner;
use duckscript::types::command::Commands;
use duckscript::types::error::ScriptError;
use duckscript::types::runtime::Context;
use duckscriptsdk;
use envmnt;
use std::cell::RefCell;
use std::rc::Rc;

pub(crate) fn execute(
    script: &Vec<String>,
    cli_arguments: &Vec<String>,
    flow_info: Option<&FlowInfo>,
    flow_state: Option<Rc<RefCell<FlowState>>>,
    validate: bool,
) {
    let mut array_command = "@ = array".to_string();
    let mut index = 0;
    for _ in cli_arguments {
        index = index + 1;
        array_command.push_str(format!(" ${{{}}}", index).as_str());
    }
    let mut script_text = script.join("\n");
    script_text.insert_str(
        0,
        format!("exit_on_error true\n{}\n", &array_command).as_str(),
    );

    let mut context = create_common_context(cli_arguments);

    match load_sdk(&mut context.commands, flow_info, flow_state) {
        Ok(_) => {
            let directory = envmnt::get_or("CARGO_MAKE_WORKING_DIRECTORY", "");

            match runner::run_script(&script_text, context) {
                Ok(_) => (),
                Err(error) => {
                    if validate {
                        error!("Error while running duckscript: {}", error);
                    }
                }
            };

            // revert to originl working directory
            if !directory.is_empty() {
                environment::setup_cwd(Some(&directory));
            }
        }
        Err(error) => {
            if validate {
                error!("Unable to load duckscript SDK: {}", error);
            }
        }
    };
}

pub(crate) fn create_common_context(cli_arguments: &Vec<String>) -> Context {
    let mut context = Context::new();
    let mut index = 0;
    for argument in cli_arguments {
        index = index + 1;

        context
            .variables
            .insert(index.to_string(), argument.to_string());
    }

    let all_vars = envmnt::vars();

    for (key, value) in all_vars {
        context.variables.insert(key, value);
    }

    context
}

pub(crate) fn load_sdk(
    commands: &mut Commands,
    flow_info: Option<&FlowInfo>,
    flow_state: Option<Rc<RefCell<FlowState>>>,
) -> Result<(), ScriptError> {
    duckscriptsdk::load(commands)?;
    sdk::load(commands, flow_info, flow_state)?;

    Ok(())
}