diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 56fe5d0f4b..20aaf9e920 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -110,13 +110,24 @@ jobs: uses: actions/cache@v4 with: path: rewatch/target - key: rewatch-build-v2-${{ matrix.rust-target }}-${{ hashFiles('rewatch/src/**', 'rewatch/Cargo.lock') }} + key: rewatch-build-v3-${{ matrix.rust-target }}-${{ hashFiles('rewatch/src/**', 'rewatch/Cargo.lock') }} + + - name: Determine Rust toolchain version + id: rust-version + shell: bash + run: | + version="$(awk -F '"' '/^rust-version[[:space:]]*=/ { print $2; exit }' rewatch/Cargo.toml)" + if [ -z "$version" ]; then + echo "rust-version missing in rewatch/Cargo.toml" >&2 + exit 1 + fi + echo "version=${version}" >> "$GITHUB_OUTPUT" - name: Install rust toolchain if: steps.rewatch-build-cache.outputs.cache-hit != 'true' uses: dtolnay/rust-toolchain@master with: - toolchain: 1.88.0 + toolchain: ${{ steps.rust-version.outputs.version }} targets: ${{ matrix.rust-target }} components: clippy, rustfmt diff --git a/CHANGELOG.md b/CHANGELOG.md index 24a6e753a5..a47f7f6016 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -32,6 +32,7 @@ - Rename Core to Stdlib in tests/tests. https://github.com/rescript-lang/rescript/pull/8005 - CI: Build on `windows-2025` runners. https://github.com/rescript-lang/rescript/pull/8006 +- Rewatch: upgrade Rust to 1.91.0. https://github.com/rescript-lang/rescript/pull/8007 # 12.0.0-rc.3 diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 81f361fb79..e86e6fe8f4 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -18,7 +18,7 @@ Happy hacking! - [Yarn CLI](https://yarnpkg.com/getting-started/install) (can be installed with `corepack`, Homebrew, etc) - C compiler toolchain (usually installed with `xcode` on Mac) - Python <= 3.11 (required to build ninja) -- Rust toolchain (required to build rewatch; follow the instructions at https://www.rust-lang.org/tools/install) +- Rust toolchain (required to build rewatch; follow the instructions at https://www.rust-lang.org/tools/install and install the version listed as `rust-version` in `rewatch/Cargo.toml`) - `opam` (OCaml Package Manager) v2.2.0 or newer - VSCode (+ [OCaml Platform Extension](https://marketplace.visualstudio.com/items?itemName=ocamllabs.ocaml-platform)) diff --git a/rewatch/Cargo.toml b/rewatch/Cargo.toml index df5f6cd6bc..c68ad659a0 100644 --- a/rewatch/Cargo.toml +++ b/rewatch/Cargo.toml @@ -2,7 +2,7 @@ name = "rescript" version = "12.0.0-rc.4" edition = "2024" -rust-version = "1.88" +rust-version = "1.91" [dependencies] ahash = "0.8.3" diff --git a/rewatch/src/build/clean.rs b/rewatch/src/build/clean.rs index a66a460769..13bc797ed9 100644 --- a/rewatch/src/build/clean.rs +++ b/rewatch/src/build/clean.rs @@ -175,10 +175,11 @@ pub fn cleanup_previous_build( // we do this by checking if the cmt file is newer than the AST file. We always compile the // interface AND implementation. For some reason the CMI file is not always rewritten if it // doesn't have any changes, that's why we just look at the CMT file. - if let Some(cmt_last_modified) = cmt_last_modified { - if cmt_last_modified > ast_last_modified && !deleted_interfaces.contains(module_name) { - module.compile_dirty = false; - } + if let Some(cmt_last_modified) = cmt_last_modified + && cmt_last_modified > ast_last_modified + && !deleted_interfaces.contains(module_name) + { + module.compile_dirty = false; } match &mut module.source_type { @@ -302,11 +303,11 @@ fn has_compile_warnings(module: &Module) -> bool { pub fn cleanup_after_build(build_state: &BuildCommandState) { build_state.modules.par_iter().for_each(|(_module_name, module)| { let package = build_state.get_package(&module.package_name).unwrap(); - if has_parse_warnings(module) { - if let SourceType::SourceFile(source_file) = &module.source_type { - remove_iast(package, &source_file.implementation.path); - remove_ast(package, &source_file.implementation.path); - } + if has_parse_warnings(module) + && let SourceType::SourceFile(source_file) = &module.source_type + { + remove_iast(package, &source_file.implementation.path); + remove_ast(package, &source_file.implementation.path); } if has_compile_warnings(module) { // only retain AST file if the compilation doesn't have warnings, we remove the AST in favor diff --git a/rewatch/src/build/compile.rs b/rewatch/src/build/compile.rs index 8048764f09..a0ec288437 100644 --- a/rewatch/src/build/compile.rs +++ b/rewatch/src/build/compile.rs @@ -368,12 +368,11 @@ pub fn compile( // so editor tooling can surface it from .compiler.log let mut touched_packages = AHashSet::::new(); for module_name in cycle.iter() { - if let Some(module) = build_state.get_module(module_name) { - if touched_packages.insert(module.package_name.clone()) { - if let Some(package) = build_state.get_package(&module.package_name) { - logs::append(package, &message); - } - } + if let Some(module) = build_state.get_module(module_name) + && touched_packages.insert(module.package_name.clone()) + && let Some(package) = build_state.get_package(&module.package_name) + { + logs::append(package, &message); } } @@ -795,24 +794,23 @@ fn compile_file( // copy js file root_config.get_package_specs().iter().for_each(|spec| { - if spec.in_source { - if let SourceType::SourceFile(SourceFile { + if spec.in_source + && let SourceType::SourceFile(SourceFile { implementation: Implementation { path, .. }, .. }) = &module.source_type - { - let source = helpers::get_source_file_from_rescript_file( - &Path::new(&package.path).join(path), - &root_config.get_suffix(spec), - ); - let destination = helpers::get_source_file_from_rescript_file( - &package.get_build_path().join(path), - &root_config.get_suffix(spec), - ); - - if source.exists() { - let _ = std::fs::copy(&source, &destination).expect("copying source file failed"); - } + { + let source = helpers::get_source_file_from_rescript_file( + &Path::new(&package.path).join(path), + &root_config.get_suffix(spec), + ); + let destination = helpers::get_source_file_from_rescript_file( + &package.get_build_path().join(path), + &root_config.get_suffix(spec), + ); + + if source.exists() { + let _ = std::fs::copy(&source, &destination).expect("copying source file failed"); } } }); @@ -912,10 +910,9 @@ pub fn mark_modules_with_expired_deps_dirty(build_state: &mut BuildCommandState) if let (Some(last_compiled_dependent), Some(last_compiled)) = (dependent_module.last_compiled_cmt, module.last_compiled_cmt) + && last_compiled_dependent < last_compiled { - if last_compiled_dependent < last_compiled { - modules_with_expired_deps.insert(dependent.to_string()); - } + modules_with_expired_deps.insert(dependent.to_string()); } } } diff --git a/rewatch/src/build/logs.rs b/rewatch/src/build/logs.rs index bb8aaf9d08..e993fec73b 100644 --- a/rewatch/src/build/logs.rs +++ b/rewatch/src/build/logs.rs @@ -55,7 +55,9 @@ pub fn initialize(packages: &AHashMap) { packages.par_iter().for_each(|(name, package)| { File::create(get_log_file_path(package, Location::Bs)) .map(|file| write_to_log_file(file, name, &format!("#Start({})\n", helpers::get_system_time()))) - .expect(&("Cannot create compiler log for package ".to_owned() + name)); + .unwrap_or_else(|err| { + panic!("Cannot create compiler log for package {name}: {err}"); + }); }) } @@ -64,10 +66,12 @@ pub fn append(package: &packages::Package, str: &str) { .append(true) .open(get_log_file_path(package, Location::Bs)) .map(|file| write_to_log_file(file, &package.name, str)) - .expect( - &("Cannot write compilerlog: ".to_owned() - + &get_log_file_path(package, Location::Bs).to_string_lossy()), - ); + .unwrap_or_else(|err| { + panic!( + "Cannot write compilerlog: {} ({err})", + get_log_file_path(package, Location::Bs).to_string_lossy() + ); + }); } pub fn finalize(packages: &AHashMap) { diff --git a/rewatch/src/build/packages.rs b/rewatch/src/build/packages.rs index fcb4856e71..c9ab7ae65b 100644 --- a/rewatch/src/build/packages.rs +++ b/rewatch/src/build/packages.rs @@ -882,10 +882,10 @@ fn get_unallowed_dependents( for deps_package_name in dependencies { if let Some(deps_package) = packages.get(deps_package_name) { let deps_allowed_dependents = deps_package.config.allowed_dependents.to_owned(); - if let Some(allowed_dependents) = deps_allowed_dependents { - if !allowed_dependents.contains(package_name) { - return Some(deps_package_name.to_string()); - } + if let Some(allowed_dependents) = deps_allowed_dependents + && !allowed_dependents.contains(package_name) + { + return Some(deps_package_name.to_string()); } } } diff --git a/rewatch/src/format.rs b/rewatch/src/format.rs index e7bf5c5707..cec0c43766 100644 --- a/rewatch/src/format.rs +++ b/rewatch/src/format.rs @@ -45,10 +45,10 @@ fn get_files_in_scope() -> Result> { && let Some(source_files) = &package.source_files { for (path, _metadata) in source_files { - if let Some(extension) = path.extension() { - if extension == "res" || extension == "resi" { - files.push(package.path.join(path).to_string_lossy().into_owned()); - } + if let Some(extension) = path.extension() + && (extension == "res" || extension == "resi") + { + files.push(package.path.join(path).to_string_lossy().into_owned()); } } } diff --git a/rewatch/src/main.rs b/rewatch/src/main.rs index ba74dbd393..cc8051ac43 100644 --- a/rewatch/src/main.rs +++ b/rewatch/src/main.rs @@ -18,11 +18,11 @@ fn main() -> Result<()> { let mut command = cli.command; - if let cli::Command::Build(build_args) = &command { - if build_args.watch { - log::warn!("`rescript build -w` is deprecated. Please use `rescript watch` instead."); - command = cli::Command::Watch(build_args.clone().into()); - } + if let cli::Command::Build(build_args) = &command + && build_args.watch + { + log::warn!("`rescript build -w` is deprecated. Please use `rescript watch` instead."); + command = cli::Command::Watch(build_args.clone().into()); } let is_tty: bool = Term::stdout().is_term() && Term::stderr().is_term(); diff --git a/rewatch/src/watcher.rs b/rewatch/src/watcher.rs index 2ce6d53989..b5c699ff28 100644 --- a/rewatch/src/watcher.rs +++ b/rewatch/src/watcher.rs @@ -37,10 +37,11 @@ fn is_in_build_path(path_buf: &Path) -> bool { let mut prev_component: Option<&std::ffi::OsStr> = None; for component in path_buf.components() { let comp_os = component.as_os_str(); - if let Some(prev) = prev_component { - if prev == "lib" && (comp_os == "bs" || comp_os == "ocaml") { - return true; - } + if let Some(prev) = prev_component + && prev == "lib" + && (comp_os == "bs" || comp_os == "ocaml") + { + return true; } prev_component = Some(comp_os); } @@ -116,14 +117,14 @@ async fn async_watch( for event in events { // if there is a file named rescript.lock in the events path, we can quit the watcher - if event.paths.iter().any(|path| path.ends_with(LOCKFILE)) { - if let EventKind::Remove(_) = event.kind { - if show_progress { - println!("\nExiting... (lockfile removed)"); - } - clean::cleanup_after_build(&build_state); - return Ok(()); + if event.paths.iter().any(|path| path.ends_with(LOCKFILE)) + && let EventKind::Remove(_) = event.kind + { + if show_progress { + println!("\nExiting... (lockfile removed)"); } + clean::cleanup_after_build(&build_state); + return Ok(()); } let paths = event