Fork of daniellemaywood.uk/gleam — Wasm codegen work
2

Configure Feed

Select the types of activity you want to include in your feed.

improve error message for version that does not exist

+112 -13
+48 -9
compiler-core/src/dependency.rs
··· 478 478 use hexpm::RetirementStatus; 479 479 480 480 use crate::{ 481 - derivation_tree::DerivationTreePrinter, 482 481 manifest::{Base16Checksum, ManifestPackage, ManifestPackageSource}, 483 482 requirement, 484 483 }; ··· 1174 1173 &vec![].into_iter().collect(), 1175 1174 ); 1176 1175 1177 - if let Err(Error::DependencyResolutionNoSolution { 1178 - root_package_name, 1179 - derivation_tree, 1180 - }) = result 1181 - { 1182 - let message = crate::error::wrap( 1183 - &DerivationTreePrinter::new(root_package_name, derivation_tree.0).print(), 1184 - ); 1176 + if let Err(error @ Error::DependencyResolutionNoSolution { .. }) = result { 1177 + let message = error.pretty_string(); 1178 + insta::assert_snapshot!(message) 1179 + } else { 1180 + panic!("expected a resolution error message") 1181 + } 1182 + } 1183 + 1184 + #[test] 1185 + fn adding_package_version_that_does_not_exist() { 1186 + let remote = remote(vec![( 1187 + "wibble", 1188 + vec![release("1.2.0", vec![]), release("1.3.0", vec![])], 1189 + )]); 1190 + 1191 + let result = resolve_versions( 1192 + &remote, 1193 + HashMap::new(), 1194 + "app".into(), 1195 + vec![("wibble".into(), Range::new("1.0.0".into()).unwrap())].into_iter(), 1196 + &vec![].into_iter().collect(), 1197 + ); 1198 + 1199 + if let Err(error @ Error::DependencyResolutionNoSolution { .. }) = result { 1200 + let message = error.pretty_string(); 1201 + insta::assert_snapshot!(message) 1202 + } else { 1203 + panic!("expected a resolution error message") 1204 + } 1205 + } 1206 + 1207 + #[test] 1208 + fn adding_package_version_that_does_not_exist_2() { 1209 + let remote = remote(vec![( 1210 + "wibble", 1211 + vec![release("1.2.0", vec![]), release("1.3.0", vec![])], 1212 + )]); 1213 + 1214 + let result = resolve_versions( 1215 + &remote, 1216 + HashMap::new(), 1217 + "app".into(), 1218 + vec![("wibble".into(), Range::new("> 2.0.0".into()).unwrap())].into_iter(), 1219 + &vec![].into_iter().collect(), 1220 + ); 1221 + 1222 + if let Err(error @ Error::DependencyResolutionNoSolution { .. }) = result { 1223 + let message = error.pretty_string(); 1185 1224 insta::assert_snapshot!(message) 1186 1225 } else { 1187 1226 panic!("expected a resolution error message")
+48 -2
compiler-core/src/derivation_tree.rs
··· 71 71 } 72 72 73 73 pub fn print(&self) -> String { 74 - self.pretty_explanation() 74 + self.explanation_for_missing_version() 75 + .or_else(|| self.explanation_for_complex_failure()) 75 76 .unwrap_or_else(|| self.fallback_explanation()) 76 77 } 77 78 79 + /// This catches the case in which we try adding a dependency's version that 80 + /// doesn't exist. That produces a very simple decision tree with just two 81 + /// nodes and can have an ad hoc explanation, telling the user the version 82 + /// they tried adding doesn't exist! 83 + /// 84 + fn explanation_for_missing_version(&self) -> Option<String> { 85 + if let DerivationTree::External(External::FromDependencyOf( 86 + base, 87 + _, 88 + package, 89 + package_ranges, 90 + )) = &self.derivation_tree 91 + && *base == self.root_package_name 92 + { 93 + let pretty_range = pretty_range(package_ranges); 94 + let message = if is_single_version(package_ranges) { 95 + format!("The package `{package}` doesn't have a version {pretty_range}.") 96 + } else { 97 + format!("The package `{package}` has no versions in the range {pretty_range}.",) 98 + }; 99 + Some(message) 100 + } else { 101 + None 102 + } 103 + } 104 + 78 105 /// Tries and print a pretty explanation for the given resolution tree. 79 106 /// If for some reason our heuristic to produce a nice error message fails 80 107 /// we return `None` so we can still produce a good enough error message! 81 108 /// 82 - fn pretty_explanation(&self) -> Option<String> { 109 + fn explanation_for_complex_failure(&self) -> Option<String> { 83 110 let root_package_index = self.nodes.get(self.root_package_name.as_str())?; 84 111 let unresolvable_nodes = self.find_unresolvable_nodes(); 85 112 if unresolvable_nodes.is_empty() { ··· 357 384 }) 358 385 .join(" or ") 359 386 } 387 + 388 + fn is_single_version(range: &Ranges<Version>) -> bool { 389 + // Note: at the time of writing this, `Ranges` has a method called 390 + // `as_singleton` which, according to its doc, should do the same thing. 391 + // However, it strangely seems to consider as a single version ranges like 392 + // this one `> 11.0.0 and <= 12.0.0`. To me this doesn't read as a single 393 + // version! 394 + 395 + // The range needs to have exactly one segment that includes exactly one 396 + // version number. 397 + let mut segments = range.iter(); 398 + if let Some((Included(lower), Included(upper))) = segments.next() 399 + && segments.next().is_none() 400 + { 401 + lower == upper 402 + } else { 403 + false 404 + } 405 + }
+7
compiler-core/src/snapshots/gleam_core__dependency__tests__adding_package_version_that_does_not_exist.snap
··· 1 + --- 2 + source: compiler-core/src/dependency.rs 3 + expression: message 4 + --- 5 + error: Dependency resolution failed 6 + 7 + The package `wibble` doesn't have a version 1.0.0.
+7
compiler-core/src/snapshots/gleam_core__dependency__tests__adding_package_version_that_does_not_exist_2.snap
··· 1 + --- 2 + source: compiler-core/src/dependency.rs 3 + expression: message 4 + --- 5 + error: Dependency resolution failed 6 + 7 + The package `wibble` has no versions in the range >= 2.0.1.
+2 -2
compiler-core/src/snapshots/gleam_core__dependency__tests__resolution_error_message.snap
··· 1 1 --- 2 2 source: compiler-core/src/dependency.rs 3 - assertion_line: 1091 4 3 expression: message 5 - snapshot_kind: text 6 4 --- 5 + error: Dependency resolution failed 6 + 7 7 There's no compatible version of `woo`: 8 8 - You require woo >= 2.0.0 and < 3.0.0 9 9 - You require wibble >= 1.0.0 and < 2.0.0