diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 1f6202d..4d2e5a1 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -121,7 +121,7 @@ jobs: runs-on: ubuntu-latest environment: name: release - url: https://pypi.org/p/pyproject-fmt + url: https://pypi.org/p/pyproject-fmt/rust permissions: id-token: write if: "startsWith(github.ref, 'refs/tags/')" diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 7740674..92aae01 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -20,7 +20,7 @@ repos: - id: tox-ini-fmt args: [ "-p", "fix" ] - repo: https://github.com/tox-dev/pyproject-fmt - rev: "2.0.1" + rev: "2.0.3" hooks: - id: pyproject-fmt - repo: https://github.com/astral-sh/ruff-pre-commit diff --git a/Cargo.lock b/Cargo.lock index b6e5a81..5972274 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -402,9 +402,9 @@ dependencies = [ [[package]] name = "pep508_rs" -version = "0.5.0" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa3d4bcbc98074b50cdfd37e7ca597aec4d816252af135a7e3ad2e67d1ad6f66" +checksum = "581c27e97a3f38c5d691962af7da93c2672b5227d59cf165b87a9b1fd53dd724" dependencies = [ "derivative", "once_cell", @@ -520,10 +520,11 @@ dependencies = [ [[package]] name = "pyproject-fmt-rust" -version = "1.0.4" +version = "1.0.6" dependencies = [ "indoc", "lexical-sort", + "pep440_rs", "pep508_rs", "pyo3", "regex", diff --git a/Cargo.toml b/Cargo.toml index 582f538..c779c61 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pyproject-fmt-rust" -version = "1.0.5" +version = "1.0.6" description = "Format pyproject.toml files" repository = "https://github.com/tox-dev/pyproject-fmt" readme = "README.md" @@ -15,7 +15,8 @@ crate-type = ["cdylib"] [dependencies] taplo = { version = "0.13.0" } # formatter pyo3 = { version = "0.21.2", features = ["abi3-py38"] } # integration with Python -pep508_rs = { version = "0.5.0" } +pep440_rs = { version = "0.6.0" } +pep508_rs = { version = "0.6.0" } lexical-sort = { version = "0.3.1" } regex = { version = "1.10.4" } diff --git a/rust/src/helpers/pep508.rs b/rust/src/helpers/pep508.rs index fbe8243..4710001 100644 --- a/rust/src/helpers/pep508.rs +++ b/rust/src/helpers/pep508.rs @@ -1,6 +1,7 @@ use std::fmt::Write; use std::str::FromStr; +use pep440_rs::Operator; use pep508_rs::{MarkerTree, Requirement, VersionOrUrl}; pub fn format_requirement(value: &str, keep_full_version: bool) -> String { @@ -23,7 +24,7 @@ pub fn format_requirement(value: &str, keep_full_version: bool) -> String { let extra_count = v.len() - 1; for (at, spec) in v.iter().enumerate() { let mut spec_repr = format!("{spec}"); - if !keep_full_version { + if !keep_full_version && spec.operator() != &Operator::TildeEqual { loop { let propose = spec_repr.strip_suffix(".0"); if propose.is_none() { @@ -39,7 +40,7 @@ pub fn format_requirement(value: &str, keep_full_version: bool) -> String { } } VersionOrUrl::Url(u) => { - write!(&mut result, "{u}").unwrap(); + write!(&mut result, " @ {u}").unwrap(); } } } @@ -109,7 +110,16 @@ mod tests { "requests[security,tests]>=2.0.0,==2.8.*; (os_name=='a' or os_name=='b') and os_name=='c' and python_version>'3.8'", true )] + #[case::do_not_strip_tilda("a~=3.0.0", "a~=3.0.0", false)] + #[case::url( + " pip @ https://github.com/pypa/pip/archive/1.3.1.zip#sha1=da9234ee9982d4bbb3c72346a6de940a148ea686 ", + "pip @ https://github.com/pypa/pip/archive/1.3.1.zip#sha1=da9234ee9982d4bbb3c72346a6de940a148ea686", + true + )] fn test_format_requirement(#[case] start: &str, #[case] expected: &str, #[case] keep_full_version: bool) { - assert_eq!(format_requirement(start, keep_full_version), expected); + let got = format_requirement(start, keep_full_version); + assert_eq!(got, expected); + // formatting remains stable + assert_eq!(format_requirement(got.as_str(), keep_full_version), expected); } }