-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathdynamic.rs
More file actions
157 lines (132 loc) · 4.56 KB
/
dynamic.rs
File metadata and controls
157 lines (132 loc) · 4.56 KB
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
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
use std::error::Error;
use std::fs;
use std::path::{Path, PathBuf};
use std::process::Command;
#[derive(Debug)]
struct Script {
name: String,
path: PathBuf,
}
fn find_scripts(dir: &Path) -> Vec<Script> {
let mut scripts = Vec::new();
// Check both root and src/bin directories
let search_paths = vec![dir.to_path_buf(), dir.join("src").join("bin")];
for search_path in search_paths {
if let Ok(entries) = fs::read_dir(search_path) {
for entry in entries.filter_map(Result::ok) {
let path = entry.path();
if path.extension().map_or(false, |ext| ext == "rs") {
// Skip main.rs and lib.rs
if let Some(file_name) = path.file_stem() {
if file_name != "main" && file_name != "lib" {
let name = file_name.to_string_lossy().into_owned();
scripts.push(Script {
name,
path: path.clone(),
});
}
}
}
}
}
}
scripts.sort_by(|a, b| a.name.cmp(&b.name));
scripts
}
fn find_deps_path(current_dir: &Path) -> PathBuf {
// First check if we're in a workspace by looking for Cargo.toml with [workspace]
let mut dir = current_dir.to_path_buf();
while dir.parent().is_some() {
let cargo_toml = dir.join("Cargo.toml");
if cargo_toml.exists() {
if let Ok(contents) = fs::read_to_string(&cargo_toml) {
if contents.contains("[workspace]") {
// Found workspace root
return dir.join("target/debug/deps");
}
}
}
dir = dir.parent().unwrap().to_path_buf();
}
// If no workspace found, use the current directory
current_dir.join("target/debug/deps")
}
fn compile_script(script: &Script) -> Result<(), Box<dyn Error>> {
println!("Compiling {}...", script.name);
// Use cargo build --bin instead of rustc
let status = Command::new("cargo")
.args(&["build", "--bin", &script.name])
.status()?;
if !status.success() {
return Err(format!("Failed to compile {}", script.name).into());
}
Ok(())
}
fn run_script(script: &Script, args: &[String]) -> Result<(), Box<dyn Error>> {
println!("Running {}...", script.name);
let status = Command::new("cargo")
.args(&["run", "--bin", &script.name, "--"])
.args(args)
.status()?;
if !status.success() {
return Err(format!(
"Script {} failed with exit code {:?}",
script.name,
status.code()
)
.into());
}
Ok(())
}
fn show_help(current_dir: &Path) {
println!("Usage:");
println!(" cargo invoke <script> [args...] # Run a specific script");
println!(" cargo invoke --help # Show this help message\n");
let scripts = find_scripts(current_dir);
if scripts.is_empty() {
println!("No Rust scripts found");
return;
}
println!("Available scripts:");
for script in scripts {
println!(" {}", script.name);
}
}
fn main() -> Result<(), Box<dyn Error>> {
let args: Vec<String> = std::env::args().collect();
// Skip the first argument (executable name)
let args: Vec<String> = if args.len() > 1 && args[1] == "invoke" {
// If called as `cargo invoke`, skip first two args
args.iter().skip(2).cloned().collect()
} else {
// If called directly, skip first arg
args.iter().skip(1).cloned().collect()
};
let current_dir = std::env::current_dir()?;
// Create target/debug directory if it doesn't exist
fs::create_dir_all("target/debug")?;
if args.is_empty() {
show_help(¤t_dir);
return Ok(());
}
let command = &args[0];
match command.as_str() {
"--help" | "-h" => {
show_help(¤t_dir);
}
_ => {
// Check if the command is a script name
let scripts = find_scripts(¤t_dir);
if let Some(script) = scripts.iter().find(|s| s.name == *command) {
// If it is a script name, run it with any remaining args
let script_args = args[1..].to_vec();
compile_script(script)?;
run_script(script, &script_args)?;
} else {
println!("Unknown script: {}", command);
show_help(¤t_dir);
}
}
}
Ok(())
}