diff --git a/buildpacks/ruby/CHANGELOG.md b/buildpacks/ruby/CHANGELOG.md index 20eefd7..3fb1c48 100644 --- a/buildpacks/ruby/CHANGELOG.md +++ b/buildpacks/ruby/CHANGELOG.md @@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Fixed +- Ruby pre-release verssions like `3.4.0.rc1` now work as expected. ([#372](https://github.com/heroku/buildpacks-ruby/pull/372)) - Layer metadata deserialization to Rust structs is now using `#[serde(deny_unknown_fields)]` this prevents the accidental scenario where metadata containing a superset of fields could accidentally be deserialized to the wrong struct. It's unlikely this is currently happening with the current buildpack, but it's a possibly-observable difference so it's being listed ([#371](https://github.com/heroku/buildpacks-ruby/pull/371)) ## [4.0.1] - 2024-12-11 diff --git a/commons/src/gemfile_lock.rs b/commons/src/gemfile_lock.rs index 455222d..fd91fc4 100644 --- a/commons/src/gemfile_lock.rs +++ b/commons/src/gemfile_lock.rs @@ -116,12 +116,12 @@ impl FromStr for GemfileLock { type Err = std::convert::Infallible; fn from_str(string: &str) -> Result { - let bundled_with_re = Regex::new("BUNDLED WITH\\s (\\d+\\.\\d+\\.\\d+)") - .expect("Internal error: Bad regex"); // Checked via clippy - let main_ruby_version_re = Regex::new("RUBY VERSION\\s ruby (\\d+\\.\\d+\\.\\d+)") - .expect("Internal error: Bad regex"); // Checked via clippy - let jruby_version_re = - Regex::new("\\(jruby ((\\d+|\\.)+)\\)").expect("Internal error: Bad regex"); // Checked via clippy + let bundled_with_re = + Regex::new("BUNDLED WITH\\s (\\d+\\.\\d+\\.\\d+)").expect("Clippy checked"); + let main_ruby_version_re = + Regex::new("RUBY VERSION\\s ruby (\\d+\\.\\d+\\.\\d+((-|\\.)\\S*\\d+)?)") + .expect("Clippy checked"); + let jruby_version_re = Regex::new("\\(jruby ((\\d+|\\.)+)\\)").expect("Clippy checked"); let bundler_version = match bundled_with_re.captures(string).and_then(|c| c.get(1)) { Some(result) => BundlerVersion::Explicit(result.as_str().to_string()), @@ -152,6 +152,75 @@ impl FromStr for GemfileLock { mod tests { use super::*; + #[test] + fn test_does_not_capture_patch_version() { + let info = GemfileLock::from_str( + r" +RUBY VERSION + ruby 3.3.5p100 + +BUNDLED WITH + 2.3.4 +", + ) + .unwrap(); + + assert_eq!( + info.bundler_version, + BundlerVersion::Explicit("2.3.4".to_string()) + ); + assert_eq!( + info.ruby_version, + RubyVersion::Explicit("3.3.5".to_string()) + ); + } + + #[test] + fn test_rc_dot_version() { + let info = GemfileLock::from_str( + r" +RUBY VERSION + ruby 3.4.0.rc1 + +BUNDLED WITH + 2.3.4 +", + ) + .unwrap(); + + assert_eq!( + info.bundler_version, + BundlerVersion::Explicit("2.3.4".to_string()) + ); + assert_eq!( + info.ruby_version, + RubyVersion::Explicit("3.4.0.rc1".to_string()) + ); + } + + #[test] + fn test_preview_version() { + let info = GemfileLock::from_str( + r" +RUBY VERSION + ruby 3.4.0.preview2 + +BUNDLED WITH + 2.3.4 +", + ) + .unwrap(); + + assert_eq!( + info.bundler_version, + BundlerVersion::Explicit("2.3.4".to_string()) + ); + assert_eq!( + info.ruby_version, + RubyVersion::Explicit("3.4.0.preview2".to_string()) + ); + } + #[test] fn test_parse_gemfile_lock() { let info = GemfileLock::from_str(