dinghy_lib/script/
device.rs

1use crate::config::ScriptDeviceConfiguration;
2use crate::utils::LogCommandExt;
3use crate::*;
4use anyhow::bail;
5use std::{fmt, fs, process};
6
7#[derive(Debug, Clone)]
8pub struct ScriptDevice {
9    pub id: String,
10    pub conf: ScriptDeviceConfiguration,
11}
12
13impl ScriptDevice {
14    fn command(&self, _build: &Build) -> Result<process::Command> {
15        if fs::metadata(&self.conf.path).is_err() {
16            bail!("Can not read {:?} for {}.", self.conf.path, self.id);
17        }
18        let mut cmd = process::Command::new(&self.conf.path);
19        cmd.env("DINGHY_TEST_DATA", &*self.id);
20        cmd.env("DINGHY_DEVICE", &*self.id);
21        if let Some(ref pf) = self.conf.platform {
22            cmd.env("DINGHY_PLATFORM", &*pf);
23        }
24        Ok(cmd)
25    }
26}
27
28impl Device for ScriptDevice {
29    fn clean_app(&self, _build_bundle: &BuildBundle) -> Result<()> {
30        Ok(())
31    }
32
33    fn debug_app(
34        &self,
35        _project: &Project,
36        _build: &Build,
37        _args: &[&str],
38        _envs: &[&str],
39    ) -> Result<BuildBundle> {
40        unimplemented!()
41    }
42
43    fn id(&self) -> &str {
44        &self.id
45    }
46
47    fn name(&self) -> &str {
48        &self.id
49    }
50
51    fn run_app(
52        &self,
53        project: &Project,
54        build: &Build,
55        args: &[&str],
56        envs: &[&str],
57    ) -> Result<BuildBundle> {
58        let root_dir = build.target_path.join("dinghy");
59        let bundle_path = &build.runnable.source;
60
61        log::trace!("About to start runner script...");
62        let test_data_path = project.link_test_data(&build.runnable)?;
63
64        let status = self
65            .command(build)?
66            .arg(&build.runnable.exe)
67            .current_dir(&build.runnable.source)
68            .env("DINGHY_TEST_DATA_PATH", test_data_path)
69            .args(args)
70            .envs(
71                envs.iter()
72                    .map(|kv| {
73                        Ok((
74                            kv.split("=")
75                                .nth(0)
76                                .ok_or_else(|| anyhow!("Wrong env spec"))?,
77                            kv.split("=")
78                                .nth(1)
79                                .ok_or_else(|| anyhow!("Wrong env spec"))?,
80                        ))
81                    })
82                    .collect::<Result<Vec<_>>>()?,
83            )
84            .log_invocation(1)
85            .status()?;
86        if !status.success() {
87            bail!("Test failed")
88        }
89
90        Ok(BuildBundle {
91            id: build.runnable.id.clone(),
92            bundle_dir: bundle_path.to_path_buf(),
93            bundle_exe: build.runnable.exe.to_path_buf(),
94            lib_dir: build.target_path.clone(),
95            root_dir: root_dir.clone(),
96            app_id: None,
97        })
98    }
99}
100
101impl DeviceCompatibility for ScriptDevice {
102    fn is_compatible_with_regular_platform(&self, platform: &RegularPlatform) -> bool {
103        self.conf
104            .platform
105            .as_ref()
106            .map_or(false, |it| *it == platform.id)
107    }
108}
109
110impl Display for ScriptDevice {
111    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
112        write!(fmt, "{}", self.id)
113    }
114}