use super::*;
use std::path::Path;
use crate::server::{ViewerTarget, ViewerTargetCapacity};
pub(super) async fn options(State(state): State<ServerState>) -> Json<LaunchOptions> {
let snapshot = state.snapshot_rx.borrow();
Json(launch_options(&snapshot, &state.preferences_path))
}
pub(super) fn launch_options(snapshot: &ViewerSnapshot, preferences_path: &Path) -> LaunchOptions {
LaunchOptions {
revision: snapshot.revision,
profiles: snapshot
.profiles
.iter()
.map(|profile| LaunchProfile {
id: profile.id.clone(),
harness: profile.harness_kind.clone(),
})
.collect(),
targets: snapshot
.targets
.iter()
.map(|target| launch_target(target, &snapshot.capacity))
.collect(),
bundles: snapshot
.bundles
.iter()
.map(|bundle| LaunchBundle {
id: bundle.id.clone(),
primary_repository: bundle.primary_repository.clone(),
repositories: bundle
.repositories
.iter()
.map(|repository| LaunchRepository {
id: repository.id.clone(),
github: repository.github.clone(),
destination: repository.destination.clone(),
})
.collect(),
})
.collect(),
hosts: snapshot
.capacity
.iter()
.map(|host| LaunchHost {
id: host.id.clone(),
label: host.label.clone(),
targets: host.target_ids.clone(),
stale: host.stale,
refreshing: host.refreshing,
has_error: host.has_error,
})
.collect(),
default: saved_default(preferences_path),
}
}
fn launch_target(target: &ViewerTarget, hosts: &[ViewerTargetCapacity]) -> LaunchTarget {
let host = hosts
.iter()
.find(|host| host.target_ids.iter().any(|id| id == &target.id));
let availability = match host {
None => LaunchAvailability::Unknown,
Some(host) if host.has_error => LaunchAvailability::Unavailable,
Some(host) if host.stale => LaunchAvailability::Stale,
Some(_) => LaunchAvailability::Ready,
};
let unavailable_reason = match (availability, host) {
(LaunchAvailability::Unavailable, Some(host)) => Some(format!(
"the host \"{}\" did not answer its last check",
host.label
)),
_ => None,
};
LaunchTarget {
id: target.id.clone(),
kind: target.kind.clone(),
requires_project_directory: target.requires_project_directory,
availability,
unavailable_reason,
host: host.map(|host| host.label.clone()),
}
}
pub(super) fn saved_default(path: &Path) -> Option<LaunchDefault> {
match mj_core::go::GoPreferences::load(path) {
Ok(preferences) => preferences.default.map(|recipe| LaunchDefault {
profile_id: recipe.profile_id,
target_id: recipe.target_id,
}),
Err(error) => {
tracing::debug!(
%error,
path = %path.display(),
"could not read fast-start preferences for launch options"
);
None
}
}
}