beet_cli/commands/
run_build.rs

1use crate::prelude::*;
2use beet::prelude::*;
3use clap::Parser;
4use std::path::PathBuf;
5use std::str::FromStr;
6use std::time::Duration;
7
8
9/// Build the project
10#[derive(Debug, Clone, Parser)]
11pub struct RunBuild {
12	/// 🦀 the commands that will be used to build the binary 🦀
13	#[command(flatten)]
14	pub(crate) build_cmd: CargoBuildCmd,
15	/// Location of the beet.toml config file
16	#[arg(long)]
17	pub(crate) beet_config: Option<PathBuf>,
18	/// Run a simple file server in this process instead of
19	/// spinning up the native binary with the --server feature
20	#[arg(long = "static")]
21	pub(crate) r#static: bool,
22	/// Only execute the provided build steps,
23	/// options are "routes", "snippets", "client-islands", "compile-server", "export-ssg", "compile-wasm", "run-server"
24	#[arg(long, value_delimiter = ',', value_parser = parse_flags)]
25	pub(crate) only: Vec<BuildFlag>,
26}
27
28fn parse_flags(s: &str) -> Result<BuildFlag, String> { BuildFlag::from_str(s) }
29
30
31
32
33pub enum RunMode {
34	Once,
35	Watch,
36}
37
38
39impl RunBuild {
40	pub fn load_config(&self) -> Result<BuildConfig> {
41		BeetConfigFile::try_load_or_default::<BuildConfig>(
42			self.beet_config.as_deref(),
43		)
44		.map_err(|e| bevyhow!("Failed to load beet config: {}", e))
45		.map(|config| config)
46	}
47
48
49	pub fn load_binary_name(&self) -> Result<String> {
50		let config = self.load_config()?;
51		let manifest = config.load_manifest()?;
52		let package_name = manifest.package_name();
53		Ok(self.build_cmd.binary_name(package_name))
54	}
55
56	pub async fn run(self, run_mode: RunMode) -> Result {
57		let mut app = App::new();
58		let config = self.load_config().unwrap_or_exit();
59		let cwd = config.template_config.workspace.root_dir.into_abs();
60		let filter = config.template_config.workspace.filter.clone();
61
62		let build_flags = if self.only.is_empty() {
63			BuildFlags::All
64		} else {
65			BuildFlags::Only(self.only)
66		};
67
68		app.insert_resource(build_flags)
69			.insert_resource(self.build_cmd)
70			.add_non_send_plugin(config)
71			.add_plugins(BuildPlugin::default());
72
73		match run_mode {
74			RunMode::Once => app.run_once(),
75			RunMode::Watch => {
76				app.run_async(
77					FsApp {
78						watcher: FsWatcher {
79							cwd: cwd.0,
80							filter,
81							debounce: Duration::from_millis(100),
82						},
83					}
84					.runner(),
85				)
86				.await
87			}
88		}
89		.into_result()
90	}
91}