resolver_cli/utils/
helpers.rs

1use std::fs;
2use std::io::Error as OutputError;
3use std::process::{Command, Output};
4use std::error::Error;
5
6// -------------------
7// Checker functions
8// -------------------
9pub fn is_node_installed() -> bool {
10    let output = Command::new("node")
11        .arg("--version")
12        .output();
13
14    check_output(output)
15}
16
17pub fn is_npm_installed() -> bool {
18    let output = Command::new("npm")
19        .arg("--version")
20        .output();
21
22    check_output(output)
23}
24
25pub fn is_nestjs_installed() -> bool {
26    let output = Command::new("nest")
27        .arg("--version")
28        .output();
29
30    check_output(output)
31}
32
33pub fn is_php_installed() -> bool {
34    let output = Command::new("php")
35        .arg("--version")
36        .output();
37
38    check_output(output)
39}
40
41pub fn is_composer_installed() -> bool {
42    let output = Command::new("composer")
43        .arg("--version")
44        .output();
45
46    check_output(output)
47}
48
49pub fn is_scarb_installed() -> bool {
50    let output = Command::new("scarb")
51        .arg("--version")
52        .output();
53
54    check_output(output)
55}
56
57pub fn is_forge_installed() -> bool {
58    let output = Command::new("forge")
59        .arg("--version")
60        .output();
61
62    check_output(output)
63}
64
65pub fn is_python_installed() -> bool {
66    //TODO: Check for python3 for macos
67    let output = Command::new("python3")
68        .arg("--version")
69        .output();
70
71    check_output(output)
72}
73
74pub fn is_pip_installed() -> bool {
75    let output = Command::new("pip3")
76        .arg("--version")
77        .output();
78
79    check_output(output)
80}
81
82pub fn is_starkli_installed() -> bool {
83    let output = Command::new("starkli")
84        .arg("--version")
85        .output();
86
87    check_output(output)
88}
89
90pub fn is_brew_installed() -> bool {
91    let output = Command::new("brew")
92        .arg("--version")
93        .output();
94
95    check_output(output)
96}
97
98pub fn is_choco_installed() -> bool {
99    let output = Command::new("choco")
100        .arg("--version")
101        .output();
102
103    check_output(output)
104}
105
106pub fn is_nargo_installed() -> bool {
107    let output = Command::new("noirup")
108        .arg("--version")
109        .output();
110
111    check_output(output)
112}
113
114pub fn get_os() -> String {
115    let os_family = std::env::consts::OS;
116
117    os_family.to_string()
118}
119
120fn check_output(output: Result<Output, OutputError>) -> bool {
121    match output {
122        Ok(output) => {
123            if output.status.success() {
124                true
125            } else {
126                false
127            }
128        },
129        _ => false
130    }
131}
132
133
134// -------------------
135// Scaffold functions
136// -------------------
137pub fn create_react_app(project_name: String) -> Result<(), Box<dyn Error>> {
138    if !is_npm_installed() {
139        return  Err("You don't have npm installed".into());
140    } else {
141        Command::new("npx")
142            .args(["create-react-app", project_name.as_str()])
143            .spawn()?
144            .wait()?;
145
146        Ok(())
147    }
148}
149
150pub fn create_react_app_with_typescript(project_name: String) -> Result<(), Box<dyn Error>> {
151    if !is_npm_installed() {
152        return  Err("You don't have npm installed".into());
153    } else {
154        Command::new("npx")
155            .args(["create-react-app", project_name.as_str(), "--template", "typescript"])
156            .spawn()?
157            .wait()?;
158
159        Ok(())
160    }
161}
162
163pub fn create_hardhat_project(project_name: String) -> Result<(), Box<dyn Error>> {
164    if !is_npm_installed() {
165        return  Err("You don't have npm installed".into());
166    } else {
167        fs::create_dir_all(project_name.as_str())?;
168
169        Command::new("npm")
170            .args(["init", "--yes"])
171            .current_dir(project_name.as_str())
172            .spawn()?
173            .wait()?;
174
175        Command::new("npx")
176            .args(["hardhat", "init"])
177            .current_dir(project_name.as_str())
178            .spawn()?
179            .wait()?;
180
181        Ok(())
182    }
183}
184
185pub fn create_nestjs_app(project_name: String) -> Result<(), Box<dyn Error>> {
186    if !is_nestjs_installed() {
187        if !is_npm_installed() {
188            return  Err("You don't have npm installed".into());
189        }
190
191        Command::new("npm")
192            .args(["i", "-g", "@nestjs/cli"])
193            .spawn()?
194            .wait()?;
195    }
196
197    Command::new("nest")
198        .args(["new", project_name.as_str()])
199        .spawn()?
200        .wait()?;
201
202    Ok(())
203}
204
205pub fn create_laravel_project(project_name: String) -> Result<(), Box<dyn Error>> {
206    if !is_php_installed() && !is_composer_installed() {
207        return  Err("You don't have PHP or Composer installed".into());
208    } else {
209        println!("Creating Laravel project: {}", project_name);
210
211        Command::new("composer")
212            .args(["create-project", "laravel/laravel", project_name.as_str()])
213            .spawn()?
214            .wait()?;
215
216        Ok(())
217    }
218}
219
220pub fn create_next_app(project_name: String) -> Result<(), Box<dyn Error>> {
221    if !is_npm_installed() {
222        return  Err("You don't have npm installed".into());
223    } else {
224        Command::new("npx")
225            .args(["create-next-app@latest", project_name.as_str()])
226            .spawn()?
227            .wait()?;
228
229        Ok(())
230    }
231}
232
233pub fn create_new_foundry_project(project_name: String) -> Result<(), Box<dyn Error>> {
234    if !is_forge_installed() {
235        return  Err("You don't have Forge installed".into());
236    } else {
237        Command::new("forge")
238            .args(["init", project_name.as_str()])
239            .spawn()?
240            .wait()?;
241
242        Ok(())
243    }
244}
245
246pub fn create_django_project(project_name: String) -> Result<(), Box<dyn Error>> {
247    if !is_python_installed() && !is_pip_installed() {
248        return  Err("You don't have Python installed".into());
249    } else {
250        Command::new("django-admin")
251            .args(["startproject", project_name.as_str()])
252            .spawn()?
253            .wait()?;
254
255        Ok(())
256    }
257}
258
259pub fn create_vue_project(project_name: String) -> Result<(), Box<dyn Error>> {
260    if !is_npm_installed() {
261        return  Err("You don't have npm installed".into());
262    } else {
263        Command::new("npm")
264            .args(["create", "vue@latest", project_name.as_str()])
265            .spawn()?
266            .wait()?;
267
268        Ok(())
269    }
270}
271
272pub fn create_vite_project(project_name: String) -> Result<(), Box<dyn Error>> {
273    if !is_npm_installed() {
274        return  Err("You don't have npm installed".into());
275    } else {
276        Command::new("npm")
277            .args(["create", "vite@latest", project_name.as_str()])
278            .spawn()?
279            .wait()?;
280
281        Ok(())
282    }
283}
284
285pub fn create_noir_project(project_name: String) -> Result<(), Box<dyn Error>> {
286    if !is_nargo_installed() {
287        return  Err("You don't have nargo installed".into());
288    } else {
289        Command::new("nargo")
290            .args(["new", project_name.as_str()])
291            .spawn()?
292            .wait()?;
293
294        Ok(())
295    }
296}
297
298pub fn create_starknet_foundry_project(project_name: String) -> Result<(), Box<dyn Error>> {
299    if !is_forge_installed() {
300        return  Err("You don't have Forge installed".into());
301    } else {
302        Command::new("snforge")
303            .args(["init", project_name.as_str()])
304            .spawn()?
305            .wait()?;
306
307        Ok(())
308    }
309}
310
311// -------------------
312// Installer functions
313// -------------------
314
315pub fn install_brew() -> Result<(), Box<dyn Error>> {
316    println!("Installing Homebrew...");
317
318    let script_url = "https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh";
319    let command = format!("curl -fsSL {} | /bin/bash", script_url);
320
321    Command::new("sh")
322        .arg("-c")
323        .arg(command)
324        .output()?;
325
326    Ok(())
327}
328
329pub fn install_choco() -> Result<(), Box<dyn Error>> {
330    println!("Installing Chocolatey...");
331
332    let powershell_script = r#"
333        Set-ExecutionPolicy Bypass -Scope Process -Force;
334        [System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072;
335        iex ((New-Object System.Net.WebClient).DownloadString('https://chocolatey.org/install.ps1'))
336    "#;
337
338    Command::new("powershell")
339        .arg("-Command")
340        .arg(powershell_script)
341        .output()?;
342
343    Ok(())
344}
345
346pub fn install_node() -> Result<(), Box<dyn Error>> {
347    println!("Installing the Latest Version of Node...");
348
349    // let os_family = std::env::consts::OS;
350    let os_family = get_os();
351
352    match os_family.as_str() {
353        "linux" => install_node_linux(),
354        "windows" => install_node_windows(),
355        "macos" => install_node_macos(),
356        _ => panic!("Unsupported OS")
357    }
358}
359
360pub fn install_node_linux() -> Result<(), Box<dyn Error>> {
361    println!("Installing Node.js on Linux...");
362
363    Command::new("sudo")
364        .arg("apt-get")
365        .args(["update"])
366        .status()?;
367
368    Command::new("sudo")
369        .arg("apt-get")
370        .args(["install", "-y", "nodejs"])
371        .status()?;
372
373    Ok(())
374}
375
376pub fn install_node_macos() -> Result<(), Box<dyn Error>> {
377    println!("Installing Node.js on macOS...");
378
379    if is_brew_installed() {
380        Command::new("brew")
381            .args(["install", "node"])
382            .status()?;
383    }
384
385    Ok(())
386}
387
388pub fn install_node_windows() -> Result<(), Box<dyn Error>> {
389    println!("Installing Node.js on Windows...");
390
391    if is_choco_installed() {
392        Command::new("choco")
393            .args(["install", "nodejs", "-y"])
394            .status()?;
395    }
396
397    Ok(())
398}
399
400pub fn install_scarb() -> Result<(), Box<dyn Error>> {
401    println!("Installing the Latest Version of Scarb...");
402
403    let install_cmd = "curl --proto '=https' --tlsv1.2 -sSf https://docs.swmansion.com/scarb/install.sh | sh";
404
405    Command::new("sh")
406        .arg("-c")
407        .arg(install_cmd)
408        .output()?;
409
410    Ok(())
411}
412
413pub fn install_starkli() -> Result<(), Box<dyn Error>> {
414    println!("Installing the Latest Version of Starkli...");
415
416    Command::new("sh")
417        .arg("-c")
418        .arg("curl https://get.starkli.sh | sh")
419        .output()?;
420
421    Command::new("sh")
422        .arg("-c")
423        .arg("starkliup")
424        .output()?;
425
426    Ok(())
427}
428
429pub fn install_composer() {}
430
431pub fn install_forge() -> Result<(), Box<dyn Error>> {
432    println!("Installing the Latest Version of Foundry...");
433
434    Command::new("sh")
435        .arg("-c")
436        .arg("curl -L https://foundry.paradigm.xyz | bash")
437        .output()?;
438
439    Command::new("sh")
440        .arg("-c")
441        .arg("foundryup")
442        .output()?;
443
444    Ok(())
445}
446
447
448pub fn install_nargo() -> Result<(), Box<dyn Error>> {
449    println!("Installing the Latest Version of Noir...");
450
451    Command::new("sh")
452        .arg("-c")
453        .arg("curl -L https://raw.githubusercontent.com/noir-lang/noirup/main/install | bash")
454        .output()?;
455
456    Command::new("sh")
457        .arg("-c")
458        .arg("noirup")
459        .output()?;
460
461    Ok(())
462}
463
464pub fn install_snforge(version: String) -> Result<(), Box<dyn Error>> {
465    if version.eq("latest") {
466        println!("Installing the Latest Version of Starknet Foundry, Please wait...");
467
468        Command::new("sh")
469            .arg("-c")
470            .arg("curl -L https://raw.githubusercontent.com/foundry-rs/starknet-foundry/master/scripts/install.sh | sh")
471            .output()?;
472
473        Command::new("sh")
474            .arg("-c")
475            .arg("snfoundryup")
476            .output()?;
477
478        Ok(())
479    } else {
480        println!("Installing Version {} of Starknet Foundry, Please wait...", version);
481
482        Command::new("sh")
483            .args(["-c", "curl -L https://raw.githubusercontent.com/foundry-rs/starknet-foundry/master/scripts/install.sh | sh"])
484            .output()?;
485
486        Command::new("sh")
487            .args(["-c", "snfoundryup", "-v", version.as_str()])
488            .output()?;
489
490        Ok(())
491    }
492
493}