Skip to content

Commit a4f3050

Browse files
committed
Add uv export support for PEP 751
1 parent 09939d4 commit a4f3050

File tree

8 files changed

+639
-8
lines changed

8 files changed

+639
-8
lines changed

crates/uv-configuration/src/export_format.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,4 +11,8 @@ pub enum ExportFormat {
1111
clap(name = "requirements.txt", alias = "requirements-txt")
1212
)]
1313
RequirementsTxt,
14+
/// Export in `pylock.toml` format.
15+
#[serde(rename = "pylock.toml", alias = "pylock-toml")]
16+
#[cfg_attr(feature = "clap", clap(name = "pylock.toml", alias = "pylock-toml"))]
17+
PylockToml,
1418
}

crates/uv-pypi-types/src/simple_json.rs

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -185,11 +185,15 @@ impl Default for Yanked {
185185
/// A dictionary mapping a hash name to a hex encoded digest of the file.
186186
///
187187
/// PEP 691 says multiple hashes can be included and the interpretation is left to the client.
188-
#[derive(Debug, Clone, Eq, PartialEq, Default, Deserialize)]
188+
#[derive(Debug, Clone, Eq, PartialEq, Default, Deserialize, Serialize)]
189189
pub struct Hashes {
190+
#[serde(skip_serializing_if = "Option::is_none")]
190191
pub md5: Option<SmallString>,
192+
#[serde(skip_serializing_if = "Option::is_none")]
191193
pub sha256: Option<SmallString>,
194+
#[serde(skip_serializing_if = "Option::is_none")]
192195
pub sha384: Option<SmallString>,
196+
#[serde(skip_serializing_if = "Option::is_none")]
193197
pub sha512: Option<SmallString>,
194198
}
195199

@@ -490,6 +494,21 @@ impl From<Hashes> for HashDigests {
490494
}
491495
}
492496

497+
impl From<HashDigests> for Hashes {
498+
fn from(value: HashDigests) -> Self {
499+
let mut hashes = Hashes::default();
500+
for digest in value.iter() {
501+
match digest.algorithm() {
502+
HashAlgorithm::Md5 => hashes.md5 = Some(digest.digest.clone()),
503+
HashAlgorithm::Sha256 => hashes.sha256 = Some(digest.digest.clone()),
504+
HashAlgorithm::Sha384 => hashes.sha384 = Some(digest.digest.clone()),
505+
HashAlgorithm::Sha512 => hashes.sha512 = Some(digest.digest.clone()),
506+
}
507+
}
508+
hashes
509+
}
510+
}
511+
493512
impl From<HashDigest> for HashDigests {
494513
fn from(value: HashDigest) -> Self {
495514
Self(Box::new([value]))

crates/uv-resolver/src/lib.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@ pub use exclusions::Exclusions;
55
pub use flat_index::{FlatDistributions, FlatIndex};
66
pub use fork_strategy::ForkStrategy;
77
pub use lock::{
8-
Installable, Lock, LockError, LockVersion, Package, PackageMap, RequirementsTxtExport,
9-
ResolverManifest, SatisfiesResult, TreeDisplay, VERSION,
8+
Installable, Lock, LockError, LockVersion, Package, PackageMap, PylockToml,
9+
RequirementsTxtExport, ResolverManifest, SatisfiesResult, TreeDisplay, VERSION,
1010
};
1111
pub use manifest::Manifest;
1212
pub use options::{Flexibility, Options, OptionsBuilder};

crates/uv-resolver/src/lock/export/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,12 @@ use uv_pep508::MarkerTree;
1414
use uv_pypi_types::ConflictItem;
1515

1616
use crate::graph_ops::{marker_reachability, Reachable};
17+
pub use crate::lock::export::pylock_toml::PylockToml;
1718
pub use crate::lock::export::requirements_txt::RequirementsTxtExport;
1819
use crate::universal_marker::resolve_conflicts;
1920
use crate::{Installable, Package};
2021

22+
mod pylock_toml;
2123
mod requirements_txt;
2224

2325
/// A flat requirement, with its associated marker.

0 commit comments

Comments
 (0)