beet_cli/commands/
build_steps.rs1use crate::prelude::*;
2use anyhow::Result;
3use beet::prelude::*;
4use std::os::unix::process::CommandExt;
5use std::path::Path;
6use std::path::PathBuf;
7use std::process::Command;
8use sweet::prelude::GracefulChild;
9
10pub struct BuildNative {
11 build_cmd: CargoBuildCmd,
12}
13
14impl BuildNative {
15 pub fn new(build_cmd: &CargoBuildCmd, watch_args: &BuildArgs) -> Self {
16 let mut build_cmd = build_cmd.clone();
17 if !watch_args.as_static {
18 build_cmd.cargo_args = Some("--features beet/server".to_string());
19 }
20 Self { build_cmd }
21 }
22}
23
24impl BuildStep for BuildNative {
25 fn run(&self) -> Result<()> {
26 println!("🌱 Compiling native binary");
27 self.build_cmd.run()?;
28 Ok(())
29 }
30}
31
32pub struct ExportStatic {
34 exe_path: PathBuf,
35 build_args: BuildArgs,
36}
37
38impl ExportStatic {
39 pub fn new(build_args: &BuildArgs, exe_path: &Path) -> Self {
40 Self {
41 build_args: build_args.clone(),
42 exe_path: exe_path.to_path_buf(),
43 }
44 }
45}
46
47impl BuildStep for ExportStatic {
48 fn run(&self) -> Result<()> {
52 println!(
53 "🌱 Running native binary to generate static files \nExecuting {}",
54 self.exe_path.display()
55 );
56 Command::new(&self.exe_path)
57 .arg("--html-dir")
58 .arg(&self.build_args.html_dir)
59 .arg("--static")
60 .status()?
61 .exit_ok()?;
62 Ok(())
63 }
64}
65
66
67pub struct BuildWasm {
68 build_cmd: CargoBuildCmd,
69 exe_path: PathBuf,
70 build_args: BuildArgs,
71}
72
73impl BuildWasm {
74 pub fn new(
75 build_native: &CargoBuildCmd,
76 build_args: &BuildArgs,
77 ) -> Result<Self> {
78 let mut build_cmd = build_native.clone();
79 build_cmd.target = Some("wasm32-unknown-unknown".to_string());
80 let exe_path = build_cmd.exe_path();
81 let this = Self {
82 build_cmd,
83 exe_path,
84 build_args: build_args.clone(),
85 };
86 Ok(this)
87 }
88
89 fn wasm_bindgen(&self) -> Result<()> {
92 Command::new("wasm-bindgen")
93 .arg("--out-dir")
94 .arg(self.build_args.html_dir.join("wasm"))
95 .arg("--out-name")
96 .arg("bindgen")
97 .arg("--target")
98 .arg("web")
99 .arg("--no-typescript")
101 .arg(&self.exe_path)
102 .status()?
103 .exit_ok()?
104 .xok()
105 }
106
107 fn wasm_opt(&self) -> Result<()> {
109 println!("🌱 Optimizing wasm binary");
110 let out_file = self
111 .build_args
112 .html_dir
113 .join("wasm")
114 .join("bindgen_bg.wasm");
115
116 let size_before = std::fs::metadata(&out_file)?.len();
117
118 Command::new("wasm-opt")
119 .arg("-Oz")
120 .arg("--output")
121 .arg(&out_file)
122 .arg(&out_file)
123 .status()?
124 .exit_ok()?;
125
126 let size_after = std::fs::metadata(&out_file)?.len();
127 println!(
128 "🌱 Reduced wasm binary from {} to {}",
129 format!("{} KB", size_before as usize / 1024),
130 format!("{} KB", size_after as usize / 1024)
131 );
132
133 Ok(())
134 }
135}
136
137impl BuildStep for BuildWasm {
138 fn run(&self) -> Result<()> {
139 println!("🌱 Compiling wasm binary");
140 self.build_cmd.spawn()?;
141 self.wasm_bindgen()?;
142 if self.build_cmd.release {
143 self.wasm_opt()?;
144 }
145 Ok(())
146 }
147}
148
149
150pub struct RunServer {
151 exe_path: PathBuf,
152 build_args: BuildArgs,
153 child_process: GracefulChild,
154}
155
156impl RunServer {
157 pub fn new(build_args: &BuildArgs, exe_path: &Path) -> Self {
158 Self {
159 build_args: build_args.clone(),
160 exe_path: exe_path.to_path_buf(),
161 child_process: GracefulChild::default().as_only_ctrlc_handler(),
162 }
163 }
164}
165
166impl BuildStep for RunServer {
167 fn run(&self) -> Result<()> {
170 if self.build_args.as_static {
171 return Ok(());
172 }
173
174 self.child_process.kill();
175
176 let child = Command::new(&self.exe_path)
177 .arg("--html-dir")
178 .arg(&self.build_args.html_dir)
179 .process_group(0)
181 .spawn()?;
182 self.child_process.set(child);
183 Ok(())
184 }
185}