use std::collections::HashSet;
use reqwest::Client;
use crate::{
LinkedProject,
client::post_graphql,
commands::{
Configs,
queries::{
self,
project::{
ProjectProject, ProjectProjectEnvironmentsEdgesNodeServiceInstancesEdgesNode,
ProjectProjectServicesEdgesNode,
},
},
},
errors::RailwayError,
};
use anyhow::{Result, bail};
use super::environment::get_matched_environment;
pub async fn get_project(
client: &Client,
configs: &Configs,
project_id: String,
) -> Result<queries::RailwayProject, RailwayError> {
let vars = queries::project::Variables { id: project_id };
let project = post_graphql::<queries::Project, _>(client, configs.get_backboard(), vars)
.await
.map_err(|e| {
if let RailwayError::GraphQLError(msg) = &e {
if msg.contains("Project not found") {
return RailwayError::ProjectNotFound;
}
}
e
})?
.project;
Ok(project)
}
pub fn get_service(
project: &ProjectProject,
service_name: String,
) -> Result<ProjectProjectServicesEdgesNode> {
let service = project
.services
.edges
.iter()
.find(|edge| edge.node.name.to_lowercase() == service_name.to_lowercase());
if let Some(service) = service {
return Ok(service.node.clone());
}
bail!(RailwayError::ServiceNotFound(service_name))
}
pub async fn ensure_project_and_environment_exist(
client: &Client,
configs: &Configs,
linked_project: &LinkedProject,
) -> Result<()> {
let project = get_project(client, configs, linked_project.project.clone()).await?;
if project.deleted_at.is_some() {
bail!(RailwayError::ProjectDeleted);
}
let environment = get_matched_environment(
&project,
linked_project
.environment_name
.clone()
.unwrap_or("Production".to_string()),
);
match environment {
Ok(environment) => {
if environment.deleted_at.is_some() {
bail!(RailwayError::EnvironmentDeleted);
}
}
Err(_) => bail!(RailwayError::EnvironmentDeleted),
};
Ok(())
}
pub fn get_service_ids_in_env(project: &ProjectProject, environment_id: &str) -> HashSet<String> {
project
.environments
.edges
.iter()
.find(|e| e.node.id == environment_id)
.map(|e| {
e.node
.service_instances
.edges
.iter()
.map(|si| si.node.service_id.clone())
.collect()
})
.unwrap_or_default()
}
pub fn find_service_instance<'a>(
project: &'a ProjectProject,
environment_id: &str,
service_id: &str,
) -> Option<&'a ProjectProjectEnvironmentsEdgesNodeServiceInstancesEdgesNode> {
project
.environments
.edges
.iter()
.find(|e| e.node.id == environment_id)
.and_then(|e| {
e.node
.service_instances
.edges
.iter()
.find(|si| si.node.service_id == service_id)
.map(|si| &si.node)
})
}