@@ -19,8 +19,10 @@ pub enum Packages {
19
19
Default ,
20
20
/// Opt in all packages.
21
21
///
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.
23
23
All ,
24
+ /// This equivalent to `All` but keeps the packages passed in.
25
+ AllWithPackages ( Vec < String > ) ,
24
26
/// Opt out of packages passed in.
25
27
///
26
28
/// As of the time of this writing, it only works on opting out workspace members.
@@ -36,14 +38,41 @@ impl Packages {
36
38
( false , 0 , 0 ) => Packages :: Default ,
37
39
( false , 0 , _) => Packages :: Packages ( package) ,
38
40
( 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) ,
40
43
( true , _, _) => Packages :: OptOut ( exclude) ,
41
44
} )
42
45
}
43
46
44
47
/// Converts selected packages to [`PackageIdSpec`]s.
45
48
pub fn to_package_id_specs ( & self , ws : & Workspace < ' _ > ) -> CargoResult < Vec < PackageIdSpec > > {
46
49
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
+ }
47
76
Packages :: All => ws
48
77
. members ( )
49
78
. map ( Package :: package_id)
@@ -111,6 +140,26 @@ impl Packages {
111
140
pub fn get_packages < ' ws > ( & self , ws : & ' ws Workspace < ' _ > ) -> CargoResult < Vec < & ' ws Package > > {
112
141
let packages: Vec < _ > = match self {
113
142
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
+ }
114
163
Packages :: All => ws. members ( ) . collect ( ) ,
115
164
Packages :: OptOut ( opt_out) => {
116
165
let ( mut patterns, mut ids) = opt_patterns_and_ids ( opt_out) ?;
@@ -161,7 +210,7 @@ impl Packages {
161
210
pub fn needs_spec_flag ( & self , ws : & Workspace < ' _ > ) -> bool {
162
211
match self {
163
212
Packages :: Default => ws. default_members ( ) . count ( ) > 1 ,
164
- Packages :: All => ws. members ( ) . count ( ) > 1 ,
213
+ Packages :: All | Packages :: AllWithPackages ( _ ) => ws. members ( ) . count ( ) > 1 ,
165
214
Packages :: Packages ( _) => true ,
166
215
Packages :: OptOut ( _) => true ,
167
216
}
0 commit comments