-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathargs.rs
146 lines (124 loc) · 4.35 KB
/
args.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
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
use clap::Parser;
use eyre::eyre;
use reqwest::blocking::multipart;
use serde_json::json;
use std::{fs, path::Path, process::Command};
use toml::Value;
#[derive(Parser)]
#[clap(about = "Build the project using cargo wasi")]
pub struct BuildArgs {
#[clap(long, short, help = "Build artifacts in release mode")]
pub release: bool,
}
#[derive(Parser)]
#[clap(about = "Deploy the module to the xxfunc service")]
pub struct DeployArgs {
#[clap(long, help = "URL of the xxfunc service")]
pub url: String,
#[clap(long, help = "Path to the module's WASM file")]
pub wasm_path: String,
}
#[derive(Parser)]
#[clap(about = "Start a module on the xxfunc service")]
pub struct StartArgs {
#[clap(long, help = "URL of the xxfunc service")]
pub url: String,
#[clap(long, help = "Name of the module to start")]
pub module_name: String,
}
#[derive(Parser)]
#[clap(about = "Stop a module on the xxfunc service")]
pub struct StopArgs {
#[clap(long, help = "URL of the xxfunc service")]
pub url: String,
#[clap(long, help = "Name of the module to stop")]
pub module_name: String,
}
pub fn build(release: bool) -> eyre::Result<()> {
let mut args = vec!["wasi", "build"];
if release {
args.push("--release");
}
let status =
Command::new("cargo").args(&args).status().expect("Failed to execute cargo wasi build");
if !status.success() {
return Err(eyre::eyre!("cargo wasi build failed"));
}
// Copy the WASM file to a specific location
let target_dir = if release {
Path::new("target/wasm32-wasi/release")
} else {
Path::new("target/wasm32-wasi/debug")
};
let project_name = get_project_name().expect("Failed to get project name");
let wasm_file = target_dir.join(format!("{}.wasm", project_name));
let dest_dir = Path::new("wasm_output");
fs::create_dir_all(dest_dir).expect("Failed to create destination directory");
fs::copy(&wasm_file, dest_dir.join("output.wasm")).expect("Failed to copy WASM file");
println!("xxfunc build completed successfully");
Ok(())
}
pub fn deploy(url: &str, wasm_file_path: &str) -> eyre::Result<()> {
let form =
multipart::Form::new().file("module", wasm_file_path).expect("Failed to create form file");
let client = reqwest::blocking::Client::new();
let response = client
.post(&format!("{}/deploy", url))
.multipart(form)
.send()
.expect("Failed to send deploy request");
if response.status().is_success() {
println!("xxfunc deploy completed successfully");
println!("Response: {}", response.text()?);
Ok(())
} else {
println!("Failed with status: {}", response.status());
Err(eyre::eyre!("xxfunc deploy failed"))
}
}
pub fn start(url: &str, module_name: &str) -> eyre::Result<()> {
let client = reqwest::blocking::Client::new();
let response = client
.post(&format!("{}/start", url))
.json(&json!({
"module": module_name
}))
.send()
.expect("Failed to send start request");
if response.status().is_success() {
println!("xxfunc start completed successfully");
Ok(())
} else {
println!("Failed with status: {}", response.status());
Err(eyre::eyre!("xxfunc start failed"))
}
}
pub fn stop(url: &str, module_name: &str) -> eyre::Result<()> {
let client = reqwest::blocking::Client::new();
let response = client
.post(&format!("{}/stop", url))
.json(&json!({
"module": module_name
}))
.send()
.expect("Failed to send stop request");
if response.status().is_success() {
println!("xxfunc stop completed successfully");
Ok(())
} else {
println!("Failed with status: {}", response.status());
Err(eyre::eyre!("xxfunc stop failed"))
}
}
// Helper function to get the project name from Cargo.toml
fn get_project_name() -> eyre::Result<String> {
let cargo_toml: Value = toml::from_str(&fs::read_to_string("Cargo.toml")?)?;
let name = cargo_toml
.get("package")
.and_then(|p| p.as_table())
.ok_or_else(|| eyre!("Invalid or missing [package] section in Cargo.toml"))?
.get("name")
.and_then(|n| n.as_str())
.ok_or_else(|| eyre!("Missing or invalid 'name' field in [package]"))?;
Ok(name.to_string())
}