beet_cli/commands/
run_build.rs

1use crate::prelude::*;
2use anyhow::Result;
3use beet::prelude::*;
4use clap::Parser;
5use std::path::PathBuf;
6
7/// Build the project
8#[derive(Debug, Clone, Parser)]
9pub struct RunBuild {
10	/// 🦀 the commands that will be used to build the binary 🦀
11	#[command(flatten)]
12	pub build_cmd: CargoBuildCmd,
13	#[command(flatten)]
14	pub build_args: BuildArgs,
15	#[command(flatten)]
16	pub build_template_map: BuildTemplateMap,
17	/// used by watch command only, inserts server step after native build
18	#[arg(long, default_value_t = false)]
19	pub server: bool,
20}
21
22// TODO probably integrate with RunBuild, and just nest
23#[derive(Debug, Clone, Parser)]
24pub struct BuildArgs {
25	/// Run a simple file server in this process instead of
26	/// spinning up the native binary with the --server feature
27	#[arg(long = "static")]
28	pub as_static: bool,
29	/// root for the emitted html files
30	#[arg(long, default_value = "target/client")]
31	pub html_dir: PathBuf,
32	/// Only execute the provided build steps,
33	/// options are `templates`, `native`, `server`, `static`, `wasm`
34	#[arg(long, value_delimiter = ',')]
35	pub only: Vec<String>,
36}
37
38impl RunBuild {
39	pub fn run(self) -> Result<()> { self.into_group()?.run() }
40
41	pub fn into_group(self) -> Result<BuildStepGroup> {
42		if self.build_args.only.is_empty() {
43			self.into_group_default()
44		} else {
45			self.into_group_custom()
46		}
47	}
48
49	fn into_group_custom(self) -> Result<BuildStepGroup> {
50		let mut group = BuildStepGroup::default();
51		let exe_path = self.build_cmd.exe_path();
52		let Self {
53			build_cmd,
54			build_args: watch_args,
55			build_template_map,
56			server: _,
57		} = self;
58		for arg in watch_args.only.iter() {
59			match arg.as_str() {
60				"templates" => group.add(build_template_map.clone()),
61				"native" => {
62					group.add(BuildNative::new(&build_cmd, &watch_args))
63				}
64				"server" => group.add(RunServer::new(&watch_args, &exe_path)),
65				"static" => {
66					group.add(ExportStatic::new(&watch_args, &exe_path))
67				}
68				"wasm" => group.add(BuildWasm::new(&build_cmd, &watch_args)?),
69				_ => anyhow::bail!("unknown build step: {}", arg),
70			};
71		}
72		Ok(group)
73	}
74	fn into_group_default(self) -> Result<BuildStepGroup> {
75		let Self {
76			build_cmd,
77			build_args: watch_args,
78			build_template_map,
79			server,
80		} = self;
81
82
83		let exe_path = build_cmd.exe_path();
84
85		let mut group = BuildStepGroup::default()
86			// 1. export the templates by statically viewing the files
87			// 		recompile depends on a templates file existing
88			// 		and build_templates doesnt depend on recompile so safe to do first
89			.with(build_template_map)
90			// 2. build the native binary
91			.with(BuildNative::new(&build_cmd, &watch_args))
92			// 3. export all static files from the app
93			//   	- html files
94			//   	- client island entries
95			.with(ExportStatic::new(&watch_args, &exe_path));
96		if server {
97			group.add(RunServer::new(&watch_args, &exe_path));
98		}
99		// 4. build the wasm binary
100		group.add(BuildWasm::new(&build_cmd, &watch_args)?);
101		Ok(group)
102	}
103}