11use crate :: core:: compiler:: { BuildConfig , MessageFormat , TimingOutput } ;
22use crate :: core:: resolver:: CliFeatures ;
3- use crate :: core:: { Edition , Workspace } ;
3+ use crate :: core:: { shell , Edition , Target , TargetKind , Workspace } ;
44use crate :: ops:: lockfile:: LOCKFILE_NAME ;
55use crate :: ops:: registry:: RegistryOrIndex ;
66use crate :: ops:: { CompileFilter , CompileOptions , NewOptions , Packages , VersionControl } ;
@@ -19,6 +19,7 @@ use cargo_util_schemas::manifest::ProfileName;
1919use cargo_util_schemas:: manifest:: RegistryName ;
2020use cargo_util_schemas:: manifest:: StringOrVec ;
2121use clap:: builder:: UnknownArgumentValueParser ;
22+ use home:: cargo_home_with_cwd;
2223use std:: ffi:: { OsStr , OsString } ;
2324use std:: path:: Path ;
2425use std:: path:: PathBuf ;
@@ -173,7 +174,11 @@ pub trait CommandExt: Sized {
173174 ) -> Self {
174175 self . _arg ( flag ( "lib" , lib) . help_heading ( heading:: TARGET_SELECTION ) )
175176 . _arg ( flag ( "bins" , bins) . help_heading ( heading:: TARGET_SELECTION ) )
176- . _arg ( optional_multi_opt ( "bin" , "NAME" , bin) . help_heading ( heading:: TARGET_SELECTION ) )
177+ . _arg (
178+ optional_multi_opt ( "bin" , "NAME" , bin)
179+ . help_heading ( heading:: TARGET_SELECTION )
180+ . add ( clap_complete:: ArgValueCandidates :: new ( get_bin_candidates) ) ,
181+ )
177182 . _arg ( flag ( "examples" , examples) . help_heading ( heading:: TARGET_SELECTION ) )
178183 . _arg (
179184 optional_multi_opt ( "example" , "NAME" , example)
@@ -188,21 +193,27 @@ pub trait CommandExt: Sized {
188193 example : & ' static str ,
189194 examples : & ' static str ,
190195 ) -> Self {
191- self . _arg ( optional_multi_opt ( "bin" , "NAME" , bin) . help_heading ( heading:: TARGET_SELECTION ) )
192- . _arg ( flag ( "bins" , bins) . help_heading ( heading:: TARGET_SELECTION ) )
193- . _arg (
194- optional_multi_opt ( "example" , "NAME" , example)
195- . help_heading ( heading:: TARGET_SELECTION ) ,
196- )
197- . _arg ( flag ( "examples" , examples) . help_heading ( heading:: TARGET_SELECTION ) )
196+ self . _arg (
197+ optional_multi_opt ( "bin" , "NAME" , bin)
198+ . help_heading ( heading:: TARGET_SELECTION )
199+ . add ( clap_complete:: ArgValueCandidates :: new ( get_bin_candidates) ) ,
200+ )
201+ . _arg ( flag ( "bins" , bins) . help_heading ( heading:: TARGET_SELECTION ) )
202+ . _arg (
203+ optional_multi_opt ( "example" , "NAME" , example) . help_heading ( heading:: TARGET_SELECTION ) ,
204+ )
205+ . _arg ( flag ( "examples" , examples) . help_heading ( heading:: TARGET_SELECTION ) )
198206 }
199207
200208 fn arg_targets_bin_example ( self , bin : & ' static str , example : & ' static str ) -> Self {
201- self . _arg ( optional_multi_opt ( "bin" , "NAME" , bin) . help_heading ( heading:: TARGET_SELECTION ) )
202- . _arg (
203- optional_multi_opt ( "example" , "NAME" , example)
204- . help_heading ( heading:: TARGET_SELECTION ) ,
205- )
209+ self . _arg (
210+ optional_multi_opt ( "bin" , "NAME" , bin)
211+ . help_heading ( heading:: TARGET_SELECTION )
212+ . add ( clap_complete:: ArgValueCandidates :: new ( get_bin_candidates) ) ,
213+ )
214+ . _arg (
215+ optional_multi_opt ( "example" , "NAME" , example) . help_heading ( heading:: TARGET_SELECTION ) ,
216+ )
206217 }
207218
208219 fn arg_features ( self ) -> Self {
@@ -333,7 +344,10 @@ pub trait CommandExt: Sized {
333344 . value_name ( "VCS" )
334345 . value_parser ( [ "git" , "hg" , "pijul" , "fossil" , "none" ] ) ,
335346 )
336- . _arg ( flag ( "bin" , "Use a binary (application) template [default]" ) )
347+ . _arg (
348+ flag ( "bin" , "Use a binary (application) template [default]" )
349+ . add ( clap_complete:: ArgValueCandidates :: new ( get_bin_candidates) ) ,
350+ )
337351 . _arg ( flag ( "lib" , "Use a library template" ) )
338352 . _arg (
339353 opt ( "edition" , "Edition to set for the crate generated" )
@@ -1027,6 +1041,32 @@ pub fn lockfile_path(
10271041 return Ok ( Some ( path) ) ;
10281042}
10291043
1044+ fn get_bin_candidates ( ) -> Vec < clap_complete:: CompletionCandidate > {
1045+ get_targets_from_metadata ( )
1046+ . unwrap_or_default ( )
1047+ . into_iter ( )
1048+ . filter_map ( |target| match target. kind ( ) {
1049+ TargetKind :: Bin => Some ( clap_complete:: CompletionCandidate :: new ( target. name ( ) ) ) ,
1050+ _ => None ,
1051+ } )
1052+ . collect :: < Vec < _ > > ( )
1053+ }
1054+
1055+ fn get_targets_from_metadata ( ) -> CargoResult < Vec < Target > > {
1056+ let cwd = std:: env:: current_dir ( ) ?;
1057+ let gctx = GlobalContext :: new ( shell:: Shell :: new ( ) , cwd. clone ( ) , cargo_home_with_cwd ( & cwd) ?) ;
1058+ let ws = Workspace :: new ( & find_root_manifest_for_wd ( & cwd) ?, & gctx) ?;
1059+
1060+ let packages = ws. members ( ) . collect :: < Vec < _ > > ( ) ;
1061+
1062+ let targets = packages
1063+ . into_iter ( )
1064+ . flat_map ( |pkg| pkg. targets ( ) . into_iter ( ) . cloned ( ) )
1065+ . collect :: < Vec < _ > > ( ) ;
1066+
1067+ Ok ( targets)
1068+ }
1069+
10301070#[ track_caller]
10311071pub fn ignore_unknown < T : Default > ( r : Result < T , clap:: parser:: MatchesError > ) -> T {
10321072 match r {
0 commit comments