dinghy-lib 0.8.4

Cross-compilation made easier - see main crate cargo-dinghy
Documentation
use crate::config::ScriptDeviceConfiguration;
use crate::utils::LogCommandExt;
use crate::*;
use anyhow::bail;
use std::{fmt, fs, process};

#[derive(Debug, Clone)]
pub struct ScriptDevice {
    pub id: String,
    pub conf: ScriptDeviceConfiguration,
}

impl ScriptDevice {
    fn command(&self, _build: &Build) -> Result<process::Command> {
        if fs::metadata(&self.conf.path).is_err() {
            bail!("Can not read {:?} for {}.", self.conf.path, self.id);
        }
        let mut cmd = process::Command::new(&self.conf.path);
        cmd.env("DINGHY_TEST_DATA", &*self.id);
        cmd.env("DINGHY_DEVICE", &*self.id);
        if let Some(ref pf) = self.conf.platform {
            cmd.env("DINGHY_PLATFORM", &*pf);
        }
        Ok(cmd)
    }
}

impl Device for ScriptDevice {
    fn clean_app(&self, _build_bundle: &BuildBundle) -> Result<()> {
        Ok(())
    }

    fn debug_app(
        &self,
        _project: &Project,
        _build: &Build,
        _args: &[&str],
        _envs: &[&str],
    ) -> Result<BuildBundle> {
        unimplemented!()
    }

    fn id(&self) -> &str {
        &self.id
    }

    fn name(&self) -> &str {
        &self.id
    }

    fn run_app(
        &self,
        project: &Project,
        build: &Build,
        args: &[&str],
        envs: &[&str],
    ) -> Result<BuildBundle> {
        let root_dir = build.target_path.join("dinghy");
        let bundle_path = &build.runnable.source;

        log::trace!("About to start runner script...");
        let test_data_path = project.link_test_data(&build.runnable)?;

        let status = self
            .command(build)?
            .arg(&build.runnable.exe)
            .current_dir(&build.runnable.source)
            .env("DINGHY_TEST_DATA_PATH", test_data_path)
            .args(args)
            .envs(
                envs.iter()
                    .map(|kv| {
                        Ok((
                            kv.split("=")
                                .nth(0)
                                .ok_or_else(|| anyhow!("Wrong env spec"))?,
                            kv.split("=")
                                .nth(1)
                                .ok_or_else(|| anyhow!("Wrong env spec"))?,
                        ))
                    })
                    .collect::<Result<Vec<_>>>()?,
            )
            .log_invocation(1)
            .status()?;
        if !status.success() {
            bail!("Test failed")
        }

        Ok(BuildBundle {
            id: build.runnable.id.clone(),
            bundle_dir: bundle_path.to_path_buf(),
            bundle_exe: build.runnable.exe.to_path_buf(),
            lib_dir: build.target_path.clone(),
            root_dir: root_dir.clone(),
            app_id: None,
        })
    }
}

impl DeviceCompatibility for ScriptDevice {
    fn is_compatible_with_regular_platform(&self, platform: &RegularPlatform) -> bool {
        self.conf
            .platform
            .as_ref()
            .map_or(false, |it| *it == platform.id)
    }
}

impl Display for ScriptDevice {
    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
        write!(fmt, "{}", self.id)
    }
}