Skip to content

Rewatch cli refactor #7551

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 2 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
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
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>,
},
}
35 changes: 35 additions & 0 deletions rewatch/src/helpers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -218,6 +218,41 @@ 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 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()
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