mk_lib/schema/
task_dependency.rs

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
use serde::{
  Deserialize,
  Serialize,
};

use super::TaskContext;

/// This struct represents a task dependency. A task can depend on other tasks.
/// If a task depends on another task, the dependent task must be executed before
/// the dependent task.
#[derive(Debug, Default, Serialize, Deserialize, PartialEq)]
pub struct TaskDependency {
  pub name: String,
}

impl TaskDependency {
  pub fn run(&self, context: &TaskContext) -> anyhow::Result<()> {
    let task_name: &str = &self.name;
    let task = context
      .task_root
      .tasks
      .get(task_name)
      .ok_or_else(|| anyhow::anyhow!("Task not found"))?;

    log::trace!("Task: {:?}", task);

    {
      let mut stack = context
        .execution_stack
        .lock()
        .map_err(|e| anyhow::anyhow!("Failed to lock execution stack: {}", e))?;

      if stack.contains(task_name) {
        anyhow::bail!("Circular dependency detected: {}", task_name);
      }

      stack.insert(task_name.into());
    }

    let mut context = TaskContext::from_context(context);
    task.run(&mut context)?;

    Ok(())
  }
}

mod test {
  #[allow(unused_imports)]
  use super::*;

  #[test]
  fn test_task_dependency() {
    let yaml = "
      name: task1
    ";
    let task_dependency = serde_yaml::from_str::<TaskDependency>(yaml).unwrap();

    assert_eq!(task_dependency.name, "task1");
  }
}