1
use hashbrown::HashMap;
2
use schemars::JsonSchema;
3
use serde::Deserialize;
4

            
5
use crate::utils::resolve_path;
6

            
7
use super::{
8
  CommandRunner,
9
  LocalRun,
10
  Task,
11
  TaskArgs,
12
};
13

            
14
#[derive(Debug, Deserialize, JsonSchema)]
15
pub struct UseCargoArgs {
16
  /// The working directory to run the command in
17
  #[serde(default)]
18
  pub work_dir: Option<String>,
19
}
20

            
21
#[derive(Debug, Deserialize, JsonSchema)]
22
#[serde(untagged)]
23
/// Enable cargo commands as tasks. Either `true` or an object with optional settings.
24
pub enum UseCargo {
25
  Bool(bool),
26
  UseCargo(Box<UseCargoArgs>),
27
}
28

            
29
impl UseCargo {
30
  pub fn capture(&self) -> anyhow::Result<HashMap<String, Task>> {
31
    self.capture_in_dir(std::path::Path::new("."))
32
  }
33

            
34
2
  pub fn capture_in_dir(&self, base_dir: &std::path::Path) -> anyhow::Result<HashMap<String, Task>> {
35
2
    match self {
36
      UseCargo::Bool(true) => self.capture_tasks_in_dir(base_dir),
37
2
      UseCargo::UseCargo(args) => args.capture_tasks_in_dir(base_dir),
38
      _ => Ok(HashMap::new()),
39
    }
40
2
  }
41

            
42
  fn capture_tasks_in_dir(&self, base_dir: &std::path::Path) -> anyhow::Result<HashMap<String, Task>> {
43
    UseCargoArgs { work_dir: None }.capture_tasks_in_dir(base_dir)
44
  }
45
}
46

            
47
impl UseCargoArgs {
48
  pub fn capture_tasks(&self) -> anyhow::Result<HashMap<String, Task>> {
49
    self.capture_tasks_in_dir(std::path::Path::new("."))
50
  }
51

            
52
2
  pub fn capture_tasks_in_dir(&self, base_dir: &std::path::Path) -> anyhow::Result<HashMap<String, Task>> {
53
2
    let resolved_work_dir = self
54
2
      .work_dir
55
2
      .as_ref()
56
2
      .map(|work_dir| resolve_path(base_dir, work_dir));
57
2
    let cargo_commands = [
58
2
      "add",
59
2
      "bench",
60
2
      "build",
61
2
      "check",
62
2
      "clean",
63
2
      "clippy",
64
2
      "doc",
65
2
      "fix",
66
2
      "fmt",
67
2
      "init",
68
2
      "install",
69
2
      "miri",
70
2
      "new",
71
2
      "publish",
72
2
      "remove",
73
2
      "report",
74
2
      "run",
75
2
      "search",
76
2
      "test",
77
2
      "uninstall",
78
2
      "update",
79
2
    ];
80

            
81
2
    let hm: HashMap<String, Task> = cargo_commands
82
2
      .iter()
83
42
      .map(|cmd| {
84
42
        let command = format!("cargo {}", cmd);
85
42
        let task = Task::Task(Box::new(TaskArgs {
86
42
          commands: vec![CommandRunner::LocalRun(LocalRun {
87
42
            command,
88
42
            shell: None,
89
42
            test: None,
90
42
            work_dir: resolved_work_dir
91
42
              .as_ref()
92
42
              .map(|work_dir| work_dir.to_string_lossy().into_owned()),
93
42
            interactive: Some(true),
94
42
            retrigger: None,
95
42
            ignore_errors: None,
96
42
            save_output_as: None,
97
42
            verbose: None,
98
          })],
99
42
          ..Default::default()
100
        }));
101
42
        (cmd.to_string(), task)
102
42
      })
103
2
      .collect();
104
2
    Ok(hm)
105
2
  }
106
}