diff --git a/CHANGELOG.md b/CHANGELOG.md index 14cbc39..44020a6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added +- Added `runtime.txt` support for the `python-3.X` major Python version form. ([#322](https://github.com/heroku/buildpacks-python/pull/322)) - Enabled `libcnb`'s `trace` feature. ([#320](https://github.com/heroku/buildpacks-python/pull/320)) ## [0.23.0] - 2025-01-13 diff --git a/src/errors.rs b/src/errors.rs index 47c614f..bea4f45 100644 --- a/src/errors.rs +++ b/src/errors.rs @@ -8,7 +8,7 @@ use crate::layers::python::PythonLayerError; use crate::package_manager::DeterminePackageManagerError; use crate::python_version::{ RequestedPythonVersion, RequestedPythonVersionError, ResolvePythonVersionError, - DEFAULT_PYTHON_FULL_VERSION, DEFAULT_PYTHON_VERSION, NEWEST_SUPPORTED_PYTHON_3_MINOR_VERSION, + DEFAULT_PYTHON_VERSION, NEWEST_SUPPORTED_PYTHON_3_MINOR_VERSION, OLDEST_SUPPORTED_PYTHON_3_MINOR_VERSION, }; use crate::python_version_file::ParsePythonVersionFileError; @@ -205,17 +205,22 @@ fn on_requested_python_version_error(error: RequestedPythonVersionError) { log_error( "Invalid Python version in runtime.txt", formatdoc! {" - The Python version specified in 'runtime.txt' is not in the correct format. + The Python version specified in 'runtime.txt' isn't in + the correct format. The following file contents were found: {cleaned_contents} - However, the file contents must begin with a 'python-' prefix, followed by the - version specified as '..'. Comments are not supported. + However, the version must be specified as either: + 1. 'python-.' (recommended, for automatic updates) + 2. 'python-..' (to pin to an exact version) + + Remember to include the 'python-' prefix. Comments aren't + supported. - For example, to request Python {DEFAULT_PYTHON_FULL_VERSION}, update the 'runtime.txt' file so it - contains exactly: - python-{DEFAULT_PYTHON_FULL_VERSION} + For example, to request the latest version of Python {DEFAULT_PYTHON_VERSION}, + update the 'runtime.txt' file so it contains: + python-{DEFAULT_PYTHON_VERSION} "}, ); } diff --git a/src/python_version.rs b/src/python_version.rs index f11c25d..75913fa 100644 --- a/src/python_version.rs +++ b/src/python_version.rs @@ -13,6 +13,8 @@ pub(crate) const DEFAULT_PYTHON_VERSION: RequestedPythonVersion = RequestedPytho patch: None, origin: PythonVersionOrigin::BuildpackDefault, }; + +#[cfg(test)] pub(crate) const DEFAULT_PYTHON_FULL_VERSION: PythonVersion = LATEST_PYTHON_3_13; pub(crate) const OLDEST_SUPPORTED_PYTHON_3_MINOR_VERSION: u16 = 9; diff --git a/src/runtime_txt.rs b/src/runtime_txt.rs index 70b7f9d..69260f9 100644 --- a/src/runtime_txt.rs +++ b/src/runtime_txt.rs @@ -2,7 +2,7 @@ use crate::python_version::{PythonVersionOrigin, RequestedPythonVersion}; /// Parse the contents of a `runtime.txt` file into a [`RequestedPythonVersion`]. /// -/// The file is expected to contain a string of form `python-X.Y.Z`. +/// The file is expected to contain a string of form `python-X.Y.Z` or `python-X.Y`. /// Any leading or trailing whitespace will be removed. pub(crate) fn parse(contents: &str) -> Result { // All leading/trailing whitespace is trimmed, since that's what the classic buildpack @@ -30,6 +30,12 @@ pub(crate) fn parse(contents: &str) -> Result Ok(RequestedPythonVersion { + major, + minor, + patch: None, + origin: PythonVersionOrigin::RuntimeTxt, + }), _ => Err(ParseRuntimeTxtError { cleaned_contents: cleaned_contents.clone(), }), @@ -48,6 +54,15 @@ mod tests { #[test] fn parse_valid() { + assert_eq!( + parse("python-1.2"), + Ok(RequestedPythonVersion { + major: 1, + minor: 2, + patch: None, + origin: PythonVersionOrigin::RuntimeTxt + }) + ); assert_eq!( parse("python-1.2.3"), Ok(RequestedPythonVersion { @@ -139,12 +154,6 @@ mod tests { cleaned_contents: "python-1".to_string(), }) ); - assert_eq!( - parse("python-1.2"), - Err(ParseRuntimeTxtError { - cleaned_contents: "python-1.2".to_string(), - }) - ); assert_eq!( parse("python-1.2.3.4"), Err(ParseRuntimeTxtError { diff --git a/tests/python_version_test.rs b/tests/python_version_test.rs index 3fd4f98..ace838b 100644 --- a/tests/python_version_test.rs +++ b/tests/python_version_test.rs @@ -392,17 +392,22 @@ fn runtime_txt_invalid_version() { context.pack_stderr, &formatdoc! {" [Error: Invalid Python version in runtime.txt] - The Python version specified in 'runtime.txt' is not in the correct format. + The Python version specified in 'runtime.txt' isn't in + the correct format. The following file contents were found: python-an.invalid.version - However, the file contents must begin with a 'python-' prefix, followed by the - version specified as '..'. Comments are not supported. + However, the version must be specified as either: + 1. 'python-.' (recommended, for automatic updates) + 2. 'python-..' (to pin to an exact version) + + Remember to include the 'python-' prefix. Comments aren't + supported. - For example, to request Python {DEFAULT_PYTHON_FULL_VERSION}, update the 'runtime.txt' file so it - contains exactly: - python-{DEFAULT_PYTHON_FULL_VERSION} + For example, to request the latest version of Python {DEFAULT_PYTHON_VERSION}, + update the 'runtime.txt' file so it contains: + python-{DEFAULT_PYTHON_VERSION} "} ); });