kea-lifecycle 0.1.0

buildpack lifecycle
Documentation
use std::path::PathBuf;

use crate::buildpack::{Version, args::BuildpackArgs, executable::ExecutablePath};

use super::{
    error::{LauncherError, Result},
    metadata::{Metadata, Process},
};

pub struct Launcher<'a> {
    pub metadata: &'a Metadata,
    pub args: &'a BuildpackArgs,
    pub default_process: Option<Process>,
    pub exec_params: ExecutablePath,
}

impl<'a> Launcher<'a> {
    pub fn from_executing_path(md: &'a Metadata, args: &'a BuildpackArgs) -> Result<Self> {
        let params = ExecutablePath::from_execuing_path().map_err(LauncherError::BuildpackError)?;
        for proc in &md.processes {
            todo!()
            // if proc.proc_type == params.executable_name() {
            //     return Self::from_process(Some(proc.clone()), md, args, params);
            // }
        }

        return Self::from_process(None, md, args, params);
    }

    pub fn from_process(
        process: Option<Process>,
        metadata: &'a Metadata,
        args: &'a BuildpackArgs,
        exec_params: ExecutablePath,
    ) -> Result<Self> {
        return Ok(Self {
            default_process: process,
            metadata,
            args,
            exec_params,
        });
    }

    pub fn create_launch_args(&self) -> Result<LaunchProcessArgs> {
        let proc = match &self.default_process {
            Some(proc) => proc,
            None => return self.creeate_launch_args_no_default_process(),
        };

        if self.args.platform_api < Version::new(0, 10) {
            let mut args = proc.args.clone();
            args.extend_from_slice(&self.exec_params.args);

            return Ok(LaunchProcessArgs {
                cmd: proc.command.entries[0].clone(),
                args,
                working_dir: proc.working_dir.clone(),
                direct: proc.direct,
            });
        }

        if proc.command.entries.len() > 1 {
            if self.exec_params.args.is_empty() {
                let mut args: Vec<String> = proc.command.entries.iter().skip(1).cloned().collect();
                args.extend_from_slice(&proc.args);

                return Ok(LaunchProcessArgs {
                    cmd: proc.command.entries[0].clone(),
                    args,
                    working_dir: proc.working_dir.clone(),
                    direct: proc.direct,
                });
            }
        }
        if self.exec_params.args.len() == 0 {
            return Ok(LaunchProcessArgs {
                cmd: proc.command.entries[0].clone(),
                args: proc.args.clone(),
                working_dir: proc.working_dir.clone(),
                direct: proc.direct,
            });
        }
        todo!()
    }

    fn creeate_launch_args_no_default_process(&self) -> Result<LaunchProcessArgs> {
        if self.exec_params.args.is_empty() {
            return Err(LauncherError::UserProvidedProcessNoArgs);
        }

        let mut args = self.exec_params.args.iter();
        if self.exec_params.args.len() > 1 && self.exec_params.args[0] == "--" {
            args.next(); // skip the --
        }

        Ok(LaunchProcessArgs {
            cmd: args.next().unwrap().clone(),
            args: args.map(String::from).collect(),
            ..Default::default()
        })
    }

    pub fn launch(&self) {}
}

#[derive(Debug, Default)]
pub struct LaunchProcessArgs {
    pub cmd: String,
    pub args: Vec<String>,
    pub working_dir: Option<PathBuf>,
    pub direct: bool,
}