Skip to content

Commit 82e3645

Browse files
committed
feat: adjust vs task
1 parent 2c346bb commit 82e3645

File tree

1 file changed

+122
-12
lines changed

1 file changed

+122
-12
lines changed

src/runners/vstasks.rs

Lines changed: 122 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,107 @@
1-
use error_stack::Report;
2-
use crate::command_utils::{run_command_by_shell, run_command_line, CommandOutput};
1+
use crate::command_utils::{run_command_by_shell, run_command_with_env_vars, CommandOutput};
32
use crate::errors::KeeperError;
43
use crate::models::Task;
54
use crate::task;
5+
use error_stack::Report;
66
use jsonc_parser::parse_to_serde_value;
77
use serde::{Deserialize, Serialize};
8+
use std::collections::HashMap;
9+
use std::env;
810

911
#[derive(Serialize, Deserialize, Debug, Default)]
1012
struct TasksJson {
1113
pub version: String,
1214
pub tasks: Option<Vec<VSTask>>,
1315
}
1416

15-
#[derive(Serialize, Deserialize, Debug, Default)]
17+
impl TasksJson {
18+
pub fn find_task(&self, task_name: &str) -> Option<VSTask> {
19+
if let Some(tasks) = &self.tasks {
20+
let result = tasks.iter().find(|task| {
21+
if let Some(label) = &task.label {
22+
label == task_name
23+
} else {
24+
false
25+
}
26+
});
27+
if let Some(task) = result {
28+
return Some(task.clone());
29+
}
30+
}
31+
None
32+
}
33+
}
34+
35+
// Command options
36+
#[derive(Serialize, Deserialize, Debug, Default, Clone)]
37+
struct CommandOptions {
38+
// current working directory
39+
cwd: Option<String>,
40+
// environment variables passed to the task
41+
env: Option<HashMap<String, String>>,
42+
}
43+
44+
// --- Platform-specific configuration ---
45+
#[derive(Serialize, Deserialize, Debug, Default, Clone)]
46+
struct PlatformConfig {
47+
command: Option<String>,
48+
args: Option<Vec<String>>,
49+
options: Option<CommandOptions>,
50+
}
51+
52+
#[derive(Serialize, Deserialize, Debug, Default, Clone)]
1653
struct VSTask {
1754
pub label: Option<String>,
1855
#[serde(rename = "type")]
1956
pub task_type: String,
2057
pub command: Option<String>,
58+
options: Option<CommandOptions>,
59+
args: Option<Vec<String>>,
60+
// Platform-specific configurations
61+
#[allow(dead_code)]
62+
windows: Option<PlatformConfig>,
63+
#[allow(dead_code)]
64+
linux: Option<PlatformConfig>,
65+
#[allow(dead_code)]
66+
osx: Option<PlatformConfig>,
67+
}
68+
69+
impl VSTask {
70+
pub fn get_command(&self) -> Option<String> {
71+
// Determine current platform
72+
#[cfg(target_os = "windows")]
73+
let platform_config = &self.windows;
74+
75+
#[cfg(target_os = "linux")]
76+
let platform_config = &self.linux;
77+
78+
#[cfg(target_os = "macos")]
79+
let platform_config = &self.osx;
80+
if let Some(config) = platform_config {
81+
if let Some(cmd) = &config.command {
82+
return Some(cmd.clone());
83+
}
84+
}
85+
self.command.clone()
86+
}
87+
88+
pub fn get_command_options(&self) -> Option<CommandOptions> {
89+
// Determine current platform
90+
#[cfg(target_os = "windows")]
91+
let platform_config = &self.windows;
92+
93+
#[cfg(target_os = "linux")]
94+
let platform_config = &self.linux;
95+
96+
#[cfg(target_os = "macos")]
97+
let platform_config = &self.osx;
98+
if let Some(config) = platform_config {
99+
if let Some(option) = &config.options {
100+
return Some(option.clone());
101+
}
102+
}
103+
self.options.clone()
104+
}
21105
}
22106

23107
pub fn is_available() -> bool {
@@ -68,20 +152,46 @@ fn parse_run_json() -> TasksJson {
68152
}
69153

70154
pub fn run_task(
71-
task: &str,
155+
task_name: &str,
72156
_task_args: &[&str],
73157
_global_args: &[&str],
74158
verbose: bool,
75159
) -> Result<CommandOutput, Report<KeeperError>> {
76-
let tasks = list_tasks()?;
77-
let task = tasks
78-
.iter()
79-
.find(|t| t.name == task)
80-
.ok_or_else(|| KeeperError::TaskNotFound(task.to_string()))?;
81-
if let Some(_runner2) = &task.runner2 {
82-
run_command_by_shell(&task.description, verbose)
160+
let tasks_json = parse_run_json();
161+
let task = tasks_json
162+
.find_task(task_name)
163+
.ok_or_else(|| KeeperError::TaskNotFound(task_name.to_string()))?;
164+
let command = task.command.clone().unwrap();
165+
if task.task_type == "shell" {
166+
run_command_by_shell(&command, verbose)
83167
} else {
84-
run_command_line(&task.description, verbose)
168+
let mut workspace_root = env::current_dir().unwrap().to_str().unwrap().to_string();
169+
let mut command_env_vars: Option<HashMap<String, String>> = None;
170+
let command = task.get_command().unwrap();
171+
let options = task.get_command_options();
172+
if let Some(options) = &options {
173+
if let Some(cwd) = &options.cwd {
174+
workspace_root = cwd.to_string();
175+
}
176+
if let Some(env_vars) = &options.env {
177+
command_env_vars = Some(env_vars.clone());
178+
}
179+
}
180+
let command_and_args = shlex::split(&command).unwrap();
181+
let command_name = command_and_args.get(0).unwrap();
182+
let mut command_args: Vec<&str> = command_and_args[1..].iter().map(AsRef::as_ref).collect();
183+
if let Some(args) = &task.args {
184+
for arg in args {
185+
command_args.push(arg);
186+
}
187+
}
188+
run_command_with_env_vars(
189+
command_name,
190+
&command_args,
191+
&Some(workspace_root),
192+
&command_env_vars,
193+
verbose,
194+
)
85195
}
86196
}
87197

0 commit comments

Comments
 (0)