1use std::time::Duration;
2
3use clap::Args;
4use reqwest::StatusCode;
5
6use crate::cmd::run;
7use crate::config;
8
9use crate::net::{self, kill_port};
10
11#[derive(Args, Debug)]
12pub struct CheckOptions {
13 #[arg(long, default_value_t = false)]
14 skip_git: bool,
15 #[arg(long, default_value_t = 3000)]
16 port: u16,
17}
18
19#[derive(Debug)]
20pub enum OsedaCheckError {
21 MissingConfig(String),
22 BadConfig(String),
23 BadGitCredentials(String),
24 DirectoryNameMismatch(String),
25 CouldNotPingLocalPresentation(String),
26}
27
28impl std::error::Error for OsedaCheckError {}
29
30impl std::fmt::Display for OsedaCheckError {
31 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
32 match self {
33 Self::MissingConfig(msg) => write!(f, "Missing config file {}", msg),
34 Self::BadConfig(msg) => write!(f, "Bad config file {}", msg),
35 Self::BadGitCredentials(msg) => write!(f, "Missing git credentials {}", msg),
36 Self::DirectoryNameMismatch(msg) => {
37 write!(f, "Project name does not match directory {}", msg)
38 }
39 Self::CouldNotPingLocalPresentation(msg) => {
40 write!(f, "Could not ping localhost after project was ran {}", msg)
41 }
42 }
43 }
44}
45
46pub fn check(opts: CheckOptions) -> Result<(), OsedaCheckError> {
47 match verify_project(opts.skip_git, opts.port) {
50 OsedaProjectStatus::DeployReady => Ok(()),
51 OsedaProjectStatus::NotDeploymentReady(err) => Err(err),
52 }
53}
54
55pub enum OsedaProjectStatus {
56 DeployReady,
57 NotDeploymentReady(OsedaCheckError),
58}
59
60pub fn verify_project(skip_git: bool, port_num: u16) -> OsedaProjectStatus {
61 let _conf = match config::read_and_validate_config(skip_git) {
64 Ok(conf) => conf,
65 Err(err) => return OsedaProjectStatus::NotDeploymentReady(err),
66 };
67
68 let _run_handle = std::thread::spawn(run::run);
69
70 std::thread::sleep(Duration::from_millis(5000));
71
72 let addr = format!("http://localhost:{}", port_num);
73 let status = match net::get_status(&addr) {
74 Ok(status) => status,
75 Err(_) => {
76 return OsedaProjectStatus::NotDeploymentReady(
77 OsedaCheckError::CouldNotPingLocalPresentation(
78 "Could not ping presentation".to_owned(),
79 ),
80 );
81 }
82 };
83
84 if status != StatusCode::OK {
85 return OsedaProjectStatus::NotDeploymentReady(
86 OsedaCheckError::CouldNotPingLocalPresentation(
87 "Presentation returned non 200 error status code".to_owned(),
88 ),
89 );
90 }
91
92 println!("Project returned status code {:?}", status);
93
94 if kill_port(port_num).is_err() {
102 println!("Warning: could not kill process on port, project could still be running");
103 } else {
104 println!("Project process sucessfully terminated");
105 }
106
107 OsedaProjectStatus::DeployReady
108}