assemble_std/extensions/
project_extensions.rs

1//! Extensions to the [`Project`](assemble_core::Project)
2
3use crate::private::ProjectSealed;
4use crate::specs::exec_spec::{ExecHandle, ExecResult, ExecSpec, ExecSpecBuilder};
5use assemble_core::prelude::ProjectResult;
6use assemble_core::project::ProjectError;
7use assemble_core::Project;
8
9/// Adds [`ExecSpec`](crate::specs::exec_spec::ExecSpec) related methods to projects.
10pub trait ProjectExec: ProjectSealed {
11    /// Automatically executes a spec and logs output streams
12    fn exec_with<F>(&self, config: F) -> ProjectResult<ExecResult>
13    where
14        F: FnOnce(&mut ExecSpecBuilder),
15    {
16        let mut builder = self.builder();
17        config(&mut builder);
18        let build = builder.build().map_err(ProjectError::custom)?;
19        self.exec(build)?.wait()
20    }
21
22    /// Execute something that can be made into an [`ExecSpec`](ExecSpec)
23    fn exec<E>(&self, spec: E) -> ProjectResult<ExecHandle>
24    where
25        E: Into<ExecSpec>;
26
27    /// Create a new builder
28    fn builder(&self) -> ExecSpecBuilder {
29        ExecSpecBuilder::new()
30    }
31}
32
33impl ProjectExec for Project {
34    fn exec<E>(&self, spec: E) -> ProjectResult<ExecHandle>
35    where
36        E: Into<ExecSpec>,
37    {
38        let path = self.project_dir();
39        let exec = spec.into();
40        exec.execute_spec(path)
41            .map_err(|e| ProjectError::custom(e).into())
42    }
43}
44
45#[cfg(test)]
46mod test {
47    use crate::ProjectExec;
48    use assemble_core::logging::{LoggingArgs, OutputType};
49    use assemble_core::Project;
50    use log::LevelFilter;
51    use std::fs;
52
53    #[test]
54    fn hello_world() {
55        LoggingArgs::init_root_logger_with(LevelFilter::Trace, OutputType::Basic);
56        let project = Project::temp(None);
57        project.with(|p| fs::create_dir(p.project_dir())).unwrap();
58        let exit_status = project.with(|p| {
59            p.exec_with(|exec| {
60                exec.exec("echo").args(&["Hello", "World"]);
61            })
62        });
63        if let Err(e) = &exit_status {
64            println!("{}", e);
65            panic!("{}", e.kind())
66        }
67    }
68}