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)]
13pub struct CheckOptions {
14 #[arg(long, default_value_t = 3000)]
17 port: u16,
18}
19#[derive(Debug)]
21pub enum OsedaCheckError {
22 MissingConfig(String),
23 BadConfig(String),
24 BadGitCredentials(String),
25 DirectoryNameMismatch(String),
26 CouldNotPingLocalPresentation(String),
27 MissingDescription(String),
28}
29
30impl std::error::Error for OsedaCheckError {}
31
32impl std::fmt::Display for OsedaCheckError {
34 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
35 match self {
36 Self::MissingConfig(msg) => write!(f, "Missing config file {}", msg),
37 Self::BadConfig(msg) => write!(f, "Bad config file {}", msg),
38 Self::BadGitCredentials(msg) => write!(f, "Missing git credentials {}", msg),
39 Self::DirectoryNameMismatch(msg) => {
40 write!(f, "Project name does not match directory {}", msg)
41 }
42 Self::CouldNotPingLocalPresentation(msg) => {
43 write!(f, "Could not ping localhost after project was ran {}", msg)
44 }
45 Self::MissingDescription(msg) => {
46 write!(f, "Config file is missing description {}", msg)
47 }
48 }
49 }
50}
51
52pub fn check(opts: CheckOptions) -> Result<(), OsedaCheckError> {
61 match verify_project(opts.port) {
64 OsedaProjectStatus::DeployReady => Ok(()),
65 OsedaProjectStatus::NotDeploymentReady(err) => Err(err),
66 }
67}
68
69pub enum OsedaProjectStatus {
71 DeployReady,
72 NotDeploymentReady(OsedaCheckError),
73}
74
75fn verify_project(port_num: u16) -> OsedaProjectStatus {
85 let _conf = match config::read_and_validate_config() {
88 Ok(conf) => conf,
89 Err(err) => return OsedaProjectStatus::NotDeploymentReady(err),
90 };
91
92 let _run_handle = std::thread::spawn(run::run);
93
94 std::thread::sleep(Duration::from_millis(10000));
95
96 let addr = format!("http://localhost:{}", port_num);
97 let status = match net::get_status(&addr) {
98 Ok(status) => status,
99 Err(_) => {
100 return OsedaProjectStatus::NotDeploymentReady(
101 OsedaCheckError::CouldNotPingLocalPresentation(
102 "Could not ping presentation".to_owned(),
103 ),
104 );
105 }
106 };
107
108 if status != StatusCode::OK {
109 return OsedaProjectStatus::NotDeploymentReady(
110 OsedaCheckError::CouldNotPingLocalPresentation(
111 "Presentation returned non 200 error status code".to_owned(),
112 ),
113 );
114 }
115
116 println!("Project returned status code {:?}", status);
117
118 if kill_port(port_num).is_err() {
126 println!("Warning: could not kill process on port, project could still be running");
127 } else {
128 println!("Project process sucessfully terminated");
129 }
130
131 OsedaProjectStatus::DeployReady
132}