feat(package): Support package version from setup.cfg (python). (#2890)

* Support package version from setup.cfg (python).

Add an additional package version extraction function to parse
the 'version' attribute under the 'metadata' section in a python
package 'setup.cfg' file.

Also add similar tests from the poetry extraction function to test
the desired behaviour.

This adds a dependency on ConfigParser:
https://crates.io/crates/configparser.

* Clean up comments

* Use rust_ini over ConfigParser

* Add mention to setup.cfg version parsing in docs
This commit is contained in:
Tom 2021-07-27 16:58:35 +01:00 committed by GitHub
parent 82f68a0a39
commit 2fa7f56cec
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 37 additions and 0 deletions

View File

@ -2096,6 +2096,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
- [**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

@ -3,6 +3,7 @@ use crate::configs::package::PackageConfig;
use crate::formatter::StringFormatter;
use crate::utils;
use ini::Ini;
use quick_xml::events::Event as QXEvent;
use quick_xml::Reader as QXReader;
use regex::Regex;
@ -96,6 +97,14 @@ fn extract_poetry_version(file_contents: &str) -> Option<String> {
Some(formatted_version)
}
fn extract_setup_cfg_version(file_contents: &str) -> Option<String> {
let ini = Ini::load_from_str(file_contents).ok()?;
let raw_version = ini.get_from(Some("metadata"), "version")?;
let formatted_version = format_version(raw_version);
Some(formatted_version)
}
fn extract_gradle_version(file_contents: &str) -> Option<String> {
let re = Regex::new(r#"(?m)^version ['"](?P<version>[^'"]+)['"]$"#).unwrap();
let caps = re.captures(file_contents)?;
@ -217,6 +226,8 @@ fn get_package_version(context: &Context, config: &PackageConfig) -> Option<Stri
extract_package_version(&package_json, config.display_private)
} else if let Ok(poetry_toml) = utils::read_file(base_dir.join("pyproject.toml")) {
extract_poetry_version(&poetry_toml)
} else if let Ok(setup_cfg) = utils::read_file(base_dir.join("setup.cfg")) {
extract_setup_cfg_version(&setup_cfg)
} else if let Ok(composer_json) = utils::read_file(base_dir.join("composer.json")) {
extract_composer_version(&composer_json)
} else if let Ok(build_gradle) = utils::read_file(base_dir.join("build.gradle")) {
@ -572,6 +583,31 @@ license = "MIT"
project_dir.close()
}
#[test]
fn test_extract_setup_cfg_version() -> io::Result<()> {
let config_name = "setup.cfg";
let config_content = String::from(
"[metadata]
version = 0.1.0",
);
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_setup_cfg_version_without_version() -> io::Result<()> {
let config_name = "setup.cfg";
let config_content = String::from("[metadata]");
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_gradle_version_single_quote() -> io::Result<()> {
let config_name = "build.gradle";