Skip to content

Commit 9798cad

Browse files
authored
Fix crash on missing dev dependency (#161)
1 parent 8542dfd commit 9798cad

15 files changed

+120
-53
lines changed

src/build/compile.rs

Lines changed: 80 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -364,33 +364,10 @@ pub fn compiler_args(
364364
packages: &Option<&AHashMap<String, packages::Package>>,
365365
build_dev_deps: bool,
366366
) -> Vec<String> {
367-
let normal_deps = config.bs_dependencies.as_ref().unwrap_or(&vec![]).to_owned();
368-
369367
let bsc_flags = config::flatten_flags(&config.bsc_flags);
370-
// don't compile dev-deps yet
371-
let dev_deps = if build_dev_deps {
372-
config.bs_dev_dependencies.as_ref().unwrap_or(&vec![]).to_owned()
373-
} else {
374-
vec![]
375-
};
376368

377-
let deps = [dev_deps, normal_deps]
378-
.concat()
379-
.par_iter()
380-
.map(|package_name| {
381-
let canonicalized_path = if let Some(packages) = packages {
382-
let package = packages.get(package_name).expect("expect package");
383-
package.path.to_string()
384-
} else {
385-
packages::read_dependency(package_name, project_root, project_root, workspace_root)
386-
.expect("cannot find dep")
387-
};
388-
vec![
389-
"-I".to_string(),
390-
packages::get_ocaml_build_path(&canonicalized_path),
391-
]
392-
})
393-
.collect::<Vec<Vec<String>>>();
369+
let dependency_paths =
370+
get_dependency_paths(config, project_root, workspace_root, packages, build_dev_deps);
394371

395372
let module_name = helpers::file_path_to_module_name(file_path, &config.get_namespace());
396373

@@ -476,7 +453,7 @@ pub fn compiler_args(
476453
namespace_args,
477454
read_cmi_args,
478455
vec!["-I".to_string(), "../ocaml".to_string()],
479-
deps.concat(),
456+
dependency_paths.concat(),
480457
uncurried_args,
481458
bsc_flags.to_owned(),
482459
warning_args,
@@ -497,6 +474,83 @@ pub fn compiler_args(
497474
.concat()
498475
}
499476

477+
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
478+
enum DependentPackage {
479+
Normal(String),
480+
Dev(String),
481+
}
482+
483+
impl DependentPackage {
484+
fn name(&self) -> &str {
485+
match self {
486+
Self::Normal(name) => name,
487+
Self::Dev(name) => name,
488+
}
489+
}
490+
491+
fn is_dev(&self) -> bool {
492+
match self {
493+
Self::Normal(_) => false,
494+
Self::Dev(_) => true,
495+
}
496+
}
497+
}
498+
499+
fn get_dependency_paths(
500+
config: &config::Config,
501+
project_root: &str,
502+
workspace_root: &Option<String>,
503+
packages: &Option<&AHashMap<String, packages::Package>>,
504+
build_dev_deps: bool,
505+
) -> Vec<Vec<String>> {
506+
let normal_deps = config
507+
.bs_dependencies
508+
.clone()
509+
.unwrap_or_default()
510+
.into_iter()
511+
.map(DependentPackage::Normal)
512+
.collect();
513+
let dev_deps = if build_dev_deps {
514+
config
515+
.bs_dev_dependencies
516+
.clone()
517+
.unwrap_or_default()
518+
.into_iter()
519+
.map(DependentPackage::Dev)
520+
.collect()
521+
} else {
522+
vec![]
523+
};
524+
525+
[dev_deps, normal_deps]
526+
.concat()
527+
.par_iter()
528+
.filter_map(|dependent_package| {
529+
let package_name = dependent_package.name();
530+
let dependency_path = if let Some(packages) = packages {
531+
packages.get(package_name).map(|package| package.path.to_string())
532+
} else {
533+
packages::read_dependency(package_name, project_root, project_root, workspace_root).ok()
534+
}
535+
.map(|canonicalized_path| {
536+
vec![
537+
"-I".to_string(),
538+
packages::get_ocaml_build_path(&canonicalized_path),
539+
]
540+
});
541+
542+
if !dependent_package.is_dev() && dependency_path.is_none() {
543+
panic!(
544+
"Expected to find dependent package {} of {}",
545+
package_name, config.name
546+
);
547+
}
548+
549+
dependency_path
550+
})
551+
.collect::<Vec<Vec<String>>>()
552+
}
553+
500554
fn compile_file(
501555
package: &packages::Package,
502556
root_package: &packages::Package,

src/config.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -289,7 +289,7 @@ fn check_if_rescript11_or_higher(version: &str) -> Result<bool, String> {
289289
fn namespace_from_package_name(package_name: &str) -> String {
290290
let len = package_name.len();
291291
let mut buf = String::with_capacity(len);
292-
292+
293293
fn aux(s: &str, capital: bool, buf: &mut String, off: usize) {
294294
if off >= s.len() {
295295
return;
@@ -529,7 +529,7 @@ mod tests {
529529

530530
let config = serde_json::from_str::<Config>(json).unwrap();
531531
if let Some(OneOrMore::Multiple(sources)) = config.sources {
532-
let src_dir = sources[0].to_qualified_without_children(None);
532+
assert_eq!(sources.len(), 2);
533533
let test_dir = sources[1].to_qualified_without_children(None);
534534

535535
assert_eq!(test_dir.type_, Some(String::from("dev")));

testrepo/packages/with-dev-deps/package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
"author": "",
88
"license": "MIT",
99
"dependencies": {
10-
"rescript": "*"
10+
"rescript": "*",
11+
"@rescript/core": "*"
1112
}
1213
}

testrepo/packages/with-dev-deps/rescript.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,5 +13,6 @@
1313
"module": "es6",
1414
"in-source": true
1515
},
16+
"bs-dependencies": ["@rescript/core"],
1617
"suffix": ".res.js"
1718
}

testrepo/yarn.lock

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,12 @@
22
# yarn lockfile v1
33

44

5+
"@rescript/core@*":
6+
version "1.6.1"
7+
resolved "https://registry.yarnpkg.com/@rescript/core/-/core-1.6.1.tgz#159670c94d64a2b8236f46be2bf09a007b1ece08"
8+
integrity sha512-vyb5k90ck+65Fgui+5vCja/mUfzKaK3kOPT4Z6aAJdHLH1eljEi1zKhXroCiCtpNLSWp8k4ulh1bdB5WS0hvqA==
9+
510
rescript@*:
6-
version "11.0.0"
7-
resolved "https://registry.yarnpkg.com/rescript/-/rescript-11.0.0.tgz#9a0b6fc998c360543c459aba49b77a572a0306cd"
8-
integrity sha512-uIUwDZZmDUb7ymGkBiiGioxMg8hXh1mze/2k/qhYQcZGgi7PrLHQIW9AksM7gb9WnpjCAvFsA8U2VgC0nA468w==
11+
version "11.1.4"
12+
resolved "https://registry.yarnpkg.com/rescript/-/rescript-11.1.4.tgz#9a42ebc4fc5363707e39cef5b3188160b63bee42"
13+
integrity sha512-0bGU0bocihjSC6MsE3TMjHjY0EUpchyrREquLS8VsZ3ohSMD+VHUEwimEfB3kpBI1vYkw3UFZ3WD8R28guz/Vw==

tests/compile.sh

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -33,51 +33,57 @@ fi
3333
node ./packages/main/src/Main.mjs > ./packages/main/src/output.txt
3434

3535
mv ./packages/main/src/Main.res ./packages/main/src/Main2.res
36-
rewatch build --no-timing=true &> ../tests/snapshots/rename-file.txt
36+
rewatch build &> ../tests/snapshots/rename-file.txt
3737
mv ./packages/main/src/Main2.res ./packages/main/src/Main.res
3838

3939
# Rename a file with a dependent - this should trigger an error
4040
mv ./packages/main/src/InternalDep.res ./packages/main/src/InternalDep2.res
41-
rewatch build --no-timing=true &> ../tests/snapshots/rename-file-internal-dep.txt
41+
rewatch build &> ../tests/snapshots/rename-file-internal-dep.txt
4242
# replace the absolute path so the snapshot is the same on all machines
4343
replace "s/$(pwd | sed "s/\//\\\\\//g")//g" ../tests/snapshots/rename-file-internal-dep.txt
4444
mv ./packages/main/src/InternalDep2.res ./packages/main/src/InternalDep.res
4545

4646
# Rename a file with a dependent in a namespaced package - this should trigger an error (regression)
4747
mv ./packages/new-namespace/src/Other_module.res ./packages/new-namespace/src/Other_module2.res
48-
rewatch build --no-timing=true &> ../tests/snapshots/rename-file-internal-dep-namespace.txt
48+
rewatch build &> ../tests/snapshots/rename-file-internal-dep-namespace.txt
4949
# replace the absolute path so the snapshot is the same on all machines
5050
replace "s/$(pwd | sed "s/\//\\\\\//g")//g" ../tests/snapshots/rename-file-internal-dep-namespace.txt
5151
mv ./packages/new-namespace/src/Other_module2.res ./packages/new-namespace/src/Other_module.res
5252

5353
rewatch build &> /dev/null
5454
mv ./packages/main/src/ModuleWithInterface.resi ./packages/main/src/ModuleWithInterface2.resi
55-
rewatch build --no-timing=true &> ../tests/snapshots/rename-interface-file.txt
55+
rewatch build &> ../tests/snapshots/rename-interface-file.txt
5656
mv ./packages/main/src/ModuleWithInterface2.resi ./packages/main/src/ModuleWithInterface.resi
5757
rewatch build &> /dev/null
5858
mv ./packages/main/src/ModuleWithInterface.res ./packages/main/src/ModuleWithInterface2.res
59-
rewatch build --no-timing=true &> ../tests/snapshots/rename-file-with-interface.txt
59+
rewatch build &> ../tests/snapshots/rename-file-with-interface.txt
6060
mv ./packages/main/src/ModuleWithInterface2.res ./packages/main/src/ModuleWithInterface.res
6161
rewatch build &> /dev/null
6262

6363
# when deleting a file that other files depend on, the compile should fail
6464
rm packages/dep02/src/Dep02.res
65-
rewatch build --no-timing=true &> ../tests/snapshots/remove-file.txt
65+
rewatch build &> ../tests/snapshots/remove-file.txt
6666
# replace the absolute path so the snapshot is the same on all machines
6767
replace "s/$(pwd | sed "s/\//\\\\\//g")//g" ../tests/snapshots/remove-file.txt
6868
git checkout -- packages/dep02/src/Dep02.res
6969
rewatch build &> /dev/null
7070

7171
# it should show an error when we have a dependency cycle
7272
echo 'Dep01.log()' >> packages/new-namespace/src/NS_alias.res
73-
rewatch build --no-timing=true &> ../tests/snapshots/dependency-cycle.txt
73+
rewatch build &> ../tests/snapshots/dependency-cycle.txt
7474
git checkout -- packages/new-namespace/src/NS_alias.res
75-
rewatch build &> /dev/null
7675

7776
# it should compile dev dependencies with the --dev flag
78-
rewatch build --dev &> /dev/null
79-
file_count=$(find ./packages/with-dev-deps -name *.mjs | wc -l)
80-
if [ "$file_count" -eq 2 ];
77+
rewatch clean &> /dev/null
78+
rewatch build --dev &> /dev/null;
79+
if [ $? -ne 0 ];
80+
then
81+
error "Failed to compile dev dependencies"
82+
exit 1
83+
fi
84+
85+
file_count=$(find ./packages/with-dev-deps/test -name *.mjs | wc -l)
86+
if [ "$file_count" -eq 1 ];
8187
then
8288
success "Compiled dev dependencies successfully"
8389
else

tests/snapshots/dependency-cycle.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
[1/7] 📦 Building package tree...[1/7] 📦 Built package tree in 0.00s
22
[2/7] 👀 Finding source files...[2/7] 👀 Found source files in 0.00s
33
[3/7] 📝 Reading compile state...[3/7] 📝 Read compile state 0.00s
4-
[4/7] 🧹 Cleaning up previous build...[4/7] 🧹 Cleaned 0/14 0.00s
4+
[4/7] 🧹 Cleaning up previous build...[4/7] 🧹 Cleaned 0/94 0.00s
55
[5/7] 🧱 Parsed 1 source files in 0.00s
66
[6/7] 🌴 Collected deps in 0.00s
77
[7/7] ❌ Compiled 0 modules in 0.00s

tests/snapshots/remove-file.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
[1/7] 📦 Building package tree...[1/7] 📦 Built package tree in 0.00s
22
[2/7] 👀 Finding source files...[2/7] 👀 Found source files in 0.00s
33
[3/7] 📝 Reading compile state...[3/7] 📝 Read compile state 0.00s
4-
[4/7] 🧹 Cleaning up previous build...[4/7] 🧹 Cleaned 1/14 0.00s
4+
[4/7] 🧹 Cleaning up previous build...[4/7] 🧹 Cleaned 1/94 0.00s
55
[5/7] 🧱 Parsed 0 source files in 0.00s
66
[6/7] 🌴 Collected deps in 0.00s
77
[7/7] ❌ Compiled 1 modules in 0.00s

tests/snapshots/rename-file-internal-dep-namespace.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
[1/7] 📦 Building package tree...[1/7] 📦 Built package tree in 0.00s
22
[2/7] 👀 Finding source files...[2/7] 👀 Found source files in 0.00s
33
[3/7] 📝 Reading compile state...[3/7] 📝 Read compile state 0.00s
4-
[4/7] 🧹 Cleaning up previous build...[4/7] 🧹 Cleaned 2/14 0.00s
4+
[4/7] 🧹 Cleaning up previous build...[4/7] 🧹 Cleaned 2/94 0.00s
55
[5/7] 🧱 Parsed 2 source files in 0.00s
66
[6/7] 🌴 Collected deps in 0.00s
77
[7/7] ❌ Compiled 3 modules in 0.00s

tests/snapshots/rename-file-internal-dep.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
[1/7] 📦 Building package tree...[1/7] 📦 Built package tree in 0.00s
22
[2/7] 👀 Finding source files...[2/7] 👀 Found source files in 0.00s
33
[3/7] 📝 Reading compile state...[3/7] 📝 Read compile state 0.00s
4-
[4/7] 🧹 Cleaning up previous build...[4/7] 🧹 Cleaned 2/14 0.00s
4+
[4/7] 🧹 Cleaning up previous build...[4/7] 🧹 Cleaned 2/94 0.00s
55
[5/7] 🧱 Parsed 2 source files in 0.00s
66
[6/7] 🌴 Collected deps in 0.00s
77
[7/7] ❌ Compiled 2 modules in 0.00s

0 commit comments

Comments
 (0)