pavex_cli_client/commands/
generate.rs1use std::{path::PathBuf, process::Command};
2
3use crate::commands::errors::{InvocationError, NonZeroExitCode, SignalTermination};
4use pavex::Blueprint;
5
6pub struct GenerateBuilder {
12 cmd: Command,
13 diagnostics_path: Option<PathBuf>,
14 blueprint: Blueprint,
15 output_directory: PathBuf,
16 check: bool,
17}
18
19impl GenerateBuilder {
20 pub(crate) fn new(cmd: Command, blueprint: Blueprint, output_directory: PathBuf) -> Self {
21 Self {
22 diagnostics_path: None,
23 blueprint,
24 cmd,
25 output_directory,
26 check: false,
27 }
28 }
29
30 pub fn execute(self) -> Result<(), GenerateError> {
37 let mut cmd = self
38 .command()
39 .map_err(GenerateError::BlueprintPersistenceError)?;
40 let cmd_debug = format!("{cmd:?}");
41 let status = cmd
42 .status()
43 .map_err(|e| InvocationError {
44 source: e,
45 command: cmd_debug.clone(),
46 })
47 .map_err(GenerateError::InvocationError)?;
48 if !status.success() {
49 if let Some(code) = status.code() {
50 return Err(GenerateError::NonZeroExitCode(NonZeroExitCode {
51 code,
52 command: cmd_debug,
53 }));
54 } else {
55 return Err(GenerateError::SignalTermination(SignalTermination {
56 command: cmd_debug,
57 }));
58 }
59 }
60 Ok(())
61 }
62
63 pub fn command(mut self) -> Result<Command, BlueprintPersistenceError> {
70 let bp_path = self.output_directory.join("blueprint.ron");
72 self.blueprint
73 .persist(&bp_path)
74 .map_err(|source| BlueprintPersistenceError { source })?;
75
76 self.cmd
77 .arg("generate")
78 .arg("-b")
79 .arg(bp_path)
80 .arg("-o")
81 .arg(self.output_directory)
82 .stdout(std::process::Stdio::inherit())
83 .stderr(std::process::Stdio::inherit());
84
85 if let Some(path) = self.diagnostics_path {
86 self.cmd.arg("--diagnostics").arg(path);
87 }
88 if self.check {
89 self.cmd.arg("--check");
90 }
91 Ok(self.cmd)
92 }
93
94 pub fn diagnostics_path(mut self, path: PathBuf) -> Self {
101 self.diagnostics_path = Some(path);
102 self
103 }
104
105 pub fn check(mut self) -> Self {
110 self.check = true;
111 self
112 }
113
114 pub fn no_check(mut self) -> Self {
118 self.check = false;
119 self
120 }
121}
122
123#[derive(Debug, thiserror::Error)]
124#[non_exhaustive]
125pub enum GenerateError {
126 #[error(transparent)]
127 InvocationError(InvocationError),
128 #[error(transparent)]
129 SignalTermination(SignalTermination),
130 #[error(transparent)]
131 NonZeroExitCode(NonZeroExitCode),
132 #[error(transparent)]
133 BlueprintPersistenceError(BlueprintPersistenceError),
134}
135
136#[derive(Debug, thiserror::Error)]
137#[error("Failed to persist the blueprint to a file")]
138pub struct BlueprintPersistenceError {
139 #[source]
140 source: anyhow::Error,
141}