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

Configure Feed

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

Change warning to error

+75 -164
+1 -5
CHANGELOG.md
··· 69 69 spans. 70 70 ([Giacomo Cavalieri](https://github.com/giacomocavalieri)) 71 71 72 - - The compiler now emits a warning when a module in the `src` directory imports 72 + - The compiler now emits an error when a module in the `src` directory imports 73 73 a dev dependency. 74 74 ([Surya Rose](https://github.com/GearsDatapacks)) 75 75 ··· 81 81 - `gleam add` now adds `dependencies` and `dev-dependencies` as tables instead 82 82 of inline tables if they are missing. 83 83 ([Andrey Kozhev](https://github.com/ankddev)) 84 - 85 - - The build tool now prevents publishing packages and exporting Erlang shipments 86 - when a module in the package's `src` directory imports a dev dependency. 87 - ([Surya Rose](https://github.com/GearsDatapacks)) 88 84 89 85 ### Language server 90 86
-15
compiler-cli/src/export.rs
··· 3 3 Result, 4 4 analyse::TargetSupport, 5 5 build::{Codegen, Compile, Mode, Options, Target}, 6 - error::Error, 7 6 paths::ProjectPaths, 8 7 }; 9 8 ··· 52 51 }, 53 52 crate::build::download_dependencies(paths, crate::cli::Reporter::new())?, 54 53 )?; 55 - 56 - let mut modules_importing_dev_dependencies = Vec::new(); 57 - 58 - for module in built.root_package.modules.iter() { 59 - if module.ast.type_info.imports_dev_dependency() { 60 - modules_importing_dev_dependencies.push(module.name.clone()); 61 - } 62 - } 63 - 64 - if !modules_importing_dev_dependencies.is_empty() { 65 - return Err(Error::CannotExportShipmentImportingDevDependency { 66 - modules: modules_importing_dev_dependencies, 67 - }); 68 - } 69 54 70 55 for entry in crate::fs::read_dir(&build)?.filter_map(Result::ok) { 71 56 let path = entry.path();
-9
compiler-cli/src/publish.rs
··· 357 357 // refuse to publish as the package is not yet finished. 358 358 let mut modules_containing_todo = vec![]; 359 359 let mut modules_containing_echo = vec![]; 360 - let mut modules_importing_dev_dependencies = vec![]; 361 360 362 361 for module in built.root_package.modules.iter() { 363 362 if module.ast.type_info.contains_todo() { 364 363 modules_containing_todo.push(module.name.clone()); 365 364 } else if module.ast.type_info.contains_echo { 366 365 modules_containing_echo.push(module.name.clone()); 367 - } else if module.ast.type_info.imports_dev_dependency() { 368 - modules_importing_dev_dependencies.push(module.name.clone()); 369 366 } 370 367 } 371 368 ··· 378 375 if !modules_containing_echo.is_empty() { 379 376 return Err(Error::CannotPublishEcho { 380 377 unfinished: modules_containing_echo, 381 - }); 382 - } 383 - 384 - if !modules_importing_dev_dependencies.is_empty() { 385 - return Err(Error::CannotPublishImportingDevDependency { 386 - modules: modules_importing_dev_dependencies, 387 378 }); 388 379 } 389 380
+1 -5
compiler-core/src/analyse/imports.rs
··· 61 61 62 62 if let Err(e) = self.check_for_invalid_imports(module_info, location) { 63 63 self.problems.error(e); 64 - return; 65 64 } 66 65 67 66 if let Err(e) = self.register_module(import, module_info) { ··· 248 247 module_info: &ModuleInterface, 249 248 location: SrcSpan, 250 249 ) -> Result<(), Error> { 251 - // Files in `src` are not allowed to import dev dependencies. We can't 252 - // raise an error here, as that would be a breaking change, so we must 253 - // raise a warning instead. 254 250 if self.origin.is_src() 255 251 && self 256 252 .environment 257 253 .dev_dependencies 258 254 .contains(&module_info.package) 259 255 { 260 - self.problems.warning(Warning::SrcImportingDevDependency { 256 + return Err(Error::SrcImportingDevDependency { 261 257 importing_module: self.environment.current_module.clone(), 262 258 imported_module: module_info.name.clone(), 263 259 package: module_info.package.clone(),
+28 -48
compiler-core/src/error.rs
··· 298 298 )] 299 299 CannotPublishLeakedInternalType { unfinished: Vec<EcoString> }, 300 300 301 - #[error("The modules {modules:?} import dev dependencies cannot be published")] 302 - CannotPublishImportingDevDependency { modules: Vec<EcoString> }, 303 - 304 - #[error("The modules {modules:?} import dev dependencies cannot be exported")] 305 - CannotExportShipmentImportingDevDependency { modules: Vec<EcoString> }, 306 - 307 301 #[error("Publishing packages to reserve names is not permitted")] 308 302 HexPackageSquatting, 309 303 ··· 1044 1038 Please make sure internal types do not appear in public functions and try again. 1045 1039 ", 1046 1040 unfinished 1047 - .iter() 1048 - .map(|name| format!(" - {}", name.as_str())) 1049 - .join("\n") 1050 - ), 1051 - level: Level::Error, 1052 - hint: None, 1053 - location: None, 1054 - }], 1055 - 1056 - Error::CannotPublishImportingDevDependency { modules } => vec![Diagnostic { 1057 - title: "Cannot publish code importing dev dependencies".into(), 1058 - text: wrap_format!( 1059 - "These modules import dev dependencies and cannot be published: 1060 - 1061 - {} 1062 - 1063 - Dev dependencies are not available for published packages, so publishing code \ 1064 - importing them would lead to invalid code when this package is added as a \ 1065 - dependency. Please make sure your package does not import dev dependencies and \ 1066 - try again.", 1067 - modules 1068 - .iter() 1069 - .map(|name| format!(" - {}", name.as_str())) 1070 - .join("\n") 1071 - ), 1072 - level: Level::Error, 1073 - hint: None, 1074 - location: None, 1075 - }], 1076 - 1077 - Error::CannotExportShipmentImportingDevDependency { modules } => vec![Diagnostic { 1078 - title: "Cannot export code importing dev dependencies".into(), 1079 - text: wrap_format!( 1080 - "These modules import dev dependencies and cannot be export \ 1081 - as an Erlang shipment: 1082 - 1083 - {} 1084 - 1085 - Dev dependencies are not available for production builds, so exported code \ 1086 - importing them would lead to invalid code when run. Please make sure your \ 1087 - package does not import dev dependencies and try again.", 1088 - modules 1089 1041 .iter() 1090 1042 .map(|name| format!(" - {}", name.as_str())) 1091 1043 .join("\n") ··· 3934 3886 location: Some(Location { 3935 3887 label: Label { 3936 3888 text: Some("You can safely remove this.".to_string()), 3889 + span: *location, 3890 + }, 3891 + path: path.clone(), 3892 + src: src.clone(), 3893 + extra_labels: vec![], 3894 + }), 3895 + }, 3896 + 3897 + TypeError::SrcImportingDevDependency { 3898 + location, 3899 + importing_module, 3900 + imported_module, 3901 + package, 3902 + } => Diagnostic { 3903 + title: "App importing dev dependency".to_string(), 3904 + text: wrap_format!( 3905 + "The application module `{importing_module}` is \ 3906 + importing the module `{imported_module}`, but `{package}`, the package it \ 3907 + belongs to, is a dev dependency. 3908 + 3909 + Dev dependencies are not included in production builds so application \ 3910 + modules should not import them. Perhaps change `{package}` to a regular dependency." 3911 + ), 3912 + hint: None, 3913 + level: Level::Error, 3914 + location: Some(Location { 3915 + label: Label { 3916 + text: None, 3937 3917 span: *location, 3938 3918 }, 3939 3919 path: path.clone(),
-6
compiler-core/src/type_.rs
··· 1003 1003 pub fn contains_todo(&self) -> bool { 1004 1004 self.warnings.iter().any(|warning| warning.is_todo()) 1005 1005 } 1006 - 1007 - pub fn imports_dev_dependency(&self) -> bool { 1008 - self.warnings 1009 - .iter() 1010 - .any(|warning| warning.imports_dev_dependency()) 1011 - } 1012 1006 } 1013 1007 1014 1008 #[derive(Debug, Clone, PartialEq, Eq, Default)]
+10 -14
compiler-core/src/type_/error.rs
··· 648 648 PrivateOpaqueType { 649 649 location: SrcSpan, 650 650 }, 651 + 652 + SrcImportingDevDependency { 653 + importing_module: EcoString, 654 + imported_module: EcoString, 655 + package: EcoString, 656 + location: SrcSpan, 657 + }, 651 658 } 652 659 653 660 #[derive(Debug, Clone, Copy, PartialEq, Eq)] ··· 1053 1060 location: SrcSpan, 1054 1061 outcome: ComparisonOutcome, 1055 1062 }, 1056 - 1057 - SrcImportingDevDependency { 1058 - importing_module: EcoString, 1059 - imported_module: EcoString, 1060 - package: EcoString, 1061 - location: SrcSpan, 1062 - }, 1063 1063 } 1064 1064 1065 1065 #[derive(Debug, Eq, Copy, PartialEq, Clone, serde::Serialize, serde::Deserialize)] ··· 1219 1219 | Error::StringConcatenationWithAddInt { location } 1220 1220 | Error::DoubleVariableAssignmentInBitArray { location } 1221 1221 | Error::NonUtf8StringAssignmentInBitArray { location } 1222 - | Error::PrivateOpaqueType { location } => location.start, 1222 + | Error::PrivateOpaqueType { location } 1223 + | Error::SrcImportingDevDependency { location, .. } => location.start, 1223 1224 Error::UnknownLabels { unknown, .. } => { 1224 1225 unknown.iter().map(|(_, s)| s.start).min().unwrap_or(0) 1225 1226 } ··· 1289 1290 | Warning::ModuleImportedTwice { 1290 1291 second: location, .. 1291 1292 } 1292 - | Warning::RedundantComparison { location, .. } 1293 - | Warning::SrcImportingDevDependency { location, .. } => *location, 1293 + | Warning::RedundantComparison { location, .. } => *location, 1294 1294 } 1295 1295 } 1296 1296 ··· 1299 1299 Self::Todo { .. } => true, 1300 1300 _ => false, 1301 1301 } 1302 - } 1303 - 1304 - pub(crate) fn imports_dev_dependency(&self) -> bool { 1305 - matches!(self, Self::SrcImportingDevDependency { .. }) 1306 1302 } 1307 1303 } 1308 1304
+16
compiler-core/src/type_/tests.rs
··· 101 101 output.push_str(&format!("-- main.gleam\n{}\n\n----- ERROR\n{error}", $src)); 102 102 insta::assert_snapshot!(insta::internals::AutoName, output, $src); 103 103 }; 104 + 105 + ($(($package:literal, $name:expr, $module_src:literal)),+, $src:literal $(,)?) => { 106 + let error = $crate::type_::tests::module_error( 107 + $src, 108 + vec![ 109 + $(($package, $name, $module_src)),* 110 + ], 111 + ); 112 + 113 + let mut output = String::from("----- SOURCE CODE\n"); 114 + for (name, src) in [$(($name, $module_src)),*] { 115 + output.push_str(&format!("-- {name}.gleam\n{src}\n\n")); 116 + } 117 + output.push_str(&format!("-- main.gleam\n{}\n\n----- ERROR\n{error}", $src)); 118 + insta::assert_snapshot!(insta::internals::AutoName, output, $src); 119 + }; 104 120 } 105 121 106 122 #[macro_export]
+14
compiler-core/src/type_/tests/errors.rs
··· 3294 3294 " 3295 3295 ); 3296 3296 } 3297 + 3298 + #[test] 3299 + fn src_importing_dev_dependency() { 3300 + assert_module_error!( 3301 + ("dev_dependency", "some_module", "pub fn main() { Nil }"), 3302 + " 3303 + import some_module 3304 + 3305 + pub fn main() { 3306 + some_module.main() 3307 + } 3308 + " 3309 + ); 3310 + }
+5 -7
compiler-core/src/type_/tests/snapshots/gleam_core__type___tests__warnings__warn_when_src_imports_dev_dependency.snap compiler-core/src/type_/tests/snapshots/gleam_core__type___tests__errors__src_importing_dev_dependency.snap
··· 1 1 --- 2 - source: compiler-core/src/type_/tests/warnings.rs 2 + source: compiler-core/src/type_/tests/errors.rs 3 3 expression: "\nimport some_module\n\npub fn main() {\n some_module.main()\n}\n" 4 4 --- 5 5 ----- SOURCE CODE ··· 15 15 } 16 16 17 17 18 - ----- WARNING 19 - warning: App importing dev dependency 20 - ┌─ /src/warning/wrn.gleam:2:1 18 + ----- ERROR 19 + error: App importing dev dependency 20 + ┌─ /src/one/two.gleam:2:1 21 21 22 22 2 │ import some_module 23 23 │ ^^^^^^^^^^^^^^^^^^ 24 24 25 - The application module `test_module` is importing the module `some_module`, 25 + The application module `themodule` is importing the module `some_module`, 26 26 but `dev_dependency`, the package it belongs to, is a dev dependency. 27 27 28 28 Dev dependencies are not included in production builds so application 29 29 modules should not import them. Perhaps change `dev_dependency` to a 30 30 regular dependency. 31 - 32 - In a future version of Gleam this may become a compile error.
-14
compiler-core/src/type_/tests/warnings.rs
··· 4211 4211 " 4212 4212 ); 4213 4213 } 4214 - 4215 - #[test] 4216 - fn warn_when_src_imports_dev_dependency() { 4217 - assert_warning!( 4218 - ("dev_dependency", "some_module", "pub fn main() { Nil }"), 4219 - " 4220 - import some_module 4221 - 4222 - pub fn main() { 4223 - some_module.main() 4224 - } 4225 - " 4226 - ); 4227 - }
-33
compiler-core/src/warning.rs
··· 1353 1353 extra_labels: vec![], 1354 1354 }), 1355 1355 }, 1356 - 1357 - type_::Warning::SrcImportingDevDependency { 1358 - location, 1359 - importing_module, 1360 - imported_module, 1361 - package, 1362 - } => { 1363 - let text = wrap(&format!( 1364 - "The application module `{importing_module}` is \ 1365 - importing the module `{imported_module}`, but `{package}`, the package it \ 1366 - belongs to, is a dev dependency. 1367 - 1368 - Dev dependencies are not included in production builds so application \ 1369 - modules should not import them. Perhaps change `{package}` to a regular dependency. 1370 - 1371 - In a future version of Gleam this may become a compile error." 1372 - )); 1373 - Diagnostic { 1374 - title: "App importing dev dependency".into(), 1375 - text, 1376 - hint: None, 1377 - level: diagnostic::Level::Warning, 1378 - location: Some(Location { 1379 - src: src.clone(), 1380 - path: path.to_path_buf(), 1381 - label: diagnostic::Label { 1382 - text: None, 1383 - span: *location, 1384 - }, 1385 - extra_labels: Vec::new(), 1386 - }), 1387 - } 1388 - } 1389 1356 }, 1390 1357 1391 1358 Warning::DeprecatedEnvironmentVariable { variable } => {
-8
docs/v2.md
··· 29 29 30 30 - [x] Emits warning when used. 31 31 32 - ## Development dependencies in `src/` code 33 - 34 - Do not allow to use dev dependencies within `src/`. 35 - 36 - - [x] Emits warning when used. 37 - - [x] Blocks `gleam export erlang-shipment`. 38 - - [x] Blocks `gleam publish`. 39 - 40 32 ## JavaScript runtime error `fn` property 41 33 42 34 On JavaScript there is a deprecated `fn` property. This was a mistake, it