Skip to content
Merged
Show file tree
Hide file tree
Changes from 13 commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
* text=auto eol=lf

*.ml linguist-language=OCaml
*.mli linguist-language=OCaml
*.res linguist-language=ReScript
Expand Down
28 changes: 25 additions & 3 deletions cli/rewatch.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,32 @@ import { rewatch_exe, bsc_exe } from "./common/bins.js";

const args = process.argv.slice(2);

const firstPositionalArgIndex = args.findIndex((arg) => !arg.startsWith("-"));

try {
child_process.execFileSync(rewatch_exe, [...args, "--bsc-path", bsc_exe], {
stdio: "inherit",
});
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], {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why do we need this branch? can we not just pass --bsc-path in both cases?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

bsc-path is not a root level arg anymore

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It might be an option to use an env var BSC_PATH instead to avoid this problem?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like this idea. Either that, or we promote --bsc-path to a root level argument again. If we decide for the env var would this be in addition to the arg?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My thinking was that it would replace the arg. What's your opinion @jfrolich?

stdio: "inherit",
});
}
}
} catch (err) {
if (err.status !== undefined) {
process.exit(err.status); // Pass through the exit code
Expand Down
17 changes: 17 additions & 0 deletions rewatch/src/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -551,3 +553,18 @@ pub fn build(
}
}
}

pub fn pass_through_legacy(args: Vec<OsString>) -> 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)
}
6 changes: 3 additions & 3 deletions rewatch/src/build/clean.rs
Original file line number Diff line number Diff line change
Expand Up @@ -335,7 +335,6 @@ pub fn clean(
path: &Path,
show_progress: bool,
bsc_path: &Option<PathBuf>,
build_dev_deps: bool,
snapshot_output: bool,
) -> Result<()> {
let project_root = helpers::get_abs_path(path);
Expand All @@ -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 {
Expand Down
178 changes: 178 additions & 0 deletions rewatch/src/cli.rs
Original file line number Diff line number Diff line change
@@ -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<InfoLevel>,

/// The command to run. If not provided it will default to build.
#[command(subcommand)]
pub command: Option<Command>,

/// 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<String>,

/// 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<String>,

/// 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<String>,
}

#[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<String>,

/// 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<String>,

/// 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<String>,
}

#[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<String>,

/// 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<OsString>,
},
/// Alias to `legacy dump`.
#[command(disable_help_flag = true)]
Dump {
#[arg(allow_hyphen_values = true, num_args = 0..)]
dump_args: Vec<OsString>,
},
/// 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<String>,

/// A custom path to bsc
#[arg(long)]
bsc_path: Option<String>,
},
/// 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<OsString>,
},
}
46 changes: 36 additions & 10 deletions rewatch/src/helpers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -181,32 +181,35 @@ 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>) -> PathBuf {
fn get_bin_dir() -> 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",
("windows", _) => "win32-x64",
_ => panic!("Unsupported architecture"),
};

Path::new("node_modules")
.join("@rescript")
.join(subfolder)
.join("bin")
}

pub fn get_bsc(root_path: &Path, workspace_root: &Option<PathBuf>) -> 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)
Expand All @@ -218,6 +221,29 @@ pub fn get_bsc(root_path: &Path, workspace_root: &Option<PathBuf>) -> PathBuf {
}
}

pub fn get_rescript_legacy(root_path: &Path, workspace_root: Option<PathBuf>) -> PathBuf {
let bin_dir = get_bin_dir();

match (
root_path
.join(&bin_dir)
.join("rescript.exe")
.canonicalize()
.map(StrippedVerbatimPath::to_stripped_verbatim_path),
workspace_root.map(|workspace_root| {
workspace_root
.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.exe"),
}
}

pub fn string_ends_with_any(s: &Path, suffixes: &[&str]) -> bool {
suffixes
.iter()
Expand Down
1 change: 1 addition & 0 deletions rewatch/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
pub mod build;
pub mod cli;
pub mod cmd;
pub mod config;
pub mod helpers;
Expand Down
Loading
Loading