Skip to content
Merged
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
33 changes: 31 additions & 2 deletions rewatch/src/build.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
pub mod build_types;
pub mod clean;
pub mod compile;
pub mod compiler_info;
pub mod deps;
pub mod logs;
pub mod namespaces;
Expand All @@ -10,6 +11,7 @@ pub mod read_compile_state;

use self::parse::parser_args;
use crate::build::compile::{mark_modules_with_deleted_deps_dirty, mark_modules_with_expired_deps_dirty};
use crate::build::compiler_info::{CompilerCheckResult, verify_compiler_info, write_compiler_info};
use crate::helpers::emojis::*;
use crate::helpers::{self};
use crate::project_context::ProjectContext;
Expand Down Expand Up @@ -109,6 +111,20 @@ pub fn get_compiler_args(rescript_file_path: &Path) -> Result<String> {
Ok(result)
}

pub fn get_compiler_info(project_context: &ProjectContext) -> Result<CompilerInfo> {
let bsc_path = helpers::get_bsc();
let bsc_hash = helpers::compute_file_hash(&bsc_path).ok_or(anyhow!(
"Failed to compute bsc hash for {}",
bsc_path.to_string_lossy()
))?;
let runtime_path = compile::get_runtime_path(&project_context.current_config, project_context)?;
Ok(CompilerInfo {
bsc_path,
bsc_hash,
runtime_path,
})
}

pub fn initialize_build(
default_timing: Option<Duration>,
filter: &Option<regex::Regex>,
Expand All @@ -117,8 +133,8 @@ pub fn initialize_build(
build_dev_deps: bool,
snapshot_output: bool,
) -> Result<BuildState> {
let bsc_path = helpers::get_bsc();
let project_context = ProjectContext::new(path)?;
let compiler = get_compiler_info(&project_context)?;

if !snapshot_output && show_progress {
print!("{} {}Building package tree...", style("[1/7]").bold().dim(), TREE);
Expand All @@ -129,6 +145,8 @@ pub fn initialize_build(
let packages = packages::make(filter, &project_context, show_progress, build_dev_deps)?;
let timing_package_tree_elapsed = timing_package_tree.elapsed();

let compiler_check = verify_compiler_info(&packages, &compiler);

if !snapshot_output && show_progress {
println!(
"{}{} {}Built package tree in {:.2}s",
Expand All @@ -139,6 +157,14 @@ pub fn initialize_build(
.unwrap_or(timing_package_tree_elapsed)
.as_secs_f64()
);
if let CompilerCheckResult::CleanedPackagesDueToCompiler = compiler_check {
println!(
"{}{} {}Cleaned previous build due to compiler update",
LINE_CLEAR,
style("[1/7]").bold().dim(),
SWEEP
);
}
}

if !packages::validate_packages_dependencies(&packages) {
Expand All @@ -156,7 +182,7 @@ pub fn initialize_build(
let _ = stdout().flush();
}

let mut build_state = BuildState::new(project_context, packages, bsc_path);
let mut build_state = BuildState::new(project_context, packages, compiler);
packages::parse_packages(&mut build_state);
let timing_source_files_elapsed = timing_source_files.elapsed();

Expand Down Expand Up @@ -448,6 +474,9 @@ pub fn incremental_build(
log_deprecations(build_state);
}

// Write per-package compiler metadata to `lib/bs/compiler-info.json` (idempotent)
write_compiler_info(build_state);

Ok(())
}
}
Expand Down
14 changes: 11 additions & 3 deletions rewatch/src/build/build_types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ use crate::build::packages::{Namespace, Package};
use crate::config::Config;
use crate::project_context::ProjectContext;
use ahash::{AHashMap, AHashSet};
use blake3::Hash;
use std::{fmt::Display, path::PathBuf, time::SystemTime};

#[derive(Debug, Clone, PartialEq)]
Expand Down Expand Up @@ -96,10 +97,17 @@ pub struct BuildState {
pub packages: AHashMap<String, Package>,
pub module_names: AHashSet<String>,
pub deleted_modules: AHashSet<String>,
pub bsc_path: PathBuf,
pub compiler_info: CompilerInfo,
pub deps_initialized: bool,
}

#[derive(Debug, Clone)]
pub struct CompilerInfo {
pub bsc_path: PathBuf,
pub bsc_hash: Hash,
pub runtime_path: PathBuf,
}

impl BuildState {
pub fn get_package(&self, package_name: &str) -> Option<&Package> {
self.packages.get(package_name)
Expand All @@ -111,15 +119,15 @@ impl BuildState {
pub fn new(
project_context: ProjectContext,
packages: AHashMap<String, Package>,
bsc_path: PathBuf,
compiler: CompilerInfo,
) -> Self {
Self {
project_context,
module_names: AHashSet::new(),
modules: AHashMap::new(),
packages,
deleted_modules: AHashSet::new(),
bsc_path,
compiler_info: compiler,
deps_initialized: false,
}
}
Expand Down
11 changes: 7 additions & 4 deletions rewatch/src/build/clean.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use super::build_types::*;
use super::packages;
use crate::build;
use crate::build::packages::Package;
use crate::config::Config;
use crate::helpers;
Expand Down Expand Up @@ -332,9 +333,8 @@ pub fn cleanup_after_build(build_state: &BuildState) {

pub fn clean(path: &Path, show_progress: bool, snapshot_output: bool, clean_dev_deps: bool) -> Result<()> {
let project_context = ProjectContext::new(path)?;

let compiler_info = build::get_compiler_info(&project_context)?;
let packages = packages::make(&None, &project_context, show_progress, clean_dev_deps)?;
let bsc_path = helpers::get_bsc();

let timing_clean_compiler_assets = Instant::now();
if !snapshot_output && show_progress {
Expand Down Expand Up @@ -364,7 +364,7 @@ pub fn clean(path: &Path, show_progress: bool, snapshot_output: bool, clean_dev_
}

let timing_clean_mjs = Instant::now();
let mut build_state = BuildState::new(project_context, packages, bsc_path);
let mut build_state = BuildState::new(project_context, packages, compiler_info);
packages::parse_packages(&mut build_state);
let root_config = build_state.get_root_config();
let suffix_for_print = if snapshot_output || !show_progress {
Expand Down Expand Up @@ -418,7 +418,7 @@ pub fn clean(path: &Path, show_progress: bool, snapshot_output: bool, clean_dev_
Ok(())
}

fn clean_package(show_progress: bool, snapshot_output: bool, package: &Package) {
pub fn clean_package(show_progress: bool, snapshot_output: bool, package: &Package) {
if show_progress {
if snapshot_output {
println!("Cleaning {}", package.name)
Expand All @@ -441,4 +441,7 @@ fn clean_package(show_progress: bool, snapshot_output: bool, package: &Package)
let path_str = package.get_ocaml_build_path();
let path = std::path::Path::new(&path_str);
let _ = std::fs::remove_dir_all(path);

// remove the per-package compiler metadata file so that a subsequent build writes fresh metadata
let _ = std::fs::remove_file(package.get_compiler_info_path());
}
42 changes: 29 additions & 13 deletions rewatch/src/build/compile.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,9 @@ use console::style;
use log::{debug, trace};
use rayon::prelude::*;
use std::path::Path;
use std::path::PathBuf;
use std::process::Command;
use std::sync::OnceLock;
use std::time::SystemTime;

pub fn compile(
Expand Down Expand Up @@ -336,22 +338,36 @@ pub fn compile(
Ok((compile_errors, compile_warnings, num_compiled_modules))
}

pub fn get_runtime_path_args(
package_config: &Config,
project_context: &ProjectContext,
) -> Result<Vec<String>> {
match std::env::var("RESCRIPT_RUNTIME") {
Ok(runtime_path) => Ok(vec!["-runtime-path".to_string(), runtime_path]),
static RUNTIME_PATH_MEMO: OnceLock<PathBuf> = OnceLock::new();

pub fn get_runtime_path(package_config: &Config, project_context: &ProjectContext) -> Result<PathBuf> {
if let Some(p) = RUNTIME_PATH_MEMO.get() {
return Ok(p.clone());
}

let resolved = match std::env::var("RESCRIPT_RUNTIME") {
Ok(runtime_path) => Ok(PathBuf::from(runtime_path)),
Err(_) => match helpers::try_package_path(package_config, project_context, "@rescript/runtime") {
Ok(runtime_path) => Ok(vec![
"-runtime-path".to_string(),
runtime_path.to_string_lossy().to_string(),
]),
Ok(runtime_path) => Ok(runtime_path),
Err(err) => Err(anyhow!(
"The rescript runtime package could not be found.\nPlease set RESCRIPT_RUNTIME environment variable or make sure the runtime package is installed.\nError: {err}"
)),
},
}
}?;

let _ = RUNTIME_PATH_MEMO.set(resolved.clone());
Ok(resolved)
}

pub fn get_runtime_path_args(
package_config: &Config,
project_context: &ProjectContext,
) -> Result<Vec<String>> {
let runtime_path = get_runtime_path(package_config, project_context)?;
Ok(vec![
"-runtime-path".to_string(),
runtime_path.to_string_lossy().to_string(),
])
}

pub fn compiler_args(
Expand Down Expand Up @@ -581,7 +597,7 @@ fn compile_file(
let BuildState {
packages,
project_context,
bsc_path,
compiler_info,
..
} = build_state;
let root_config = build_state.get_root_config();
Expand Down Expand Up @@ -612,7 +628,7 @@ fn compile_file(
package.is_local_dep,
)?;

let to_mjs = Command::new(bsc_path)
let to_mjs = Command::new(&compiler_info.bsc_path)
.current_dir(
build_path_abs
.canonicalize()
Expand Down
Loading
Loading