diff --git a/CHANGELOG.md b/CHANGELOG.md index a99b260dd..57c96a828 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,6 +19,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). ### Fixed - Lockfile parsing of bun-generated yarn lockfiles +- Maven lockfile generation on Windows ### Removed diff --git a/Cargo.lock b/Cargo.lock index f11d8d228..2b2adb2ff 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2080,6 +2080,12 @@ dependencies = [ "zeroize", ] +[[package]] +name = "dunce" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92773504d58c093f6de2459af4af33faa518c13451eb8f2b5698ed3d36e7c813" + [[package]] name = "dyn-clone" version = "1.0.17" @@ -3678,6 +3684,7 @@ name = "lockfile_generator" version = "0.1.0" dependencies = [ "anyhow", + "dunce", "glob", "serde", "serde_json", diff --git a/lockfile_generator/Cargo.toml b/lockfile_generator/Cargo.toml index f11e3950a..61de61300 100644 --- a/lockfile_generator/Cargo.toml +++ b/lockfile_generator/Cargo.toml @@ -13,3 +13,4 @@ anyhow = "1.0.75" glob = "0.3.1" thiserror = "1.0.49" tempfile = "3.3.0" +dunce = "1.0.5" diff --git a/lockfile_generator/src/gradle.rs b/lockfile_generator/src/gradle.rs index 00cd46329..bce555747 100644 --- a/lockfile_generator/src/gradle.rs +++ b/lockfile_generator/src/gradle.rs @@ -51,7 +51,7 @@ impl Generator for Gradle { fn generate_lockfile(&self, manifest_path: &Path) -> Result { self.check_prerequisites(manifest_path)?; - let canonicalized = fs::canonicalize(manifest_path)?; + let canonicalized = dunce::canonicalize(manifest_path)?; let project_path = canonicalized .parent() .ok_or_else(|| Error::InvalidManifest(manifest_path.to_path_buf()))?; diff --git a/lockfile_generator/src/lib.rs b/lockfile_generator/src/lib.rs index cbe7824ec..4729a2db9 100644 --- a/lockfile_generator/src/lib.rs +++ b/lockfile_generator/src/lib.rs @@ -53,7 +53,7 @@ pub trait Generator { fn generate_lockfile(&self, manifest_path: &Path) -> Result { self.check_prerequisites(manifest_path)?; - let canonicalized = fs::canonicalize(manifest_path)?; + let canonicalized = dunce::canonicalize(manifest_path)?; let project_path = canonicalized .parent() .ok_or_else(|| Error::InvalidManifest(manifest_path.to_path_buf()))?; @@ -69,7 +69,6 @@ pub trait Generator { let mut command = self.command(&canonicalized); command.current_dir(project_path); command.stdin(Stdio::null()); - command.stdout(Stdio::null()); // Provide better error message, including the failed program's name. let output = command.output().map_err(|err| { @@ -143,7 +142,7 @@ pub enum Error { Json(#[from] JsonError), NonZeroExit(Output), PipReportVersionMismatch(&'static str, String), - ProcessCreation(String, String, io::Error), + ProcessCreation(String, String, #[source] io::Error), StripPrefix(#[from] StripPrefixError), UnsupportedCommandVersion(&'static str, &'static str, String), NoLockfileGenerated, diff --git a/lockfile_generator/src/maven.rs b/lockfile_generator/src/maven.rs index 84aaf2cb5..3918974b2 100644 --- a/lockfile_generator/src/maven.rs +++ b/lockfile_generator/src/maven.rs @@ -7,6 +7,17 @@ use crate::{Error, Generator, Result}; pub struct Maven; +#[cfg(not(windows))] +fn maven_command() -> Command { + Command::new("mvn") +} + +#[cfg(windows)] +fn maven_command() -> Command { + // Maven uses a batch script on Windows + Command::new("mvn.cmd") +} + impl Generator for Maven { fn lockfile_path(&self, manifest_path: &Path) -> Result { let project_path = manifest_path @@ -17,7 +28,7 @@ impl Generator for Maven { fn command(&self, manifest_path: &Path) -> Command { let lockfile_path = self.lockfile_path(manifest_path).unwrap(); - let mut command = Command::new("mvn"); + let mut command = maven_command(); command.args([ "-q", "help:effective-pom", diff --git a/lockfile_generator/src/pip.rs b/lockfile_generator/src/pip.rs index f748aea82..b6cd3efa1 100644 --- a/lockfile_generator/src/pip.rs +++ b/lockfile_generator/src/pip.rs @@ -1,7 +1,6 @@ //! Python pip ecosystem. use std::fmt::Write; -use std::fs; use std::path::{Path, PathBuf}; use std::process::{Command, Stdio}; @@ -56,7 +55,7 @@ impl Generator for Pip { /// we provide a custom method here which parses this output and transforms /// it into the locked requirements.txt format our lockfile parser expects. fn generate_lockfile(&self, manifest_path: &Path) -> Result { - let canonicalized = fs::canonicalize(manifest_path)?; + let canonicalized = dunce::canonicalize(manifest_path)?; let project_path = canonicalized .parent() .ok_or_else(|| Error::InvalidManifest(manifest_path.to_path_buf()))?; diff --git a/lockfile_generator/src/yarn.rs b/lockfile_generator/src/yarn.rs index 38f6c8061..587bf34bb 100644 --- a/lockfile_generator/src/yarn.rs +++ b/lockfile_generator/src/yarn.rs @@ -1,7 +1,6 @@ //! JavaScript yarn ecosystem. use std::ffi::OsStr; -use std::fs; use std::path::{Path, PathBuf}; use std::process::Command; @@ -42,7 +41,7 @@ impl Generator for Yarn { /// Get the yarn version of the project. fn yarn_version(manifest_path: &Path) -> Result { - let canonicalized = fs::canonicalize(manifest_path)?; + let canonicalized = dunce::canonicalize(manifest_path)?; let project_path = canonicalized .parent() .ok_or_else(|| Error::InvalidManifest(manifest_path.to_path_buf()))?;