From 61a4b50c01ad148212eab9fcb3fee7bf506273ea Mon Sep 17 00:00:00 2001
From: Paul Buschmann
Date: Sun, 15 Jun 2025 20:14:25 +0200
Subject: [PATCH 01/22] chore: force LF on windows
---
.gitattributes | 2 ++
1 file changed, 2 insertions(+)
diff --git a/.gitattributes b/.gitattributes
index 873ddfb587..666eddc88d 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -1,3 +1,5 @@
+* text=auto eol=lf
+
*.ml linguist-language=OCaml
*.mli linguist-language=OCaml
*.res linguist-language=ReScript
From 475f49dbe31177e99d9fedd433f7b44a56261a6e Mon Sep 17 00:00:00 2001
From: Paul Buschmann
Date: Sun, 15 Jun 2025 21:14:43 +0200
Subject: [PATCH 02/22] feat: upstream changes of rescript-lang/rewatch#162
---
rewatch/src/build.rs | 17 ++++
rewatch/src/build/clean.rs | 6 +-
rewatch/src/cli.rs | 178 +++++++++++++++++++++++++++++++++++
rewatch/src/helpers.rs | 35 +++++++
rewatch/src/lib.rs | 1 +
rewatch/src/main.rs | 187 ++++++++++++++-----------------------
rewatch/tests/compile.sh | 16 ++--
rewatch/tests/utils.sh | 4 +-
8 files changed, 315 insertions(+), 129 deletions(-)
create mode 100644 rewatch/src/cli.rs
diff --git a/rewatch/src/build.rs b/rewatch/src/build.rs
index c76120064e..ab00db8aad 100644
--- a/rewatch/src/build.rs
+++ b/rewatch/src/build.rs
@@ -18,10 +18,12 @@ use console::style;
use indicatif::{ProgressBar, ProgressStyle};
use log::log_enabled;
use serde::Serialize;
+use std::ffi::OsString;
use std::fmt;
use std::fs::File;
use std::io::{stdout, Write};
use std::path::{Path, PathBuf};
+use std::process::Stdio;
use std::time::{Duration, Instant};
use self::compile::compiler_args;
@@ -551,3 +553,18 @@ pub fn build(
}
}
}
+
+pub fn pass_through_legacy(args: Vec) -> i32 {
+ let project_root = helpers::get_abs_path(Path::new("."));
+ let workspace_root = helpers::get_workspace_root(&project_root);
+
+ let bsb_path = helpers::get_rescript_legacy(&project_root, workspace_root);
+
+ let status = std::process::Command::new(bsb_path)
+ .args(args)
+ .stdout(Stdio::inherit())
+ .stderr(Stdio::inherit())
+ .status();
+
+ status.map(|s| s.code().unwrap_or(1)).unwrap_or(1)
+}
diff --git a/rewatch/src/build/clean.rs b/rewatch/src/build/clean.rs
index 5624e6ac33..0057437997 100644
--- a/rewatch/src/build/clean.rs
+++ b/rewatch/src/build/clean.rs
@@ -335,7 +335,6 @@ pub fn clean(
path: &Path,
show_progress: bool,
bsc_path: &Option,
- build_dev_deps: bool,
snapshot_output: bool,
) -> Result<()> {
let project_root = helpers::get_abs_path(path);
@@ -345,8 +344,9 @@ pub fn clean(
&project_root,
&workspace_root,
show_progress,
- // Always clean dev dependencies
- build_dev_deps,
+ // Build the package tree with dev dependencies.
+ // They should always be cleaned if they are there.
+ true,
)?;
let root_config_name = packages::read_package_name(&project_root)?;
let bsc_path = match bsc_path {
diff --git a/rewatch/src/cli.rs b/rewatch/src/cli.rs
new file mode 100644
index 0000000000..87ec1efb09
--- /dev/null
+++ b/rewatch/src/cli.rs
@@ -0,0 +1,178 @@
+use std::ffi::OsString;
+
+use clap::{Args, Parser, Subcommand};
+use clap_verbosity_flag::InfoLevel;
+
+/// Rewatch is an alternative build system for the Rescript Compiler bsb (which uses Ninja internally). It strives
+/// to deliver consistent and faster builds in monorepo setups with multiple packages, where the
+/// default build system fails to pick up changed interfaces across multiple packages.
+#[derive(Parser, Debug)]
+#[command(version)]
+#[command(args_conflicts_with_subcommands = true)]
+pub struct Cli {
+ /// Verbosity:
+ /// -v -> Debug
+ /// -vv -> Trace
+ /// -q -> Warn
+ /// -qq -> Error
+ /// -qqq -> Off.
+ /// Default (/ no argument given): 'info'
+ #[command(flatten)]
+ pub verbose: clap_verbosity_flag::Verbosity,
+
+ /// The command to run. If not provided it will default to build.
+ #[command(subcommand)]
+ pub command: Option,
+
+ /// The relative path to where the main rescript.json resides. IE - the root of your project.
+ #[arg(default_value = ".")]
+ pub folder: String,
+
+ #[command(flatten)]
+ pub build_args: BuildArgs,
+}
+
+#[derive(Args, Debug, Clone)]
+pub struct BuildArgs {
+ /// Filter files by regex
+ ///
+ /// Filter allows for a regex to be supplied which will filter the files to be compiled. For
+ /// instance, to filter out test files for compilation while doing feature work.
+ #[arg(short, long)]
+ pub filter: Option,
+
+ /// Action after build
+ ///
+ /// This allows one to pass an additional command to the watcher, which allows it to run when
+ /// finished. For instance, to play a sound when done compiling, or to run a test suite.
+ /// NOTE - You may need to add '--color=always' to your subcommand in case you want to output
+ /// color as well
+ #[arg(short, long)]
+ pub after_build: Option,
+
+ /// Create source_dirs.json
+ ///
+ /// This creates a source_dirs.json file at the root of the monorepo, which is needed when you
+ /// want to use Reanalyze
+ #[arg(short, long, default_value_t = false, num_args = 0..=1)]
+ pub create_sourcedirs: bool,
+
+ /// Build development dependencies
+ ///
+ /// This is the flag to also compile development dependencies
+ /// It's important to know that we currently do not discern between project src, and
+ /// dependencies. So enabling this flag will enable building _all_ development dependencies of
+ /// _all_ packages
+ #[arg(long, default_value_t = false, num_args = 0..=1)]
+ pub dev: bool,
+
+ /// Disable timing on the output
+ #[arg(short, long, default_value_t = false, num_args = 0..=1)]
+ pub no_timing: bool,
+
+ /// simple output for snapshot testing
+ #[arg(short, long, default_value = "false", num_args = 0..=1)]
+ pub snapshot_output: bool,
+
+ /// Path to bsc
+ #[arg(long)]
+ pub bsc_path: Option,
+}
+
+#[derive(Args, Clone, Debug)]
+pub struct WatchArgs {
+ /// Filter files by regex
+ ///
+ /// Filter allows for a regex to be supplied which will filter the files to be compiled. For
+ /// instance, to filter out test files for compilation while doing feature work.
+ #[arg(short, long)]
+ pub filter: Option,
+
+ /// Action after build
+ ///
+ /// This allows one to pass an additional command to the watcher, which allows it to run when
+ /// finished. For instance, to play a sound when done compiling, or to run a test suite.
+ /// NOTE - You may need to add '--color=always' to your subcommand in case you want to output
+ /// color as well
+ #[arg(short, long)]
+ pub after_build: Option,
+
+ /// Create source_dirs.json
+ ///
+ /// This creates a source_dirs.json file at the root of the monorepo, which is needed when you
+ /// want to use Reanalyze
+ #[arg(short, long, default_value_t = false, num_args = 0..=1)]
+ pub create_sourcedirs: bool,
+
+ /// Build development dependencies
+ ///
+ /// This is the flag to also compile development dependencies
+ /// It's important to know that we currently do not discern between project src, and
+ /// dependencies. So enabling this flag will enable building _all_ development dependencies of
+ /// _all_ packages
+ #[arg(long, default_value_t = false, num_args = 0..=1)]
+ pub dev: bool,
+
+ /// simple output for snapshot testing
+ #[arg(short, long, default_value = "false", num_args = 0..=1)]
+ pub snapshot_output: bool,
+
+ /// Path to bsc
+ #[arg(long)]
+ pub bsc_path: Option,
+}
+
+#[derive(Subcommand, Clone, Debug)]
+pub enum Command {
+ /// Build using Rewatch
+ Build(BuildArgs),
+ /// Build, then start a watcher
+ Watch(WatchArgs),
+ /// Clean the build artifacts
+ Clean {
+ /// Path to bsc
+ #[arg(long)]
+ bsc_path: Option,
+
+ /// simple output for snapshot testing
+ #[arg(short, long, default_value = "false", num_args = 0..=1)]
+ snapshot_output: bool,
+ },
+ /// Alias to `legacy format`.
+ #[command(disable_help_flag = true)]
+ Format {
+ #[arg(allow_hyphen_values = true, num_args = 0..)]
+ format_args: Vec,
+ },
+ /// Alias to `legacy dump`.
+ #[command(disable_help_flag = true)]
+ Dump {
+ #[arg(allow_hyphen_values = true, num_args = 0..)]
+ dump_args: Vec,
+ },
+ /// This prints the compiler arguments. It expects the path to a rescript.json file.
+ CompilerArgs {
+ /// Path to a rescript.json file
+ #[command()]
+ path: String,
+
+ #[arg(long, default_value_t = false, num_args = 0..=1)]
+ dev: bool,
+
+ /// To be used in conjunction with compiler_args
+ #[arg(long)]
+ rescript_version: Option,
+
+ /// A custom path to bsc
+ #[arg(long)]
+ bsc_path: Option,
+ },
+ /// Use the legacy build system.
+ ///
+ /// After this command is encountered, the rest of the arguments are passed to the legacy build system.
+ #[command(disable_help_flag = true)]
+ Legacy {
+ #[arg(allow_hyphen_values = true, num_args = 0..)]
+ legacy_args: Vec,
+ },
+}
diff --git a/rewatch/src/helpers.rs b/rewatch/src/helpers.rs
index a91dee77f5..b05dc9b2ad 100644
--- a/rewatch/src/helpers.rs
+++ b/rewatch/src/helpers.rs
@@ -218,6 +218,41 @@ pub fn get_bsc(root_path: &Path, workspace_root: &Option) -> PathBuf {
}
}
+pub fn get_rescript_legacy(root_path: &Path, workspace_root: Option) -> PathBuf {
+ let subfolder = match (std::env::consts::OS, std::env::consts::ARCH) {
+ ("macos", "aarch64") => "darwin-arm64",
+ ("macos", _) => "darwin-x64",
+ ("linux", "aarch64") => "linux-arm64",
+ ("linux", _) => "linux-x64",
+ ("windows", "aarch64") => "win-arm64",
+ ("windows", _) => "win-x64",
+ _ => panic!("Unsupported architecture"),
+ };
+
+ let legacy_path_fragment = Path::new("node_modules")
+ .join("@rescript")
+ .join(subfolder)
+ .join("bin")
+ .join("rescript-legacy");
+
+ match (
+ root_path
+ .join(&legacy_path_fragment)
+ .canonicalize()
+ .map(StrippedVerbatimPath::to_stripped_verbatim_path),
+ workspace_root.map(|workspace_root| {
+ workspace_root
+ .join(&legacy_path_fragment)
+ .canonicalize()
+ .map(StrippedVerbatimPath::to_stripped_verbatim_path)
+ }),
+ ) {
+ (Ok(path), _) => path,
+ (_, Some(Ok(path))) => path,
+ _ => panic!("Could not find rescript-legacy"),
+ }
+}
+
pub fn string_ends_with_any(s: &Path, suffixes: &[&str]) -> bool {
suffixes
.iter()
diff --git a/rewatch/src/lib.rs b/rewatch/src/lib.rs
index 9dc6f5591c..2df92a48f3 100644
--- a/rewatch/src/lib.rs
+++ b/rewatch/src/lib.rs
@@ -1,4 +1,5 @@
pub mod build;
+pub mod cli;
pub mod cmd;
pub mod config;
pub mod helpers;
diff --git a/rewatch/src/main.rs b/rewatch/src/main.rs
index 5c27a4d02b..dcebec5945 100644
--- a/rewatch/src/main.rs
+++ b/rewatch/src/main.rs
@@ -1,93 +1,17 @@
use anyhow::Result;
-use clap::{Parser, ValueEnum};
-use clap_verbosity_flag::InfoLevel;
+use clap::Parser;
use log::LevelFilter;
use regex::Regex;
-use std::io::Write;
-use std::path::{Path, PathBuf};
+use std::{
+ io::Write,
+ path::{Path, PathBuf},
+};
-use rewatch::{build, cmd, lock, watcher};
-
-#[derive(Debug, Clone, ValueEnum)]
-enum Command {
- /// Build using Rewatch
- Build,
- /// Build, then start a watcher
- Watch,
- /// Clean the build artifacts
- Clean,
-}
-
-/// Rewatch is an alternative build system for the Rescript Compiler bsb (which uses Ninja internally). It strives
-/// to deliver consistent and faster builds in monorepo setups with multiple packages, where the
-/// default build system fails to pick up changed interfaces across multiple packages.
-#[derive(Parser, Debug)]
-#[command(version)]
-struct Args {
- #[arg(value_enum)]
- command: Option,
-
- /// The relative path to where the main rescript.json resides. IE - the root of your project.
- folder: Option,
-
- /// Filter allows for a regex to be supplied which will filter the files to be compiled. For
- /// instance, to filter out test files for compilation while doing feature work.
- #[arg(short, long)]
- filter: Option,
-
- /// This allows one to pass an additional command to the watcher, which allows it to run when
- /// finished. For instance, to play a sound when done compiling, or to run a test suite.
- /// NOTE - You may need to add '--color=always' to your subcommand in case you want to output
- /// colour as well
- #[arg(short, long)]
- after_build: Option,
-
- // Disable timing on the output
- #[arg(short, long, default_value = "false", num_args = 0..=1)]
- no_timing: bool,
-
- // simple output for snapshot testing
- #[arg(short, long, default_value = "false", num_args = 0..=1)]
- snapshot_output: bool,
-
- /// Verbosity:
- /// -v -> Debug
- /// -vv -> Trace
- /// -q -> Warn
- /// -qq -> Error
- /// -qqq -> Off.
- /// Default (/ no argument given): 'info'
- #[command(flatten)]
- verbose: clap_verbosity_flag::Verbosity,
-
- /// This creates a source_dirs.json file at the root of the monorepo, which is needed when you
- /// want to use Reanalyze
- #[arg(short, long, default_value_t = false, num_args = 0..=1)]
- create_sourcedirs: bool,
-
- /// This prints the compiler arguments. It expects the path to a rescript.json file.
- /// This also requires --bsc-path and --rescript-version to be present
- #[arg(long)]
- compiler_args: Option,
-
- /// This is the flag to also compile development dependencies
- /// It's important to know that we currently do not discern between project src, and
- /// dependencies. So enabling this flag will enable building _all_ development dependencies of
- /// _all_ packages
- #[arg(long, default_value_t = false, num_args = 0..=1)]
- dev: bool,
-
- /// To be used in conjunction with compiler_args
- #[arg(long)]
- rescript_version: Option,
-
- /// A custom path to bsc
- #[arg(long)]
- bsc_path: Option,
-}
+use rewatch::{build, cli, cmd, lock, watcher};
fn main() -> Result<()> {
- let args = Args::parse();
+ let args = cli::Cli::parse();
+
let log_level_filter = args.verbose.log_level_filter();
env_logger::Builder::new()
@@ -96,82 +20,113 @@ fn main() -> Result<()> {
.target(env_logger::fmt::Target::Stdout)
.init();
- let command = args.command.unwrap_or(Command::Build);
- let folder = args.folder.unwrap_or(".".to_string());
- let filter = args
- .filter
- .map(|filter| Regex::new(filter.as_ref()).expect("Could not parse regex"));
+ let command = args.command.unwrap_or(cli::Command::Build(args.build_args));
- match args.compiler_args {
- None => (),
- Some(path) => {
+ // handle those commands early, because we don't need a lock for them
+ match command.clone() {
+ cli::Command::Legacy { legacy_args } => {
+ let code = build::pass_through_legacy(legacy_args);
+ std::process::exit(code);
+ }
+ cli::Command::Format { mut format_args } => {
+ format_args.insert(0, "format".into());
+ let code = build::pass_through_legacy(format_args);
+ std::process::exit(code);
+ }
+ cli::Command::Dump { mut dump_args } => {
+ dump_args.insert(0, "dump".into());
+ let code = build::pass_through_legacy(dump_args);
+ std::process::exit(code);
+ }
+ cli::Command::CompilerArgs {
+ path,
+ dev,
+ rescript_version,
+ bsc_path,
+ } => {
println!(
"{}",
build::get_compiler_args(
Path::new(&path),
- args.rescript_version,
- &args.bsc_path.map(PathBuf::from),
- args.dev
+ rescript_version,
+ &bsc_path.map(PathBuf::from),
+ dev
)?
);
std::process::exit(0);
}
+ _ => (),
}
// The 'normal run' mode will show the 'pretty' formatted progress. But if we turn off the log
// level, we should never show that.
let show_progress = log_level_filter == LevelFilter::Info;
- match lock::get(&folder) {
+ match lock::get(&args.folder) {
lock::Lock::Error(ref e) => {
println!("Could not start Rewatch: {e}");
std::process::exit(1)
}
lock::Lock::Aquired(_) => match command {
- Command::Clean => build::clean::clean(
- Path::new(&folder),
+ cli::Command::Clean {
+ bsc_path,
+ snapshot_output,
+ } => build::clean::clean(
+ Path::new(&args.folder),
show_progress,
- &args.bsc_path.map(PathBuf::from),
- args.dev,
- args.snapshot_output,
+ &bsc_path.map(PathBuf::from),
+ snapshot_output,
),
- Command::Build => {
+ cli::Command::Build(build_args) => {
+ let filter = build_args
+ .filter
+ .map(|filter| Regex::new(filter.as_ref()).expect("Could not parse regex"));
+
match build::build(
&filter,
- Path::new(&folder),
+ Path::new(&args.folder),
show_progress,
- args.no_timing,
- args.create_sourcedirs,
- &args.bsc_path.map(PathBuf::from),
- args.dev,
- args.snapshot_output,
+ build_args.no_timing,
+ build_args.create_sourcedirs,
+ &build_args.bsc_path.map(PathBuf::from),
+ build_args.dev,
+ build_args.snapshot_output,
) {
Err(e) => {
println!("{e}");
std::process::exit(1)
}
Ok(_) => {
- if let Some(args_after_build) = args.after_build {
+ if let Some(args_after_build) = build_args.after_build {
cmd::run(args_after_build)
}
std::process::exit(0)
}
};
}
- Command::Watch => {
+ cli::Command::Watch(watch_args) => {
+ let filter = watch_args
+ .filter
+ .map(|filter| Regex::new(filter.as_ref()).expect("Could not parse regex"));
watcher::start(
&filter,
show_progress,
- &folder,
- args.after_build,
- args.create_sourcedirs,
- args.dev,
- args.bsc_path,
- args.snapshot_output,
+ &args.folder,
+ watch_args.after_build,
+ watch_args.create_sourcedirs,
+ watch_args.dev,
+ watch_args.bsc_path,
+ watch_args.snapshot_output,
);
Ok(())
}
+ cli::Command::CompilerArgs { .. }
+ | cli::Command::Legacy { .. }
+ | cli::Command::Format { .. }
+ | cli::Command::Dump { .. } => {
+ unreachable!("command already handled")
+ }
},
}
}
diff --git a/rewatch/tests/compile.sh b/rewatch/tests/compile.sh
index fd035bf902..9fc6ebb4bc 100755
--- a/rewatch/tests/compile.sh
+++ b/rewatch/tests/compile.sh
@@ -33,32 +33,32 @@ fi
node ./packages/main/src/Main.mjs > ./packages/main/src/output.txt
mv ./packages/main/src/Main.res ./packages/main/src/Main2.res
-rewatch build &> ../tests/snapshots/rename-file.txt
+rewatch build --no-timing --snapshot-output &> ../tests/snapshots/rename-file.txt
mv ./packages/main/src/Main2.res ./packages/main/src/Main.res
# Rename a file with a dependent - this should trigger an error
mv ./packages/main/src/InternalDep.res ./packages/main/src/InternalDep2.res
-rewatch build &> ../tests/snapshots/rename-file-internal-dep.txt
+rewatch build --no-timing --snapshot-output &> ../tests/snapshots/rename-file-internal-dep.txt
# normalize paths so the snapshot is the same on all machines
normalize_paths ../tests/snapshots/rename-file-internal-dep.txt
mv ./packages/main/src/InternalDep2.res ./packages/main/src/InternalDep.res
# Rename a file with a dependent in a namespaced package - this should trigger an error (regression)
mv ./packages/new-namespace/src/Other_module.res ./packages/new-namespace/src/Other_module2.res
-rewatch build &> ../tests/snapshots/rename-file-internal-dep-namespace.txt
+rewatch build --no-timing --snapshot-output &> ../tests/snapshots/rename-file-internal-dep-namespace.txt
# normalize paths so the snapshot is the same on all machines
normalize_paths ../tests/snapshots/rename-file-internal-dep-namespace.txt
mv ./packages/new-namespace/src/Other_module2.res ./packages/new-namespace/src/Other_module.res
rewatch build &> /dev/null
mv ./packages/main/src/ModuleWithInterface.resi ./packages/main/src/ModuleWithInterface2.resi
-rewatch build &> ../tests/snapshots/rename-interface-file.txt
+rewatch build --no-timing --snapshot-output &> ../tests/snapshots/rename-interface-file.txt
# normalize paths so the snapshot is the same on all machines
normalize_paths ../tests/snapshots/rename-interface-file.txt
mv ./packages/main/src/ModuleWithInterface2.resi ./packages/main/src/ModuleWithInterface.resi
rewatch build &> /dev/null
mv ./packages/main/src/ModuleWithInterface.res ./packages/main/src/ModuleWithInterface2.res
-rewatch build &> ../tests/snapshots/rename-file-with-interface.txt
+rewatch build --no-timing --snapshot-output &> ../tests/snapshots/rename-file-with-interface.txt
# normalize paths so the snapshot is the same on all machines
normalize_paths ../tests/snapshots/rename-file-with-interface.txt
mv ./packages/main/src/ModuleWithInterface2.res ./packages/main/src/ModuleWithInterface.res
@@ -66,7 +66,7 @@ rewatch build &> /dev/null
# when deleting a file that other files depend on, the compile should fail
rm packages/dep02/src/Dep02.res
-rewatch build &> ../tests/snapshots/remove-file.txt
+rewatch build --no-timing --snapshot-output &> ../tests/snapshots/remove-file.txt
# normalize paths so the snapshot is the same on all machines
normalize_paths ../tests/snapshots/remove-file.txt
git checkout -- packages/dep02/src/Dep02.res
@@ -74,7 +74,7 @@ rewatch build &> /dev/null
# it should show an error when we have a dependency cycle
echo 'Dep01.log()' >> packages/new-namespace/src/NS_alias.res
-rewatch build &> ../tests/snapshots/dependency-cycle.txt
+rewatch build --no-timing --snapshot-output &> ../tests/snapshots/dependency-cycle.txt
git checkout -- packages/new-namespace/src/NS_alias.res
# it should compile dev dependencies with the --dev flag
@@ -95,7 +95,7 @@ else
exit 1
fi
-rewatch clean --dev &> /dev/null
+rewatch clean &> /dev/null
file_count=$(find ./packages/with-dev-deps -name *.mjs | wc -l)
if [ "$file_count" -eq 0 ];
then
diff --git a/rewatch/tests/utils.sh b/rewatch/tests/utils.sh
index 1dffbe8a8d..bef51f9fce 100644
--- a/rewatch/tests/utils.sh
+++ b/rewatch/tests/utils.sh
@@ -3,8 +3,8 @@ overwrite() { echo -e "\r\033[1A\033[0K$@"; }
success() { echo -e "- ✅ \033[32m$1\033[0m"; }
error() { echo -e "- 🛑 \033[31m$1\033[0m"; }
bold() { echo -e "\033[1m$1\033[0m"; }
-rewatch() { RUST_BACKTRACE=1 $REWATCH_EXECUTABLE --no-timing=true --snapshot-output=true $@; }
-rewatch_bg() { RUST_BACKTRACE=1 nohup $REWATCH_EXECUTABLE --no-timing=true --snapshot-output=true $@; }
+rewatch() { RUST_BACKTRACE=1 $REWATCH_EXECUTABLE $@; }
+rewatch_bg() { RUST_BACKTRACE=1 nohup $REWATCH_EXECUTABLE $@; }
# Detect if running on Windows
is_windows() {
From 110ba77a28fa0a61677d4f2de5017af917705896 Mon Sep 17 00:00:00 2001
From: Bushuo
Date: Mon, 16 Jun 2025 21:47:10 +0200
Subject: [PATCH 03/22] test: update cli arg ordering
---
rewatch/tests/compile.sh | 14 +++++++-------
rewatch/tests/suite-ci.sh | 5 ++++-
rewatch/tests/utils.sh | 4 ++--
3 files changed, 13 insertions(+), 10 deletions(-)
diff --git a/rewatch/tests/compile.sh b/rewatch/tests/compile.sh
index 9fc6ebb4bc..f694b3b0bb 100755
--- a/rewatch/tests/compile.sh
+++ b/rewatch/tests/compile.sh
@@ -33,32 +33,32 @@ fi
node ./packages/main/src/Main.mjs > ./packages/main/src/output.txt
mv ./packages/main/src/Main.res ./packages/main/src/Main2.res
-rewatch build --no-timing --snapshot-output &> ../tests/snapshots/rename-file.txt
+rewatch build --snapshot-output &> ../tests/snapshots/rename-file.txt
mv ./packages/main/src/Main2.res ./packages/main/src/Main.res
# Rename a file with a dependent - this should trigger an error
mv ./packages/main/src/InternalDep.res ./packages/main/src/InternalDep2.res
-rewatch build --no-timing --snapshot-output &> ../tests/snapshots/rename-file-internal-dep.txt
+rewatch build --snapshot-output &> ../tests/snapshots/rename-file-internal-dep.txt
# normalize paths so the snapshot is the same on all machines
normalize_paths ../tests/snapshots/rename-file-internal-dep.txt
mv ./packages/main/src/InternalDep2.res ./packages/main/src/InternalDep.res
# Rename a file with a dependent in a namespaced package - this should trigger an error (regression)
mv ./packages/new-namespace/src/Other_module.res ./packages/new-namespace/src/Other_module2.res
-rewatch build --no-timing --snapshot-output &> ../tests/snapshots/rename-file-internal-dep-namespace.txt
+rewatch build --snapshot-output &> ../tests/snapshots/rename-file-internal-dep-namespace.txt
# normalize paths so the snapshot is the same on all machines
normalize_paths ../tests/snapshots/rename-file-internal-dep-namespace.txt
mv ./packages/new-namespace/src/Other_module2.res ./packages/new-namespace/src/Other_module.res
rewatch build &> /dev/null
mv ./packages/main/src/ModuleWithInterface.resi ./packages/main/src/ModuleWithInterface2.resi
-rewatch build --no-timing --snapshot-output &> ../tests/snapshots/rename-interface-file.txt
+rewatch build --snapshot-output &> ../tests/snapshots/rename-interface-file.txt
# normalize paths so the snapshot is the same on all machines
normalize_paths ../tests/snapshots/rename-interface-file.txt
mv ./packages/main/src/ModuleWithInterface2.resi ./packages/main/src/ModuleWithInterface.resi
rewatch build &> /dev/null
mv ./packages/main/src/ModuleWithInterface.res ./packages/main/src/ModuleWithInterface2.res
-rewatch build --no-timing --snapshot-output &> ../tests/snapshots/rename-file-with-interface.txt
+rewatch build --snapshot-output &> ../tests/snapshots/rename-file-with-interface.txt
# normalize paths so the snapshot is the same on all machines
normalize_paths ../tests/snapshots/rename-file-with-interface.txt
mv ./packages/main/src/ModuleWithInterface2.res ./packages/main/src/ModuleWithInterface.res
@@ -66,7 +66,7 @@ rewatch build &> /dev/null
# when deleting a file that other files depend on, the compile should fail
rm packages/dep02/src/Dep02.res
-rewatch build --no-timing --snapshot-output &> ../tests/snapshots/remove-file.txt
+rewatch build --snapshot-output &> ../tests/snapshots/remove-file.txt
# normalize paths so the snapshot is the same on all machines
normalize_paths ../tests/snapshots/remove-file.txt
git checkout -- packages/dep02/src/Dep02.res
@@ -74,7 +74,7 @@ rewatch build &> /dev/null
# it should show an error when we have a dependency cycle
echo 'Dep01.log()' >> packages/new-namespace/src/NS_alias.res
-rewatch build --no-timing --snapshot-output &> ../tests/snapshots/dependency-cycle.txt
+rewatch build --snapshot-output &> ../tests/snapshots/dependency-cycle.txt
git checkout -- packages/new-namespace/src/NS_alias.res
# it should compile dev dependencies with the --dev flag
diff --git a/rewatch/tests/suite-ci.sh b/rewatch/tests/suite-ci.sh
index d36319b988..9e5eefe1a8 100755
--- a/rewatch/tests/suite-ci.sh
+++ b/rewatch/tests/suite-ci.sh
@@ -8,10 +8,13 @@ cd $(dirname $0)
# Get rewatch executable location from the first argument or use default
if [ -n "$1" ]; then
REWATCH_EXECUTABLE="$1"
+ BSC_PATH=""
else
- REWATCH_EXECUTABLE="../target/release/rewatch --bsc-path ../../_build/install/default/bin/bsc"
+ REWATCH_EXECUTABLE="../target/release/rewatch"
+ BSC_PATH="--bsc-path ../../_build/install/default/bin/bsc"
fi
export REWATCH_EXECUTABLE
+export BSC_PATH
source ./utils.sh
diff --git a/rewatch/tests/utils.sh b/rewatch/tests/utils.sh
index bef51f9fce..44a22ba0e3 100644
--- a/rewatch/tests/utils.sh
+++ b/rewatch/tests/utils.sh
@@ -3,8 +3,8 @@ overwrite() { echo -e "\r\033[1A\033[0K$@"; }
success() { echo -e "- ✅ \033[32m$1\033[0m"; }
error() { echo -e "- 🛑 \033[31m$1\033[0m"; }
bold() { echo -e "\033[1m$1\033[0m"; }
-rewatch() { RUST_BACKTRACE=1 $REWATCH_EXECUTABLE $@; }
-rewatch_bg() { RUST_BACKTRACE=1 nohup $REWATCH_EXECUTABLE $@; }
+rewatch() { RUST_BACKTRACE=1 $REWATCH_EXECUTABLE $@ $BSC_PATH; }
+rewatch_bg() { RUST_BACKTRACE=1 nohup $REWATCH_EXECUTABLE $@ $BSC_PATH; }
# Detect if running on Windows
is_windows() {
From 9859117877e9ac4418db33ee9cbd28ab3272e139 Mon Sep 17 00:00:00 2001
From: Bushuo
Date: Wed, 18 Jun 2025 20:39:14 +0200
Subject: [PATCH 04/22] fix: look for rescript.exe not rescript-legacy
---
rewatch/src/helpers.rs | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/rewatch/src/helpers.rs b/rewatch/src/helpers.rs
index b05dc9b2ad..358c4c6ef1 100644
--- a/rewatch/src/helpers.rs
+++ b/rewatch/src/helpers.rs
@@ -233,7 +233,7 @@ pub fn get_rescript_legacy(root_path: &Path, workspace_root: Option) ->
.join("@rescript")
.join(subfolder)
.join("bin")
- .join("rescript-legacy");
+ .join("rescript.exe");
match (
root_path
From 46c8454987039499c979f0af3b962482ff04ea41 Mon Sep 17 00:00:00 2001
From: Bushuo
Date: Wed, 18 Jun 2025 23:55:36 +0200
Subject: [PATCH 05/22] test: add legacy test repo
---
.../packages/compiled-by-legacy/package.json | 9 +++++++++
.../packages/compiled-by-legacy/rescript.json | 12 ++++++++++++
.../packages/compiled-by-legacy/src/Main.res | 1 +
.../packages/compiled-by-legacy/src/Main.res.js | 9 +++++++++
4 files changed, 31 insertions(+)
create mode 100644 rewatch/testrepo/packages/compiled-by-legacy/package.json
create mode 100644 rewatch/testrepo/packages/compiled-by-legacy/rescript.json
create mode 100644 rewatch/testrepo/packages/compiled-by-legacy/src/Main.res
create mode 100644 rewatch/testrepo/packages/compiled-by-legacy/src/Main.res.js
diff --git a/rewatch/testrepo/packages/compiled-by-legacy/package.json b/rewatch/testrepo/packages/compiled-by-legacy/package.json
new file mode 100644
index 0000000000..34d940f905
--- /dev/null
+++ b/rewatch/testrepo/packages/compiled-by-legacy/package.json
@@ -0,0 +1,9 @@
+{
+ "name": "@testrepo/compiled-by-legacy",
+ "version": "0.0.1",
+ "keywords": [
+ "rescript"
+ ],
+ "author": "",
+ "license": "MIT"
+}
diff --git a/rewatch/testrepo/packages/compiled-by-legacy/rescript.json b/rewatch/testrepo/packages/compiled-by-legacy/rescript.json
new file mode 100644
index 0000000000..f94702ab3e
--- /dev/null
+++ b/rewatch/testrepo/packages/compiled-by-legacy/rescript.json
@@ -0,0 +1,12 @@
+{
+ "name": "@testrepo/compiled-by-legacy",
+ "sources": {
+ "dir": "src",
+ "subdirs": true
+ },
+ "package-specs": {
+ "module": "es6",
+ "in-source": true
+ },
+ "suffix": ".res.js"
+}
diff --git a/rewatch/testrepo/packages/compiled-by-legacy/src/Main.res b/rewatch/testrepo/packages/compiled-by-legacy/src/Main.res
new file mode 100644
index 0000000000..3b0c82647f
--- /dev/null
+++ b/rewatch/testrepo/packages/compiled-by-legacy/src/Main.res
@@ -0,0 +1 @@
+let x = 1
\ No newline at end of file
diff --git a/rewatch/testrepo/packages/compiled-by-legacy/src/Main.res.js b/rewatch/testrepo/packages/compiled-by-legacy/src/Main.res.js
new file mode 100644
index 0000000000..618d7a44e8
--- /dev/null
+++ b/rewatch/testrepo/packages/compiled-by-legacy/src/Main.res.js
@@ -0,0 +1,9 @@
+// Generated by ReScript, PLEASE EDIT WITH CARE
+
+
+let x = 1;
+
+export {
+ x,
+}
+/* No side effect */
From b4a1dbb4a8357f593a83588a12cbd854cad75fbc Mon Sep 17 00:00:00 2001
From: Bushuo
Date: Thu, 19 Jun 2025 00:10:37 +0200
Subject: [PATCH 06/22] test: add legacy build system compile tests
---
rewatch/tests/legacy-utils.sh | 3 +++
rewatch/tests/legacy.sh | 28 ++++++++++++++++++++++++++++
rewatch/tests/suffix.sh | 2 +-
rewatch/tests/suite-ci.sh | 2 +-
4 files changed, 33 insertions(+), 2 deletions(-)
create mode 100644 rewatch/tests/legacy-utils.sh
create mode 100755 rewatch/tests/legacy.sh
diff --git a/rewatch/tests/legacy-utils.sh b/rewatch/tests/legacy-utils.sh
new file mode 100644
index 0000000000..3899df52c8
--- /dev/null
+++ b/rewatch/tests/legacy-utils.sh
@@ -0,0 +1,3 @@
+source "utils.sh"
+
+rewatch_legacy() { RUST_BACKTRACE=1 "../../$REWATCH_EXECUTABLE" legacy $@; }
\ No newline at end of file
diff --git a/rewatch/tests/legacy.sh b/rewatch/tests/legacy.sh
new file mode 100755
index 0000000000..231029534c
--- /dev/null
+++ b/rewatch/tests/legacy.sh
@@ -0,0 +1,28 @@
+source "./legacy-utils.sh"
+cd ../testrepo/packages/compiled-by-legacy
+
+bold "Test: It should use the legacy build system"
+
+if rewatch_legacy clean &> /dev/null;
+then
+ success "Test package cleaned"
+else
+ error "Error cleaning test package"
+ exit 1
+fi
+
+if rewatch_legacy build &> /dev/null;
+then
+ success "Test package built"
+else
+ error "Error building test package"
+ exit 1
+fi
+
+if git diff --exit-code ./;
+then
+ success "Test package has no changes"
+else
+ error "Build has changed"
+ exit 1
+fi
diff --git a/rewatch/tests/suffix.sh b/rewatch/tests/suffix.sh
index 3768005297..f51ca93306 100755
--- a/rewatch/tests/suffix.sh
+++ b/rewatch/tests/suffix.sh
@@ -27,7 +27,7 @@ fi
# Count files with new extension
file_count=$(find ./packages -name *.res.js | wc -l)
-if [ "$file_count" -eq 24 ];
+if [ "$file_count" -eq 25 ];
then
success "Found files with correct suffix"
else
diff --git a/rewatch/tests/suite-ci.sh b/rewatch/tests/suite-ci.sh
index 9e5eefe1a8..fd5f11544b 100755
--- a/rewatch/tests/suite-ci.sh
+++ b/rewatch/tests/suite-ci.sh
@@ -40,4 +40,4 @@ else
exit 1
fi
-./compile.sh && ./watch.sh && ./lock.sh && ./suffix.sh
+./compile.sh && ./watch.sh && ./lock.sh && ./suffix.sh && ./legacy.sh
From aaed46593732a85b158c6f3b425b37a05c98608c Mon Sep 17 00:00:00 2001
From: Bushuo
Date: Thu, 19 Jun 2025 22:48:01 +0200
Subject: [PATCH 07/22] test: print stderr output on failure
---
rewatch/tests/legacy.sh | 10 ++++++++--
1 file changed, 8 insertions(+), 2 deletions(-)
diff --git a/rewatch/tests/legacy.sh b/rewatch/tests/legacy.sh
index 231029534c..b3d5c3e029 100755
--- a/rewatch/tests/legacy.sh
+++ b/rewatch/tests/legacy.sh
@@ -3,19 +3,25 @@ cd ../testrepo/packages/compiled-by-legacy
bold "Test: It should use the legacy build system"
-if rewatch_legacy clean &> /dev/null;
+error_output=$(rewatch_legacy clean 2>&1 >/dev/null)
+
+if [ $? -eq 0 ];
then
success "Test package cleaned"
else
error "Error cleaning test package"
+ printf "%s\n" "$error_output" >&2
exit 1
fi
-if rewatch_legacy build &> /dev/null;
+error_output=$(rewatch_legacy build 2>&1 >/dev/null)
+
+if [ $? -eq 0 ];
then
success "Test package built"
else
error "Error building test package"
+ printf "%s\n" "$error_output" >&2
exit 1
fi
From 107e5106ee3824459dbe67c0dff293b0c7c06ae1 Mon Sep 17 00:00:00 2001
From: Bushuo
Date: Fri, 20 Jun 2025 01:05:36 +0200
Subject: [PATCH 08/22] refactor: extract fn to get binary dir
---
rewatch/src/helpers.rs | 45 +++++++++++++++++-------------------------
1 file changed, 18 insertions(+), 27 deletions(-)
diff --git a/rewatch/src/helpers.rs b/rewatch/src/helpers.rs
index 358c4c6ef1..61f68272ed 100644
--- a/rewatch/src/helpers.rs
+++ b/rewatch/src/helpers.rs
@@ -181,7 +181,7 @@ pub fn create_path_for_path(path: &Path) {
fs::DirBuilder::new().recursive(true).create(path).unwrap();
}
-pub fn get_bsc(root_path: &Path, workspace_root: &Option) -> PathBuf {
+fn get_bin_dir() -> PathBuf {
let subfolder = match (std::env::consts::OS, std::env::consts::ARCH) {
("macos", "aarch64") => "darwin-arm64",
("macos", _) => "darwin-x64",
@@ -192,21 +192,24 @@ pub fn get_bsc(root_path: &Path, workspace_root: &Option) -> PathBuf {
_ => panic!("Unsupported architecture"),
};
+ Path::new("node_modules")
+ .join("@rescript")
+ .join(subfolder)
+ .join("bin")
+}
+
+pub fn get_bsc(root_path: &Path, workspace_root: &Option) -> PathBuf {
+ let bin_dir = get_bin_dir();
+
match (
root_path
- .join("node_modules")
- .join("@rescript")
- .join(subfolder)
- .join("bin")
+ .join(&bin_dir)
.join("bsc.exe")
.canonicalize()
.map(StrippedVerbatimPath::to_stripped_verbatim_path),
workspace_root.as_ref().map(|workspace_root| {
workspace_root
- .join("node_modules")
- .join("@rescript")
- .join(subfolder)
- .join("bin")
+ .join(&bin_dir)
.join("bsc.exe")
.canonicalize()
.map(StrippedVerbatimPath::to_stripped_verbatim_path)
@@ -219,37 +222,25 @@ pub fn get_bsc(root_path: &Path, workspace_root: &Option) -> PathBuf {
}
pub fn get_rescript_legacy(root_path: &Path, workspace_root: Option) -> PathBuf {
- let subfolder = match (std::env::consts::OS, std::env::consts::ARCH) {
- ("macos", "aarch64") => "darwin-arm64",
- ("macos", _) => "darwin-x64",
- ("linux", "aarch64") => "linux-arm64",
- ("linux", _) => "linux-x64",
- ("windows", "aarch64") => "win-arm64",
- ("windows", _) => "win-x64",
- _ => panic!("Unsupported architecture"),
- };
-
- let legacy_path_fragment = Path::new("node_modules")
- .join("@rescript")
- .join(subfolder)
- .join("bin")
- .join("rescript.exe");
+ let bin_dir = get_bin_dir();
match (
root_path
- .join(&legacy_path_fragment)
+ .join(&bin_dir)
+ .join("rescript.exe")
.canonicalize()
.map(StrippedVerbatimPath::to_stripped_verbatim_path),
workspace_root.map(|workspace_root| {
workspace_root
- .join(&legacy_path_fragment)
+ .join(&bin_dir)
+ .join("rescript.exe")
.canonicalize()
.map(StrippedVerbatimPath::to_stripped_verbatim_path)
}),
) {
(Ok(path), _) => path,
(_, Some(Ok(path))) => path,
- _ => panic!("Could not find rescript-legacy"),
+ _ => panic!("Could not find rescript.exe"),
}
}
From 18dddc3c177a76707fb9d411a0bb6bf47ca6d66c Mon Sep 17 00:00:00 2001
From: Bushuo
Date: Fri, 20 Jun 2025 23:13:11 +0200
Subject: [PATCH 09/22] fix: windows binary path
---
rewatch/src/helpers.rs | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/rewatch/src/helpers.rs b/rewatch/src/helpers.rs
index 61f68272ed..5b9c93dc61 100644
--- a/rewatch/src/helpers.rs
+++ b/rewatch/src/helpers.rs
@@ -188,7 +188,7 @@ fn get_bin_dir() -> PathBuf {
("linux", "aarch64") => "linux-arm64",
("linux", _) => "linux-x64",
("windows", "aarch64") => "win-arm64",
- ("windows", _) => "win-x64",
+ ("windows", _) => "win32-x64",
_ => panic!("Unsupported architecture"),
};
From 66974f9b7ee4254ab95652d3eb639ba40313bb5b Mon Sep 17 00:00:00 2001
From: Bushuo
Date: Sat, 21 Jun 2025 19:22:23 +0200
Subject: [PATCH 10/22] fix: pass bsc-path arg only to specific subcommands
---
cli/rewatch.js | 36 +++++++++++++++++++++++++++++++++---
1 file changed, 33 insertions(+), 3 deletions(-)
diff --git a/cli/rewatch.js b/cli/rewatch.js
index 6df646ed4b..fed7289d45 100755
--- a/cli/rewatch.js
+++ b/cli/rewatch.js
@@ -7,6 +7,36 @@ import { rewatch_exe, bsc_exe } from "./common/bins.js";
const args = process.argv.slice(2);
-child_process.spawnSync(rewatch_exe, [...args, "--bsc-path", bsc_exe], {
- stdio: "inherit",
-});
+const firstPositionalArgIndex = args.findIndex((arg) => !arg.startsWith("-"));
+
+try {
+ if (firstPositionalArgIndex !== -1) {
+ const subcommand = args[firstPositionalArgIndex];
+ const subcommandArgs = args.slice(firstPositionalArgIndex + 1);
+
+ if (
+ subcommand === "build" ||
+ subcommand === "watch" ||
+ subcommand === "clean" ||
+ subcommand === "compiler-args"
+ ) {
+ child_process.execFileSync(
+ rewatch_exe,
+ [...subcommandArgs, "--bsc-path", bsc_exe],
+ {
+ stdio: "inherit",
+ }
+ );
+ } else {
+ child_process.execFileSync(rewatch_exe, [...args], {
+ stdio: "inherit",
+ });
+ }
+ }
+} catch (err) {
+ if (err.status !== undefined) {
+ process.exit(err.status); // Pass through the exit code
+ } else {
+ process.exit(1); // Generic error
+ }
+}
From d2c561de8835aee97a39a9fa05b98a41357245e5 Mon Sep 17 00:00:00 2001
From: Bushuo
Date: Sun, 22 Jun 2025 19:27:34 +0200
Subject: [PATCH 11/22] test: add package to testrepo deps
---
rewatch/testrepo/bsconfig.json | 6 ++++--
rewatch/testrepo/package.json | 3 ++-
.../testrepo/packages/compiled-by-legacy/rescript.json | 1 +
.../testrepo/packages/compiled-by-legacy/src/Main.mjs | 9 +++++++++
rewatch/testrepo/packages/main/package.json | 1 +
rewatch/testrepo/yarn.lock | 7 +++++++
6 files changed, 24 insertions(+), 3 deletions(-)
create mode 100644 rewatch/testrepo/packages/compiled-by-legacy/src/Main.mjs
diff --git a/rewatch/testrepo/bsconfig.json b/rewatch/testrepo/bsconfig.json
index 706ee9066a..95e49a9f45 100644
--- a/rewatch/testrepo/bsconfig.json
+++ b/rewatch/testrepo/bsconfig.json
@@ -20,7 +20,8 @@
"@testrepo/dep02",
"@testrepo/new-namespace",
"@testrepo/namespace-casing",
- "@testrepo/with-dev-deps"
+ "@testrepo/with-dev-deps",
+ "@testrepo/compiled-by-legacy"
],
"bs-dependencies": [
"@testrepo/main",
@@ -28,7 +29,8 @@
"@testrepo/dep02",
"@testrepo/new-namespace",
"@testrepo/namespace-casing",
- "@testrepo/with-dev-deps"
+ "@testrepo/with-dev-deps",
+ "@testrepo/compiled-by-legacy"
],
"reason": {
"react-jsx": 3
diff --git a/rewatch/testrepo/package.json b/rewatch/testrepo/package.json
index 3436184038..2ed3978be5 100644
--- a/rewatch/testrepo/package.json
+++ b/rewatch/testrepo/package.json
@@ -8,7 +8,8 @@
"packages/dep02",
"packages/new-namespace",
"packages/namespace-casing",
- "packages/with-dev-deps"
+ "packages/with-dev-deps",
+ "packages/compiled-by-legacy"
]
},
"dependencies": {
diff --git a/rewatch/testrepo/packages/compiled-by-legacy/rescript.json b/rewatch/testrepo/packages/compiled-by-legacy/rescript.json
index f94702ab3e..d62afdf93c 100644
--- a/rewatch/testrepo/packages/compiled-by-legacy/rescript.json
+++ b/rewatch/testrepo/packages/compiled-by-legacy/rescript.json
@@ -1,5 +1,6 @@
{
"name": "@testrepo/compiled-by-legacy",
+ "namespace": true,
"sources": {
"dir": "src",
"subdirs": true
diff --git a/rewatch/testrepo/packages/compiled-by-legacy/src/Main.mjs b/rewatch/testrepo/packages/compiled-by-legacy/src/Main.mjs
new file mode 100644
index 0000000000..618d7a44e8
--- /dev/null
+++ b/rewatch/testrepo/packages/compiled-by-legacy/src/Main.mjs
@@ -0,0 +1,9 @@
+// Generated by ReScript, PLEASE EDIT WITH CARE
+
+
+let x = 1;
+
+export {
+ x,
+}
+/* No side effect */
diff --git a/rewatch/testrepo/packages/main/package.json b/rewatch/testrepo/packages/main/package.json
index 10954e0797..1813de299d 100644
--- a/rewatch/testrepo/packages/main/package.json
+++ b/rewatch/testrepo/packages/main/package.json
@@ -12,6 +12,7 @@
"author": "",
"license": "MIT",
"dependencies": {
+ "@testrepo/compiled-by-legacy": "*",
"@testrepo/dep01": "*"
}
}
diff --git a/rewatch/testrepo/yarn.lock b/rewatch/testrepo/yarn.lock
index ac41b3d2c1..beb6bf912d 100644
--- a/rewatch/testrepo/yarn.lock
+++ b/rewatch/testrepo/yarn.lock
@@ -40,6 +40,12 @@ __metadata:
languageName: node
linkType: hard
+"@testrepo/compiled-by-legacy@npm:*, @testrepo/compiled-by-legacy@workspace:packages/compiled-by-legacy":
+ version: 0.0.0-use.local
+ resolution: "@testrepo/compiled-by-legacy@workspace:packages/compiled-by-legacy"
+ languageName: unknown
+ linkType: soft
+
"@testrepo/dep01@npm:*, @testrepo/dep01@workspace:packages/dep01":
version: 0.0.0-use.local
resolution: "@testrepo/dep01@workspace:packages/dep01"
@@ -58,6 +64,7 @@ __metadata:
version: 0.0.0-use.local
resolution: "@testrepo/main@workspace:packages/main"
dependencies:
+ "@testrepo/compiled-by-legacy": "npm:*"
"@testrepo/dep01": "npm:*"
languageName: unknown
linkType: soft
From 7742361212e86e724887bf9f58f3154ee9f2ef83 Mon Sep 17 00:00:00 2001
From: Bushuo
Date: Sun, 22 Jun 2025 19:46:58 +0200
Subject: [PATCH 12/22] test: update snapshots
---
rewatch/tests/snapshots/dependency-cycle.txt | 2 +-
rewatch/tests/snapshots/remove-file.txt | 2 +-
rewatch/tests/snapshots/rename-file-internal-dep-namespace.txt | 2 +-
rewatch/tests/snapshots/rename-file-internal-dep.txt | 2 +-
rewatch/tests/snapshots/rename-file-with-interface.txt | 2 +-
rewatch/tests/snapshots/rename-file.txt | 2 +-
rewatch/tests/snapshots/rename-interface-file.txt | 2 +-
rewatch/tests/suffix.sh | 2 +-
8 files changed, 8 insertions(+), 8 deletions(-)
diff --git a/rewatch/tests/snapshots/dependency-cycle.txt b/rewatch/tests/snapshots/dependency-cycle.txt
index c949d4005c..c6d7f793e8 100644
--- a/rewatch/tests/snapshots/dependency-cycle.txt
+++ b/rewatch/tests/snapshots/dependency-cycle.txt
@@ -1,4 +1,4 @@
-Cleaned 0/14
+Cleaned 0/15
Parsed 1 source files
Compiled 0 modules
diff --git a/rewatch/tests/snapshots/remove-file.txt b/rewatch/tests/snapshots/remove-file.txt
index 921f9d4246..8d68cdd418 100644
--- a/rewatch/tests/snapshots/remove-file.txt
+++ b/rewatch/tests/snapshots/remove-file.txt
@@ -1,4 +1,4 @@
-Cleaned 1/14
+Cleaned 1/15
Parsed 0 source files
Compiled 1 modules
diff --git a/rewatch/tests/snapshots/rename-file-internal-dep-namespace.txt b/rewatch/tests/snapshots/rename-file-internal-dep-namespace.txt
index 1950bad9e3..3263c0fe88 100644
--- a/rewatch/tests/snapshots/rename-file-internal-dep-namespace.txt
+++ b/rewatch/tests/snapshots/rename-file-internal-dep-namespace.txt
@@ -1,4 +1,4 @@
-Cleaned 2/14
+Cleaned 2/15
Parsed 2 source files
Compiled 3 modules
diff --git a/rewatch/tests/snapshots/rename-file-internal-dep.txt b/rewatch/tests/snapshots/rename-file-internal-dep.txt
index f81a6dece4..829a187871 100644
--- a/rewatch/tests/snapshots/rename-file-internal-dep.txt
+++ b/rewatch/tests/snapshots/rename-file-internal-dep.txt
@@ -1,4 +1,4 @@
-Cleaned 2/14
+Cleaned 2/15
Parsed 2 source files
Compiled 2 modules
diff --git a/rewatch/tests/snapshots/rename-file-with-interface.txt b/rewatch/tests/snapshots/rename-file-with-interface.txt
index 257fba3570..e784d71b9e 100644
--- a/rewatch/tests/snapshots/rename-file-with-interface.txt
+++ b/rewatch/tests/snapshots/rename-file-with-interface.txt
@@ -1,4 +1,4 @@
[2K
No implementation file found for interface file (skipping): src/ModuleWithInterface.resi
-Cleaned 2/14
+Cleaned 2/15
Parsed 1 source files
Compiled 2 modules
diff --git a/rewatch/tests/snapshots/rename-file.txt b/rewatch/tests/snapshots/rename-file.txt
index 5b20d86fd7..5458530d74 100644
--- a/rewatch/tests/snapshots/rename-file.txt
+++ b/rewatch/tests/snapshots/rename-file.txt
@@ -1,3 +1,3 @@
-Cleaned 1/14
+Cleaned 1/15
Parsed 1 source files
Compiled 1 modules
diff --git a/rewatch/tests/snapshots/rename-interface-file.txt b/rewatch/tests/snapshots/rename-interface-file.txt
index e2d7fd9752..26d7ffe3e6 100644
--- a/rewatch/tests/snapshots/rename-interface-file.txt
+++ b/rewatch/tests/snapshots/rename-interface-file.txt
@@ -1,4 +1,4 @@
[2K
No implementation file found for interface file (skipping): src/ModuleWithInterface2.resi
-Cleaned 1/14
+Cleaned 1/15
Parsed 1 source files
Compiled 2 modules
diff --git a/rewatch/tests/suffix.sh b/rewatch/tests/suffix.sh
index f51ca93306..d644a34e99 100755
--- a/rewatch/tests/suffix.sh
+++ b/rewatch/tests/suffix.sh
@@ -27,7 +27,7 @@ fi
# Count files with new extension
file_count=$(find ./packages -name *.res.js | wc -l)
-if [ "$file_count" -eq 25 ];
+if [ "$file_count" -eq 26 ];
then
success "Found files with correct suffix"
else
From fb9400cedcb5aa48d2203a9e671b4fb4fdd68c55 Mon Sep 17 00:00:00 2001
From: Bushuo
Date: Sun, 22 Jun 2025 20:03:07 +0200
Subject: [PATCH 13/22] test: improve test output
---
rewatch/tests/compile.sh | 8 +++++---
1 file changed, 5 insertions(+), 3 deletions(-)
diff --git a/rewatch/tests/compile.sh b/rewatch/tests/compile.sh
index f694b3b0bb..a465933c9e 100755
--- a/rewatch/tests/compile.sh
+++ b/rewatch/tests/compile.sh
@@ -87,21 +87,23 @@ then
fi
file_count=$(find ./packages/with-dev-deps/test -name *.mjs | wc -l)
-if [ "$file_count" -eq 1 ];
+expected_file_count=1
+if [ "$file_count" -eq $expected_file_count ];
then
success "Compiled dev dependencies successfully"
else
- error "Expected 2 files to be compiled with the --dev flag, found $file_count"
+ error "Expected $expected_file_count files to be compiled with the --dev flag, found $file_count"
exit 1
fi
-rewatch clean &> /dev/null
+error_output=$(rewatch clean 2>&1 >/dev/null)
file_count=$(find ./packages/with-dev-deps -name *.mjs | wc -l)
if [ "$file_count" -eq 0 ];
then
success "Cleaned dev dependencies successfully"
else
error "Expected 0 files remaining after cleaning, found $file_count"
+ printf "%s\n" "$error_output" >&2
exit 1
fi
From 9bf9d43048543ea6fd86e43b590ce364b3e4f9a8 Mon Sep 17 00:00:00 2001
From: Bushuo
Date: Mon, 23 Jun 2025 09:24:25 +0200
Subject: [PATCH 14/22] fix: args passing in cli wrapper
---
cli/rewatch.js | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/cli/rewatch.js b/cli/rewatch.js
index fed7289d45..d363ebe477 100755
--- a/cli/rewatch.js
+++ b/cli/rewatch.js
@@ -12,7 +12,7 @@ const firstPositionalArgIndex = args.findIndex((arg) => !arg.startsWith("-"));
try {
if (firstPositionalArgIndex !== -1) {
const subcommand = args[firstPositionalArgIndex];
- const subcommandArgs = args.slice(firstPositionalArgIndex + 1);
+ const subcommandWithArgs = args.slice(firstPositionalArgIndex);
if (
subcommand === "build" ||
@@ -22,7 +22,7 @@ try {
) {
child_process.execFileSync(
rewatch_exe,
- [...subcommandArgs, "--bsc-path", bsc_exe],
+ [...subcommandWithArgs, "--bsc-path", bsc_exe],
{
stdio: "inherit",
}
From 7faf311279d3eafc91666b1662cb4409df9be008 Mon Sep 17 00:00:00 2001
From: Bushuo
Date: Mon, 23 Jun 2025 21:09:35 +0200
Subject: [PATCH 15/22] fix: pass `--bsc-path` to implicit build command
---
cli/rewatch.js | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/cli/rewatch.js b/cli/rewatch.js
index d363ebe477..d7e65e077e 100755
--- a/cli/rewatch.js
+++ b/cli/rewatch.js
@@ -32,6 +32,11 @@ try {
stdio: "inherit",
});
}
+ } else {
+ // no subcommand means build subcommand
+ child_process.execFileSync(rewatch_exe, [...args, "--bsc-path", bsc_exe], {
+ stdio: "inherit",
+ });
}
} catch (err) {
if (err.status !== undefined) {
From b730d9f1419645507a0cd7c9f4d1c8409d07d4ef Mon Sep 17 00:00:00 2001
From: Bushuo
Date: Sat, 28 Jun 2025 23:21:12 +0200
Subject: [PATCH 16/22] fix: wrong path to `rescript` executable
refactor `cli.rs` to remove duplication of docstrings
---
rewatch/src/build.rs | 10 +-
rewatch/src/build/clean.rs | 2 +-
rewatch/src/cli.rs | 193 ++++++++++++------
rewatch/src/helpers.rs | 6 +-
rewatch/src/main.rs | 172 ++++++++--------
.../packages/compiled-by-legacy/rescript.json | 2 +-
rewatch/tests/legacy.sh | 26 ++-
7 files changed, 256 insertions(+), 155 deletions(-)
diff --git a/rewatch/src/build.rs b/rewatch/src/build.rs
index ab00db8aad..50ab16a216 100644
--- a/rewatch/src/build.rs
+++ b/rewatch/src/build.rs
@@ -59,7 +59,7 @@ pub struct CompilerArgs {
pub fn get_compiler_args(
path: &Path,
rescript_version: Option,
- bsc_path: &Option,
+ bsc_path: Option,
build_dev_deps: bool,
) -> Result {
let filename = &helpers::get_abs_path(path);
@@ -501,7 +501,7 @@ pub fn build(
show_progress: bool,
no_timing: bool,
create_sourcedirs: bool,
- bsc_path: &Option,
+ bsc_path: Option,
build_dev_deps: bool,
snapshot_output: bool,
) -> Result {
@@ -516,7 +516,7 @@ pub fn build(
filter,
show_progress,
path,
- bsc_path,
+ &bsc_path,
build_dev_deps,
snapshot_output,
)
@@ -558,9 +558,9 @@ pub fn pass_through_legacy(args: Vec) -> i32 {
let project_root = helpers::get_abs_path(Path::new("."));
let workspace_root = helpers::get_workspace_root(&project_root);
- let bsb_path = helpers::get_rescript_legacy(&project_root, workspace_root);
+ let rescript_legacy_path = helpers::get_rescript_legacy(&project_root, workspace_root);
- let status = std::process::Command::new(bsb_path)
+ let status = std::process::Command::new(rescript_legacy_path)
.args(args)
.stdout(Stdio::inherit())
.stderr(Stdio::inherit())
diff --git a/rewatch/src/build/clean.rs b/rewatch/src/build/clean.rs
index 0057437997..8a09bef035 100644
--- a/rewatch/src/build/clean.rs
+++ b/rewatch/src/build/clean.rs
@@ -334,7 +334,7 @@ pub fn cleanup_after_build(build_state: &BuildState) {
pub fn clean(
path: &Path,
show_progress: bool,
- bsc_path: &Option,
+ bsc_path: Option,
snapshot_output: bool,
) -> Result<()> {
let project_root = helpers::get_abs_path(path);
diff --git a/rewatch/src/cli.rs b/rewatch/src/cli.rs
index 87ec1efb09..d9a088d8ae 100644
--- a/rewatch/src/cli.rs
+++ b/rewatch/src/cli.rs
@@ -1,4 +1,4 @@
-use std::ffi::OsString;
+use std::{ffi::OsString, ops::Deref};
use clap::{Args, Parser, Subcommand};
use clap_verbosity_flag::InfoLevel;
@@ -24,23 +24,29 @@ pub struct Cli {
#[command(subcommand)]
pub command: Option,
+ #[command(flatten)]
+ pub build_args: BuildArgs,
+}
+
+#[derive(Args, Debug, Clone)]
+pub struct FolderArg {
/// The relative path to where the main rescript.json resides. IE - the root of your project.
#[arg(default_value = ".")]
pub folder: String,
-
- #[command(flatten)]
- pub build_args: BuildArgs,
}
#[derive(Args, Debug, Clone)]
-pub struct BuildArgs {
+pub struct FilterArg {
/// Filter files by regex
///
/// Filter allows for a regex to be supplied which will filter the files to be compiled. For
/// instance, to filter out test files for compilation while doing feature work.
#[arg(short, long)]
pub filter: Option,
+}
+#[derive(Args, Debug, Clone)]
+pub struct AfterBuildArg {
/// Action after build
///
/// This allows one to pass an additional command to the watcher, which allows it to run when
@@ -49,14 +55,20 @@ pub struct BuildArgs {
/// color as well
#[arg(short, long)]
pub after_build: Option,
+}
+#[derive(Args, Debug, Clone, Copy)]
+pub struct CreateSourceDirsArg {
/// Create source_dirs.json
///
/// This creates a source_dirs.json file at the root of the monorepo, which is needed when you
/// want to use Reanalyze
#[arg(short, long, default_value_t = false, num_args = 0..=1)]
pub create_sourcedirs: bool,
+}
+#[derive(Args, Debug, Clone, Copy)]
+pub struct DevArg {
/// Build development dependencies
///
/// This is the flag to also compile development dependencies
@@ -65,61 +77,72 @@ pub struct BuildArgs {
/// _all_ packages
#[arg(long, default_value_t = false, num_args = 0..=1)]
pub dev: bool,
+}
- /// Disable timing on the output
- #[arg(short, long, default_value_t = false, num_args = 0..=1)]
- pub no_timing: bool,
+#[derive(Args, Debug, Clone)]
+pub struct BscPathArg {
+ /// Custom path to bsc
+ #[arg(long)]
+ pub bsc_path: Option,
+}
+#[derive(Args, Debug, Clone, Copy)]
+pub struct SnapshotOutputArg {
/// simple output for snapshot testing
#[arg(short, long, default_value = "false", num_args = 0..=1)]
pub snapshot_output: bool,
+}
- /// Path to bsc
- #[arg(long)]
- pub bsc_path: Option,
+#[derive(Args, Debug, Clone)]
+pub struct BuildArgs {
+ #[command(flatten)]
+ pub folder: FolderArg,
+
+ #[command(flatten)]
+ pub filter: FilterArg,
+
+ #[command(flatten)]
+ pub after_build: AfterBuildArg,
+
+ #[command(flatten)]
+ pub create_sourcedirs: CreateSourceDirsArg,
+
+ #[command(flatten)]
+ pub dev: DevArg,
+
+ /// Disable timing on the output
+ #[arg(short, long, default_value_t = false, num_args = 0..=1)]
+ pub no_timing: bool,
+
+ #[command(flatten)]
+ pub snapshot_output: SnapshotOutputArg,
+
+ #[command(flatten)]
+ pub bsc_path: BscPathArg,
}
#[derive(Args, Clone, Debug)]
pub struct WatchArgs {
- /// Filter files by regex
- ///
- /// Filter allows for a regex to be supplied which will filter the files to be compiled. For
- /// instance, to filter out test files for compilation while doing feature work.
- #[arg(short, long)]
- pub filter: Option,
+ #[command(flatten)]
+ pub folder: FolderArg,
- /// Action after build
- ///
- /// This allows one to pass an additional command to the watcher, which allows it to run when
- /// finished. For instance, to play a sound when done compiling, or to run a test suite.
- /// NOTE - You may need to add '--color=always' to your subcommand in case you want to output
- /// color as well
- #[arg(short, long)]
- pub after_build: Option,
+ #[command(flatten)]
+ pub filter: FilterArg,
- /// Create source_dirs.json
- ///
- /// This creates a source_dirs.json file at the root of the monorepo, which is needed when you
- /// want to use Reanalyze
- #[arg(short, long, default_value_t = false, num_args = 0..=1)]
- pub create_sourcedirs: bool,
+ #[command(flatten)]
+ pub after_build: AfterBuildArg,
- /// Build development dependencies
- ///
- /// This is the flag to also compile development dependencies
- /// It's important to know that we currently do not discern between project src, and
- /// dependencies. So enabling this flag will enable building _all_ development dependencies of
- /// _all_ packages
- #[arg(long, default_value_t = false, num_args = 0..=1)]
- pub dev: bool,
+ #[command(flatten)]
+ pub create_sourcedirs: CreateSourceDirsArg,
- /// simple output for snapshot testing
- #[arg(short, long, default_value = "false", num_args = 0..=1)]
- pub snapshot_output: bool,
+ #[command(flatten)]
+ pub dev: DevArg,
- /// Path to bsc
- #[arg(long)]
- pub bsc_path: Option,
+ #[command(flatten)]
+ pub snapshot_output: SnapshotOutputArg,
+
+ #[command(flatten)]
+ pub bsc_path: BscPathArg,
}
#[derive(Subcommand, Clone, Debug)]
@@ -130,13 +153,14 @@ pub enum Command {
Watch(WatchArgs),
/// Clean the build artifacts
Clean {
- /// Path to bsc
- #[arg(long)]
- bsc_path: Option,
+ #[command(flatten)]
+ folder: FolderArg,
+
+ #[command(flatten)]
+ bsc_path: BscPathArg,
- /// simple output for snapshot testing
- #[arg(short, long, default_value = "false", num_args = 0..=1)]
- snapshot_output: bool,
+ #[command(flatten)]
+ snapshot_output: SnapshotOutputArg,
},
/// Alias to `legacy format`.
#[command(disable_help_flag = true)]
@@ -156,23 +180,78 @@ pub enum Command {
#[command()]
path: String,
- #[arg(long, default_value_t = false, num_args = 0..=1)]
- dev: bool,
+ #[command(flatten)]
+ dev: DevArg,
/// To be used in conjunction with compiler_args
#[arg(long)]
rescript_version: Option,
- /// A custom path to bsc
- #[arg(long)]
- bsc_path: Option,
+ #[command(flatten)]
+ bsc_path: BscPathArg,
},
/// Use the legacy build system.
///
/// After this command is encountered, the rest of the arguments are passed to the legacy build system.
- #[command(disable_help_flag = true)]
+ #[command(disable_help_flag = true, external_subcommand = true)]
Legacy {
#[arg(allow_hyphen_values = true, num_args = 0..)]
legacy_args: Vec,
},
}
+
+impl Deref for FolderArg {
+ type Target = str;
+
+ fn deref(&self) -> &Self::Target {
+ &self.folder
+ }
+}
+
+impl Deref for FilterArg {
+ type Target = Option;
+
+ fn deref(&self) -> &Self::Target {
+ &self.filter
+ }
+}
+
+impl Deref for AfterBuildArg {
+ type Target = Option;
+
+ fn deref(&self) -> &Self::Target {
+ &self.after_build
+ }
+}
+
+impl Deref for CreateSourceDirsArg {
+ type Target = bool;
+
+ fn deref(&self) -> &Self::Target {
+ &self.create_sourcedirs
+ }
+}
+
+impl Deref for DevArg {
+ type Target = bool;
+
+ fn deref(&self) -> &Self::Target {
+ &self.dev
+ }
+}
+
+impl Deref for BscPathArg {
+ type Target = Option;
+
+ fn deref(&self) -> &Self::Target {
+ &self.bsc_path
+ }
+}
+
+impl Deref for SnapshotOutputArg {
+ type Target = bool;
+
+ fn deref(&self) -> &Self::Target {
+ &self.snapshot_output
+ }
+}
diff --git a/rewatch/src/helpers.rs b/rewatch/src/helpers.rs
index 5b9c93dc61..9b6661c2e4 100644
--- a/rewatch/src/helpers.rs
+++ b/rewatch/src/helpers.rs
@@ -222,18 +222,18 @@ pub fn get_bsc(root_path: &Path, workspace_root: &Option) -> PathBuf {
}
pub fn get_rescript_legacy(root_path: &Path, workspace_root: Option) -> PathBuf {
- let bin_dir = get_bin_dir();
+ let bin_dir = Path::new("node_modules").join("rescript").join("cli");
match (
root_path
.join(&bin_dir)
- .join("rescript.exe")
+ .join("rescript.js")
.canonicalize()
.map(StrippedVerbatimPath::to_stripped_verbatim_path),
workspace_root.map(|workspace_root| {
workspace_root
.join(&bin_dir)
- .join("rescript.exe")
+ .join("rescript.js")
.canonicalize()
.map(StrippedVerbatimPath::to_stripped_verbatim_path)
}),
diff --git a/rewatch/src/main.rs b/rewatch/src/main.rs
index dcebec5945..3cd1c5d084 100644
--- a/rewatch/src/main.rs
+++ b/rewatch/src/main.rs
@@ -22,22 +22,11 @@ fn main() -> Result<()> {
let command = args.command.unwrap_or(cli::Command::Build(args.build_args));
- // handle those commands early, because we don't need a lock for them
+ // The 'normal run' mode will show the 'pretty' formatted progress. But if we turn off the log
+ // level, we should never show that.
+ let show_progress = log_level_filter == LevelFilter::Info;
+
match command.clone() {
- cli::Command::Legacy { legacy_args } => {
- let code = build::pass_through_legacy(legacy_args);
- std::process::exit(code);
- }
- cli::Command::Format { mut format_args } => {
- format_args.insert(0, "format".into());
- let code = build::pass_through_legacy(format_args);
- std::process::exit(code);
- }
- cli::Command::Dump { mut dump_args } => {
- dump_args.insert(0, "dump".into());
- let code = build::pass_through_legacy(dump_args);
- std::process::exit(code);
- }
cli::Command::CompilerArgs {
path,
dev,
@@ -49,84 +38,99 @@ fn main() -> Result<()> {
build::get_compiler_args(
Path::new(&path),
rescript_version,
- &bsc_path.map(PathBuf::from),
- dev
+ bsc_path.as_ref().map(PathBuf::from),
+ *dev
)?
);
std::process::exit(0);
}
- _ => (),
- }
+ cli::Command::Build(build_args) => {
+ let _lock = get_lock(&build_args.folder);
- // The 'normal run' mode will show the 'pretty' formatted progress. But if we turn off the log
- // level, we should never show that.
- let show_progress = log_level_filter == LevelFilter::Info;
+ let filter = build_args
+ .filter
+ .as_ref()
+ .map(|filter| Regex::new(&filter).expect("Could not parse regex"));
- match lock::get(&args.folder) {
- lock::Lock::Error(ref e) => {
- println!("Could not start Rewatch: {e}");
- std::process::exit(1)
+ match build::build(
+ &filter,
+ Path::new(&build_args.folder as &str),
+ show_progress,
+ build_args.no_timing,
+ *build_args.create_sourcedirs,
+ build_args.bsc_path.as_ref().map(PathBuf::from),
+ *build_args.dev,
+ *build_args.snapshot_output,
+ ) {
+ Err(e) => {
+ println!("{e}");
+ std::process::exit(1)
+ }
+ Ok(_) => {
+ if let Some(args_after_build) = (*build_args.after_build).clone() {
+ cmd::run(args_after_build)
+ }
+ std::process::exit(0)
+ }
+ };
}
- lock::Lock::Aquired(_) => match command {
- cli::Command::Clean {
- bsc_path,
- snapshot_output,
- } => build::clean::clean(
- Path::new(&args.folder),
+ cli::Command::Watch(watch_args) => {
+ let _lock = get_lock(&watch_args.folder);
+
+ let filter = watch_args
+ .filter
+ .as_ref()
+ .map(|filter| Regex::new(&filter).expect("Could not parse regex"));
+ watcher::start(
+ &filter,
show_progress,
- &bsc_path.map(PathBuf::from),
- snapshot_output,
- ),
- cli::Command::Build(build_args) => {
- let filter = build_args
- .filter
- .map(|filter| Regex::new(filter.as_ref()).expect("Could not parse regex"));
+ &watch_args.folder,
+ (*watch_args.after_build).clone(),
+ *watch_args.create_sourcedirs,
+ *watch_args.dev,
+ (*watch_args.bsc_path).clone(),
+ *watch_args.snapshot_output,
+ );
- match build::build(
- &filter,
- Path::new(&args.folder),
- show_progress,
- build_args.no_timing,
- build_args.create_sourcedirs,
- &build_args.bsc_path.map(PathBuf::from),
- build_args.dev,
- build_args.snapshot_output,
- ) {
- Err(e) => {
- println!("{e}");
- std::process::exit(1)
- }
- Ok(_) => {
- if let Some(args_after_build) = build_args.after_build {
- cmd::run(args_after_build)
- }
- std::process::exit(0)
- }
- };
- }
- cli::Command::Watch(watch_args) => {
- let filter = watch_args
- .filter
- .map(|filter| Regex::new(filter.as_ref()).expect("Could not parse regex"));
- watcher::start(
- &filter,
- show_progress,
- &args.folder,
- watch_args.after_build,
- watch_args.create_sourcedirs,
- watch_args.dev,
- watch_args.bsc_path,
- watch_args.snapshot_output,
- );
+ Ok(())
+ }
+ cli::Command::Clean {
+ folder,
+ bsc_path,
+ snapshot_output,
+ } => {
+ let _lock = get_lock(&folder);
- Ok(())
- }
- cli::Command::CompilerArgs { .. }
- | cli::Command::Legacy { .. }
- | cli::Command::Format { .. }
- | cli::Command::Dump { .. } => {
- unreachable!("command already handled")
- }
- },
+ build::clean::clean(
+ Path::new(&folder as &str),
+ show_progress,
+ bsc_path.as_ref().map(PathBuf::from),
+ *snapshot_output,
+ )
+ }
+ cli::Command::Legacy { legacy_args } => {
+ let code = build::pass_through_legacy(legacy_args);
+ std::process::exit(code);
+ }
+ cli::Command::Format { mut format_args } => {
+ format_args.insert(0, "format".into());
+ let code = build::pass_through_legacy(format_args);
+ std::process::exit(code);
+ }
+ cli::Command::Dump { mut dump_args } => {
+ dump_args.insert(0, "dump".into());
+ let code = build::pass_through_legacy(dump_args);
+ std::process::exit(code);
+ }
+ }
+}
+
+fn get_lock(folder: &str) -> lock::Lock {
+ match lock::get(folder) {
+ lock::Lock::Error(error) => {
+ println!("Could not start Rewatch: {error}");
+ std::process::exit(1);
+ }
+ acquired_lock => acquired_lock,
}
}
diff --git a/rewatch/testrepo/packages/compiled-by-legacy/rescript.json b/rewatch/testrepo/packages/compiled-by-legacy/rescript.json
index d62afdf93c..3722c661d5 100644
--- a/rewatch/testrepo/packages/compiled-by-legacy/rescript.json
+++ b/rewatch/testrepo/packages/compiled-by-legacy/rescript.json
@@ -6,7 +6,7 @@
"subdirs": true
},
"package-specs": {
- "module": "es6",
+ "module": "esmodule",
"in-source": true
},
"suffix": ".res.js"
diff --git a/rewatch/tests/legacy.sh b/rewatch/tests/legacy.sh
index b3d5c3e029..a5e3de54cb 100755
--- a/rewatch/tests/legacy.sh
+++ b/rewatch/tests/legacy.sh
@@ -3,19 +3,26 @@ cd ../testrepo/packages/compiled-by-legacy
bold "Test: It should use the legacy build system"
-error_output=$(rewatch_legacy clean 2>&1 >/dev/null)
+error_output=$(rewatch_legacy 2>&1 >/dev/null)
+if [ -n "$error_output" ];
+then
+ error "Error running rewatch"
+ printf "%s\n" "$error_output" >&2
+ exit 1
+fi
-if [ $? -eq 0 ];
+error_output=$(rewatch_legacy clean 2>&1 >/dev/null)
+file_count=$(find . -name "*.res.js" | wc -l)
+if [ $? -eq 0 ] && [ $file_count -eq 0 ];
then
success "Test package cleaned"
else
- error "Error cleaning test package"
+ error "Error cleaning test package. File count was $file_count."
printf "%s\n" "$error_output" >&2
exit 1
fi
error_output=$(rewatch_legacy build 2>&1 >/dev/null)
-
if [ $? -eq 0 ];
then
success "Test package built"
@@ -32,3 +39,14 @@ else
error "Build has changed"
exit 1
fi
+
+error_output=$(rewatch_legacy format -all 2>&1 >/dev/null)
+git_diff_file_count=$(git diff --name-only ./ | wc -l)
+if [ $? -eq 0 ] && [ $git_diff_file_count -eq 1 ];
+then
+ success "Test package formatted. Got $git_diff_file_count changed files."
+else
+ error "Error formatting test package"
+ printf "%s\n" "$error_output" >&2
+ exit 1
+fi
\ No newline at end of file
From f003508b6ee18f0af42f5488e266cfe209092e5a Mon Sep 17 00:00:00 2001
From: Bushuo
Date: Sat, 28 Jun 2025 23:32:54 +0200
Subject: [PATCH 17/22] fix: legacy tests inconsistency
---
rewatch/tests/legacy.sh | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/rewatch/tests/legacy.sh b/rewatch/tests/legacy.sh
index a5e3de54cb..19f80a029b 100755
--- a/rewatch/tests/legacy.sh
+++ b/rewatch/tests/legacy.sh
@@ -4,9 +4,9 @@ cd ../testrepo/packages/compiled-by-legacy
bold "Test: It should use the legacy build system"
error_output=$(rewatch_legacy 2>&1 >/dev/null)
-if [ -n "$error_output" ];
+if [ $? -ne 0 ];
then
- error "Error running rewatch"
+ error "Error running rewatch legacy"
printf "%s\n" "$error_output" >&2
exit 1
fi
From c88b2d40fb66821af12f6479cd6b454388084d0e Mon Sep 17 00:00:00 2001
From: Bushuo
Date: Sun, 29 Jun 2025 00:11:37 +0200
Subject: [PATCH 18/22] test: is error output printed correctly
---
rewatch/tests/legacy.sh | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/rewatch/tests/legacy.sh b/rewatch/tests/legacy.sh
index 19f80a029b..3a350c2a3a 100755
--- a/rewatch/tests/legacy.sh
+++ b/rewatch/tests/legacy.sh
@@ -7,7 +7,7 @@ error_output=$(rewatch_legacy 2>&1 >/dev/null)
if [ $? -ne 0 ];
then
error "Error running rewatch legacy"
- printf "%s\n" "$error_output" >&2
+ echo $error_output
exit 1
fi
@@ -18,7 +18,7 @@ then
success "Test package cleaned"
else
error "Error cleaning test package. File count was $file_count."
- printf "%s\n" "$error_output" >&2
+ echo $error_output
exit 1
fi
@@ -28,7 +28,7 @@ then
success "Test package built"
else
error "Error building test package"
- printf "%s\n" "$error_output" >&2
+ echo $error_output
exit 1
fi
@@ -47,6 +47,6 @@ then
success "Test package formatted. Got $git_diff_file_count changed files."
else
error "Error formatting test package"
- printf "%s\n" "$error_output" >&2
+ echo $error_output
exit 1
fi
\ No newline at end of file
From 876b7971fcfa7c8ab038c538583e5f5fb917ca1e Mon Sep 17 00:00:00 2001
From: Bushuo
Date: Sun, 29 Jun 2025 00:23:46 +0200
Subject: [PATCH 19/22] debug: print whole output of rewatch legacy
---
rewatch/tests/legacy.sh | 1 +
1 file changed, 1 insertion(+)
diff --git a/rewatch/tests/legacy.sh b/rewatch/tests/legacy.sh
index 3a350c2a3a..6a09359ef7 100755
--- a/rewatch/tests/legacy.sh
+++ b/rewatch/tests/legacy.sh
@@ -3,6 +3,7 @@ cd ../testrepo/packages/compiled-by-legacy
bold "Test: It should use the legacy build system"
+rewatch_legacy
error_output=$(rewatch_legacy 2>&1 >/dev/null)
if [ $? -ne 0 ];
then
From 635159bb7527d3d78aed41ce7e34501e5369a131 Mon Sep 17 00:00:00 2001
From: Paul Buschmann
Date: Sun, 29 Jun 2025 12:19:44 +0200
Subject: [PATCH 20/22] fix: node script invocation on windows
---
rewatch/src/build.rs | 13 ++++++++++---
rewatch/tests/legacy.sh | 1 -
2 files changed, 10 insertions(+), 4 deletions(-)
diff --git a/rewatch/src/build.rs b/rewatch/src/build.rs
index 50ab16a216..7562872f02 100644
--- a/rewatch/src/build.rs
+++ b/rewatch/src/build.rs
@@ -554,17 +554,24 @@ pub fn build(
}
}
-pub fn pass_through_legacy(args: Vec) -> i32 {
+pub fn pass_through_legacy(mut args: Vec) -> i32 {
let project_root = helpers::get_abs_path(Path::new("."));
let workspace_root = helpers::get_workspace_root(&project_root);
let rescript_legacy_path = helpers::get_rescript_legacy(&project_root, workspace_root);
- let status = std::process::Command::new(rescript_legacy_path)
+ args.insert(0, rescript_legacy_path.into());
+ let status = std::process::Command::new("node")
.args(args)
.stdout(Stdio::inherit())
.stderr(Stdio::inherit())
.status();
- status.map(|s| s.code().unwrap_or(1)).unwrap_or(1)
+ match status {
+ Ok(s) => s.code().unwrap_or(0),
+ Err(err) => {
+ eprintln!("Error running the legacy build system: {err}");
+ 1
+ }
+ }
}
diff --git a/rewatch/tests/legacy.sh b/rewatch/tests/legacy.sh
index 6a09359ef7..3a350c2a3a 100755
--- a/rewatch/tests/legacy.sh
+++ b/rewatch/tests/legacy.sh
@@ -3,7 +3,6 @@ cd ../testrepo/packages/compiled-by-legacy
bold "Test: It should use the legacy build system"
-rewatch_legacy
error_output=$(rewatch_legacy 2>&1 >/dev/null)
if [ $? -ne 0 ];
then
From 2006080116c8341622d6f01f1e3d53383bf0b8b8 Mon Sep 17 00:00:00 2001
From: Paul Buschmann
Date: Mon, 30 Jun 2025 15:26:25 +0200
Subject: [PATCH 21/22] Update CHANGELOG.md
---
CHANGELOG.md | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index bd9695b714..6ac6282de1 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -12,6 +12,10 @@
# 12.0.0-alpha.15 (Unreleased)
+#### :boom: Breaking Change
+
+- The legacy rescript cli can be called through rewatch via `rewatch legacy`. Arguments to rewatch need to be passed after the subcommand. https://github.com/rescript-lang/rescript/pull/7551
+
#### :bug: Bug fix
- Ignore inferred arity in functions inside `%raw` functions, leaving to `%ffi` the responsibility to check the arity since it gives an error in case of mismatch. https://github.com/rescript-lang/rescript/pull/7542
From 834f890546635bc677b8c92dd403a55876b4c9dc Mon Sep 17 00:00:00 2001
From: Paul Buschmann
Date: Mon, 30 Jun 2025 16:18:51 +0200
Subject: [PATCH 22/22] Update CHANGELOG.md
---
CHANGELOG.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 6ac6282de1..0b52d12ecf 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -14,7 +14,7 @@
#### :boom: Breaking Change
-- The legacy rescript cli can be called through rewatch via `rewatch legacy`. Arguments to rewatch need to be passed after the subcommand. https://github.com/rescript-lang/rescript/pull/7551
+- The legacy rescript cli can be called through rewatch via `rewatch legacy`. Arguments to rewatch need to be passed after the subcommand. Argument `--compiler-args` is now a subcommand `compiler-args`. https://github.com/rescript-lang/rescript/pull/7551
#### :bug: Bug fix