22
33use std:: collections:: BTreeSet ;
44
5- use crate :: core:: Package ;
5+ use crate :: core:: { Package , PackageIdSpecQuery } ;
66use crate :: core:: { PackageIdSpec , Workspace } ;
77use crate :: util:: restricted_names:: is_glob_pattern;
88use crate :: util:: CargoResult ;
@@ -50,16 +50,24 @@ impl Packages {
5050 . map ( |id| id. to_spec ( ) )
5151 . collect ( ) ,
5252 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) ?;
5454 let specs = ws
5555 . members ( )
5656 . 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)
5862 } )
5963 . map ( Package :: package_id)
6064 . map ( |id| id. to_spec ( ) )
6165 . collect ( ) ;
6266 let warn = |e| ws. config ( ) . shell ( ) . warn ( e) ;
67+ let names = ids
68+ . into_iter ( )
69+ . map ( |id| id. to_string ( ) )
70+ . collect :: < BTreeSet < _ > > ( ) ;
6371 emit_package_not_found ( ws, names, true ) . or_else ( warn) ?;
6472 emit_pattern_not_found ( ws, patterns, true ) . or_else ( warn) ?;
6573 specs
@@ -68,11 +76,7 @@ impl Packages {
6876 vec ! [ ws. current( ) ?. package_id( ) . to_spec( ) ]
6977 }
7078 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) ?;
7680 if !patterns. is_empty ( ) {
7781 let matched_pkgs = ws
7882 . members ( )
@@ -82,7 +86,7 @@ impl Packages {
8286 specs. extend ( matched_pkgs) ;
8387 }
8488 emit_pattern_not_found ( ws, patterns, false ) ?;
85- specs
89+ specs. into_iter ( ) . collect ( )
8690 }
8791 Packages :: Default => ws
8892 . default_members ( )
@@ -109,25 +113,41 @@ impl Packages {
109113 Packages :: Default => ws. default_members ( ) . collect ( ) ,
110114 Packages :: All => ws. members ( ) . collect ( ) ,
111115 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) ?;
113117 let packages = ws
114118 . members ( )
115119 . 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)
117125 } )
118126 . collect ( ) ;
127+ let names = ids
128+ . into_iter ( )
129+ . map ( |id| id. to_string ( ) )
130+ . collect :: < BTreeSet < _ > > ( ) ;
119131 emit_package_not_found ( ws, names, true ) ?;
120132 emit_pattern_not_found ( ws, patterns, true ) ?;
121133 packages
122134 }
123135 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) ?;
125137 let packages = ws
126138 . members ( )
127139 . 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)
129145 } )
130146 . collect ( ) ;
147+ let names = ids
148+ . into_iter ( )
149+ . map ( |id| id. to_string ( ) )
150+ . collect :: < BTreeSet < _ > > ( ) ;
131151 emit_package_not_found ( ws, names, false ) ?;
132152 emit_pattern_not_found ( ws, patterns, false ) ?;
133153 packages
@@ -151,7 +171,7 @@ impl Packages {
151171/// Emits "package not found" error.
152172fn emit_package_not_found (
153173 ws : & Workspace < ' _ > ,
154- opt_names : BTreeSet < & str > ,
174+ opt_names : BTreeSet < String > ,
155175 opt_out : bool ,
156176) -> CargoResult < ( ) > {
157177 if !opt_names. is_empty ( ) {
@@ -188,20 +208,22 @@ fn emit_pattern_not_found(
188208}
189209
190210/// 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 (
193213 opt : & [ String ] ,
194- ) -> CargoResult < ( Vec < ( glob:: Pattern , bool ) > , BTreeSet < & str > ) > {
214+ ) -> CargoResult < ( Vec < ( glob:: Pattern , bool ) > , BTreeSet < PackageIdSpec > ) > {
195215 let mut opt_patterns = Vec :: new ( ) ;
196- let mut opt_names = BTreeSet :: new ( ) ;
216+ let mut opt_ids = BTreeSet :: new ( ) ;
197217 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 ( ) ) ,
202224 }
203225 }
204- Ok ( ( opt_patterns, opt_names ) )
226+ Ok ( ( opt_patterns, opt_ids ) )
205227}
206228
207229/// Checks whether a package matches any of a list of glob patterns generated
0 commit comments