@@ -16,7 +16,7 @@ use uv_cli::{
16
16
compat:: CompatArgs , CacheCommand , CacheNamespace , Cli , Commands , PipCommand , PipNamespace ,
17
17
ProjectCommand ,
18
18
} ;
19
- use uv_cli:: { PythonCommand , PythonNamespace , ToolCommand , ToolNamespace } ;
19
+ use uv_cli:: { PythonCommand , PythonNamespace , ToolCommand , ToolNamespace , TopLevelArgs } ;
20
20
#[ cfg( feature = "self-update" ) ]
21
21
use uv_cli:: { SelfCommand , SelfNamespace , SelfUpdateArgs } ;
22
22
use uv_fs:: CWD ;
@@ -58,17 +58,17 @@ pub(crate) mod version;
58
58
#[ instrument( skip_all) ]
59
59
async fn run ( cli : Cli ) -> Result < ExitStatus > {
60
60
// Enable flag to pick up warnings generated by workspace loading.
61
- if !cli. global_args . quiet {
61
+ if !cli. top_level . global_args . quiet {
62
62
uv_warnings:: enable ( ) ;
63
63
}
64
64
65
65
// Switch directories as early as possible.
66
- if let Some ( directory) = cli. global_args . directory . as_ref ( ) {
66
+ if let Some ( directory) = cli. top_level . global_args . directory . as_ref ( ) {
67
67
std:: env:: set_current_dir ( directory) ?;
68
68
}
69
69
70
70
// The `--isolated` argument is deprecated on preview APIs, and warns on non-preview APIs.
71
- let deprecated_isolated = if cli. global_args . isolated {
71
+ let deprecated_isolated = if cli. top_level . global_args . isolated {
72
72
match & * cli. command {
73
73
// Supports `--isolated` as its own argument, so we can't warn either way.
74
74
Commands :: Tool ( ToolNamespace {
@@ -106,15 +106,15 @@ async fn run(cli: Cli) -> Result<ExitStatus> {
106
106
// If found, this file is combined with the user configuration file.
107
107
// 3. The nearest configuration file (`uv.toml` or `pyproject.toml`) in the directory tree,
108
108
// starting from the current directory.
109
- let filesystem = if let Some ( config_file) = cli. config_file . as_ref ( ) {
109
+ let filesystem = if let Some ( config_file) = cli. top_level . config_file . as_ref ( ) {
110
110
if config_file
111
111
. file_name ( )
112
112
. is_some_and ( |file_name| file_name == "pyproject.toml" )
113
113
{
114
114
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." ) ;
115
115
}
116
116
Some ( FilesystemOptions :: from_file ( config_file) ?)
117
- } else if deprecated_isolated || cli. no_config {
117
+ } else if deprecated_isolated || cli. top_level . no_config {
118
118
None
119
119
} else if matches ! ( & * cli. command, Commands :: Tool ( _) ) {
120
120
// For commands that operate at the user-level, ignore local configuration.
@@ -175,10 +175,10 @@ async fn run(cli: Cli) -> Result<ExitStatus> {
175
175
. combine ( filesystem) ;
176
176
177
177
// Resolve the global settings.
178
- let globals = GlobalSettings :: resolve ( & cli. global_args , filesystem. as_ref ( ) ) ;
178
+ let globals = GlobalSettings :: resolve ( & cli. top_level . global_args , filesystem. as_ref ( ) ) ;
179
179
180
180
// Resolve the cache settings.
181
- let cache_settings = CacheSettings :: resolve ( * cli. cache_args , filesystem. as_ref ( ) ) ;
181
+ let cache_settings = CacheSettings :: resolve ( * cli. top_level . cache_args , filesystem. as_ref ( ) ) ;
182
182
183
183
// Configure the `tracing` crate, which controls internal logging.
184
184
#[ cfg( feature = "tracing-durations-export" ) ]
@@ -687,7 +687,7 @@ async fn run(cli: Cli) -> Result<ExitStatus> {
687
687
args. hash_checking ,
688
688
args. python ,
689
689
args. settings ,
690
- cli. no_config ,
690
+ cli. top_level . no_config ,
691
691
globals. python_preference ,
692
692
globals. python_downloads ,
693
693
globals. connectivity ,
@@ -743,7 +743,7 @@ async fn run(cli: Cli) -> Result<ExitStatus> {
743
743
args. settings . exclude_newer ,
744
744
globals. concurrency ,
745
745
globals. native_tls ,
746
- cli. no_config ,
746
+ cli. top_level . no_config ,
747
747
args. no_project ,
748
748
& cache,
749
749
printer,
@@ -757,7 +757,7 @@ async fn run(cli: Cli) -> Result<ExitStatus> {
757
757
run_command,
758
758
script,
759
759
globals,
760
- cli. no_config ,
760
+ cli. top_level . no_config ,
761
761
filesystem,
762
762
cache,
763
763
printer,
@@ -777,7 +777,30 @@ async fn run(cli: Cli) -> Result<ExitStatus> {
777
777
Ok ( ExitStatus :: Success )
778
778
}
779
779
Commands :: GenerateShellCompletion ( args) => {
780
+ // uv
780
781
args. shell . generate ( & mut Cli :: command ( ) , & mut stdout ( ) ) ;
782
+
783
+ // uvx: combine `uv tool uvx` with the top-level arguments
784
+ let mut uvx = Cli :: command ( )
785
+ . find_subcommand ( "tool" )
786
+ . unwrap ( )
787
+ . find_subcommand ( "uvx" )
788
+ . unwrap ( )
789
+ . clone ( )
790
+ // Avoid duplicating the `--help` and `--version` flags from the top-level arguments.
791
+ . disable_help_flag ( true )
792
+ . disable_version_flag ( true )
793
+ . version ( env ! ( "CARGO_PKG_VERSION" ) ) ;
794
+
795
+ // Copy the top-level arguments into the `uvx` command. (Like `Args::augment_args`, but
796
+ // expanded to skip collisions.)
797
+ for arg in TopLevelArgs :: command ( ) . get_arguments ( ) {
798
+ if arg. get_id ( ) != "isolated" {
799
+ uvx = uvx. arg ( arg) ;
800
+ }
801
+ }
802
+ args. shell . generate ( & mut uvx, & mut stdout ( ) ) ;
803
+
781
804
Ok ( ExitStatus :: Success )
782
805
}
783
806
Commands :: Tool ( ToolNamespace {
@@ -974,7 +997,7 @@ async fn run(cli: Cli) -> Result<ExitStatus> {
974
997
globals. python_downloads ,
975
998
globals. native_tls ,
976
999
globals. connectivity ,
977
- cli. no_config ,
1000
+ cli. top_level . no_config ,
978
1001
printer,
979
1002
)
980
1003
. await
@@ -1000,7 +1023,7 @@ async fn run(cli: Cli) -> Result<ExitStatus> {
1000
1023
commands:: python_find (
1001
1024
args. request ,
1002
1025
args. no_project ,
1003
- cli. no_config ,
1026
+ cli. top_level . no_config ,
1004
1027
args. system ,
1005
1028
globals. python_preference ,
1006
1029
& cache,
0 commit comments