Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Generate shell completion for uvx #7388

Merged
merged 3 commits into from
Sep 17, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions crates/uv-cli/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,13 @@ pub struct Cli {
#[command(subcommand)]
pub command: Box<Commands>,

#[command(flatten)]
pub top_level: TopLevelArgs,
}

#[derive(Parser)]
#[command(disable_help_flag = true, disable_version_flag = true)]
pub struct TopLevelArgs {
bluss marked this conversation as resolved.
Show resolved Hide resolved
#[command(flatten)]
pub cache_args: Box<CacheArgs>,

Expand Down
48 changes: 35 additions & 13 deletions crates/uv/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ use uv_cli::{
compat::CompatArgs, CacheCommand, CacheNamespace, Cli, Commands, PipCommand, PipNamespace,
ProjectCommand,
};
use uv_cli::{PythonCommand, PythonNamespace, ToolCommand, ToolNamespace};
use uv_cli::{PythonCommand, PythonNamespace, ToolCommand, ToolNamespace, TopLevelArgs};
#[cfg(feature = "self-update")]
use uv_cli::{SelfCommand, SelfNamespace, SelfUpdateArgs};
use uv_fs::CWD;
Expand Down Expand Up @@ -58,17 +58,17 @@ pub(crate) mod version;
#[instrument(skip_all)]
async fn run(cli: Cli) -> Result<ExitStatus> {
// Enable flag to pick up warnings generated by workspace loading.
if !cli.global_args.quiet {
if !cli.top_level.global_args.quiet {
uv_warnings::enable();
}

// Switch directories as early as possible.
if let Some(directory) = cli.global_args.directory.as_ref() {
if let Some(directory) = cli.top_level.global_args.directory.as_ref() {
std::env::set_current_dir(directory)?;
}

// The `--isolated` argument is deprecated on preview APIs, and warns on non-preview APIs.
let deprecated_isolated = if cli.global_args.isolated {
let deprecated_isolated = if cli.top_level.global_args.isolated {
match &*cli.command {
// Supports `--isolated` as its own argument, so we can't warn either way.
Commands::Tool(ToolNamespace {
Expand Down Expand Up @@ -106,15 +106,15 @@ async fn run(cli: Cli) -> Result<ExitStatus> {
// If found, this file is combined with the user configuration file.
// 3. The nearest configuration file (`uv.toml` or `pyproject.toml`) in the directory tree,
// starting from the current directory.
let filesystem = if let Some(config_file) = cli.config_file.as_ref() {
let filesystem = if let Some(config_file) = cli.top_level.config_file.as_ref() {
if config_file
.file_name()
.is_some_and(|file_name| file_name == "pyproject.toml")
{
warn_user!("The `--config-file` argument expects to receive a `uv.toml` file, not a `pyproject.toml`. If you're trying to run a command from another project, use the `--directory` argument instead.");
}
Some(FilesystemOptions::from_file(config_file)?)
} else if deprecated_isolated || cli.no_config {
} else if deprecated_isolated || cli.top_level.no_config {
None
} else if matches!(&*cli.command, Commands::Tool(_)) {
// For commands that operate at the user-level, ignore local configuration.
Expand Down Expand Up @@ -175,10 +175,10 @@ async fn run(cli: Cli) -> Result<ExitStatus> {
.combine(filesystem);

// Resolve the global settings.
let globals = GlobalSettings::resolve(&cli.global_args, filesystem.as_ref());
let globals = GlobalSettings::resolve(&cli.top_level.global_args, filesystem.as_ref());

// Resolve the cache settings.
let cache_settings = CacheSettings::resolve(*cli.cache_args, filesystem.as_ref());
let cache_settings = CacheSettings::resolve(*cli.top_level.cache_args, filesystem.as_ref());

// Configure the `tracing` crate, which controls internal logging.
#[cfg(feature = "tracing-durations-export")]
Expand Down Expand Up @@ -687,7 +687,7 @@ async fn run(cli: Cli) -> Result<ExitStatus> {
args.hash_checking,
args.python,
args.settings,
cli.no_config,
cli.top_level.no_config,
globals.python_preference,
globals.python_downloads,
globals.connectivity,
Expand Down Expand Up @@ -743,7 +743,7 @@ async fn run(cli: Cli) -> Result<ExitStatus> {
args.settings.exclude_newer,
globals.concurrency,
globals.native_tls,
cli.no_config,
cli.top_level.no_config,
args.no_project,
&cache,
printer,
Expand All @@ -757,7 +757,7 @@ async fn run(cli: Cli) -> Result<ExitStatus> {
run_command,
script,
globals,
cli.no_config,
cli.top_level.no_config,
filesystem,
cache,
printer,
Expand All @@ -777,7 +777,29 @@ async fn run(cli: Cli) -> Result<ExitStatus> {
Ok(ExitStatus::Success)
}
Commands::GenerateShellCompletion(args) => {
// uv
args.shell.generate(&mut Cli::command(), &mut stdout());

// uvx: combine `uv tool uvx` with top level arguments
let mut uvx = Cli::command()
.find_subcommand("tool")
.unwrap()
.find_subcommand("uvx")
.unwrap()
.clone()
// avoid duplicating TopLevelArgs's help, version
.disable_help_flag(true)
.disable_version_flag(true)
.version("dummy_for_completion");
bluss marked this conversation as resolved.
Show resolved Hide resolved

// like Args::augment_args but open coded to skip collisions
for arg in TopLevelArgs::command().get_arguments() {
if arg.get_id() != "isolated" {
uvx = uvx.arg(arg);
}
}
args.shell.generate(&mut uvx, &mut stdout());

bluss marked this conversation as resolved.
Show resolved Hide resolved
Ok(ExitStatus::Success)
}
Commands::Tool(ToolNamespace {
Expand Down Expand Up @@ -974,7 +996,7 @@ async fn run(cli: Cli) -> Result<ExitStatus> {
globals.python_downloads,
globals.native_tls,
globals.connectivity,
cli.no_config,
cli.top_level.no_config,
printer,
)
.await
Expand All @@ -1000,7 +1022,7 @@ async fn run(cli: Cli) -> Result<ExitStatus> {
commands::python_find(
args.request,
args.no_project,
cli.no_config,
cli.top_level.no_config,
args.system,
globals.python_preference,
&cache,
Expand Down
Loading