Skip to content

Commit 6d7e95f

Browse files
committed
Avoid treating non-existent --find-links as relative URLs
1 parent 00a4adf commit 6d7e95f

File tree

3 files changed

+51
-9
lines changed

3 files changed

+51
-9
lines changed

crates/uv-client/src/flat_index.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -243,8 +243,12 @@ impl<'a> FlatIndexClient<'a> {
243243
path: &Path,
244244
flat_index: &IndexUrl,
245245
) -> Result<FlatIndexEntries, FindLinksDirectoryError> {
246+
// The path context is provided by the caller.
247+
#[allow(clippy::disallowed_methods)]
248+
let entries = std::fs::read_dir(path)?;
249+
246250
let mut dists = Vec::new();
247-
for entry in fs_err::read_dir(path)? {
251+
for entry in entries {
248252
let entry = entry?;
249253
let metadata = entry.metadata()?;
250254

crates/uv-distribution-types/src/index_url.rs

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
1-
use itertools::Either;
2-
use rustc_hash::{FxHashMap, FxHashSet};
31
use std::borrow::Cow;
42
use std::fmt::{Display, Formatter};
53
use std::ops::Deref;
6-
use std::path::Path;
74
use std::str::FromStr;
85
use std::sync::{Arc, LazyLock, RwLock};
6+
7+
use itertools::Either;
8+
use rustc_hash::{FxHashMap, FxHashSet};
99
use thiserror::Error;
1010
use url::{ParseError, Url};
1111

12-
use uv_pep508::{VerbatimUrl, VerbatimUrlError};
12+
use uv_pep508::{split_scheme, Scheme, VerbatimUrl, VerbatimUrlError};
1313

1414
use crate::{Index, Verbatim};
1515

@@ -114,10 +114,23 @@ impl FromStr for IndexUrl {
114114
type Err = IndexUrlError;
115115

116116
fn from_str(s: &str) -> Result<Self, Self::Err> {
117-
let url = if Path::new(s).exists() {
118-
VerbatimUrl::from_absolute_path(std::path::absolute(s)?)?
119-
} else {
120-
VerbatimUrl::parse_url(s)?
117+
let url = match split_scheme(s) {
118+
Some((scheme, ..)) => {
119+
match Scheme::parse(scheme) {
120+
Some(_) => {
121+
// Ex) `https://pypi.org/simple`
122+
VerbatimUrl::parse_url(s)?
123+
}
124+
None => {
125+
// Ex) `C:\Users\user\index`
126+
VerbatimUrl::from_absolute_path(std::path::absolute(s)?)?
127+
}
128+
}
129+
}
130+
None => {
131+
// Ex) `/Users/user/index`
132+
VerbatimUrl::from_absolute_path(std::path::absolute(s)?)?
133+
}
121134
};
122135
Ok(Self::from(url.with_given(s)))
123136
}

crates/uv/tests/it/pip_install.rs

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,31 @@ fn missing_pyproject_toml() {
7979
);
8080
}
8181

82+
#[test]
83+
fn missing_find_links() -> Result<()> {
84+
let context = TestContext::new("3.12");
85+
let requirements_txt = context.temp_dir.child("requirements.txt");
86+
requirements_txt.write_str("flask")?;
87+
88+
uv_snapshot!(context.filters(), context.pip_install()
89+
.arg("-r")
90+
.arg("requirements.txt")
91+
.arg("--find-links")
92+
.arg("./missing")
93+
.arg("--strict"), @r###"
94+
success: false
95+
exit_code: 2
96+
----- stdout -----
97+
98+
----- stderr -----
99+
error: Failed to read `--find-links` directory: [TEMP_DIR]/missing
100+
Caused by: No such file or directory (os error 2)
101+
"###
102+
);
103+
104+
Ok(())
105+
}
106+
82107
#[test]
83108
fn invalid_pyproject_toml_syntax() -> Result<()> {
84109
let context = TestContext::new("3.12");

0 commit comments

Comments
 (0)