mk_lib/schema/
task_context.rs1use std::sync::Arc;
2
3use hashbrown::HashMap;
4use indicatif::{
5 MultiProgress,
6 ProgressDrawTarget,
7};
8
9use crate::defaults::{
10 default_ignore_errors,
11 default_shell,
12 default_verbose,
13};
14
15use super::{
16 ExecutionStack,
17 Shell,
18 TaskRoot,
19};
20
21#[derive(Clone)]
25pub struct TaskContext {
26 pub task_root: Arc<TaskRoot>,
27 pub execution_stack: ExecutionStack,
28 pub multi: Arc<MultiProgress>,
29 pub env_vars: HashMap<String, String>,
30 pub shell: Option<Arc<Shell>>,
31 pub ignore_errors: Option<bool>,
32 pub verbose: Option<bool>,
33 pub is_nested: bool,
34}
35
36impl TaskContext {
37 pub fn empty() -> Self {
38 let mp = MultiProgress::with_draw_target(ProgressDrawTarget::hidden());
39 Self {
40 task_root: Arc::new(TaskRoot::default()),
41 execution_stack: ExecutionStack::default(),
42 multi: Arc::new(mp),
43 env_vars: HashMap::new(),
44 shell: None,
45 ignore_errors: None,
46 verbose: None,
47 is_nested: false,
48 }
49 }
50
51 pub fn empty_with_root(task_root: Arc<TaskRoot>) -> Self {
52 let mp = MultiProgress::with_draw_target(ProgressDrawTarget::hidden());
53 Self {
54 task_root: task_root.clone(),
55 execution_stack: ExecutionStack::default(),
56 multi: Arc::new(mp),
57 env_vars: HashMap::new(),
58 shell: None,
59 ignore_errors: None,
60 verbose: None,
61 is_nested: false,
62 }
63 }
64
65 pub fn new(task_root: Arc<TaskRoot>, execution_stack: ExecutionStack) -> Self {
66 Self {
67 task_root: task_root.clone(),
68 execution_stack,
69 multi: Arc::new(MultiProgress::new()),
70 env_vars: HashMap::new(),
71 shell: None,
72 ignore_errors: None,
73 verbose: None,
74 is_nested: false,
75 }
76 }
77
78 pub fn from_context(context: &TaskContext) -> Self {
79 Self {
80 task_root: context.task_root.clone(),
81 execution_stack: context.execution_stack.clone(),
82 multi: context.multi.clone(),
83 env_vars: context.env_vars.clone(),
84 shell: context.shell.clone(),
85 ignore_errors: context.ignore_errors,
86 verbose: context.verbose,
87 is_nested: true,
88 }
89 }
90
91 pub fn from_context_with_args(context: &TaskContext, ignore_errors: bool, verbose: bool) -> Self {
92 Self {
93 task_root: context.task_root.clone(),
94 execution_stack: context.execution_stack.clone(),
95 multi: context.multi.clone(),
96 env_vars: context.env_vars.clone(),
97 shell: context.shell.clone(),
98 ignore_errors: Some(ignore_errors),
99 verbose: Some(verbose),
100 is_nested: true,
101 }
102 }
103
104 pub fn extend_env_vars<I>(&mut self, iter: I)
105 where
106 I: IntoIterator<Item = (String, String)>,
107 {
108 self.env_vars.extend(iter);
109 }
110
111 pub fn set_shell(&mut self, shell: &Shell) {
112 let shell = Arc::new(Shell::from_shell(shell));
113 self.shell = Some(shell);
114 }
115
116 pub fn set_ignore_errors(&mut self, ignore_errors: bool) {
117 self.ignore_errors = Some(ignore_errors);
118 }
119
120 pub fn set_verbose(&mut self, verbose: bool) {
121 self.verbose = Some(verbose);
122 }
123
124 pub fn shell(&self) -> Arc<Shell> {
125 self.shell.clone().unwrap_or_else(|| Arc::new(default_shell()))
126 }
127
128 pub fn ignore_errors(&self) -> bool {
129 self.ignore_errors.unwrap_or(default_ignore_errors())
130 }
131
132 pub fn verbose(&self) -> bool {
133 self.verbose.unwrap_or(default_verbose())
134 }
135}
136
137#[cfg(test)]
138mod test {
139 use super::*;
140
141 #[test]
142 fn test_task_context_1() -> anyhow::Result<()> {
143 {
144 let context = TaskContext::empty();
145 assert_eq!(context.shell().cmd(), "sh".to_string());
146 assert!(!context.ignore_errors());
147 assert!(context.verbose());
148 }
149
150 Ok(())
151 }
152
153 #[test]
154 fn test_task_context_2() -> anyhow::Result<()> {
155 {
156 let mut context = TaskContext::empty();
157 context.set_shell(&Shell::String("bash".to_string()));
158 assert_eq!(context.shell().cmd(), "bash".to_string());
159 }
160
161 Ok(())
162 }
163
164 #[test]
165 fn test_task_context_3() -> anyhow::Result<()> {
166 {
167 let mut context = TaskContext::empty();
168 context.extend_env_vars(vec![("key".to_string(), "value".to_string())]);
169 assert_eq!(context.env_vars.get("key"), Some(&"value".to_string()));
170 }
171
172 Ok(())
173 }
174
175 #[test]
176 fn test_task_context_4() -> anyhow::Result<()> {
177 {
178 let mut context = TaskContext::empty();
179 context.set_ignore_errors(true);
180 assert!(context.ignore_errors());
181 }
182
183 Ok(())
184 }
185
186 #[test]
187 fn test_task_context_5() -> anyhow::Result<()> {
188 {
189 let mut context = TaskContext::empty();
190 context.set_verbose(true);
191 assert!(context.verbose());
192 }
193
194 Ok(())
195 }
196}