diff --git a/CHANGELOG.md b/CHANGELOG.md index 5afea5fa5d..9abef28ebd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -44,6 +44,7 @@ - Fix inside comment printing for empty dict. https://github.com/rescript-lang/rescript/pull/7654 - Fix I/O error message when trying to extract extra info from non-existing file. https://github.com/rescript-lang/rescript/pull/7656 - Fix fatal error when JSX expression used without configuring JSX in rescript.json. https://github.com/rescript-lang/rescript/pull/7656 +- Rewatch: Only allow access to `"bs-dev-dependencies"` from `"type": "dev"` source files. https://github.com/rescript-lang/rescript/pull/7650 # 12.0.0-beta.1 diff --git a/rewatch/src/build.rs b/rewatch/src/build.rs index 4545e3f0f3..d215e18b61 100644 --- a/rewatch/src/build.rs +++ b/rewatch/src/build.rs @@ -8,6 +8,8 @@ pub mod packages; pub mod parse; pub mod read_compile_state; +use self::compile::compiler_args; +use self::parse::parser_args; use crate::build::compile::{mark_modules_with_deleted_deps_dirty, mark_modules_with_expired_deps_dirty}; use crate::helpers::emojis::*; use crate::helpers::{self, get_workspace_root}; @@ -26,9 +28,6 @@ use std::path::{Path, PathBuf}; use std::process::Stdio; use std::time::{Duration, Instant}; -use self::compile::compiler_args; -use self::parse::parser_args; - fn is_dirty(module: &Module) -> bool { match module.source_type { SourceType::SourceFile(SourceFile { @@ -56,7 +55,7 @@ pub struct CompilerArgs { pub parser_args: Vec, } -pub fn get_compiler_args(path: &Path, build_dev_deps: bool) -> Result { +pub fn get_compiler_args(path: &Path) -> Result { let filename = &helpers::get_abs_path(path); let package_root = helpers::get_abs_path(&helpers::get_nearest_config(&path).expect("Couldn't find package root")); @@ -64,6 +63,10 @@ pub fn get_compiler_args(path: &Path, build_dev_deps: bool) -> Result { let root_rescript_config = packages::read_config(&workspace_root.to_owned().unwrap_or(package_root.to_owned()))?; let rescript_config = packages::read_config(&package_root)?; + let is_type_dev = match filename.strip_prefix(&package_root) { + Err(_) => false, + Ok(relative_path) => root_rescript_config.find_is_type_dev_for_path(relative_path), + }; // make PathBuf from package root and get the relative path for filename let relative_filename = filename.strip_prefix(PathBuf::from(&package_root)).unwrap(); @@ -97,7 +100,7 @@ pub fn get_compiler_args(path: &Path, build_dev_deps: bool) -> Result { &package_root, &workspace_root, &None, - build_dev_deps, + is_type_dev, true, ); @@ -281,7 +284,6 @@ pub fn incremental_build( show_progress: bool, only_incremental: bool, create_sourcedirs: bool, - build_dev_deps: bool, snapshot_output: bool, ) -> Result<(), IncrementalBuildError> { logs::initialize(&build_state.packages); @@ -393,7 +395,6 @@ pub fn incremental_build( show_progress, || pb.inc(1), |size| pb.set_length(size), - build_dev_deps, ) .map_err(|e| IncrementalBuildError { kind: IncrementalBuildErrorKind::CompileError(Some(e.to_string())), @@ -500,7 +501,6 @@ pub fn build( show_progress, false, create_sourcedirs, - build_dev_deps, snapshot_output, ) { Ok(_) => { diff --git a/rewatch/src/build/build_types.rs b/rewatch/src/build/build_types.rs index da1d976648..e8c1a28ee4 100644 --- a/rewatch/src/build/build_types.rs +++ b/rewatch/src/build/build_types.rs @@ -71,6 +71,7 @@ pub struct Module { pub last_compiled_cmi: Option, pub last_compiled_cmt: Option, pub deps_dirty: bool, + pub is_type_dev: bool, } impl Module { diff --git a/rewatch/src/build/compile.rs b/rewatch/src/build/compile.rs index 6f8f8e9327..494968f48d 100644 --- a/rewatch/src/build/compile.rs +++ b/rewatch/src/build/compile.rs @@ -22,7 +22,6 @@ pub fn compile( show_progress: bool, inc: impl Fn() + std::marker::Sync, set_length: impl Fn(u64), - build_dev_deps: bool, ) -> anyhow::Result<(String, String, usize)> { let mut compiled_modules = AHashSet::::new(); let dirty_modules = build_state @@ -170,7 +169,6 @@ pub fn compile( &build_state.packages, &build_state.project_root, &build_state.workspace_root, - build_dev_deps, ); Some(result) } @@ -186,7 +184,6 @@ pub fn compile( &build_state.packages, &build_state.project_root, &build_state.workspace_root, - build_dev_deps, ); let cmi_digest_after = helpers::compute_file_hash(Path::new(&cmi_path)); @@ -360,13 +357,13 @@ pub fn compiler_args( // if packages are known, we pass a reference here // this saves us a scan to find their paths packages: &Option<&AHashMap>, - build_dev_deps: bool, + // Is the file listed as "type":"dev"? + is_type_dev: bool, is_local_dep: bool, ) -> Vec { let bsc_flags = config::flatten_flags(&config.bsc_flags); - let dependency_paths = - get_dependency_paths(config, project_root, workspace_root, packages, build_dev_deps); + let dependency_paths = get_dependency_paths(config, project_root, workspace_root, packages, is_type_dev); let module_name = helpers::file_path_to_module_name(file_path, &config.get_namespace()); @@ -504,7 +501,7 @@ fn get_dependency_paths( project_root: &Path, workspace_root: &Option, packages: &Option<&AHashMap>, - build_dev_deps: bool, + is_file_type_dev: bool, ) -> Vec> { let normal_deps = config .bs_dependencies @@ -513,7 +510,9 @@ fn get_dependency_paths( .into_iter() .map(DependentPackage::Normal) .collect(); - let dev_deps = if build_dev_deps { + + // We can only access dev dependencies for source_files that are marked as "type":"dev" + let dev_deps = if is_file_type_dev { config .bs_dev_dependencies .clone() @@ -569,7 +568,6 @@ fn compile_file( packages: &AHashMap, project_root: &Path, workspace_root: &Option, - build_dev_deps: bool, ) -> Result, String> { let ocaml_build_path_abs = package.get_ocaml_build_path(); let build_path_abs = package.get_build_path(); @@ -583,6 +581,7 @@ fn compile_file( }?; let module_name = helpers::file_path_to_module_name(implementation_file_path, &package.namespace); let has_interface = module.get_interface().is_some(); + let is_type_dev = module.is_type_dev; let to_mjs_args = compiler_args( &package.config, &root_package.config, @@ -593,7 +592,7 @@ fn compile_file( project_root, workspace_root, &Some(packages), - build_dev_deps, + is_type_dev, package.is_local_dep, ); diff --git a/rewatch/src/build/packages.rs b/rewatch/src/build/packages.rs index 3ab8e1e308..2b4f193766 100644 --- a/rewatch/src/build/packages.rs +++ b/rewatch/src/build/packages.rs @@ -19,6 +19,7 @@ use std::time::SystemTime; #[derive(Debug, Clone)] pub struct SourceFileMeta { pub modified: SystemTime, + pub is_type_dev: bool, } #[derive(Debug, Clone)] @@ -112,6 +113,13 @@ impl Package { .expect("namespace should be set for mlmap module"); self.get_build_path().join(format!("{}.cmi", suffix)) } + + pub fn is_source_file_type_dev(&self, path: &Path) -> bool { + self.source_files + .as_ref() + .and_then(|sf| sf.get(path).map(|sfm| sfm.is_type_dev)) + .unwrap_or(false) + } } impl PartialEq for Package { @@ -138,6 +146,7 @@ pub fn read_folders( package_dir: &Path, path: &Path, recurse: bool, + is_type_dev: bool, ) -> Result, Box> { let mut map: AHashMap = AHashMap::new(); let path_buf = PathBuf::from(path); @@ -147,6 +156,7 @@ pub fn read_folders( path.to_owned(), SourceFileMeta { modified: meta.modified().unwrap(), + is_type_dev, }, ) }); @@ -159,7 +169,7 @@ pub fn read_folders( let path_ext = entry_path_buf.extension().and_then(|x| x.to_str()); let new_path = path_buf.join(&name); if metadata.file_type().is_dir() && recurse { - match read_folders(filter, package_dir, &new_path, recurse) { + match read_folders(filter, package_dir, &new_path, recurse, is_type_dev) { Ok(s) => map.extend(s), Err(e) => log::error!("Could not read directory: {}", e), } @@ -174,6 +184,7 @@ pub fn read_folders( path, SourceFileMeta { modified: metadata.modified().unwrap(), + is_type_dev, }, ); } @@ -297,11 +308,16 @@ fn read_dependencies( project_root: &Path, workspace_root: &Option, show_progress: bool, + build_dev_deps: bool, ) -> Vec { - return parent_config - .bs_dependencies - .to_owned() - .unwrap_or_default() + let mut dependencies = parent_config.bs_dependencies.to_owned().unwrap_or_default(); + + // Concatenate dev dependencies if build_dev_deps is true + if build_dev_deps && let Some(dev_deps) = parent_config.bs_dev_dependencies.to_owned() { + dependencies.extend(dev_deps); + } + + dependencies .iter() .filter_map(|package_name| { if registered_dependencies_set.contains(package_name) { @@ -360,7 +376,8 @@ fn read_dependencies( &canonical_path, project_root, workspace_root, - show_progress + show_progress, + build_dev_deps ); Dependency { @@ -371,7 +388,7 @@ fn read_dependencies( dependencies, } }) - .collect::>(); + .collect() } fn flatten_dependencies(dependencies: Vec) -> Vec { @@ -461,6 +478,7 @@ fn read_packages( project_root: &Path, workspace_root: &Option, show_progress: bool, + build_dev_deps: bool, ) -> Result> { let root_config = read_config(project_root)?; @@ -477,6 +495,7 @@ fn read_packages( project_root, workspace_root, show_progress, + build_dev_deps, )); dependencies.iter().for_each(|d| { if !map.contains_key(&d.name) { @@ -515,9 +534,14 @@ pub fn get_source_files( }; let path_dir = Path::new(&source.dir); + let is_type_dev = type_ + .as_ref() + .map(|t| t.as_str() == "dev") + .unwrap_or(false) + .clone(); match (build_dev_deps, type_) { (false, Some(type_)) if type_ == "dev" => (), - _ => match read_folders(filter, package_dir, path_dir, recurse) { + _ => match read_folders(filter, package_dir, path_dir, recurse, is_type_dev) { Ok(files) => map.extend(files), Err(_e) => log::error!( @@ -596,7 +620,7 @@ pub fn make( show_progress: bool, build_dev_deps: bool, ) -> Result> { - let map = read_packages(root_folder, workspace_root, show_progress)?; + let map = read_packages(root_folder, workspace_root, show_progress, build_dev_deps)?; /* Once we have the deduplicated packages, we can add the source files for each - to minimize * the IO */ @@ -720,6 +744,8 @@ pub fn parse_packages(build_state: &mut BuildState) { compile_dirty: false, last_compiled_cmt: None, last_compiled_cmi: None, + // Not sure if this is correct + is_type_dev: false, }, ); }); @@ -772,6 +798,7 @@ pub fn parse_packages(build_state: &mut BuildState) { compile_dirty: true, last_compiled_cmt: None, last_compiled_cmi: None, + is_type_dev: metadata.is_type_dev, }); } else { // remove last character of string: resi -> res, rei -> re, mli -> ml @@ -833,6 +860,7 @@ pub fn parse_packages(build_state: &mut BuildState) { compile_dirty: true, last_compiled_cmt: None, last_compiled_cmi: None, + is_type_dev: metadata.is_type_dev, }); } } diff --git a/rewatch/src/cli.rs b/rewatch/src/cli.rs index 5967ffc9a7..544e8c8637 100644 --- a/rewatch/src/cli.rs +++ b/rewatch/src/cli.rs @@ -214,9 +214,6 @@ pub enum Command { /// Path to a rescript file (.res or .resi) #[command()] path: String, - - #[command(flatten)] - dev: DevArg, }, /// Use the legacy build system. /// diff --git a/rewatch/src/config.rs b/rewatch/src/config.rs index 254d2ed22c..b547ea61c4 100644 --- a/rewatch/src/config.rs +++ b/rewatch/src/config.rs @@ -29,6 +29,15 @@ pub struct PackageSource { pub type_: Option, } +impl PackageSource { + fn is_type_dev(&self) -> bool { + match &self.type_ { + Some(type_) => type_ == "dev", + None => false, + } + } +} + impl Eq for PackageSource {} #[derive(Deserialize, Debug, Clone, PartialEq, Hash)] @@ -99,6 +108,35 @@ impl Source { }, } } + + fn find_is_type_dev_for_sub_folder( + &self, + relative_parent_path: &Path, + target_source_folder: &Path, + ) -> bool { + match &self { + Source::Shorthand(sub_folder) => { + relative_parent_path.join(Path::new(sub_folder)) == *target_source_folder + } + Source::Qualified(package_source) => { + // Note that we no longer check if type_ is dev of the nested subfolder. + // A parent was type:dev, so we assume all subfolders are as well. + let next_parent_path = relative_parent_path.join(Path::new(&package_source.dir)); + if next_parent_path == *target_source_folder { + return true; + }; + + match &package_source.subdirs { + None => false, + Some(Subdirs::Recurse(false)) => false, + Some(Subdirs::Recurse(true)) => target_source_folder.starts_with(&next_parent_path), + Some(Subdirs::Qualified(nested_sources)) => nested_sources.iter().any(|nested_source| { + nested_source.find_is_type_dev_for_sub_folder(&next_parent_path, target_source_folder) + }), + } + } + } + } } impl Eq for Source {} @@ -182,7 +220,7 @@ pub type GenTypeConfig = serde_json::Value; /// # bsconfig.json representation /// This is tricky, there is a lot of ambiguity. This is probably incomplete. -#[derive(Deserialize, Debug, Clone)] +#[derive(Deserialize, Debug, Clone, Default)] pub struct Config { pub name: String, // In the case of monorepos, the root source won't necessarily have to have sources. It can @@ -470,6 +508,48 @@ impl Config { .or(self.suffix.clone()) .unwrap_or(".js".to_string()) } + + // TODO: needs improving! + + pub fn find_is_type_dev_for_path(&self, relative_path: &Path) -> bool { + let relative_parent = match relative_path.parent() { + None => return false, + Some(parent) => Path::new(parent), + }; + + let package_sources = match self.sources.as_ref() { + None => vec![], + Some(OneOrMore::Single(Source::Shorthand(_))) => vec![], + Some(OneOrMore::Single(Source::Qualified(source))) => vec![source], + Some(OneOrMore::Multiple(multiple)) => multiple + .iter() + .filter_map(|source| match source { + Source::Shorthand(_) => None, + Source::Qualified(package_source) => Some(package_source), + }) + .collect(), + }; + + package_sources.iter().any(|package_source| { + if !package_source.is_type_dev() { + false + } else { + let dir_path = Path::new(&package_source.dir); + if dir_path == relative_parent { + return true; + }; + + match &package_source.subdirs { + None => false, + Some(Subdirs::Recurse(false)) => false, + Some(Subdirs::Recurse(true)) => relative_path.starts_with(dir_path), + Some(Subdirs::Qualified(sub_dirs)) => sub_dirs + .iter() + .any(|sub_dir| sub_dir.find_is_type_dev_for_sub_folder(dir_path, relative_parent)), + } + } + }) + } } #[cfg(test)] @@ -771,4 +851,105 @@ mod tests { Some(vec!["@testrepo/main".to_string()]) ); } + + fn test_find_is_type_dev(source: OneOrMore, path: &Path, expected: bool) { + let config = Config { + name: String::from("testrepo"), + sources: Some(source), + ..Default::default() + }; + let result = config.find_is_type_dev_for_path(path); + assert_eq!(result, expected); + } + + #[test] + fn test_find_is_type_dev_for_exact_match() { + test_find_is_type_dev( + OneOrMore::Single(Source::Qualified(PackageSource { + dir: String::from("src"), + subdirs: None, + type_: Some(String::from("dev")), + })), + Path::new("src/Foo.res"), + true, + ) + } + + #[test] + fn test_find_is_type_dev_for_none_dev() { + test_find_is_type_dev( + OneOrMore::Single(Source::Qualified(PackageSource { + dir: String::from("src"), + subdirs: None, + type_: None, + })), + Path::new("src/Foo.res"), + false, + ) + } + + #[test] + fn test_find_is_type_dev_for_multiple_sources() { + test_find_is_type_dev( + OneOrMore::Multiple(vec![Source::Qualified(PackageSource { + dir: String::from("src"), + subdirs: None, + type_: Some(String::from("dev")), + })]), + Path::new("src/Foo.res"), + true, + ) + } + + #[test] + fn test_find_is_type_dev_for_shorthand() { + test_find_is_type_dev( + OneOrMore::Multiple(vec![Source::Shorthand(String::from("src"))]), + Path::new("src/Foo.res"), + false, + ) + } + + #[test] + fn test_find_is_type_dev_for_recursive_folder() { + test_find_is_type_dev( + OneOrMore::Multiple(vec![Source::Qualified(PackageSource { + dir: String::from("src"), + subdirs: Some(Subdirs::Recurse(true)), + type_: Some(String::from("dev")), + })]), + Path::new("src/bar/Foo.res"), + true, + ) + } + + #[test] + fn test_find_is_type_dev_for_sub_folder() { + test_find_is_type_dev( + OneOrMore::Multiple(vec![Source::Qualified(PackageSource { + dir: String::from("src"), + subdirs: Some(Subdirs::Qualified(vec![Source::Qualified(PackageSource { + dir: String::from("bar"), + subdirs: None, + type_: None, + })])), + type_: Some(String::from("dev")), + })]), + Path::new("src/bar/Foo.res"), + true, + ) + } + + #[test] + fn test_find_is_type_dev_for_sub_folder_shorthand() { + test_find_is_type_dev( + OneOrMore::Multiple(vec![Source::Qualified(PackageSource { + dir: String::from("src"), + subdirs: Some(Subdirs::Qualified(vec![Source::Shorthand(String::from("bar"))])), + type_: Some(String::from("dev")), + })]), + Path::new("src/bar/Foo.res"), + true, + ) + } } diff --git a/rewatch/src/main.rs b/rewatch/src/main.rs index cb9a57fcd2..a5d3d31d96 100644 --- a/rewatch/src/main.rs +++ b/rewatch/src/main.rs @@ -30,8 +30,8 @@ fn main() -> Result<()> { let show_progress = log_level_filter == LevelFilter::Info; match command { - cli::Command::CompilerArgs { path, dev } => { - println!("{}", build::get_compiler_args(Path::new(&path), *dev)?); + cli::Command::CompilerArgs { path } => { + println!("{}", build::get_compiler_args(Path::new(&path))?); std::process::exit(0); } cli::Command::Build(build_args) => { diff --git a/rewatch/src/watcher.rs b/rewatch/src/watcher.rs index f9fb7f6398..2843a9d110 100644 --- a/rewatch/src/watcher.rs +++ b/rewatch/src/watcher.rs @@ -217,7 +217,6 @@ async fn async_watch( show_progress, !initial_build, create_sourcedirs, - build_dev_deps, snapshot_output, ) .is_ok() @@ -262,7 +261,6 @@ async fn async_watch( show_progress, false, create_sourcedirs, - build_dev_deps, snapshot_output, ); if let Some(a) = after_build.clone() { diff --git a/rewatch/testrepo/packages/with-dev-deps/package.json b/rewatch/testrepo/packages/with-dev-deps/package.json index 007ab59b9a..ba75a51072 100644 --- a/rewatch/testrepo/packages/with-dev-deps/package.json +++ b/rewatch/testrepo/packages/with-dev-deps/package.json @@ -5,5 +5,8 @@ "rescript" ], "author": "", - "license": "MIT" + "license": "MIT", + "devDependencies": { + "@rescript/webapi": "0.1.0-experimental-73e6a0d" + } } diff --git a/rewatch/testrepo/packages/with-dev-deps/rescript.json b/rewatch/testrepo/packages/with-dev-deps/rescript.json index 8cae5b6dcc..77d543741b 100644 --- a/rewatch/testrepo/packages/with-dev-deps/rescript.json +++ b/rewatch/testrepo/packages/with-dev-deps/rescript.json @@ -9,6 +9,9 @@ "type": "dev" } ], + "bs-dev-dependencies": [ + "@rescript/webapi" + ], "package-specs": { "module": "es6", "in-source": true diff --git a/rewatch/testrepo/yarn.lock b/rewatch/testrepo/yarn.lock index fa0f31c40a..b51c2075ba 100644 --- a/rewatch/testrepo/yarn.lock +++ b/rewatch/testrepo/yarn.lock @@ -12,6 +12,13 @@ __metadata: languageName: node linkType: hard +"@rescript/darwin-arm64@npm:12.0.0-beta.1": + version: 12.0.0-beta.1 + resolution: "@rescript/darwin-arm64@npm:12.0.0-beta.1" + conditions: os=darwin & cpu=arm64 + languageName: node + linkType: hard + "@rescript/darwin-x64@npm:12.0.0-alpha.15": version: 12.0.0-alpha.15 resolution: "@rescript/darwin-x64@npm:12.0.0-alpha.15" @@ -19,6 +26,13 @@ __metadata: languageName: node linkType: hard +"@rescript/darwin-x64@npm:12.0.0-beta.1": + version: 12.0.0-beta.1 + resolution: "@rescript/darwin-x64@npm:12.0.0-beta.1" + conditions: os=darwin & cpu=x64 + languageName: node + linkType: hard + "@rescript/linux-arm64@npm:12.0.0-alpha.15": version: 12.0.0-alpha.15 resolution: "@rescript/linux-arm64@npm:12.0.0-alpha.15" @@ -26,6 +40,13 @@ __metadata: languageName: node linkType: hard +"@rescript/linux-arm64@npm:12.0.0-beta.1": + version: 12.0.0-beta.1 + resolution: "@rescript/linux-arm64@npm:12.0.0-beta.1" + conditions: os=linux & cpu=arm64 + languageName: node + linkType: hard + "@rescript/linux-x64@npm:12.0.0-alpha.15": version: 12.0.0-alpha.15 resolution: "@rescript/linux-x64@npm:12.0.0-alpha.15" @@ -33,6 +54,22 @@ __metadata: languageName: node linkType: hard +"@rescript/linux-x64@npm:12.0.0-beta.1": + version: 12.0.0-beta.1 + resolution: "@rescript/linux-x64@npm:12.0.0-beta.1" + conditions: os=linux & cpu=x64 + languageName: node + linkType: hard + +"@rescript/webapi@npm:0.1.0-experimental-73e6a0d": + version: 0.1.0-experimental-73e6a0d + resolution: "@rescript/webapi@npm:0.1.0-experimental-73e6a0d" + dependencies: + rescript: "npm:^12.0.0-alpha.13" + checksum: 10c0/71553ebc51fec9c29ef5d1b4a4f6954cd9e29b622629005e29128504cc5a40d26e50308935b5d2e51c653b61674f096b731615c5c8399bd152517e32824554a8 + languageName: node + linkType: hard + "@rescript/win32-x64@npm:12.0.0-alpha.15": version: 12.0.0-alpha.15 resolution: "@rescript/win32-x64@npm:12.0.0-alpha.15" @@ -40,6 +77,13 @@ __metadata: languageName: node linkType: hard +"@rescript/win32-x64@npm:12.0.0-beta.1": + version: 12.0.0-beta.1 + resolution: "@rescript/win32-x64@npm:12.0.0-beta.1" + conditions: os=win32 & cpu=x64 + 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" @@ -90,6 +134,8 @@ __metadata: "@testrepo/with-dev-deps@workspace:packages/with-dev-deps": version: 0.0.0-use.local resolution: "@testrepo/with-dev-deps@workspace:packages/with-dev-deps" + dependencies: + "@rescript/webapi": "npm:0.1.0-experimental-73e6a0d" languageName: unknown linkType: soft @@ -123,6 +169,36 @@ __metadata: languageName: node linkType: hard +"rescript@npm:^12.0.0-alpha.13": + version: 12.0.0-beta.1 + resolution: "rescript@npm:12.0.0-beta.1" + dependencies: + "@rescript/darwin-arm64": "npm:12.0.0-beta.1" + "@rescript/darwin-x64": "npm:12.0.0-beta.1" + "@rescript/linux-arm64": "npm:12.0.0-beta.1" + "@rescript/linux-x64": "npm:12.0.0-beta.1" + "@rescript/win32-x64": "npm:12.0.0-beta.1" + dependenciesMeta: + "@rescript/darwin-arm64": + optional: true + "@rescript/darwin-x64": + optional: true + "@rescript/linux-arm64": + optional: true + "@rescript/linux-x64": + optional: true + "@rescript/win32-x64": + optional: true + bin: + bsc: cli/bsc.js + bstracing: cli/bstracing.js + rescript: cli/rescript.js + rescript-legacy: cli/rescript-legacy.js + rescript-tools: cli/rescript-tools.js + checksum: 10c0/ec18e0ccd0791dec7b2bfaa44e0a011e1f171025d0743e06b51f7f4d81c8333bdf3b02f47b72f5b9a5cfa409bdf51e64998833696314e77b6f51afe376a4c3ad + languageName: node + linkType: hard + "testrepo@workspace:.": version: 0.0.0-use.local resolution: "testrepo@workspace:." diff --git a/rewatch/tests/compile.sh b/rewatch/tests/compile.sh index 15f1bf09c3..31c1f9f9f7 100755 --- a/rewatch/tests/compile.sh +++ b/rewatch/tests/compile.sh @@ -81,6 +81,13 @@ echo 'Dep01.log()' >> packages/new-namespace/src/NS_alias.res rewatch build --snapshot-output &> ../tests/snapshots/dependency-cycle.txt git checkout -- packages/new-namespace/src/NS_alias.res +# this should not compile because "@rescript/webapi" is part of bs-dev-dependencies +# and FileToTest.res is not listed as "type":"dev" +echo 'open WebAPI' >> packages/with-dev-deps/src/FileToTest.res +rewatch build --snapshot-output &> ../tests/snapshots/bs-dev-dependency-used-by-non-dev-source.txt +normalize_paths ../tests/snapshots/bs-dev-dependency-used-by-non-dev-source.txt +git checkout -- packages/with-dev-deps/src/FileToTest.res + # it should compile dev dependencies with the --dev flag rewatch clean --dev &> /dev/null rewatch build --dev &> /dev/null; diff --git a/rewatch/tests/snapshots/bs-dev-dependency-used-by-non-dev-source.txt b/rewatch/tests/snapshots/bs-dev-dependency-used-by-non-dev-source.txt new file mode 100644 index 0000000000..cdd55a694f --- /dev/null +++ b/rewatch/tests/snapshots/bs-dev-dependency-used-by-non-dev-source.txt @@ -0,0 +1,19 @@ +Cleaned 0/15 +Parsed 2 source files +Compiled 2 modules + + We've found a bug for you! + /packages/with-dev-deps/src/FileToTest.res:2:6-11 + + 1 │ let add = (a, b) => a + b + 2 │ open WebAPI + 3 │ + + The module or file WebAPI can't be found. + - If it's a third-party dependency: + - Did you add it to the "bs-dependencies" or "bs-dev-dependencies" in rescript.json? + - Did you include the file's directory to the "sources" in rescript.json? + + + +Incremental build failed. Error:  Failed to Compile. See Errors Above diff --git a/rewatch/tests/utils.sh b/rewatch/tests/utils.sh index bef51f9fce..c183f7f1f7 100644 --- a/rewatch/tests/utils.sh +++ b/rewatch/tests/utils.sh @@ -35,7 +35,10 @@ normalize_paths() { else if is_windows; then sed -i "s#$(pwd_prefix)##g" $1 + # Then normalize backslashes to forward slashes sed -i "s#\\\\#/#g" $1 + # Finally remove any remaining drive letter paths (like D:/a/rescript/rescript/rewatch/testrepo) + sed -i "s#[A-Z]:/\(a/\)\?[^:]*rescript/rescript/rewatch/testrepo##g" $1 else sed -i "s#$(pwd_prefix)##g" $1; fi