rapid_cli/commands/
run.rs1use super::RapidCommand;
2use crate::{
3 cli::{current_directory, Config},
4 rapid_config::config::{find_rapid_config, is_rapid, AppType, RapidConfig},
5 tui::logo,
6};
7use clap::{arg, value_parser, ArgAction, ArgMatches, Command};
8use spinach::Spinach;
9use std::{path::PathBuf, process::Command as StdCommand, str::FromStr};
10use log::info;
11pub struct Run {}
12
13impl RapidCommand for Run {
14 fn cmd() -> clap::Command {
15 Command::new("run")
16 .about("A command for running various rapid applications")
17 .arg(
18 arg!(
19 -server --server "Runs a rapid server application"
20 )
21 .required(false)
22 .action(ArgAction::SetTrue)
23 .value_parser(value_parser!(PathBuf)),
24 )
25 .arg(
26 arg!(
27 -app --app "Runs a rapid fullstack application"
28 )
29 .required(false)
30 .action(ArgAction::SetTrue)
31 .value_parser(value_parser!(PathBuf)),
32 )
33 }
34
35 fn execute(_: &Config, args: &ArgMatches) -> Result<(), crate::cli::CliError<'static>> {
36 ctrlc::set_handler(move || {
38 std::process::exit(0);
39 })
40 .expect("Error: Could not stop process");
41
42 println!("{}", logo());
43 parse_run_args(args).unwrap();
44 Ok(())
46 }
47}
48
49pub fn get_server_port(config: &RapidConfig, fallback_port: u16) -> u16 {
50 let app_type = &config.app_type;
51
52 match app_type.as_str() {
53 "server" => match &config.server {
54 Some(val) => match val.port {
55 Some(p) => p,
56 None => fallback_port,
57 },
58 _ => fallback_port,
59 },
60 "remix" => match &config.remix {
61 Some(val) => match val.server_port {
62 Some(s_port) => s_port,
63 None => fallback_port,
64 },
65 _ => fallback_port,
66 },
67 _ => fallback_port,
68 }
69}
70
71fn parse_run_args(args: &ArgMatches) -> Result<(), ()> {
72 let rapid_config = find_rapid_config();
74
75 let server_port = get_server_port(&rapid_config, 8080);
76
77 if !is_rapid() {
79 eprintln!("Could not find a valid config file in the current working directory. Please make sure you are in a official rapid project before running this command.");
80 std::process::exit(64);
82 }
83 const RUN_ARGS: [&str; 3] = ["server", "remix", "app"];
85
86 for arg in RUN_ARGS {
87 match args.get_one::<PathBuf>(arg) {
88 Some(val) => {
89 if val == &PathBuf::from("true") {
90 match arg {
91 "server" => {
92 handle_run_server(server_port, rapid_config.app_type);
93 return Ok(());
94 }
95 "remix" => {
96 handle_run_server(server_port, rapid_config.app_type);
97 return Ok(());
98 }
99 "app" => {
100 println!("Coming soon!");
101 return Ok(());
102 }
103 _ => {
105 println!("{} {}", "No application found for the type: ", arg);
106 return Ok(());
107 }
108 }
109 }
110 }
111 None => break,
112 }
113 }
114
115 let application_type = AppType::from_str(&rapid_config.app_type).expect("Error: invalid rapid application type!");
117
118 match application_type {
119 AppType::Nextjs => {
120 handle_run_server(server_port, rapid_config.app_type);
121 return Ok(());
122 }
123 AppType::Server => {
124 handle_run_server(server_port, rapid_config.app_type);
125 return Ok(());
126 }
127 AppType::Remix => {
128 handle_run_server(server_port, rapid_config.app_type);
129 return Ok(());
130 }
131 }
132}
133
134fn handle_run_server(server_port: u16, app_type: String) {
135 let install_list = StdCommand::new("sh")
138 .arg("-c")
139 .arg("cargo install --list")
140 .output()
141 .expect("Could not complete pre-run checks.");
142
143 let mut hot_reload_command = format!(
149 "systemfd --no-pid --quiet -s http::{} -- cargo watch -x run -q --ignore 'bindings.ts'",
150 server_port
151 );
152
153 if app_type == String::from("remix") {
155 hot_reload_command = String::from("systemfd --no-pid --quiet -s http::8080 -- cargo watch -x run -w app/api -q --ignore 'bindings.ts'");
156 }
157
158 if !std::str::from_utf8(&install_list.stdout).unwrap().contains("cargo-watch")
160 || !std::str::from_utf8(&install_list.stdout).unwrap().contains("systemfd")
161 {
162 let s = Spinach::new("Installing build scripts...");
163 StdCommand::new("sh")
165 .arg("-c")
166 .arg("cargo install cargo-watch")
167 .output()
168 .expect("Could not install rapid dev server binaries. Please try again.");
169
170 StdCommand::new("sh")
171 .arg("-c")
172 .arg("cargo install systemfd")
173 .output()
174 .expect("Could not install rapid dev server binaries. Please try again.");
175
176 s.succeed("Rapid build scripts installed!");
177 }
178
179 info!("building rapid application...");
180
181 StdCommand::new("sh")
183 .current_dir(current_directory())
184 .arg("-c")
185 .arg(hot_reload_command)
186 .spawn()
187 .unwrap()
188 .wait()
189 .expect("Error: Could not run development server. Please try again!");
190}