Skip to content

Commit

Permalink
feat: support watch mode for build (#173)
Browse files Browse the repository at this point in the history
* feat: support watch mode for build

* internal: original_target_dir judge
  • Loading branch information
Young-Flash authored Aug 23, 2024
1 parent bae2661 commit 5e6a4cb
Show file tree
Hide file tree
Showing 5 changed files with 62 additions and 23 deletions.
21 changes: 17 additions & 4 deletions crates/moon/src/cli/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
use anyhow::Context;
use moonbuild::dry_run;
use moonbuild::entry;
use moonbuild::watch::watching;
use mooncake::pkg::sync::auto_sync;
use moonutil::common::lower_surface_targets;
use moonutil::common::FileLock;
Expand All @@ -43,6 +44,10 @@ pub struct BuildSubcommand {

#[clap(flatten)]
pub auto_sync_flags: AutoSyncFlags,

/// Monitor the file system and automatically build artifacts
#[clap(long, short)]
pub watch: bool,
}

pub fn run_build(cli: &UniversalFlags, cmd: &BuildSubcommand) -> anyhow::Result<i32> {
Expand Down Expand Up @@ -110,6 +115,7 @@ fn run_build_internal(
cli.quiet,
)?;

let original_target_dir = target_dir;
let mut moonc_opt = super::get_compiler_flags(source_dir, &cmd.build_flags)?;
moonc_opt.build_opt.deny_warn = cmd.build_flags.deny_warn;
let run_mode = RunMode::Build;
Expand Down Expand Up @@ -154,9 +160,16 @@ fn run_build_internal(
trace::open("trace.json").context("failed to open `trace.json`")?;
}

let result = entry::run_build(&moonc_opt, &moonbuild_opt, &module);
if trace_flag {
trace::close();
if cmd.watch {
let reg_cfg = RegistryConfig::load();
watching(
&moonc_opt,
&moonbuild_opt,
&reg_cfg,
&module,
original_target_dir,
)
} else {
entry::run_build(&moonc_opt, &moonbuild_opt, &module)
}
result
}
13 changes: 10 additions & 3 deletions crates/moon/src/cli/check.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@
// For inquiries, you can contact us via e-mail at jichuruanjian@idea.edu.cn.

use anyhow::Context;
use moonbuild::check;
use moonbuild::dry_run;
use moonbuild::watch::watching;
use moonbuild::watcher_is_running;
use moonbuild::{entry, MOON_PID_NAME};
use mooncake::pkg::sync::auto_sync;
Expand Down Expand Up @@ -63,7 +63,7 @@ pub fn run_check(cli: &UniversalFlags, cmd: &CheckSubcommand) -> anyhow::Result<
mut target_dir,
} = cli.source_tgt_dir.try_into_package_dirs()?;

// make a dedicated directory for the watch mode so that we don't block(MOON_LOCK) the normal no-watch mode
// make a dedicated directory for the watch mode so that we don't block(MOON_LOCK) the normal no-watch mode(automatically trigger by ide in background)
if cmd.watch {
target_dir = target_dir.join(WATCH_MODE_DIR);
std::fs::create_dir_all(&target_dir).context(format!(
Expand Down Expand Up @@ -132,6 +132,7 @@ fn run_check_internal(
cli.quiet,
)?;

let original_target_dir = target_dir;
let mut moonc_opt = get_compiler_flags(source_dir, &cmd.build_flags)?;
moonc_opt.build_opt.deny_warn = cmd.build_flags.deny_warn;
let run_mode = RunMode::Check;
Expand Down Expand Up @@ -180,7 +181,13 @@ fn run_check_internal(

if watch_mode {
let reg_cfg = RegistryConfig::load();
check::watch::watch_single_thread(&moonc_opt, &moonbuild_opt, &reg_cfg, &module)
watching(
&moonc_opt,
&moonbuild_opt,
&reg_cfg,
&module,
original_target_dir,
)
} else {
let pid_path = target_dir.join(MOON_PID_NAME);
let running = watcher_is_running(&pid_path);
Expand Down
1 change: 0 additions & 1 deletion crates/moonbuild/src/check/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,3 @@
// For inquiries, you can contact us via e-mail at jichuruanjian@idea.edu.cn.

pub mod normal;
pub mod watch;
1 change: 1 addition & 0 deletions crates/moonbuild/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ pub mod new;
pub mod runtest;
pub mod section_capture;
pub mod upgrade;
pub mod watch;

use sysinfo::{ProcessExt, System, SystemExt};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,19 +25,23 @@ use moonutil::mooncakes::RegistryConfig;
use notify::event::ModifyKind;
use notify::{Config, EventKind, RecommendedWatcher, RecursiveMode, Watcher};

use moonutil::common::{MoonbuildOpt, MooncOpt, MOON_MOD_JSON, MOON_PKG_JSON, WATCH_MODE_DIR};
use moonutil::common::{
MoonbuildOpt, MooncOpt, RunMode, MOON_MOD_JSON, MOON_PKG_JSON, WATCH_MODE_DIR,
};
use std::path::Path;
use std::sync::atomic::{AtomicBool, Ordering};
use std::sync::Arc;

pub fn watch_single_thread(
pub fn watching(
moonc_opt: &MooncOpt,
moonbuild_opt: &MoonbuildOpt,
registry_config: &RegistryConfig,
module: &ModuleDB,
original_target_dir: &Path,
) -> anyhow::Result<i32> {
let (source_dir, target_dir) = (&moonbuild_opt.source_dir, &moonbuild_opt.target_dir);

run_check_and_print(moonc_opt, moonbuild_opt, module);
run_and_print(moonc_opt, moonbuild_opt, module)?;

let (tx, rx) = std::sync::mpsc::channel();
let tx_for_exit = tx.clone();
Expand Down Expand Up @@ -68,18 +72,22 @@ pub fn watch_single_thread(
EventKind::Other if exit_flag.load(Ordering::SeqCst) => {
break;
}
// when a file was modified, multiple events may be received, we only care about those modified data
// when a file was modified, multiple events may be received, we only care about data those modified data
EventKind::Modify(ModifyKind::Data(_)) => {
let origin_target_dir = target_dir
.ancestors()
.find(|p| p.ends_with(WATCH_MODE_DIR))
.unwrap()
.parent()
.unwrap();
// check --watch will own a subdir named `watch` in target_dir but build --watch still use the original target_dir
let original_target_dir = match moonbuild_opt.run_mode {
RunMode::Check => target_dir
.ancestors()
.find(|p| p.ends_with(WATCH_MODE_DIR))
.unwrap()
.parent()
.unwrap(),
_ => original_target_dir,
};
if event.paths.iter().all(|p| {
p.starts_with(
// can't be `target_dir` since the real target dir for watch mode is `target_dir/watch`
origin_target_dir,
original_target_dir,
)
}) {
continue;
Expand Down Expand Up @@ -124,9 +132,9 @@ pub fn watch_single_thread(
continue;
}
};
run_check_and_print(moonc_opt, moonbuild_opt, &module);
run_and_print(moonc_opt, moonbuild_opt, &module)?;
} else {
run_check_and_print(moonc_opt, moonbuild_opt, module);
run_and_print(moonc_opt, moonbuild_opt, module)?;
}
}
_ => {
Expand All @@ -144,9 +152,19 @@ pub fn watch_single_thread(
Ok(0)
}

fn run_check_and_print(moonc_opt: &MooncOpt, moonbuild_opt: &MoonbuildOpt, module: &ModuleDB) {
fn run_and_print(
moonc_opt: &MooncOpt,
moonbuild_opt: &MoonbuildOpt,
module: &ModuleDB,
) -> anyhow::Result<()> {
print!("{esc}[2J{esc}[1;1H", esc = 27 as char);
let result = crate::entry::run_check(moonc_opt, moonbuild_opt, module);
let result = match moonbuild_opt.run_mode {
RunMode::Check => crate::entry::run_check(moonc_opt, moonbuild_opt, module),
RunMode::Build => crate::entry::run_build(moonc_opt, moonbuild_opt, module),
_ => {
anyhow::bail!("watch mode only support check and build");
}
};
match result {
Ok(0) => {
println!(
Expand All @@ -168,4 +186,5 @@ fn run_check_and_print(moonc_opt: &MooncOpt, moonbuild_opt: &MoonbuildOpt, modul
);
}
}
Ok(())
}

0 comments on commit 5e6a4cb

Please sign in to comment.