beet_cli/commands/
run_build.rs1use crate::prelude::*;
2use beet::prelude::*;
3use clap::Parser;
4use std::path::PathBuf;
5use std::str::FromStr;
6use std::time::Duration;
7
8
9#[derive(Debug, Clone, Parser)]
11pub struct RunBuild {
12 #[command(flatten)]
14 pub(crate) build_cmd: CargoBuildCmd,
15 #[arg(long)]
17 pub(crate) beet_config: Option<PathBuf>,
18 #[arg(long = "static")]
21 pub(crate) r#static: bool,
22 #[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}