assemble_std/extensions/
project_extensions.rs1use 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
9pub trait ProjectExec: ProjectSealed {
11 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 fn exec<E>(&self, spec: E) -> ProjectResult<ExecHandle>
24 where
25 E: Into<ExecSpec>;
26
27 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}