Skip to content

Commit

Permalink
Allow reading --with-requirements from stdin in uv add and uv run
Browse files Browse the repository at this point in the history
  • Loading branch information
zanieb committed Jan 9, 2025
1 parent e2c5526 commit b8134d6
Show file tree
Hide file tree
Showing 4 changed files with 62 additions and 9 deletions.
5 changes: 0 additions & 5 deletions crates/uv/src/commands/project/add.rs
Original file line number Diff line number Diff line change
Expand Up @@ -98,11 +98,6 @@ pub(crate) async fn add(
RequirementsSource::SetupCfg(_) => {
bail!("Adding requirements from a `setup.cfg` is not supported in `uv add`");
}
RequirementsSource::RequirementsTxt(path) => {
if path == Path::new("-") {
bail!("Reading requirements from stdin is not supported in `uv add`");
}
}
_ => {}
}
}
Expand Down
15 changes: 14 additions & 1 deletion crates/uv/src/commands/project/run.rs
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ pub(crate) async fn run(
) -> anyhow::Result<ExitStatus> {
// These cases seem quite complex because (in theory) they should change the "current package".
// Let's ban them entirely for now.
let mut requirements_from_stdin: bool = false;
for source in &requirements {
match source {
RequirementsSource::PyprojectToml(_) => {
Expand All @@ -106,13 +107,22 @@ pub(crate) async fn run(
}
RequirementsSource::RequirementsTxt(path) => {
if path == Path::new("-") {
bail!("Reading requirements from stdin is not supported in `uv run`");
requirements_from_stdin = true;
}
}
_ => {}
}
}

// Fail early if stdin is used for multiple purposes.
if matches!(
command,
Some(RunCommand::PythonStdin(..)) | Some(RunCommand::PythonGuiStdin(..))
) && requirements_from_stdin
{
bail!("Cannot read both requirements file and script from stdin");
}

// Initialize any shared state.
let state = SharedState::default();

Expand Down Expand Up @@ -169,6 +179,9 @@ pub(crate) async fn run(
)?;
}
Pep723Item::Stdin(_) => {
if requirements_from_stdin {
bail!("Cannot read both requirements file and script from stdin");
}
writeln!(
printer.stderr(),
"Reading inline script metadata from `{}`",
Expand Down
13 changes: 13 additions & 0 deletions crates/uv/tests/it/edit.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
#![allow(clippy::disallowed_types)]

use anyhow::Result;
use assert_cmd::assert::OutputAssertExt;
use assert_fs::prelude::*;
Expand Down Expand Up @@ -4611,6 +4613,17 @@ fn add_requirements_file() -> Result<()> {
);
});

// Passing stdin should succeed
uv_snapshot!(context.filters(), context.add().arg("-r").arg("-").stdin(std::fs::File::open(requirements_txt)?), @r###"
success: true
exit_code: 0
----- stdout -----
----- stderr -----
Resolved [N] packages in [TIME]
Audited [N] packages in [TIME]
"###);

// Passing a `setup.py` should fail.
uv_snapshot!(context.filters(), context.add().arg("-r").arg("setup.py"), @r###"
success: false
Expand Down
38 changes: 35 additions & 3 deletions crates/uv/tests/it/run.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2124,19 +2124,51 @@ fn run_requirements_txt() -> Result<()> {
+ sniffio==1.3.1
"###);

// But reject `-` as a requirements file.
// Allow `-` for stdin.
uv_snapshot!(context.filters(), context.run()
.arg("--with-requirements")
.arg("-")
.arg("--with")
.arg("iniconfig")
.arg("main.py"), @r###"
.arg("main.py")
.stdin(std::fs::File::open(&requirements_txt)?), @r###"
success: true
exit_code: 0
----- stdout -----
----- stderr -----
Resolved 6 packages in [TIME]
Audited 4 packages in [TIME]
Resolved 2 packages in [TIME]
"###);

// But not in combination with reading the script from stdin
uv_snapshot!(context.filters(), context.run()
.arg("--with-requirements")
.arg("-")
// The script to run
.arg("-")
.stdin(std::fs::File::open(&requirements_txt)?), @r###"
success: false
exit_code: 2
----- stdout -----
----- stderr -----
error: Cannot read both requirements file and script from stdin
"###);

uv_snapshot!(context.filters(), context.run()
.arg("--with-requirements")
.arg("-")
.arg("--script")
.arg("-")
.stdin(std::fs::File::open(&requirements_txt)?), @r###"
success: false
exit_code: 2
----- stdout -----
----- stderr -----
error: Reading requirements from stdin is not supported in `uv run`
error: Cannot read both requirements file and script from stdin
"###);

Ok(())
Expand Down

0 comments on commit b8134d6

Please sign in to comment.