From 2412c1933126c7660aaa9110ab7df67b23f2c253 Mon Sep 17 00:00:00 2001 From: benev0 Date: Fri, 12 Sep 2025 04:02:00 -0400 Subject: [PATCH 1/7] add offline caches --- compiler-cli/src/dependencies.rs | 71 +++++++++++++++++++++++++------- compiler-core/src/hex.rs | 4 ++ compiler-core/src/paths.rs | 12 ++++++ 3 files changed, 72 insertions(+), 15 deletions(-) diff --git a/compiler-cli/src/dependencies.rs b/compiler-cli/src/dependencies.rs index 3b40dfd9ce7..ee47dc77b15 100644 --- a/compiler-cli/src/dependencies.rs +++ b/compiler-cli/src/dependencies.rs @@ -1,18 +1,13 @@ mod dependency_manager; use std::{ - cell::RefCell, - collections::{HashMap, HashSet}, - process::Command, - rc::Rc, - time::Instant, + cell::RefCell, collections::{HashMap, HashSet}, io::Read, process::Command, rc::Rc, time::Instant }; use camino::{Utf8Path, Utf8PathBuf}; use ecow::{EcoString, eco_format}; use flate2::read::GzDecoder; use gleam_core::{ - Error, Result, build::{Mode, Target, Telemetry}, config::PackageConfig, dependency::{self, PackageFetchError}, @@ -22,6 +17,9 @@ use gleam_core::{ manifest::{Base16Checksum, Manifest, ManifestPackage, ManifestPackageSource, Resolved}, paths::ProjectPaths, requirement::Requirement, + io::{ FileSystemReader, FileSystemWriter, HttpClient as _,}, + paths::{global_hexpm_package_release_response_cache, global_hexpm_packages_response_cache}, + Error, Result }; use hexpm::version::Version; use itertools::Itertools; @@ -34,11 +32,7 @@ pub use dependency_manager::DependencyManagerConfig; mod tests; use crate::{ - TreeOptions, - build_lock::{BuildLock, Guard}, - cli, - fs::{self, ProjectIO}, - http::HttpClient, + build_lock::{BuildLock, Guard}, cli, fs::{self, ProjectIO}, http::HttpClient, TreeOptions }; struct Symbols { @@ -1093,8 +1087,37 @@ async fn lookup_package( Some(provided_package) => Ok(provided_package.to_manifest_package(name.as_str())), None => { let config = hexpm::Config::new(); + // performance may be able to be improved by reading from local cache first + // depending on the volatility of the endpoint + // retirement status volatile, content volatile one hour after initial publication + // content may be edited or deleted by admins + let mut resp_body = Vec::new(); let release = - hex::get_package_release(&name, &version, &config, &HttpClient::new()).await?; + hex::get_package_release(&name, &version, &config, Some(&mut resp_body), &HttpClient::new()).await; + let fs = ProjectIO::new(); + let cache_path = global_hexpm_package_release_response_cache(&name, &version.to_string()); + let release = match release { + Ok(rel) => { + // save + // FIXME: I may not need to wright every time + let _ = fs.write_bytes(&cache_path, &resp_body); + rel + }, + Err(_) => { + // load + let cached_result = fs.read_bytes(&cache_path) + .map_err(|err| Error::FileIo { + action: FileIoAction::Read, + kind: FileKind::File, + path: cache_path, + err: Some(err.to_string()), + })?; + + // FIXME: I crash when the cache is bad + // author note + serde_json::from_slice(&cached_result).expect("cache bad") + } + }; let build_tools = release .meta .build_tools @@ -1187,10 +1210,28 @@ impl dependency::PackageFetcher for PackageFetcher { let response = self .runtime .block_on(self.http.send(request)) - .map_err(PackageFetchError::fetch_error)?; + .map_err(PackageFetchError::fetch_error); + + let fs = ProjectIO::new(); + let cache_path = &global_hexpm_packages_response_cache(package); + let pkg = match response { + Ok(resp) => { + tracing::debug!(package = package, "saving_hex_package"); + let _ = fs.write_bytes(cache_path, resp.body()); + hexpm::repository_v2_get_package_response(resp, HEXPM_PUBLIC_KEY) + }, + Err(_err) => { + tracing::debug!(package = package, "fetching_package_data_from_cache"); + let reader = fs.reader(cache_path) + .map_err(PackageFetchError::fetch_error)?; + let mut decoder = GzDecoder::new(reader); + let mut data = Vec::new(); + let _ = decoder.read_to_end(&mut data) + .map_err(PackageFetchError::fetch_error)?; + hexpm::repository_v2_package_parse_body(&data, HEXPM_PUBLIC_KEY) + }, + }.map_err(PackageFetchError::from)?; - let pkg = hexpm::repository_v2_get_package_response(response, HEXPM_PUBLIC_KEY) - .map_err(PackageFetchError::from)?; let pkg = Rc::new(pkg); let pkg_ref = Rc::clone(&pkg); self.cache_package(package, pkg); diff --git a/compiler-core/src/hex.rs b/compiler-core/src/hex.rs index 408ed96d6ae..72b732a4592 100644 --- a/compiler-core/src/hex.rs +++ b/compiler-core/src/hex.rs @@ -316,6 +316,7 @@ pub async fn get_package_release( name: &str, version: &Version, config: &hexpm::Config, + raw_response: Option<&mut Vec>, http: &Http, ) -> Result> { let version = version.to_string(); @@ -326,5 +327,8 @@ pub async fn get_package_release( ); let request = hexpm::api_get_package_release_request(name, &version, None, config); let response = http.send(request).await?; + if let Some(data) = raw_response { + data.clone_from(response.body()); + } hexpm::api_get_package_release_response(response).map_err(Error::hex) } diff --git a/compiler-core/src/paths.rs b/compiler-core/src/paths.rs index ff6079e00d9..bdea4fbf991 100644 --- a/compiler-core/src/paths.rs +++ b/compiler-core/src/paths.rs @@ -130,6 +130,18 @@ pub fn global_package_cache_package_tarball(package_name: &str, version: &str) - global_packages_cache().join(format!("{package_name}-{version}.tar")) } +pub fn global_hexpm_packages_response_cache(package_name: &str) -> Utf8PathBuf { + global_hexpm_response_cache_path().join(format!("packages-{package_name}.gz")) +} + +pub fn global_hexpm_package_release_response_cache(package_name: &str, version: &str) -> Utf8PathBuf { + global_hexpm_response_cache_path().join(format!("packages-{package_name}-releases-{version}.json")) +} + +fn global_hexpm_response_cache_path() -> Utf8PathBuf { + global_hexpm_cache().join("response") +} + pub fn global_hexpm_credentials_path() -> Utf8PathBuf { global_hexpm_cache().join("credentials") } From 6bc55aac09a5e11a7b736101ab7898072b11db43 Mon Sep 17 00:00:00 2001 From: benev0 Date: Fri, 12 Sep 2025 04:40:46 -0400 Subject: [PATCH 2/7] format imports --- compiler-cli/src/dependencies.rs | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/compiler-cli/src/dependencies.rs b/compiler-cli/src/dependencies.rs index ee47dc77b15..600362baa37 100644 --- a/compiler-cli/src/dependencies.rs +++ b/compiler-cli/src/dependencies.rs @@ -13,12 +13,11 @@ use gleam_core::{ dependency::{self, PackageFetchError}, error::{FileIoAction, FileKind, ShellCommandFailureReason, StandardIoAction}, hex::{self, HEXPM_PUBLIC_KEY}, - io::{HttpClient as _, TarUnpacker, WrappedReader}, - manifest::{Base16Checksum, Manifest, ManifestPackage, ManifestPackageSource, Resolved}, + io::{ TarUnpacker, WrappedReader, FileSystemReader, FileSystemWriter, HttpClient as _ }, + manifest::{ Base16Checksum, Manifest, ManifestPackage, ManifestPackageSource, Resolved }, paths::ProjectPaths, requirement::Requirement, - io::{ FileSystemReader, FileSystemWriter, HttpClient as _,}, - paths::{global_hexpm_package_release_response_cache, global_hexpm_packages_response_cache}, + paths::{ global_hexpm_package_release_response_cache, global_hexpm_packages_response_cache }, Error, Result }; use hexpm::version::Version; From c86e3d051ba174fadc7b51a4478385d033376b1d Mon Sep 17 00:00:00 2001 From: benev0 Date: Fri, 12 Sep 2025 04:47:55 -0400 Subject: [PATCH 3/7] remove panic on failed parse --- compiler-cli/src/dependencies.rs | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/compiler-cli/src/dependencies.rs b/compiler-cli/src/dependencies.rs index 600362baa37..54fa8170562 100644 --- a/compiler-cli/src/dependencies.rs +++ b/compiler-cli/src/dependencies.rs @@ -1097,24 +1097,25 @@ async fn lookup_package( let cache_path = global_hexpm_package_release_response_cache(&name, &version.to_string()); let release = match release { Ok(rel) => { - // save - // FIXME: I may not need to wright every time let _ = fs.write_bytes(&cache_path, &resp_body); rel }, Err(_) => { - // load let cached_result = fs.read_bytes(&cache_path) .map_err(|err| Error::FileIo { action: FileIoAction::Read, kind: FileKind::File, - path: cache_path, + path: cache_path.clone(), err: Some(err.to_string()), })?; - // FIXME: I crash when the cache is bad - // author note - serde_json::from_slice(&cached_result).expect("cache bad") + serde_json::from_slice(&cached_result) + .map_err(|err| Error::FileIo { + action: FileIoAction::Read, + kind: FileKind::File, + path: cache_path, + err: Some(err.to_string()), + })? } }; let build_tools = release From 9960d5c83407255098eb8f45222d4b4782cb887e Mon Sep 17 00:00:00 2001 From: benev0 Date: Fri, 12 Sep 2025 04:57:31 -0400 Subject: [PATCH 4/7] update changelog --- CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index a3c1834ddf7..730491e0ad0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -268,6 +268,9 @@ ### Build tool +- Dependency resolution will use cache when offline. + ([Ben Ownby](https://github.com/benev0)) + - New projects are generated using OTP28 on GitHub Actions. ([Louis Pilfold](https://github.com/lpil)) From 619132554915db4a80ea42764b6bb47d9003cbc8 Mon Sep 17 00:00:00 2001 From: benev0 Date: Mon, 22 Sep 2025 09:51:57 -0400 Subject: [PATCH 5/7] rust format --- compiler-cli/src/dependencies.rs | 66 ++++++++++++++++++++------------ compiler-core/src/paths.rs | 8 +++- 2 files changed, 48 insertions(+), 26 deletions(-) diff --git a/compiler-cli/src/dependencies.rs b/compiler-cli/src/dependencies.rs index 54fa8170562..dfa862d47bb 100644 --- a/compiler-cli/src/dependencies.rs +++ b/compiler-cli/src/dependencies.rs @@ -1,24 +1,29 @@ mod dependency_manager; use std::{ - cell::RefCell, collections::{HashMap, HashSet}, io::Read, process::Command, rc::Rc, time::Instant + cell::RefCell, + collections::{HashMap, HashSet}, + io::Read, + process::Command, + rc::Rc, + time::Instant, }; use camino::{Utf8Path, Utf8PathBuf}; use ecow::{EcoString, eco_format}; use flate2::read::GzDecoder; use gleam_core::{ + Error, Result, build::{Mode, Target, Telemetry}, config::PackageConfig, dependency::{self, PackageFetchError}, error::{FileIoAction, FileKind, ShellCommandFailureReason, StandardIoAction}, hex::{self, HEXPM_PUBLIC_KEY}, - io::{ TarUnpacker, WrappedReader, FileSystemReader, FileSystemWriter, HttpClient as _ }, - manifest::{ Base16Checksum, Manifest, ManifestPackage, ManifestPackageSource, Resolved }, + io::{FileSystemReader, FileSystemWriter, HttpClient as _, TarUnpacker, WrappedReader}, + manifest::{Base16Checksum, Manifest, ManifestPackage, ManifestPackageSource, Resolved}, paths::ProjectPaths, + paths::{global_hexpm_package_release_response_cache, global_hexpm_packages_response_cache}, requirement::Requirement, - paths::{ global_hexpm_package_release_response_cache, global_hexpm_packages_response_cache }, - Error, Result }; use hexpm::version::Version; use itertools::Itertools; @@ -31,7 +36,11 @@ pub use dependency_manager::DependencyManagerConfig; mod tests; use crate::{ - build_lock::{BuildLock, Guard}, cli, fs::{self, ProjectIO}, http::HttpClient, TreeOptions + TreeOptions, + build_lock::{BuildLock, Guard}, + cli, + fs::{self, ProjectIO}, + http::HttpClient, }; struct Symbols { @@ -1091,30 +1100,36 @@ async fn lookup_package( // retirement status volatile, content volatile one hour after initial publication // content may be edited or deleted by admins let mut resp_body = Vec::new(); - let release = - hex::get_package_release(&name, &version, &config, Some(&mut resp_body), &HttpClient::new()).await; + let release = hex::get_package_release( + &name, + &version, + &config, + Some(&mut resp_body), + &HttpClient::new(), + ) + .await; let fs = ProjectIO::new(); - let cache_path = global_hexpm_package_release_response_cache(&name, &version.to_string()); + let cache_path = + global_hexpm_package_release_response_cache(&name, &version.to_string()); let release = match release { Ok(rel) => { let _ = fs.write_bytes(&cache_path, &resp_body); rel - }, + } Err(_) => { - let cached_result = fs.read_bytes(&cache_path) - .map_err(|err| Error::FileIo { + let cached_result = + fs.read_bytes(&cache_path).map_err(|err| Error::FileIo { action: FileIoAction::Read, kind: FileKind::File, path: cache_path.clone(), err: Some(err.to_string()), - })?; + })?; - serde_json::from_slice(&cached_result) - .map_err(|err| Error::FileIo { - action: FileIoAction::Read, - kind: FileKind::File, - path: cache_path, - err: Some(err.to_string()), + serde_json::from_slice(&cached_result).map_err(|err| Error::FileIo { + action: FileIoAction::Read, + kind: FileKind::File, + path: cache_path, + err: Some(err.to_string()), })? } }; @@ -1219,18 +1234,21 @@ impl dependency::PackageFetcher for PackageFetcher { tracing::debug!(package = package, "saving_hex_package"); let _ = fs.write_bytes(cache_path, resp.body()); hexpm::repository_v2_get_package_response(resp, HEXPM_PUBLIC_KEY) - }, + } Err(_err) => { tracing::debug!(package = package, "fetching_package_data_from_cache"); - let reader = fs.reader(cache_path) + let reader = fs + .reader(cache_path) .map_err(PackageFetchError::fetch_error)?; let mut decoder = GzDecoder::new(reader); let mut data = Vec::new(); - let _ = decoder.read_to_end(&mut data) + let _ = decoder + .read_to_end(&mut data) .map_err(PackageFetchError::fetch_error)?; hexpm::repository_v2_package_parse_body(&data, HEXPM_PUBLIC_KEY) - }, - }.map_err(PackageFetchError::from)?; + } + } + .map_err(PackageFetchError::from)?; let pkg = Rc::new(pkg); let pkg_ref = Rc::clone(&pkg); diff --git a/compiler-core/src/paths.rs b/compiler-core/src/paths.rs index bdea4fbf991..90a4380178f 100644 --- a/compiler-core/src/paths.rs +++ b/compiler-core/src/paths.rs @@ -134,8 +134,12 @@ pub fn global_hexpm_packages_response_cache(package_name: &str) -> Utf8PathBuf { global_hexpm_response_cache_path().join(format!("packages-{package_name}.gz")) } -pub fn global_hexpm_package_release_response_cache(package_name: &str, version: &str) -> Utf8PathBuf { - global_hexpm_response_cache_path().join(format!("packages-{package_name}-releases-{version}.json")) +pub fn global_hexpm_package_release_response_cache( + package_name: &str, + version: &str, +) -> Utf8PathBuf { + global_hexpm_response_cache_path() + .join(format!("packages-{package_name}-releases-{version}.json")) } fn global_hexpm_response_cache_path() -> Utf8PathBuf { From df6df4f4877f762fa0467635b25355070afca0c4 Mon Sep 17 00:00:00 2001 From: benev0 Date: Wed, 24 Sep 2025 12:48:41 -0400 Subject: [PATCH 6/7] add cache warnings --- compiler-cli/src/dependencies.rs | 25 ++++++++++--------------- compiler-core/src/warning.rs | 14 ++++++++++++++ 2 files changed, 24 insertions(+), 15 deletions(-) diff --git a/compiler-cli/src/dependencies.rs b/compiler-cli/src/dependencies.rs index dfa862d47bb..9a42c6fe1ec 100644 --- a/compiler-cli/src/dependencies.rs +++ b/compiler-cli/src/dependencies.rs @@ -13,17 +13,7 @@ use camino::{Utf8Path, Utf8PathBuf}; use ecow::{EcoString, eco_format}; use flate2::read::GzDecoder; use gleam_core::{ - Error, Result, - build::{Mode, Target, Telemetry}, - config::PackageConfig, - dependency::{self, PackageFetchError}, - error::{FileIoAction, FileKind, ShellCommandFailureReason, StandardIoAction}, - hex::{self, HEXPM_PUBLIC_KEY}, - io::{FileSystemReader, FileSystemWriter, HttpClient as _, TarUnpacker, WrappedReader}, - manifest::{Base16Checksum, Manifest, ManifestPackage, ManifestPackageSource, Resolved}, - paths::ProjectPaths, - paths::{global_hexpm_package_release_response_cache, global_hexpm_packages_response_cache}, - requirement::Requirement, + build::{Mode, Target, Telemetry}, config::PackageConfig, dependency::{self, PackageFetchError}, error::{FileIoAction, FileKind, ShellCommandFailureReason, StandardIoAction}, hex::{self, HEXPM_PUBLIC_KEY}, io::{FileSystemReader, FileSystemWriter, HttpClient as _, TarUnpacker, WrappedReader}, manifest::{Base16Checksum, Manifest, ManifestPackage, ManifestPackageSource, Resolved}, paths::{global_hexpm_package_release_response_cache, global_hexpm_packages_response_cache, ProjectPaths}, requirement::Requirement, warning::WarningEmitterIO, Error, Result, Warning }; use hexpm::version::Version; use itertools::Itertools; @@ -39,7 +29,7 @@ use crate::{ TreeOptions, build_lock::{BuildLock, Guard}, cli, - fs::{self, ProjectIO}, + fs::{self, ConsoleWarningEmitter, ProjectIO}, http::HttpClient, }; @@ -1117,6 +1107,7 @@ async fn lookup_package( rel } Err(_) => { + tracing::debug!(name=%name, version=%version, "fetching_release_data_from_json_cache_file"); let cached_result = fs.read_bytes(&cache_path).map_err(|err| Error::FileIo { action: FileIoAction::Read, @@ -1124,13 +1115,16 @@ async fn lookup_package( path: cache_path.clone(), err: Some(err.to_string()), })?; - - serde_json::from_slice(&cached_result).map_err(|err| Error::FileIo { + let release = serde_json::from_slice(&cached_result).map_err(|err| Error::FileIo { action: FileIoAction::Read, kind: FileKind::File, path: cache_path, err: Some(err.to_string()), - })? + })?; + + ConsoleWarningEmitter.emit_warning(Warning::LocalCache { message: "json cache is not secure; verify dependencies when online.".into() }); + + release } }; let build_tools = release @@ -1245,6 +1239,7 @@ impl dependency::PackageFetcher for PackageFetcher { let _ = decoder .read_to_end(&mut data) .map_err(PackageFetchError::fetch_error)?; + ConsoleWarningEmitter.emit_warning(Warning::LocalCache { message: "Hexpm repository cache used; dependencies may be outdated.".into() }); hexpm::repository_v2_package_parse_body(&data, HEXPM_PUBLIC_KEY) } } diff --git a/compiler-core/src/warning.rs b/compiler-core/src/warning.rs index 37f2b403a71..89d2db47e49 100644 --- a/compiler-core/src/warning.rs +++ b/compiler-core/src/warning.rs @@ -167,6 +167,10 @@ pub enum Warning { DeprecatedEnvironmentVariable { variable: DeprecatedEnvironmentVariable, }, + + LocalCache { + message: EcoString, + } } #[derive(Debug, Clone, Eq, PartialEq, Copy)] @@ -1422,6 +1426,16 @@ The imported value could not be used in this module anyway." location: None, } } + + Warning::LocalCache { message } => { + Diagnostic { + title: "Use of cached files".into(), + text: message.into(), + level: diagnostic::Level::Warning, + location: None, + hint: None, + } + }, } } From d7e97308dcaee4ec1db620ca04d9a3a13b368ba0 Mon Sep 17 00:00:00 2001 From: benev0 Date: Wed, 24 Sep 2025 12:50:25 -0400 Subject: [PATCH 7/7] rust fmt --- compiler-cli/src/dependencies.rs | 37 ++++++++++++++++++++++++-------- compiler-core/src/warning.rs | 16 ++++++-------- 2 files changed, 35 insertions(+), 18 deletions(-) diff --git a/compiler-cli/src/dependencies.rs b/compiler-cli/src/dependencies.rs index 9a42c6fe1ec..28b7de987d3 100644 --- a/compiler-cli/src/dependencies.rs +++ b/compiler-cli/src/dependencies.rs @@ -13,7 +13,20 @@ use camino::{Utf8Path, Utf8PathBuf}; use ecow::{EcoString, eco_format}; use flate2::read::GzDecoder; use gleam_core::{ - build::{Mode, Target, Telemetry}, config::PackageConfig, dependency::{self, PackageFetchError}, error::{FileIoAction, FileKind, ShellCommandFailureReason, StandardIoAction}, hex::{self, HEXPM_PUBLIC_KEY}, io::{FileSystemReader, FileSystemWriter, HttpClient as _, TarUnpacker, WrappedReader}, manifest::{Base16Checksum, Manifest, ManifestPackage, ManifestPackageSource, Resolved}, paths::{global_hexpm_package_release_response_cache, global_hexpm_packages_response_cache, ProjectPaths}, requirement::Requirement, warning::WarningEmitterIO, Error, Result, Warning + Error, Result, Warning, + build::{Mode, Target, Telemetry}, + config::PackageConfig, + dependency::{self, PackageFetchError}, + error::{FileIoAction, FileKind, ShellCommandFailureReason, StandardIoAction}, + hex::{self, HEXPM_PUBLIC_KEY}, + io::{FileSystemReader, FileSystemWriter, HttpClient as _, TarUnpacker, WrappedReader}, + manifest::{Base16Checksum, Manifest, ManifestPackage, ManifestPackageSource, Resolved}, + paths::{ + ProjectPaths, global_hexpm_package_release_response_cache, + global_hexpm_packages_response_cache, + }, + requirement::Requirement, + warning::WarningEmitterIO, }; use hexpm::version::Version; use itertools::Itertools; @@ -1115,14 +1128,18 @@ async fn lookup_package( path: cache_path.clone(), err: Some(err.to_string()), })?; - let release = serde_json::from_slice(&cached_result).map_err(|err| Error::FileIo { - action: FileIoAction::Read, - kind: FileKind::File, - path: cache_path, - err: Some(err.to_string()), - })?; + let release = + serde_json::from_slice(&cached_result).map_err(|err| Error::FileIo { + action: FileIoAction::Read, + kind: FileKind::File, + path: cache_path, + err: Some(err.to_string()), + })?; - ConsoleWarningEmitter.emit_warning(Warning::LocalCache { message: "json cache is not secure; verify dependencies when online.".into() }); + ConsoleWarningEmitter.emit_warning(Warning::LocalCache { + message: "json cache is not secure; verify dependencies when online." + .into(), + }); release } @@ -1239,7 +1256,9 @@ impl dependency::PackageFetcher for PackageFetcher { let _ = decoder .read_to_end(&mut data) .map_err(PackageFetchError::fetch_error)?; - ConsoleWarningEmitter.emit_warning(Warning::LocalCache { message: "Hexpm repository cache used; dependencies may be outdated.".into() }); + ConsoleWarningEmitter.emit_warning(Warning::LocalCache { + message: "Hexpm repository cache used; dependencies may be outdated.".into(), + }); hexpm::repository_v2_package_parse_body(&data, HEXPM_PUBLIC_KEY) } } diff --git a/compiler-core/src/warning.rs b/compiler-core/src/warning.rs index 89d2db47e49..a77419fa6fa 100644 --- a/compiler-core/src/warning.rs +++ b/compiler-core/src/warning.rs @@ -170,7 +170,7 @@ pub enum Warning { LocalCache { message: EcoString, - } + }, } #[derive(Debug, Clone, Eq, PartialEq, Copy)] @@ -1427,14 +1427,12 @@ The imported value could not be used in this module anyway." } } - Warning::LocalCache { message } => { - Diagnostic { - title: "Use of cached files".into(), - text: message.into(), - level: diagnostic::Level::Warning, - location: None, - hint: None, - } + Warning::LocalCache { message } => Diagnostic { + title: "Use of cached files".into(), + text: message.into(), + level: diagnostic::Level::Warning, + location: None, + hint: None, }, } }