Skip to content

Commit

Permalink
Retain markers (astral-sh#807)
Browse files Browse the repository at this point in the history
  • Loading branch information
mitsuhiko authored Feb 28, 2024
1 parent 7e3b04a commit 5bbbd7f
Show file tree
Hide file tree
Showing 5 changed files with 107 additions and 47 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ that were not yet released.

_Unreleased_

- Retain markers when adding dependencies with features when uv is used. #807

<!-- released start -->

## 0.27.0
Expand Down
83 changes: 41 additions & 42 deletions rye/src/cli/add.rs
Original file line number Diff line number Diff line change
Expand Up @@ -448,49 +448,44 @@ fn resolve_requirements_with_uv(
output: CommandOutput,
default_operator: &Operator,
) -> Result<(), Error> {
let mut cmd = Uv::ensure_exists(output)?.cmd();
cmd.arg("pip")
.arg("compile")
.arg("--python-version")
.arg(py_ver.format_simple())
.arg("--no-deps")
.arg("--no-header")
.arg("-")
.env("VIRTUAL_ENV", pyproject_toml.venv_path().as_os_str());
if pre {
cmd.arg("--prerelease=allow");
}
if output == CommandOutput::Quiet {
cmd.arg("-q");
}
// this primarily exists for testing
if let Ok(dt) = env::var("__RYE_UV_EXCLUDE_NEWER") {
cmd.arg("--exclude-newer").arg(dt);
}
let sources = ExpandedSources::from_sources(&pyproject_toml.sources()?)?;
sources.add_as_pip_args(&mut cmd);
let mut child = cmd
.stdin(Stdio::piped())
.stdout(Stdio::piped())
.stderr(Stdio::piped())
.spawn()?;
let child_stdin = child.stdin.as_mut().unwrap();
for requirement in &*requirements {
writeln!(child_stdin, "{}", requirement)?;
}

let rv = child.wait_with_output()?;
if !rv.status.success() {
let log = String::from_utf8_lossy(&rv.stderr);
bail!("failed to resolve packages:\n{}", log);
}
for req in requirements {
let mut cmd = Uv::ensure_exists(output)?.cmd();
cmd.arg("pip")
.arg("compile")
.arg("--python-version")
.arg(py_ver.format_simple())
.arg("--no-deps")
.arg("--no-header")
.arg("-")
.env("VIRTUAL_ENV", pyproject_toml.venv_path().as_os_str());
if pre {
cmd.arg("--prerelease=allow");
}
if output == CommandOutput::Quiet {
cmd.arg("-q");
}
// this primarily exists for testing
if let Ok(dt) = env::var("__RYE_UV_EXCLUDE_NEWER") {
cmd.arg("--exclude-newer").arg(dt);
}
let sources = ExpandedSources::from_sources(&pyproject_toml.sources()?)?;
sources.add_as_pip_args(&mut cmd);
let mut child = cmd
.stdin(Stdio::piped())
.stdout(Stdio::piped())
.stderr(Stdio::piped())
.spawn()?;
let child_stdin = child.stdin.as_mut().unwrap();
writeln!(child_stdin, "{}", req)?;

let rv = child.wait_with_output()?;
if !rv.status.success() {
let log = String::from_utf8_lossy(&rv.stderr);
bail!("failed to resolve packages:\n{}", log);
}

for (line, req) in String::from_utf8_lossy(&rv.stdout)
.lines()
.zip(requirements)
{
*req = line.parse()?;
if let Some(ref mut version_or_url) = req.version_or_url {
let mut new_req: Requirement = String::from_utf8_lossy(&rv.stdout).parse()?;
if let Some(ref mut version_or_url) = new_req.version_or_url {
if let VersionOrUrl::VersionSpecifier(ref mut specs) = version_or_url {
*version_or_url = VersionOrUrl::VersionSpecifier(VersionSpecifiers::from_iter({
let mut new_specs = Vec::new();
Expand All @@ -511,6 +506,10 @@ fn resolve_requirements_with_uv(
}));
}
}
if let Some(old_extras) = &req.extras {
new_req.extras = Some(old_extras.clone());
}
*req = new_req;
}

Ok(())
Expand Down
15 changes: 15 additions & 0 deletions rye/tests/common/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,21 @@ impl Space {
self.cmd(get_bin())
}

#[allow(unused)]
pub fn load_toml<P: AsRef<Path>, R, F: FnOnce(&toml_edit::Document) -> R>(
&self,
path: P,
f: F,
) -> R {
let p = self.project_path().join(path.as_ref());
let mut doc = if p.is_file() {
std::fs::read_to_string(&p).unwrap().parse().unwrap()
} else {
toml_edit::Document::default()
};
f(&doc)
}

#[allow(unused)]
pub fn edit_toml<P: AsRef<Path>, R, F: FnOnce(&mut toml_edit::Document) -> R>(
&self,
Expand Down
50 changes: 47 additions & 3 deletions rye/tests/test_add.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ fn test_add_flask() {
----- stdout -----
Initializing new virtualenv in [TEMP_PATH]/project/.venv
Python version: [email protected]
Added colorama>=0.4.6 as regular dependency
Added flask>=3.0.0 as regular dependency
Added colorama>=0.4.6 as regular dependency
Reusing already existing virtualenv
Generating production lockfile: [TEMP_PATH]/project/requirements.lock
Generating dev lockfile: [TEMP_PATH]/project/requirements-dev.lock
Expand All @@ -42,6 +42,50 @@ fn test_add_flask() {
"###);
}

#[test]
fn test_add_flask_dotenv() {
let space = Space::new();
space.init("my-project");
// add colorama to ensure we have this as a dependency on all platforms
rye_cmd_snapshot!(space.rye_cmd().arg("add").arg("flask[dotenv]").arg("colorama"), @r###"
success: true
exit_code: 0
----- stdout -----
Initializing new virtualenv in [TEMP_PATH]/project/.venv
Python version: [email protected]
Added flask[dotenv]>=3.0.0 as regular dependency
Added colorama>=0.4.6 as regular dependency
Reusing already existing virtualenv
Generating production lockfile: [TEMP_PATH]/project/requirements.lock
Generating dev lockfile: [TEMP_PATH]/project/requirements-dev.lock
Installing dependencies
Done!
----- stderr -----
Built 1 editable in [EXECUTION_TIME]
Resolved 9 packages in [EXECUTION_TIME]
Downloaded 9 packages in [EXECUTION_TIME]
Installed 10 packages in [EXECUTION_TIME]
+ blinker==1.7.0
+ click==8.1.7
+ colorama==0.4.6
+ flask==3.0.0
+ itsdangerous==2.1.2
+ jinja2==3.1.2
+ markupsafe==2.1.3
+ my-project==0.1.0 (from file:[TEMP_PATH]/project)
+ python-dotenv==1.0.0
+ werkzeug==3.0.1
"###);

space.load_toml("pyproject.toml", |doc| {
let deps = doc["project"]["dependencies"].as_array().unwrap();
assert!(deps
.iter()
.any(|x| x.as_str() == Some("flask[dotenv]>=3.0.0")));
});
}

#[test]
fn test_add_from_find_links() {
let space = Space::new();
Expand All @@ -62,8 +106,8 @@ fn test_add_from_find_links() {
----- stdout -----
Initializing new virtualenv in [TEMP_PATH]/project/.venv
Python version: [email protected]
Added colorama>=0.4.6 as regular dependency
Added tqdm>=4.66.1 as regular dependency
Added colorama>=0.4.6 as regular dependency
Reusing already existing virtualenv
Generating production lockfile: [TEMP_PATH]/project/requirements.lock
Generating dev lockfile: [TEMP_PATH]/project/requirements-dev.lock
Expand Down Expand Up @@ -94,8 +138,8 @@ fn test_add_flask_wrong_venv_exported() {
----- stdout -----
Initializing new virtualenv in [TEMP_PATH]/project/.venv
Python version: [email protected]
Added colorama>=0.4.6 as regular dependency
Added flask>=3.0.0 as regular dependency
Added colorama>=0.4.6 as regular dependency
Reusing already existing virtualenv
Generating production lockfile: [TEMP_PATH]/project/requirements.lock
Generating dev lockfile: [TEMP_PATH]/project/requirements-dev.lock
Expand Down
4 changes: 2 additions & 2 deletions rye/tests/test_sync.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,8 @@ fn test_add_and_sync_no_auto_sync() {
----- stdout -----
Initializing new virtualenv in [TEMP_PATH]/project/.venv
Python version: [email protected]
Added colorama>=0.4.6 as regular dependency
Added flask>=3.0.0 as regular dependency
Added colorama>=0.4.6 as regular dependency
----- stderr -----
"###);
Expand Down Expand Up @@ -95,8 +95,8 @@ fn test_add_autosync() {
----- stdout -----
Initializing new virtualenv in [TEMP_PATH]/project/.venv
Python version: [email protected]
Added colorama>=0.4.6 as regular dependency
Added flask>=3.0.0 as regular dependency
Added colorama>=0.4.6 as regular dependency
Reusing already existing virtualenv
Generating production lockfile: [TEMP_PATH]/project/requirements.lock
Generating dev lockfile: [TEMP_PATH]/project/requirements-dev.lock
Expand Down

0 comments on commit 5bbbd7f

Please sign in to comment.