@@ -19,8 +19,10 @@ pub enum Packages {
1919 Default ,
2020 /// Opt in all packages.
2121 ///
22- /// As of the time of this writing, it only works on opting in all workspace members.
22+ /// As of the time of this writing, it only works on opting in all workspace members.
2323 All ,
24+ /// This equivalent to `All` but keeps the packages passed in.
25+ AllWithPackages ( Vec < String > ) ,
2426 /// Opt out of packages passed in.
2527 ///
2628 /// As of the time of this writing, it only works on opting out workspace members.
@@ -36,14 +38,41 @@ impl Packages {
3638 ( false , 0 , 0 ) => Packages :: Default ,
3739 ( false , 0 , _) => Packages :: Packages ( package) ,
3840 ( false , _, _) => anyhow:: bail!( "--exclude can only be used together with --workspace" ) ,
39- ( true , 0 , _) => Packages :: All ,
41+ ( true , 0 , 0 ) => Packages :: All ,
42+ ( true , 0 , _) => Packages :: AllWithPackages ( package) ,
4043 ( true , _, _) => Packages :: OptOut ( exclude) ,
4144 } )
4245 }
4346
4447 /// Converts selected packages to [`PackageIdSpec`]s.
4548 pub fn to_package_id_specs ( & self , ws : & Workspace < ' _ > ) -> CargoResult < Vec < PackageIdSpec > > {
4649 let specs = match self {
50+ Packages :: AllWithPackages ( packages) => {
51+ let ( mut patterns, mut ids) = opt_patterns_and_ids ( packages) ?;
52+ let _: Vec < _ > = ws
53+ . members ( )
54+ . filter ( |pkg| {
55+ let id = ids. iter ( ) . find ( |id| id. matches ( pkg. package_id ( ) ) ) . cloned ( ) ;
56+ if let Some ( id) = & id {
57+ ids. remove ( id) ;
58+ }
59+ !id. is_some ( ) && !match_patterns ( pkg, & mut patterns)
60+ } )
61+ . map ( Package :: package_id)
62+ . map ( |id| id. to_spec ( ) )
63+ . collect ( ) ;
64+ let warn = |e| ws. gctx ( ) . shell ( ) . warn ( e) ;
65+ let names = ids
66+ . into_iter ( )
67+ . map ( |id| id. to_string ( ) )
68+ . collect :: < BTreeSet < _ > > ( ) ;
69+ emit_package_not_found ( ws, names, false ) . or_else ( warn) ?;
70+ emit_pattern_not_found ( ws, patterns, false ) . or_else ( warn) ?;
71+ ws. members ( )
72+ . map ( Package :: package_id)
73+ . map ( |id| id. to_spec ( ) )
74+ . collect ( )
75+ }
4776 Packages :: All => ws
4877 . members ( )
4978 . map ( Package :: package_id)
@@ -111,6 +140,26 @@ impl Packages {
111140 pub fn get_packages < ' ws > ( & self , ws : & ' ws Workspace < ' _ > ) -> CargoResult < Vec < & ' ws Package > > {
112141 let packages: Vec < _ > = match self {
113142 Packages :: Default => ws. default_members ( ) . collect ( ) ,
143+ Packages :: AllWithPackages ( packages) => {
144+ let ( mut patterns, mut ids) = opt_patterns_and_ids ( packages) ?;
145+ let _: Vec < _ > = ws
146+ . members ( )
147+ . filter ( |pkg| {
148+ let id = ids. iter ( ) . find ( |id| id. matches ( pkg. package_id ( ) ) ) . cloned ( ) ;
149+ if let Some ( id) = & id {
150+ ids. remove ( id) ;
151+ }
152+ !id. is_some ( ) && !match_patterns ( pkg, & mut patterns)
153+ } )
154+ . collect ( ) ;
155+ let names = ids
156+ . into_iter ( )
157+ . map ( |id| id. to_string ( ) )
158+ . collect :: < BTreeSet < _ > > ( ) ;
159+ emit_package_not_found ( ws, names, false ) ?;
160+ emit_pattern_not_found ( ws, patterns, false ) ?;
161+ ws. members ( ) . collect ( )
162+ }
114163 Packages :: All => ws. members ( ) . collect ( ) ,
115164 Packages :: OptOut ( opt_out) => {
116165 let ( mut patterns, mut ids) = opt_patterns_and_ids ( opt_out) ?;
@@ -161,7 +210,7 @@ impl Packages {
161210 pub fn needs_spec_flag ( & self , ws : & Workspace < ' _ > ) -> bool {
162211 match self {
163212 Packages :: Default => ws. default_members ( ) . count ( ) > 1 ,
164- Packages :: All => ws. members ( ) . count ( ) > 1 ,
213+ Packages :: All | Packages :: AllWithPackages ( _ ) => ws. members ( ) . count ( ) > 1 ,
165214 Packages :: Packages ( _) => true ,
166215 Packages :: OptOut ( _) => true ,
167216 }
0 commit comments