11use crate :: CargoResult ;
2+ use crate :: core:: Dependency ;
23use crate :: core:: compiler:: {
34 BuildConfig , CompileKind , MessageFormat , RustcTargetData , TimingOutput ,
45} ;
56use crate :: core:: resolver:: { CliFeatures , ForceAllTargets , HasDevUnits } ;
6- use crate :: core:: { Dependency , PackageId } ;
77use crate :: core:: { Edition , Package , TargetKind , Workspace , profiles:: Profiles , shell} ;
88use crate :: ops:: lockfile:: LOCKFILE_NAME ;
99use crate :: ops:: registry:: RegistryOrIndex ;
10- use crate :: ops:: {
11- self , CompileFilter , CompileOptions , InstallTracker , NewOptions , Packages , VersionControl ,
12- resolve_root,
13- } ;
10+ use crate :: ops:: { self , CompileFilter , CompileOptions , NewOptions , Packages , VersionControl } ;
1411use crate :: util:: important_paths:: find_root_manifest_for_wd;
1512use crate :: util:: interning:: InternedString ;
1613use crate :: util:: is_rustup;
@@ -26,11 +23,12 @@ use cargo_util_schemas::manifest::ProfileName;
2623use cargo_util_schemas:: manifest:: RegistryName ;
2724use cargo_util_schemas:: manifest:: StringOrVec ;
2825use clap:: builder:: UnknownArgumentValueParser ;
26+ use clap_complete:: ArgValueCandidates ;
2927use home:: cargo_home_with_cwd;
3028use indexmap:: IndexSet ;
3129use itertools:: Itertools ;
3230use semver:: Version ;
33- use std:: collections:: { BTreeSet , HashMap , HashSet } ;
31+ use std:: collections:: { HashMap , HashSet } ;
3432use std:: ffi:: { OsStr , OsString } ;
3533use std:: path:: Path ;
3634use std:: path:: PathBuf ;
@@ -63,7 +61,13 @@ pub trait CommandExt: Sized {
6361 all : & ' static str ,
6462 exclude : & ' static str ,
6563 ) -> Self {
66- self . arg_package_spec_no_all ( package, all, exclude) . _arg (
64+ self . arg_package_spec_no_all (
65+ package,
66+ all,
67+ exclude,
68+ ArgValueCandidates :: new ( get_ws_member_candidates) ,
69+ )
70+ . _arg (
6771 flag ( "all" , "Alias for --workspace (deprecated)" )
6872 . help_heading ( heading:: PACKAGE_SELECTION ) ,
6973 )
@@ -77,6 +81,7 @@ pub trait CommandExt: Sized {
7781 package : & ' static str ,
7882 all : & ' static str ,
7983 exclude : & ' static str ,
84+ package_completion : ArgValueCandidates ,
8085 ) -> Self {
8186 let unsupported_short_arg = {
8287 let value_parser = UnknownArgumentValueParser :: suggest_arg ( "--exclude" ) ;
@@ -87,7 +92,7 @@ pub trait CommandExt: Sized {
8792 . action ( ArgAction :: SetTrue )
8893 . hide ( true )
8994 } ;
90- self . arg_package_spec_simple ( package)
95+ self . arg_package_spec_simple ( package, package_completion )
9196 . _arg ( flag ( "workspace" , all) . help_heading ( heading:: PACKAGE_SELECTION ) )
9297 . _arg (
9398 multi_opt ( "exclude" , "SPEC" , exclude)
@@ -99,75 +104,16 @@ pub trait CommandExt: Sized {
99104 . _arg ( unsupported_short_arg)
100105 }
101106
102- fn arg_dependency_package_spec_no_all (
107+ fn arg_package_spec_simple (
103108 self ,
104109 package : & ' static str ,
105- all : & ' static str ,
106- exclude : & ' static str ,
110+ package_completion : ArgValueCandidates ,
107111 ) -> Self {
108- let unsupported_short_arg = {
109- let value_parser = UnknownArgumentValueParser :: suggest_arg ( "--exclude" ) ;
110- Arg :: new ( "unsupported-short-exclude-flag" )
111- . help ( "" )
112- . short ( 'x' )
113- . value_parser ( value_parser)
114- . action ( ArgAction :: SetTrue )
115- . hide ( true )
116- } ;
117- self . arg_dependency_package_spec_simple ( package)
118- . _arg ( flag ( "workspace" , all) . help_heading ( heading:: PACKAGE_SELECTION ) )
119- . _arg (
120- multi_opt ( "exclude" , "SPEC" , exclude)
121- . help_heading ( heading:: PACKAGE_SELECTION )
122- . add ( clap_complete:: ArgValueCandidates :: new (
123- get_ws_member_candidates,
124- ) ) ,
125- )
126- . _arg ( unsupported_short_arg)
127- }
128-
129- fn arg_package_spec_simple ( self , package : & ' static str ) -> Self {
130112 self . _arg (
131113 optional_multi_opt ( "package" , "SPEC" , package)
132114 . short ( 'p' )
133115 . help_heading ( heading:: PACKAGE_SELECTION )
134- . add ( clap_complete:: ArgValueCandidates :: new (
135- get_ws_member_candidates,
136- ) ) ,
137- )
138- }
139-
140- fn arg_installed_package_spec_simple ( self , package : & ' static str ) -> Self {
141- self . _arg (
142- optional_multi_opt ( "package" , "SPEC" , package)
143- . short ( 'p' )
144- . help_heading ( heading:: PACKAGE_SELECTION )
145- . add ( clap_complete:: ArgValueCandidates :: new (
146- get_installed_package_candidates,
147- ) ) ,
148- )
149- }
150-
151- fn arg_dependency_package_spec_simple ( self , package : & ' static str ) -> Self {
152- self . _arg (
153- optional_multi_opt ( "package" , "SPEC" , package)
154- . short ( 'p' )
155- . help_heading ( heading:: PACKAGE_SELECTION )
156- . add ( clap_complete:: ArgValueCandidates :: new (
157- get_dependency_package_candidates,
158- ) ) ,
159- )
160- }
161-
162- fn arg_clean_package_spec_simple ( self , package : & ' static str ) -> Self {
163- // TODO(completions): add dynamic completions for `cargo clean -p`
164- self . _arg (
165- optional_multi_opt ( "package" , "SPEC" , package)
166- . short ( 'p' )
167- . help_heading ( heading:: PACKAGE_SELECTION )
168- . add (
169- clap_complete:: ArgValueCandidates :: new ( Vec :: new) , // TODO(complete): implement dynamic completion for `cargo clean -p`
170- ) ,
116+ . add ( package_completion) ,
171117 )
172118 }
173119
@@ -1566,7 +1512,7 @@ fn get_ws_member_packages() -> CargoResult<Vec<Package>> {
15661512 Ok ( packages)
15671513}
15681514
1569- fn get_ws_member_candidates ( ) -> Vec < clap_complete:: CompletionCandidate > {
1515+ pub fn get_ws_member_candidates ( ) -> Vec < clap_complete:: CompletionCandidate > {
15701516 get_ws_member_packages ( )
15711517 . unwrap_or_default ( )
15721518 . into_iter ( )
@@ -1582,35 +1528,6 @@ fn get_ws_member_candidates() -> Vec<clap_complete::CompletionCandidate> {
15821528 . collect :: < Vec < _ > > ( )
15831529}
15841530
1585- fn get_installed_packages ( ) -> CargoResult < Vec < ( PackageId , BTreeSet < String > ) > > {
1586- let gctx = new_gctx_for_completions ( ) ?;
1587- let root = resolve_root ( None , & gctx) ?;
1588-
1589- let tracker = InstallTracker :: load ( & gctx, & root) ?;
1590- Ok ( tracker
1591- . all_installed_bins ( )
1592- . map ( |( package_id, bins) | ( * package_id, bins. clone ( ) ) )
1593- . collect ( ) )
1594- }
1595- fn get_installed_package_candidates ( ) -> Vec < clap_complete:: CompletionCandidate > {
1596- get_installed_packages ( )
1597- . unwrap_or_default ( )
1598- . into_iter ( )
1599- . map ( |( pkg, bins) | {
1600- let single_binary = bins. iter ( ) . next ( ) . take_if ( |_| bins. len ( ) == 1 ) ;
1601-
1602- let help = if single_binary. is_some_and ( |bin| bin == pkg. name ( ) . as_str ( ) ) {
1603- None
1604- } else {
1605- let binaries = bins. into_iter ( ) . collect :: < Vec < _ > > ( ) . as_slice ( ) . join ( ", " ) ;
1606- Some ( binaries)
1607- } ;
1608-
1609- clap_complete:: CompletionCandidate :: new ( pkg. name ( ) . as_str ( ) ) . help ( help. map ( From :: from) )
1610- } )
1611- . collect ( )
1612- }
1613-
16141531pub fn get_dependency_package_candidates ( ) -> Vec < clap_complete:: CompletionCandidate > {
16151532 get_packages ( )
16161533 . unwrap_or_default ( )
0 commit comments