Skip to content

Commit

Permalink
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Include commit_id and requested_revision in direct_url.json
Browse files Browse the repository at this point in the history
charliermarsh committed Jan 22, 2025
1 parent d454f9c commit d7fb013
Showing 11 changed files with 319 additions and 158 deletions.
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 0 additions & 1 deletion crates/uv-distribution-types/Cargo.toml
Original file line number Diff line number Diff line change
@@ -28,7 +28,6 @@ uv-pep508 = { workspace = true }
uv-platform-tags = { workspace = true }
uv-pypi-types = { workspace = true }

anyhow = { workspace = true }
arcstr = { workspace = true }
bitflags = { workspace = true }
fs-err = { workspace = true }
98 changes: 31 additions & 67 deletions crates/uv-distribution-types/src/cached.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,9 @@
use std::path::{Path, PathBuf};

use anyhow::{anyhow, Result};

use uv_cache_info::CacheInfo;
use uv_distribution_filename::WheelFilename;
use uv_normalize::PackageName;
use uv_pep508::VerbatimUrl;
use uv_pypi_types::{HashDigest, ParsedDirectoryUrl};
use uv_pypi_types::{HashDigest, VerbatimParsedUrl};

use crate::{
BuiltDist, Dist, DistributionMetadata, Hashed, InstalledMetadata, InstalledVersion, Name,
@@ -33,10 +30,8 @@ pub struct CachedRegistryDist {
#[derive(Debug, Clone, Hash, PartialEq, Eq)]
pub struct CachedDirectUrlDist {
pub filename: WheelFilename,
pub url: VerbatimUrl,
pub url: VerbatimParsedUrl,
pub path: PathBuf,
pub editable: bool,
pub r#virtual: bool,
pub hashes: Vec<HashDigest>,
pub cache_info: CacheInfo,
}
@@ -59,21 +54,23 @@ impl CachedDist {
}),
Dist::Built(BuiltDist::DirectUrl(dist)) => Self::Url(CachedDirectUrlDist {
filename,
url: dist.url,
url: VerbatimParsedUrl {
parsed_url: dist.parsed_url(),
verbatim: dist.url,
},
hashes,
cache_info,
path,
editable: false,
r#virtual: false,
}),
Dist::Built(BuiltDist::Path(dist)) => Self::Url(CachedDirectUrlDist {
filename,
url: dist.url,
url: VerbatimParsedUrl {
parsed_url: dist.parsed_url(),
verbatim: dist.url,
},
hashes,
cache_info,
path,
editable: false,
r#virtual: false,
}),
Dist::Source(SourceDist::Registry(_dist)) => Self::Registry(CachedRegistryDist {
filename,
@@ -83,39 +80,43 @@ impl CachedDist {
}),
Dist::Source(SourceDist::DirectUrl(dist)) => Self::Url(CachedDirectUrlDist {
filename,
url: dist.url,
url: VerbatimParsedUrl {
parsed_url: dist.parsed_url(),
verbatim: dist.url,
},
hashes,
cache_info,
path,
editable: false,
r#virtual: false,
}),
Dist::Source(SourceDist::Git(dist)) => Self::Url(CachedDirectUrlDist {
filename,
url: dist.url,
url: VerbatimParsedUrl {
parsed_url: dist.parsed_url(),
verbatim: dist.url,
},
hashes,
cache_info,
path,
editable: false,
r#virtual: false,
}),
Dist::Source(SourceDist::Path(dist)) => Self::Url(CachedDirectUrlDist {
filename,
url: dist.url,
url: VerbatimParsedUrl {
parsed_url: dist.parsed_url(),
verbatim: dist.url,
},
hashes,
cache_info,
path,
editable: false,
r#virtual: false,
}),
Dist::Source(SourceDist::Directory(dist)) => Self::Url(CachedDirectUrlDist {
filename,
url: dist.url,
url: VerbatimParsedUrl {
parsed_url: dist.parsed_url(),
verbatim: dist.url,
},
hashes,
cache_info,
path,
editable: dist.editable,
r#virtual: dist.r#virtual,
}),
}
}
@@ -137,26 +138,10 @@ impl CachedDist {
}

/// Return the [`ParsedUrl`] of the distribution, if it exists.
pub fn parsed_url(&self) -> Result<Option<ParsedUrl>> {
pub fn parsed_url(&self) -> Option<&ParsedUrl> {
match self {
Self::Registry(_) => Ok(None),
Self::Url(dist) => {
if dist.editable {
assert_eq!(dist.url.scheme(), "file", "{}", dist.url);
let path = dist
.url
.to_file_path()
.map_err(|()| anyhow!("Invalid path in file URL"))?;
Ok(Some(ParsedUrl::Directory(ParsedDirectoryUrl {
url: dist.url.raw().clone(),
install_path: path,
editable: dist.editable,
r#virtual: dist.r#virtual,
})))
} else {
Ok(Some(ParsedUrl::try_from(dist.url.to_url())?))
}
}
Self::Registry(_) => None,
Self::Url(dist) => Some(&dist.url.parsed_url),
}
}

@@ -175,27 +160,6 @@ impl Hashed for CachedRegistryDist {
}
}

impl CachedDirectUrlDist {
/// Initialize a [`CachedDirectUrlDist`] from a [`WheelFilename`], [`url::Url`], and [`Path`].
pub fn from_url(
filename: WheelFilename,
url: VerbatimUrl,
hashes: Vec<HashDigest>,
cache_info: CacheInfo,
path: PathBuf,
) -> Self {
Self {
filename,
url,
hashes,
cache_info,
path,
editable: false,
r#virtual: false,
}
}
}

impl Name for CachedRegistryDist {
fn name(&self) -> &PackageName {
&self.filename.name
@@ -225,7 +189,7 @@ impl DistributionMetadata for CachedRegistryDist {

impl DistributionMetadata for CachedDirectUrlDist {
fn version_or_url(&self) -> VersionOrUrlRef {
VersionOrUrlRef::Url(&self.url)
VersionOrUrlRef::Url(&self.url.verbatim)
}
}

@@ -246,7 +210,7 @@ impl InstalledMetadata for CachedRegistryDist {

impl InstalledMetadata for CachedDirectUrlDist {
fn installed_version(&self) -> InstalledVersion {
InstalledVersion::Url(&self.url, &self.filename.version)
InstalledVersion::Url(&self.url.verbatim, &self.filename.version)
}
}

72 changes: 71 additions & 1 deletion crates/uv-distribution-types/src/lib.rs
Original file line number Diff line number Diff line change
@@ -47,7 +47,9 @@ use uv_git::GitUrl;
use uv_normalize::PackageName;
use uv_pep440::Version;
use uv_pep508::{Pep508Url, VerbatimUrl};
use uv_pypi_types::{ParsedUrl, VerbatimParsedUrl};
use uv_pypi_types::{
ParsedArchiveUrl, ParsedDirectoryUrl, ParsedGitUrl, ParsedPathUrl, ParsedUrl, VerbatimParsedUrl,
};

pub use crate::annotation::*;
pub use crate::any::*;
@@ -662,6 +664,74 @@ impl RegistryBuiltDist {
}
}

impl DirectUrlBuiltDist {
/// Return the [`ParsedUrl`] for the distribution.
pub fn parsed_url(&self) -> ParsedUrl {
ParsedUrl::Archive(ParsedArchiveUrl::from_source(
(*self.location).clone(),
None,
DistExtension::Wheel,
))
}
}

impl PathBuiltDist {
/// Return the [`ParsedUrl`] for the distribution.
pub fn parsed_url(&self) -> ParsedUrl {
ParsedUrl::Path(ParsedPathUrl::from_source(
self.install_path.clone(),
DistExtension::Wheel,
self.url.to_url(),
))
}
}

impl PathSourceDist {
/// Return the [`ParsedUrl`] for the distribution.
pub fn parsed_url(&self) -> ParsedUrl {
ParsedUrl::Path(ParsedPathUrl::from_source(
self.install_path.clone(),
DistExtension::Source(self.ext),
self.url.to_url(),
))
}
}

impl DirectUrlSourceDist {
/// Return the [`ParsedUrl`] for the distribution.
pub fn parsed_url(&self) -> ParsedUrl {
ParsedUrl::Archive(ParsedArchiveUrl::from_source(
(*self.location).clone(),
self.subdirectory.clone(),
DistExtension::Source(self.ext),
))
}
}

impl GitSourceDist {
/// Return the [`ParsedUrl`] for the distribution.
pub fn parsed_url(&self) -> ParsedUrl {
ParsedUrl::Git(ParsedGitUrl::from_source(
self.git.repository().clone(),
self.git.reference().clone(),
self.git.precise(),
self.subdirectory.clone(),
))
}
}

impl DirectorySourceDist {
/// Return the [`ParsedUrl`] for the distribution.
pub fn parsed_url(&self) -> ParsedUrl {
ParsedUrl::Directory(ParsedDirectoryUrl::from_source(
self.install_path.clone(),
self.editable,
self.r#virtual,
self.url.to_url(),
))
}
}

impl Name for RegistryBuiltWheel {
fn name(&self) -> &PackageName {
&self.filename.name
64 changes: 44 additions & 20 deletions crates/uv-distribution/src/index/cached_wheel.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
use std::path::Path;

use crate::archive::Archive;
use crate::{HttpArchivePointer, LocalArchivePointer};
use uv_cache::{Cache, CacheBucket, CacheEntry};
use uv_cache_info::CacheInfo;
use uv_distribution_filename::WheelFilename;
use uv_distribution_types::{CachedDirectUrlDist, CachedRegistryDist, Hashed};
use uv_pep508::VerbatimUrl;
use uv_pypi_types::HashDigest;
use uv_distribution_types::{
CachedDirectUrlDist, CachedRegistryDist, DirectUrlSourceDist, DirectorySourceDist,
GitSourceDist, Hashed, PathSourceDist,
};
use uv_pypi_types::{HashDigest, VerbatimParsedUrl};

use crate::archive::Archive;
use crate::{HttpArchivePointer, LocalArchivePointer};

#[derive(Debug, Clone)]
pub struct CachedWheel {
@@ -53,40 +56,61 @@ impl CachedWheel {
}
}

/// Convert a [`CachedWheel`] into a [`CachedDirectUrlDist`].
pub fn into_url_dist(self, url: VerbatimUrl) -> CachedDirectUrlDist {
/// Convert a [`CachedWheel`] into a [`CachedDirectUrlDist`] by merging in the given
/// [`DirectUrlSourceDist`].
pub fn into_url_dist(self, dist: &DirectUrlSourceDist) -> CachedDirectUrlDist {
CachedDirectUrlDist {
filename: self.filename,
url: VerbatimParsedUrl {
parsed_url: dist.parsed_url(),
verbatim: dist.url.clone(),
},
path: self.entry.into_path_buf(),
hashes: self.hashes,
cache_info: self.cache_info,
}
}

/// Convert a [`CachedWheel`] into a [`CachedDirectUrlDist`] by merging in the given
/// [`PathSourceDist`].
pub fn into_path_dist(self, dist: &PathSourceDist) -> CachedDirectUrlDist {
CachedDirectUrlDist {
filename: self.filename,
url,
url: VerbatimParsedUrl {
parsed_url: dist.parsed_url(),
verbatim: dist.url.clone(),
},
path: self.entry.into_path_buf(),
editable: false,
r#virtual: false,
hashes: self.hashes,
cache_info: self.cache_info,
}
}

/// Convert a [`CachedWheel`] into an editable [`CachedDirectUrlDist`].
pub fn into_editable(self, url: VerbatimUrl) -> CachedDirectUrlDist {
/// Convert a [`CachedWheel`] into a [`CachedDirectUrlDist`] by merging in the given
/// [`DirectorySourceDist`].
pub fn into_directory_dist(self, dist: &DirectorySourceDist) -> CachedDirectUrlDist {
CachedDirectUrlDist {
filename: self.filename,
url,
url: VerbatimParsedUrl {
parsed_url: dist.parsed_url(),
verbatim: dist.url.clone(),
},
path: self.entry.into_path_buf(),
editable: true,
r#virtual: false,
hashes: self.hashes,
cache_info: self.cache_info,
}
}

/// Convert a [`CachedWheel`] into an editable [`CachedDirectUrlDist`].
pub fn into_virtual(self, url: VerbatimUrl) -> CachedDirectUrlDist {
/// Convert a [`CachedWheel`] into a [`CachedDirectUrlDist`] by merging in the given
/// [`GitSourceDist`].
pub fn into_git_dist(self, dist: &GitSourceDist) -> CachedDirectUrlDist {
CachedDirectUrlDist {
filename: self.filename,
url,
url: VerbatimParsedUrl {
parsed_url: dist.parsed_url(),
verbatim: dist.url.clone(),
},
path: self.entry.into_path_buf(),
editable: false,
r#virtual: true,
hashes: self.hashes,
cache_info: self.cache_info,
}
1 change: 1 addition & 0 deletions crates/uv-installer/Cargo.toml
Original file line number Diff line number Diff line change
@@ -23,6 +23,7 @@ uv-configuration = { workspace = true }
uv-distribution = { workspace = true }
uv-distribution-types = { workspace = true }
uv-fs = { workspace = true }
uv-git = { workspace = true }
uv-install-wheel = { workspace = true, default-features = false }
uv-normalize = { workspace = true }
uv-pep440 = { workspace = true }
6 changes: 2 additions & 4 deletions crates/uv-installer/src/installer.rs
Original file line number Diff line number Diff line change
@@ -166,10 +166,8 @@ fn install(
wheel.path(),
wheel.filename(),
wheel
.parsed_url()?
.as_ref()
.map(uv_pypi_types::DirectUrl::try_from)
.transpose()?
.parsed_url()
.map(uv_pypi_types::DirectUrl::from)
.as_ref(),
if wheel.cache_info().is_empty() {
None
50 changes: 26 additions & 24 deletions crates/uv-installer/src/plan.rs
Original file line number Diff line number Diff line change
@@ -2,7 +2,7 @@ use anyhow::{bail, Result};
use tracing::{debug, warn};

use uv_cache::{Cache, CacheBucket, WheelCache};
use uv_cache_info::{CacheInfo, Timestamp};
use uv_cache_info::Timestamp;
use uv_configuration::{BuildOptions, ConfigSettings, Reinstall};
use uv_distribution::{
BuiltWheelIndex, HttpArchivePointer, LocalArchivePointer, RegistryWheelIndex,
@@ -13,7 +13,7 @@ use uv_distribution_types::{
};
use uv_fs::Simplified;
use uv_platform_tags::Tags;
use uv_pypi_types::RequirementSource;
use uv_pypi_types::{RequirementSource, VerbatimParsedUrl};
use uv_python::PythonEnvironment;
use uv_types::HashStrategy;

@@ -163,18 +163,21 @@ impl<'a> Planner<'a> {

// Read the HTTP pointer.
if let Some(pointer) = HttpArchivePointer::read_from(&cache_entry)? {
let cache_info = pointer.to_cache_info();
let archive = pointer.into_archive();
if archive.satisfies(hasher.get(dist)) {
let cached_dist = CachedDirectUrlDist::from_url(
wheel.filename.clone(),
wheel.url.clone(),
archive.hashes,
CacheInfo::default(),
cache.archive(&archive.id),
);
let cached_dist = CachedDirectUrlDist {
filename: wheel.filename.clone(),
url: VerbatimParsedUrl {
parsed_url: wheel.parsed_url(),
verbatim: wheel.url.clone(),
},
hashes: archive.hashes,
cache_info,
path: cache.archive(&archive.id),
};

debug!("URL wheel requirement already cached: {cached_dist}");
// STOPSHIP(charlie): If these are mismatched, skip and warn.
cached.push(CachedDist::Url(cached_dist));
continue;
}
@@ -215,13 +218,16 @@ impl<'a> Planner<'a> {
let cache_info = pointer.to_cache_info();
let archive = pointer.into_archive();
if archive.satisfies(hasher.get(dist)) {
let cached_dist = CachedDirectUrlDist::from_url(
wheel.filename.clone(),
wheel.url.clone(),
archive.hashes,
let cached_dist = CachedDirectUrlDist {
filename: wheel.filename.clone(),
url: VerbatimParsedUrl {
parsed_url: wheel.parsed_url(),
verbatim: wheel.url.clone(),
},
hashes: archive.hashes,
cache_info,
cache.archive(&archive.id),
);
path: cache.archive(&archive.id),
};

debug!("Path wheel requirement already cached: {cached_dist}");
cached.push(CachedDist::Url(cached_dist));
@@ -259,7 +265,7 @@ impl<'a> Planner<'a> {
// the filename in advance.
if let Some(wheel) = built_index.url(sdist)? {
if wheel.filename.name == sdist.name {
let cached_dist = wheel.into_url_dist(sdist.url.clone());
let cached_dist = wheel.into_url_dist(sdist);
debug!("URL source requirement already cached: {cached_dist}");
cached.push(CachedDist::Url(cached_dist));
continue;
@@ -277,7 +283,7 @@ impl<'a> Planner<'a> {
// the filename in advance.
if let Some(wheel) = built_index.git(sdist) {
if wheel.filename.name == sdist.name {
let cached_dist = wheel.into_url_dist(sdist.url.clone());
let cached_dist = wheel.into_git_dist(sdist);
debug!("Git source requirement already cached: {cached_dist}");
cached.push(CachedDist::Url(cached_dist));
continue;
@@ -300,7 +306,7 @@ impl<'a> Planner<'a> {
// the filename in advance.
if let Some(wheel) = built_index.path(sdist)? {
if wheel.filename.name == sdist.name {
let cached_dist = wheel.into_url_dist(sdist.url.clone());
let cached_dist = wheel.into_path_dist(sdist);
debug!("Path source requirement already cached: {cached_dist}");
cached.push(CachedDist::Url(cached_dist));
continue;
@@ -323,11 +329,7 @@ impl<'a> Planner<'a> {
// the filename in advance.
if let Some(wheel) = built_index.directory(sdist)? {
if wheel.filename.name == sdist.name {
let cached_dist = if sdist.editable {
wheel.into_editable(sdist.url.clone())
} else {
wheel.into_url_dist(sdist.url.clone())
};
let cached_dist = wheel.into_directory_dist(sdist);
debug!("Directory source requirement already cached: {cached_dist}");
cached.push(CachedDist::Url(cached_dist));
continue;
17 changes: 9 additions & 8 deletions crates/uv-installer/src/satisfies.rs
Original file line number Diff line number Diff line change
@@ -7,6 +7,7 @@ use url::Url;
use uv_cache_info::CacheInfo;
use uv_cache_key::{CanonicalUrl, RepositoryUrl};
use uv_distribution_types::{InstalledDirectUrlDist, InstalledDist};
use uv_git::GitOid;
use uv_pypi_types::{DirInfo, DirectUrl, RequirementSource, VcsInfo, VcsKind};

#[derive(Debug, Copy, Clone)]
@@ -97,7 +98,7 @@ impl RequirementSatisfaction {
RequirementSource::Git {
url: _,
repository: requested_repository,
reference: requested_reference,
reference: _,
precise: requested_precise,
subdirectory: requested_subdirectory,
} => {
@@ -110,8 +111,8 @@ impl RequirementSatisfaction {
vcs_info:
VcsInfo {
vcs: VcsKind::Git,
requested_revision: installed_reference,
commit_id: _,
requested_revision: _,
commit_id: installed_precise,
},
subdirectory: installed_subdirectory,
} = direct_url.as_ref()
@@ -137,12 +138,12 @@ impl RequirementSatisfaction {
return Ok(Self::Mismatch);
}

if installed_reference.as_deref() != requested_reference.as_str()
&& installed_reference != &requested_precise.map(|git_sha| git_sha.to_string())
{
// TODO(charlie): It would be more consistent for us to compare the requested
// revisions here.
if installed_precise.as_deref() != requested_precise.as_ref().map(GitOid::as_str) {
debug!(
"Reference mismatch: {:?} vs. {:?} and {:?}",
installed_reference, requested_reference, requested_precise
"Precise mismatch: {:?} vs. {:?}",
installed_precise, requested_precise
);
return Ok(Self::OutOfDate);
}
54 changes: 22 additions & 32 deletions crates/uv-pypi-types/src/parsed_url.rs
Original file line number Diff line number Diff line change
@@ -406,75 +406,65 @@ impl TryFrom<Url> for ParsedUrl {
}
}

impl TryFrom<&ParsedUrl> for DirectUrl {
type Error = ParsedUrlError;

fn try_from(value: &ParsedUrl) -> Result<Self, Self::Error> {
impl From<&ParsedUrl> for DirectUrl {
fn from(value: &ParsedUrl) -> Self {
match value {
ParsedUrl::Path(value) => Self::try_from(value),
ParsedUrl::Directory(value) => Self::try_from(value),
ParsedUrl::Git(value) => Self::try_from(value),
ParsedUrl::Archive(value) => Self::try_from(value),
ParsedUrl::Path(value) => Self::from(value),
ParsedUrl::Directory(value) => Self::from(value),
ParsedUrl::Git(value) => Self::from(value),
ParsedUrl::Archive(value) => Self::from(value),
}
}
}

impl TryFrom<&ParsedPathUrl> for DirectUrl {
type Error = ParsedUrlError;

fn try_from(value: &ParsedPathUrl) -> Result<Self, Self::Error> {
Ok(Self::ArchiveUrl {
impl From<&ParsedPathUrl> for DirectUrl {
fn from(value: &ParsedPathUrl) -> Self {
Self::ArchiveUrl {
url: value.url.to_string(),
archive_info: ArchiveInfo {
hash: None,
hashes: None,
},
subdirectory: None,
})
}
}
}

impl TryFrom<&ParsedDirectoryUrl> for DirectUrl {
type Error = ParsedUrlError;

fn try_from(value: &ParsedDirectoryUrl) -> Result<Self, Self::Error> {
Ok(Self::LocalDirectory {
impl From<&ParsedDirectoryUrl> for DirectUrl {
fn from(value: &ParsedDirectoryUrl) -> Self {
Self::LocalDirectory {
url: value.url.to_string(),
dir_info: DirInfo {
editable: value.editable.then_some(true),
},
})
}
}
}

impl TryFrom<&ParsedArchiveUrl> for DirectUrl {
type Error = ParsedUrlError;

fn try_from(value: &ParsedArchiveUrl) -> Result<Self, Self::Error> {
Ok(Self::ArchiveUrl {
impl From<&ParsedArchiveUrl> for DirectUrl {
fn from(value: &ParsedArchiveUrl) -> Self {
Self::ArchiveUrl {
url: value.url.to_string(),
archive_info: ArchiveInfo {
hash: None,
hashes: None,
},
subdirectory: value.subdirectory.clone(),
})
}
}
}

impl TryFrom<&ParsedGitUrl> for DirectUrl {
type Error = ParsedUrlError;

fn try_from(value: &ParsedGitUrl) -> Result<Self, Self::Error> {
Ok(Self::VcsUrl {
impl From<&ParsedGitUrl> for DirectUrl {
fn from(value: &ParsedGitUrl) -> Self {
Self::VcsUrl {
url: value.url.repository().to_string(),
vcs_info: VcsInfo {
vcs: VcsKind::Git,
commit_id: value.url.precise().as_ref().map(ToString::to_string),
requested_revision: value.url.reference().as_str().map(ToString::to_string),
},
subdirectory: value.subdirectory.clone(),
})
}
}
}

112 changes: 112 additions & 0 deletions crates/uv/tests/it/pip_install.rs
Original file line number Diff line number Diff line change
@@ -5825,6 +5825,7 @@ fn already_installed_remote_url() {
----- stdout -----
----- stderr -----
Resolved 1 package in [TIME]
Audited 1 package in [TIME]
"###);

@@ -8257,3 +8258,114 @@ fn cyclic_build_dependency() {
"###
);
}

#[test]
fn direct_url_json_git_default() -> Result<()> {
let context = TestContext::new("3.12");
let requirements_txt = context.temp_dir.child("requirements.txt");
requirements_txt.write_str(
"uv-public-pypackage @ git+https://github.com/astral-test/uv-public-pypackage",
)?;

uv_snapshot!(context.pip_install()
.arg("-r")
.arg("requirements.txt")
.arg("--strict"), @r###"
success: true
exit_code: 0
----- stdout -----
----- stderr -----
Resolved 1 package in [TIME]
Prepared 1 package in [TIME]
Installed 1 package in [TIME]
+ uv-public-pypackage==0.1.0 (from git+https://github.com/astral-test/uv-public-pypackage@b270df1a2fb5d012294e9aaf05e7e0bab1e6a389)
"###
);

let direct_url = context.venv.child(if cfg!(windows) {
"Lib\\site-packages\\uv_public_pypackage-0.1.0.dist-info\\direct_url.json"
} else {
"lib/python3.12/site-packages/uv_public_pypackage-0.1.0.dist-info/direct_url.json"
});
direct_url.assert(predicates::path::is_file());

let direct_url_content = fs_err::read_to_string(direct_url.path())?;
insta::assert_snapshot!(direct_url_content, @r###"{"url":"https://github.com/astral-test/uv-public-pypackage","vcs_info":{"vcs":"git","commit_id":"b270df1a2fb5d012294e9aaf05e7e0bab1e6a389"}}"###);

Ok(())
}

#[test]
fn direct_url_json_git_tag() -> Result<()> {
let context = TestContext::new("3.12");
let requirements_txt = context.temp_dir.child("requirements.txt");
requirements_txt.write_str(
"uv-public-pypackage @ git+https://github.com/astral-test/uv-public-pypackage@0.0.1",
)?;

uv_snapshot!(context.pip_install()
.arg("-r")
.arg("requirements.txt")
.arg("--strict"), @r###"
success: true
exit_code: 0
----- stdout -----
----- stderr -----
Resolved 1 package in [TIME]
Prepared 1 package in [TIME]
Installed 1 package in [TIME]
+ uv-public-pypackage==0.1.0 (from git+https://github.com/astral-test/uv-public-pypackage@0dacfd662c64cb4ceb16e6cf65a157a8b715b979)
"###
);

let direct_url = context.venv.child(if cfg!(windows) {
"Lib\\site-packages\\uv_public_pypackage-0.1.0.dist-info\\direct_url.json"
} else {
"lib/python3.12/site-packages/uv_public_pypackage-0.1.0.dist-info/direct_url.json"
});
direct_url.assert(predicates::path::is_file());

let direct_url_content = fs_err::read_to_string(direct_url.path())?;
insta::assert_snapshot!(direct_url_content, @r###"{"url":"https://github.com/astral-test/uv-public-pypackage","vcs_info":{"vcs":"git","commit_id":"0dacfd662c64cb4ceb16e6cf65a157a8b715b979","requested_revision":"0.0.1"}}"###);

Ok(())
}

#[test]
fn direct_url_json_direct_url() -> Result<()> {
let context = TestContext::new("3.12");
let requirements_txt = context.temp_dir.child("requirements.txt");
requirements_txt.write_str(
"source-distribution @ https://files.pythonhosted.org/packages/1f/e5/5b016c945d745f8b108e759d428341488a6aee8f51f07c6c4e33498bb91f/source_distribution-0.0.3.tar.gz",
)?;

uv_snapshot!(context.pip_install()
.arg("-r")
.arg("requirements.txt")
.arg("--strict"), @r###"
success: true
exit_code: 0
----- stdout -----
----- stderr -----
Resolved 1 package in [TIME]
Prepared 1 package in [TIME]
Installed 1 package in [TIME]
+ source-distribution==0.0.3 (from https://files.pythonhosted.org/packages/1f/e5/5b016c945d745f8b108e759d428341488a6aee8f51f07c6c4e33498bb91f/source_distribution-0.0.3.tar.gz)
"###
);

let direct_url = context.venv.child(if cfg!(windows) {
"Lib\\site-packages\\source_distribution-0.0.3.dist-info\\direct_url.json"
} else {
"lib/python3.12/site-packages/source_distribution-0.0.3.dist-info/direct_url.json"
});
direct_url.assert(predicates::path::is_file());

let direct_url_content = fs_err::read_to_string(direct_url.path())?;
insta::assert_snapshot!(direct_url_content, @r###"{"url":"https://files.pythonhosted.org/packages/1f/e5/5b016c945d745f8b108e759d428341488a6aee8f51f07c6c4e33498bb91f/source_distribution-0.0.3.tar.gz","archive_info":{}}"###);

Ok(())
}

0 comments on commit d7fb013

Please sign in to comment.