Skip to content
Open
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@

- The compiler will now raise warning for inefficient use of `list.length()`
when trying to check is list empty via `0 < list.length(list)` or
`list.length(list) > 0` as well as in other cases. For example, the following
`list.length(list) > 0` as well as in other cases. For example, the following
code:

```gleam
Expand Down Expand Up @@ -343,3 +343,7 @@
- Fixed a bug where adding `echo` to the subject of a `case` expression would
prevent variant inference from working correctly.
([Surya Rose](https://github.com/GearsDatapacks))

- Added an error message when attempting to update packages that are not dependencies
of the project, instead of failing silently.
([Etienne Boutet](https://github.com/EtienneBoutet))
22 changes: 22 additions & 0 deletions compiler-cli/src/dependencies.rs
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,9 @@ pub fn update(paths: &ProjectPaths, packages: Vec<String>) -> Result<()> {
UseManifest::Yes
};

let config = crate::config::read(paths.root_config())?;
assert_packages_exist_locally(&config, packages.clone())?;

// Update specific packages
_ = download(
paths,
Expand All @@ -240,6 +243,25 @@ pub fn update(paths: &ProjectPaths, packages: Vec<String>) -> Result<()> {
Ok(())
}

pub fn assert_packages_exist_locally(config: &PackageConfig, packages: Vec<String>) -> Result<()> {
let missing_packages: Vec<String> = packages
.iter()
.filter(|package_name| {
let package_name_eco = EcoString::from(package_name.as_str());
!config.dependencies.contains_key(&package_name_eco)
&& !config.dev_dependencies.contains_key(&package_name_eco)
})
.cloned()
.collect();

if !missing_packages.is_empty() {
return Err(Error::PackagesToUpdateNotExist {
packages: missing_packages,
});
}
Ok(())
}

/// Edit the manifest.toml file in this proejct, removing all extra requirements and packages
/// that are no longer present in the gleam.toml config.
pub fn cleanup<Telem: Telemetry>(paths: &ProjectPaths, telemetry: Telem) -> Result<Manifest> {
Expand Down
23 changes: 23 additions & 0 deletions compiler-cli/src/dependencies/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1347,3 +1347,26 @@ fn test_pretty_print_major_versions_available() {

insta::assert_snapshot!(output);
}

#[test]
fn test_assert_packages_exist_locally() {
let config = package_config(
HashMap::from([(
"existing_package".into(),
Requirement::hex("~>1.0").unwrap(),
)]),
HashMap::from([("dev_package".into(), Requirement::hex("~>2.0").unwrap())]),
);

assert!(assert_packages_exist_locally(&config, vec!["existing_package".to_string()]).is_ok());
assert!(assert_packages_exist_locally(&config, vec!["dev_package".to_string()]).is_ok());

let result = assert_packages_exist_locally(&config, vec!["nonexistent_package".to_string()]);
assert!(result.is_err());
match result {
Err(Error::PackagesToUpdateNotExist { packages }) => {
assert_eq!(packages, vec!["nonexistent_package".to_string()]);
}
_ => panic!("Expected PackagesToUpdateNotExist error"),
}
}
21 changes: 21 additions & 0 deletions compiler-core/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,9 @@ file_names.iter().map(|x| x.as_str()).join(", "))]
#[error("Packages not exist: {}", packages.iter().join(", "))]
RemovedPackagesNotExist { packages: Vec<String> },

#[error("Packages to update not exist: {}", packages.iter().join(", "))]
PackagesToUpdateNotExist { packages: Vec<String> },

#[error("unable to find project root")]
UnableToFindProjectRoot { path: String },

Expand Down Expand Up @@ -958,6 +961,24 @@ If you want to overwrite these files, delete them and run the command again.
"These packages are not dependencies of your package so they could not
be removed.

{}
",
packages
.iter()
.map(|p| format!(" - {}", p.as_str()))
.join("\n")
),
level: Level::Error,
hint: None,
location: None,
}],

Error::PackagesToUpdateNotExist { packages } => vec![Diagnostic {
title: "Packages not found".into(),
text: format!(
"These packages are not dependencies of your package so they could not
be updated.

{}
",
packages
Expand Down