Skip to content

Commit

Permalink
Allow uv run to execute Python scripts directly
Browse files Browse the repository at this point in the history
e.g. `uv run foo.py` implies `python foo.py`
  • Loading branch information
zanieb committed Apr 19, 2024
1 parent 9f2bc19 commit 3de9f35
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 4 deletions.
3 changes: 2 additions & 1 deletion crates/uv/src/cli.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use std::ffi::OsString;
use std::path::PathBuf;
use std::str::FromStr;

Expand Down Expand Up @@ -1632,7 +1633,7 @@ pub(crate) struct RunArgs {

/// The arguments to the command.
#[arg(allow_hyphen_values = true)]
pub(crate) args: Vec<String>,
pub(crate) args: Vec<OsString>,

/// Always use a new virtual environment for execution.
#[arg(long)]
Expand Down
24 changes: 21 additions & 3 deletions crates/uv/src/commands/run.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ use platform_tags::Tags;
use pypi_types::Yanked;
use std::ffi::OsString;
use std::fmt::Write;
use std::path::PathBuf;
use std::{env, iter};
use tempfile::{tempdir_in, TempDir};
use tokio::process::Command;
Expand Down Expand Up @@ -40,14 +41,28 @@ use uv_types::{BuildIsolation, EmptyInstalledPackages, HashStrategy, InFlight};
#[allow(clippy::unnecessary_wraps, clippy::too_many_arguments)]
pub(crate) async fn run(
target: Option<String>,
args: Vec<String>,
mut args: Vec<OsString>,
mut requirements: Vec<RequirementsSource>,
isolated: bool,
no_workspace: bool,
cache: &Cache,
printer: Printer,
) -> Result<ExitStatus> {
let command = target.unwrap_or("python".to_string());
let command = if let Some(target) = target {
let target_path = PathBuf::from(&target);
if target_path
.extension()
.map_or(false, |ext| ext.eq_ignore_ascii_case("py"))
&& target_path.exists()
{
args.insert(0, target_path.as_os_str().into());
"python".to_string()
} else {
target
}
} else {
"python".to_string()
};

// Copy the requirements into a set of overrides; we'll use this to prioritize
// requested requirements over those discovered in the project.
Expand Down Expand Up @@ -91,7 +106,10 @@ pub(crate) async fn run(
// Standard input, output, and error streams are all inherited
// TODO(zanieb): Throw a nicer error message if the command is not found
let space = if args.is_empty() { "" } else { " " };
debug!("Running `{command}{space}{}`", args.join(" "));
debug!(
"Running `{command}{space}{}`",
args.iter().map(|arg| arg.to_string_lossy()).join(" ")
);
let mut handle = process.spawn()?;
let status = handle.wait().await?;

Expand Down

0 comments on commit 3de9f35

Please sign in to comment.