From db022c7e7e99bc128f291a5e1886f27538ab49ae Mon Sep 17 00:00:00 2001 From: Ruben Arts Date: Tue, 17 Sep 2024 16:42:27 +0200 Subject: [PATCH] fix: `subdirectory` in pypi url (#2065) --- .../src/pypi/pypi_requirement.rs | 22 ++++++++++++++++- crates/pixi_manifest/src/target.rs | 5 ++++ schema/examples/valid/full.toml | 4 ++++ schema/model.py | 7 +++++- schema/schema.json | 24 +++++++++++++++++++ 5 files changed, 60 insertions(+), 2 deletions(-) diff --git a/crates/pixi_manifest/src/pypi/pypi_requirement.rs b/crates/pixi_manifest/src/pypi/pypi_requirement.rs index 3607a1612..abf069e2d 100644 --- a/crates/pixi_manifest/src/pypi/pypi_requirement.rs +++ b/crates/pixi_manifest/src/pypi/pypi_requirement.rs @@ -34,7 +34,8 @@ impl TryFrom for ParsedGitUrl { // Strip the git+ from the url. let url_without_git = url.as_str().strip_prefix("git+").unwrap_or(url.as_str()); - let url = Url::parse(url_without_git)?; + let mut url = Url::parse(url_without_git)?; + url.set_fragment(None); // Split the repository url and the rev. let (repository_url, rev) = if let Some((prefix, suffix)) = url @@ -954,6 +955,25 @@ mod tests { GitRevParseError::InvalidCharacters(characters) )) if characters == "main" ); + + // With subdirectory + let parsed = pep508_rs::Requirement::from_str( + "ribasim@git+https://github.com/Deltares/Ribasim.git#subdirectory=python/ribasim", + ) + .unwrap(); + assert_eq!( + PyPiRequirement::try_from(parsed).unwrap(), + PyPiRequirement::Git { + url: ParsedGitUrl { + git: Url::parse("https://github.com/Deltares/Ribasim.git").unwrap(), + branch: None, + tag: None, + rev: None, + subdirectory: Some("python/ribasim".to_string()), + }, + extras: vec![], + } + ); } #[test] diff --git a/crates/pixi_manifest/src/target.rs b/crates/pixi_manifest/src/target.rs index 04ba84d35..affc225c4 100644 --- a/crates/pixi_manifest/src/target.rs +++ b/crates/pixi_manifest/src/target.rs @@ -222,6 +222,11 @@ impl Target { /// /// This will overwrite any existing dependency of the same name pub fn add_pypi_dependency(&mut self, name: PyPiPackageName, requirement: PyPiRequirement) { + tracing::info!( + "Adding pypi dependency: {} {}", + name.as_normalized(), + requirement + ); self.pypi_dependencies .get_or_insert_with(Default::default) .insert(name, requirement); diff --git a/schema/examples/valid/full.toml b/schema/examples/valid/full.toml index 576b85116..515b953e9 100644 --- a/schema/examples/valid/full.toml +++ b/schema/examples/valid/full.toml @@ -185,6 +185,10 @@ warmup = "python warmup.py" [feature.cuda2.target.osx-arm64.dependencies] mlx = "x.y.z" +[feature.dev.pypi-dependencies] +ribasim = { git = "https://github.com/Deltares/Ribasim.git", subdirectory = "python/ribasim" } +ribasim2 = { path = "test/riba", subdirectory = "python/ribasim" } + # Channels and Platforms are not available as separate tables as they are implemented as lists [feature.cuda2] channels = ["nvidia"] diff --git a/schema/model.py b/schema/model.py index 69ddbe0b1..2b0062703 100644 --- a/schema/model.py +++ b/schema/model.py @@ -24,7 +24,6 @@ VERSION = CARGO_TOML_DATA["package"]["version"] SCHEMA_URI = f"https://pixi.sh/v{VERSION}/schema/manifest/schema.json" - NonEmptyStr = Annotated[str, StringConstraints(min_length=1)] Md5Sum = Annotated[str, StringConstraints(pattern=r"^[a-fA-F0-9]{32}$")] Sha256Sum = Annotated[str, StringConstraints(pattern=r"^[a-fA-F0-9]{64}$")] @@ -200,6 +199,9 @@ class _PyPiGitRequirement(_PyPIRequirement): None, description="The `git` URL to the repo e.g https://github.com/prefix-dev/pixi", ) + subdirectory: NonEmptyStr | None = Field( + None, description="The subdirectory in the repo, a path from the root of the repo." + ) class PyPIGitRevRequirement(_PyPiGitRequirement): @@ -222,6 +224,9 @@ class PyPIPathRequirement(_PyPIRequirement): editable: Optional[bool] = Field( None, description="If `true` the package will be installed as editable" ) + subdirectory: NonEmptyStr | None = Field( + None, description="The subdirectory in the repo, a path from the root of the repo." + ) class PyPIUrlRequirement(_PyPIRequirement): diff --git a/schema/schema.json b/schema/schema.json index 11dff59b5..a2a259959 100644 --- a/schema/schema.json +++ b/schema/schema.json @@ -826,6 +826,12 @@ "description": "The `git` URL to the repo e.g https://github.com/prefix-dev/pixi", "type": "string", "minLength": 1 + }, + "subdirectory": { + "title": "Subdirectory", + "description": "The subdirectory in the repo, a path from the root of the repo.", + "type": "string", + "minLength": 1 } } }, @@ -854,6 +860,12 @@ "description": "A `git` SHA revision to use", "type": "string", "minLength": 1 + }, + "subdirectory": { + "title": "Subdirectory", + "description": "The subdirectory in the repo, a path from the root of the repo.", + "type": "string", + "minLength": 1 } } }, @@ -877,6 +889,12 @@ "type": "string", "minLength": 1 }, + "subdirectory": { + "title": "Subdirectory", + "description": "The subdirectory in the repo, a path from the root of the repo.", + "type": "string", + "minLength": 1 + }, "tag": { "title": "Tag", "description": "A `git` tag to use", @@ -994,6 +1012,12 @@ "description": "A path to a local source or wheel", "type": "string", "minLength": 1 + }, + "subdirectory": { + "title": "Subdirectory", + "description": "The subdirectory in the repo, a path from the root of the repo.", + "type": "string", + "minLength": 1 } } },