2
2
3
3
use std:: collections:: BTreeSet ;
4
4
5
- use crate :: core:: Package ;
5
+ use crate :: core:: { Package , PackageIdSpecQuery } ;
6
6
use crate :: core:: { PackageIdSpec , Workspace } ;
7
7
use crate :: util:: restricted_names:: is_glob_pattern;
8
8
use crate :: util:: CargoResult ;
@@ -50,16 +50,24 @@ impl Packages {
50
50
. map ( |id| id. to_spec ( ) )
51
51
. collect ( ) ,
52
52
Packages :: OptOut ( opt_out) => {
53
- let ( mut patterns, mut names ) = opt_patterns_and_names ( opt_out) ?;
53
+ let ( mut patterns, mut ids ) = opt_patterns_and_ids ( opt_out) ?;
54
54
let specs = ws
55
55
. members ( )
56
56
. filter ( |pkg| {
57
- !names. remove ( pkg. name ( ) . as_str ( ) ) && !match_patterns ( pkg, & mut patterns)
57
+ let id = ids. iter ( ) . find ( |id| id. matches ( pkg. package_id ( ) ) ) . cloned ( ) ;
58
+ if let Some ( id) = & id {
59
+ ids. remove ( id) ;
60
+ }
61
+ !id. is_some ( ) && !match_patterns ( pkg, & mut patterns)
58
62
} )
59
63
. map ( Package :: package_id)
60
64
. map ( |id| id. to_spec ( ) )
61
65
. collect ( ) ;
62
66
let warn = |e| ws. config ( ) . shell ( ) . warn ( e) ;
67
+ let names = ids
68
+ . into_iter ( )
69
+ . map ( |id| id. to_string ( ) )
70
+ . collect :: < BTreeSet < _ > > ( ) ;
63
71
emit_package_not_found ( ws, names, true ) . or_else ( warn) ?;
64
72
emit_pattern_not_found ( ws, patterns, true ) . or_else ( warn) ?;
65
73
specs
@@ -68,11 +76,7 @@ impl Packages {
68
76
vec ! [ ws. current( ) ?. package_id( ) . to_spec( ) ]
69
77
}
70
78
Packages :: Packages ( opt_in) => {
71
- let ( mut patterns, packages) = opt_patterns_and_names ( opt_in) ?;
72
- let mut specs = packages
73
- . iter ( )
74
- . map ( |p| PackageIdSpec :: parse ( p) )
75
- . collect :: < Result < Vec < _ > , _ > > ( ) ?;
79
+ let ( mut patterns, mut specs) = opt_patterns_and_ids ( opt_in) ?;
76
80
if !patterns. is_empty ( ) {
77
81
let matched_pkgs = ws
78
82
. members ( )
@@ -82,7 +86,7 @@ impl Packages {
82
86
specs. extend ( matched_pkgs) ;
83
87
}
84
88
emit_pattern_not_found ( ws, patterns, false ) ?;
85
- specs
89
+ specs. into_iter ( ) . collect ( )
86
90
}
87
91
Packages :: Default => ws
88
92
. default_members ( )
@@ -109,25 +113,41 @@ impl Packages {
109
113
Packages :: Default => ws. default_members ( ) . collect ( ) ,
110
114
Packages :: All => ws. members ( ) . collect ( ) ,
111
115
Packages :: OptOut ( opt_out) => {
112
- let ( mut patterns, mut names ) = opt_patterns_and_names ( opt_out) ?;
116
+ let ( mut patterns, mut ids ) = opt_patterns_and_ids ( opt_out) ?;
113
117
let packages = ws
114
118
. members ( )
115
119
. filter ( |pkg| {
116
- !names. remove ( pkg. name ( ) . as_str ( ) ) && !match_patterns ( pkg, & mut patterns)
120
+ let id = ids. iter ( ) . find ( |id| id. matches ( pkg. package_id ( ) ) ) . cloned ( ) ;
121
+ if let Some ( id) = & id {
122
+ ids. remove ( id) ;
123
+ }
124
+ !id. is_some ( ) && !match_patterns ( pkg, & mut patterns)
117
125
} )
118
126
. collect ( ) ;
127
+ let names = ids
128
+ . into_iter ( )
129
+ . map ( |id| id. to_string ( ) )
130
+ . collect :: < BTreeSet < _ > > ( ) ;
119
131
emit_package_not_found ( ws, names, true ) ?;
120
132
emit_pattern_not_found ( ws, patterns, true ) ?;
121
133
packages
122
134
}
123
135
Packages :: Packages ( opt_in) => {
124
- let ( mut patterns, mut names ) = opt_patterns_and_names ( opt_in) ?;
136
+ let ( mut patterns, mut ids ) = opt_patterns_and_ids ( opt_in) ?;
125
137
let packages = ws
126
138
. members ( )
127
139
. filter ( |pkg| {
128
- names. remove ( pkg. name ( ) . as_str ( ) ) || match_patterns ( pkg, & mut patterns)
140
+ let id = ids. iter ( ) . find ( |id| id. matches ( pkg. package_id ( ) ) ) . cloned ( ) ;
141
+ if let Some ( id) = & id {
142
+ ids. remove ( id) ;
143
+ }
144
+ id. is_some ( ) || match_patterns ( pkg, & mut patterns)
129
145
} )
130
146
. collect ( ) ;
147
+ let names = ids
148
+ . into_iter ( )
149
+ . map ( |id| id. to_string ( ) )
150
+ . collect :: < BTreeSet < _ > > ( ) ;
131
151
emit_package_not_found ( ws, names, false ) ?;
132
152
emit_pattern_not_found ( ws, patterns, false ) ?;
133
153
packages
@@ -151,7 +171,7 @@ impl Packages {
151
171
/// Emits "package not found" error.
152
172
fn emit_package_not_found (
153
173
ws : & Workspace < ' _ > ,
154
- opt_names : BTreeSet < & str > ,
174
+ opt_names : BTreeSet < String > ,
155
175
opt_out : bool ,
156
176
) -> CargoResult < ( ) > {
157
177
if !opt_names. is_empty ( ) {
@@ -188,20 +208,22 @@ fn emit_pattern_not_found(
188
208
}
189
209
190
210
/// Given a list opt-in or opt-out package selection strings, generates two
191
- /// collections that represent glob patterns and package names respectively.
192
- fn opt_patterns_and_names (
211
+ /// collections that represent glob patterns and package id specs respectively.
212
+ fn opt_patterns_and_ids (
193
213
opt : & [ String ] ,
194
- ) -> CargoResult < ( Vec < ( glob:: Pattern , bool ) > , BTreeSet < & str > ) > {
214
+ ) -> CargoResult < ( Vec < ( glob:: Pattern , bool ) > , BTreeSet < PackageIdSpec > ) > {
195
215
let mut opt_patterns = Vec :: new ( ) ;
196
- let mut opt_names = BTreeSet :: new ( ) ;
216
+ let mut opt_ids = BTreeSet :: new ( ) ;
197
217
for x in opt. iter ( ) {
198
- if PackageIdSpec :: parse ( x) . is_err ( ) && is_glob_pattern ( x) {
199
- opt_patterns. push ( ( build_glob ( x) ?, false ) ) ;
200
- } else {
201
- opt_names. insert ( String :: as_str ( x) ) ;
218
+ match PackageIdSpec :: parse ( x) {
219
+ Ok ( spec) => {
220
+ opt_ids. insert ( spec) ;
221
+ }
222
+ Err ( _) if is_glob_pattern ( x) => opt_patterns. push ( ( build_glob ( x) ?, false ) ) ,
223
+ Err ( e) => return Err ( e. into ( ) ) ,
202
224
}
203
225
}
204
- Ok ( ( opt_patterns, opt_names ) )
226
+ Ok ( ( opt_patterns, opt_ids ) )
205
227
}
206
228
207
229
/// Checks whether a package matches any of a list of glob patterns generated
0 commit comments