1extern crate proc_macro;
4extern crate quote;
5extern crate syn;
6extern crate tinyrick_macros;
7extern crate tinyrick_models;
8
9pub use ctor::ctor;
10pub use die::die;
11pub use tinyrick_macros::{default_task, task};
12pub use tinyrick_models::{DEFAULT_TASK, DEPENDENCY_CACHE, TASKS};
13
14use std::env;
15use std::process;
16
17pub static FEATURE: &str = "letmeout";
19
20pub static VERBOSE_ENVIRONMENT_NAME: &str = "VERBOSE";
22
23#[macro_export]
25macro_rules! deps {
26 ($t : expr) => {
27 {
28 let mut has_run = false;
29
30 {
31 let cache_lock = ::tinyrick::DEPENDENCY_CACHE.lock();
32 has_run = match cache_lock {
33 Err(e) => ::die::die!(1; e.to_string()),
34 Ok(cache) => cache.contains_key("$t"),
35 };
36 }
37
38 if !has_run {
39 $t();
40
41 let mut cache_lock = ::tinyrick::DEPENDENCY_CACHE.lock();
42
43 match cache_lock {
44 Err(e) => ::die::die!(1; e.to_string()),
45 Ok(mut cache) => cache.insert("$t", true),
46 };
47 }
48 }
49 };
50}
51
52pub fn list_tasks() {
54 let d = &match DEFAULT_TASK.lock() {
55 Err(e) => die!(1; e.to_string()),
56 Ok(d_guard) => d_guard.unwrap_or(""),
57 };
58
59 if d != &"" {
60 println!("Default Task: {}\n", d);
61 }
62
63 let t_guard = match TASKS.lock() {
64 Err(e) => die!(1; e.to_string()),
65 Ok(guard) => guard,
66 };
67 let mut ts = t_guard.keys().collect::<Vec<&&str>>();
68 ts.sort();
69
70 println!("Tasks:");
71
72 if ts.is_empty() {
73 println!("(none)")
74 }
75
76 for t in ts {
77 println!(" * {}", t);
78 }
79}
80
81pub fn run() {
83 let task_string_names = env::args().collect::<Vec<String>>();
84
85 let mut task_names: Vec<&str> = task_string_names
86 .iter()
87 .skip(1)
88 .map(String::as_str)
89 .collect();
90
91 if task_names.is_empty() {
92 let t_lock = DEFAULT_TASK.lock();
93
94 match t_lock {
95 Err(e) => die!(1; e.to_string()),
96 Ok(t_guard) => match t_guard.as_ref() {
97 Some(t) => task_names.push(t),
98 _ => {
99 die!(1; "error: missing default task");
100 }
101 },
102 }
103 }
104
105 if task_names.contains(&"-l") || task_names.contains(&"--list") {
106 list_tasks();
107 die!(0);
108 }
109
110 let ts_lock = TASKS.lock();
111 let ts = match ts_lock {
112 Err(e) => die!(1; e.to_string()),
113 Ok(ts_guard) => ts_guard,
114 };
115
116 for task_name in task_names {
117 match ts.get(task_name) {
118 Some(t) => t(),
119 _ => die!(1; format!("error: unknown task: {}", task_name)),
120 }
121 }
122}
123
124pub fn binary_suffix() -> String {
126 if cfg!(windows) {
127 return ".exe".to_string();
128 }
129
130 String::new()
131}
132
133pub fn exec(command: &str, args: &[&str]) {
137 if command.is_empty() {
138 die!("error: blank command");
139 }
140
141 let command_str = if args.is_empty() {
142 command
143 } else {
144 &format!("{} {}", command, args.join(" "))
145 };
146
147 if env::var(VERBOSE_ENVIRONMENT_NAME).is_ok() {
148 println!("info: running command: {}", command_str);
149 }
150
151 let success = match process::Command::new(command).args(args).status() {
152 Err(e) => die!(format!(
153 "error: unprocessable command: {}: {}",
154 command_str,
155 e.to_string()
156 )),
157 Ok(status) => status.success(),
158 };
159
160 if !success {
161 die!(1; format!("error: command failed: {}", command_str));
162 }
163}
164
165#[macro_export]
169macro_rules! exec {
170 ($p : expr $(, $a:expr)* $(,)?) => {
171 ::tinyrick::exec($p, &[ $( $a, )* ])
172 };
173}