use std::fmt;
use std::path::{Path, PathBuf};
use crate::durability::Durability;
use crate::pal::error::PalError;
use crate::pal::ids::{AppId, JobId, PtyId};
use crate::session_record::ProcessIdentity;
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
#[non_exhaustive]
pub(crate) enum ProcessLiveness {
Live,
Dead,
InspectFailed,
}
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub(crate) enum Breakaway {
Permitted,
#[cfg(feature = "private-test-util")]
Forbidden,
}
#[derive(Clone, Debug)]
pub(crate) struct SupervisorSpawn {
pub exe: PathBuf,
pub args: Vec<String>,
}
#[derive(Clone, Debug)]
pub(crate) struct AppSpawn {
pub command: Vec<String>,
pub launch_directory: PathBuf,
pub pty: PtyId,
pub job: JobId,
}
#[cfg_attr(test, mockall::automock)]
pub(crate) trait Processes: Send + Sync + fmt::Debug + 'static {
fn current_exe(&self) -> Result<PathBuf, PalError>;
fn spawn_supervisor(&self, request: &SupervisorSpawn) -> Result<ProcessIdentity, PalError>;
fn durability(&self) -> Durability;
fn probe(&self, identity: &ProcessIdentity) -> ProcessLiveness;
fn terminate(&self, identity: &ProcessIdentity) -> Result<(), PalError>;
fn create_lifetime_job(&self) -> Result<JobId, PalError>;
fn close_job(&self, job: JobId);
fn spawn_app(&self, request: &AppSpawn) -> Result<AppId, PalError>;
fn wait_app(&self, app: AppId) -> Result<i32, PalError>;
fn current_identity(&self) -> Result<ProcessIdentity, PalError>;
fn random_nonce(&self) -> String;
}
#[must_use]
pub(crate) fn resolve_command_path(command: &str, launch_directory: &Path) -> PathBuf {
let path = Path::new(command);
if path.is_absolute() {
path.to_path_buf()
} else if command.contains('/') || command.contains('\\') {
launch_directory.join(path)
} else {
path.to_path_buf()
}
}
#[cfg(test)]
#[cfg_attr(coverage_nightly, coverage(off))]
mod tests {
use super::*;
#[test]
fn resolve_command_path_joins_relative_with_separator() {
let dir = Path::new("/work");
assert_eq!(
resolve_command_path("bin/app.exe", dir),
PathBuf::from("/work/bin/app.exe")
);
assert_eq!(
resolve_command_path("app.exe", dir),
PathBuf::from("app.exe")
);
assert_eq!(
resolve_command_path("/abs/app.exe", dir),
PathBuf::from("/abs/app.exe")
);
}
}