feat(package): Extract package version from PEP 621 compliant pyproject.toml (#3950)

* feat(package): Extract package version from PEP621 pyproject.toml

* Update docs explaining PEP 621 package version

* Only read pyproject.toml once

* Simplify get_pep621_version

* Handle version formatting in get_pyproject_version
This commit is contained in:
Tom Fleet 2022-05-02 17:44:01 +01:00 committed by GitHub
parent 2e80aec5cb
commit 1b938fd484
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 81 additions and 9 deletions

View File

@ -2503,7 +2503,7 @@ symbol = "☁️ "
The `package` module is shown when the current directory is the repository for a
package, and shows its current version. The module currently supports `npm`, `nimble`, `cargo`,
`poetry`, `composer`, `gradle`, `julia`, `mix`, `helm`, `shards` and `dart` packages.
`poetry`, `python`, `composer`, `gradle`, `julia`, `mix`, `helm`, `shards` and `dart` packages.
- [**npm**](https://docs.npmjs.com/cli/commands/npm) The `npm` package version is extracted from the `package.json` present
in the current directory
@ -2511,7 +2511,7 @@ package, and shows its current version. The module currently supports `npm`, `ni
- [**Nimble**](https://github.com/nim-lang/nimble) - The `nimble` package version is extracted from the `*.nimble` file present in the current directory with the `nimble dump` command
- [**Poetry**](https://python-poetry.org/) The `poetry` package version is extracted from the `pyproject.toml` present
in the current directory
- [**Python**](https://www.python.org) - The `python` package version is extracted from the `setup.cfg` present in the current directory
- [**Python**](https://www.python.org) - The `python` package version is extracted from a [PEP 621](https://peps.python.org/pep-0621/) compliant `pyproject.toml` or a `setup.cfg` present in the current directory
- [**Composer**](https://getcomposer.org/) The `composer` package version is extracted from the `composer.json` present
in the current directory
- [**Gradle**](https://gradle.org/) The `gradle` package version is extracted from the `build.gradle` present

View File

@ -66,16 +66,25 @@ fn get_node_package_version(context: &Context, config: &PackageConfig) -> Option
Some(formatted_version)
}
fn get_poetry_version(context: &Context, config: &PackageConfig) -> Option<String> {
let file_contents = context.read_file_from_pwd("pyproject.toml")?;
let poetry_toml: toml::Value = toml::from_str(&file_contents).ok()?;
let raw_version = poetry_toml
fn get_poetry_version(pyproject: &toml::Value) -> Option<&str> {
pyproject
.get("tool")?
.get("poetry")?
.get("version")?
.as_str()?;
.as_str()
}
format_version(raw_version, config.version_format)
fn get_pep621_version(pyproject: &toml::Value) -> Option<&str> {
pyproject.get("project")?.get("version")?.as_str()
}
fn get_pyproject_version(context: &Context, config: &PackageConfig) -> Option<String> {
let file_contents = context.read_file_from_pwd("pyproject.toml")?;
let pyproject_toml: toml::Value = toml::from_str(&file_contents).ok()?;
get_pep621_version(&pyproject_toml)
.or_else(|| get_poetry_version(&pyproject_toml))
.and_then(|raw_version| format_version(raw_version, config.version_format))
}
fn get_setup_cfg_version(context: &Context, config: &PackageConfig) -> Option<String> {
@ -252,7 +261,7 @@ fn get_version(context: &Context, config: &PackageConfig) -> Option<String> {
get_cargo_version,
get_nimble_version,
get_node_package_version,
get_poetry_version,
get_pyproject_version,
get_setup_cfg_version,
get_composer_version,
get_gradle_version,
@ -632,6 +641,69 @@ license = "MIT"
project_dir.close()
}
#[test]
fn test_extract_pep621_version() -> io::Result<()> {
let config_name = "pyproject.toml";
let config_content = toml::toml! {
[project]
name = "starship"
version = "0.1.0"
}
.to_string();
let project_dir = create_project_dir()?;
fill_config(&project_dir, config_name, Some(&config_content))?;
expect_output(&project_dir, Some("v0.1.0"), None);
project_dir.close()
}
#[test]
fn test_extract_pep621_version_without_version() -> io::Result<()> {
let config_name = "pyproject.toml";
let config_content = toml::toml! {
[project]
name = "starship"
}
.to_string();
let project_dir = create_project_dir()?;
fill_config(&project_dir, config_name, Some(&config_content))?;
expect_output(&project_dir, None, None);
project_dir.close()
}
#[test]
fn test_extract_pep621_version_attr_directive() -> io::Result<()> {
let config_name = "pyproject.toml";
let config_content = toml::toml! {
[project]
name = "starship"
version = {attr = "starship.__version__"}
}
.to_string();
let project_dir = create_project_dir()?;
fill_config(&project_dir, config_name, Some(&config_content))?;
expect_output(&project_dir, None, None);
project_dir.close()
}
#[test]
fn test_extract_pep621_version_file_directive() -> io::Result<()> {
let config_name = "pyproject.toml";
let config_content = toml::toml! {
[project]
name = "starship"
version = {file = "VERSION.txt"}
}
.to_string();
let project_dir = create_project_dir()?;
fill_config(&project_dir, config_name, Some(&config_content))?;
expect_output(&project_dir, None, None);
project_dir.close()
}
#[test]
fn test_extract_setup_cfg_version() -> io::Result<()> {
let config_name = "setup.cfg";