Skip to main content

forge_engine/exec/
host.rs

1use std::path::Path;
2
3use async_trait::async_trait;
4use check_runner::ExecutionBackend as RunnerExecutionBackend;
5
6use crate::config::ForgeConfig;
7use crate::error::ForgeResult;
8use crate::exec::backend::*;
9
10/// Check if an environment variable key is allowed to pass through.
11pub fn is_env_allowed(key: &str) -> bool {
12    check_runner::is_env_allowed(key)
13}
14
15/// HostBackend — runs commands via tokio::process::Command with kill_on_drop.
16pub struct HostBackend {
17    inner: check_runner::HostBackend,
18}
19
20impl HostBackend {
21    pub fn new(config: &ForgeConfig) -> Self {
22        Self {
23            inner: check_runner::HostBackend::new(&crate::exec::backend::runner_config(config)),
24        }
25    }
26}
27
28#[async_trait]
29impl ExecutionBackend for HostBackend {
30    fn kind(&self) -> ExecutionBackendKind {
31        self.inner.kind()
32    }
33
34    async fn prepare_workspace(&self, fixture: &Path) -> ForgeResult<Workspace> {
35        Ok(self.inner.prepare_workspace(fixture).await?)
36    }
37
38    async fn run_command(
39        &self,
40        workspace: &Path,
41        program: &str,
42        args: &[&str],
43        env: &[(&str, &str)],
44        timeout_secs: u64,
45    ) -> ForgeResult<CommandOutput> {
46        Ok(self
47            .inner
48            .run_command(workspace, program, args, env, timeout_secs)
49            .await?)
50    }
51
52    async fn collect_logs(
53        &self,
54        fmt: &CommandOutput,
55        clippy: &CommandOutput,
56        test: &CommandOutput,
57    ) -> ForgeResult<LogBundle> {
58        Ok(self.inner.collect_logs(fmt, clippy, test).await?)
59    }
60}
61
62/// Recursively copy a directory (public for container backend).
63pub fn copy_dir_recursive_pub(src: &Path, dst: &Path) -> ForgeResult<()> {
64    Ok(sandbox_workspace::copy_dir_recursive_pub(src, dst)?)
65}