11use crate :: BrewResult ;
22use crate :: delegate;
33use crate :: homebrew;
4+ use anyhow:: anyhow;
45use std:: fs;
56use std:: io;
67use std:: path:: { Path , PathBuf } ;
78use std:: process:: ExitCode ;
89
10+ #[ derive( Default ) ]
11+ struct Args < ' a > {
12+ formula : bool ,
13+ cask : bool ,
14+ packages : Vec < & ' a str > ,
15+ }
16+
917pub fn run ( args : & [ String ] ) -> BrewResult < ExitCode > {
10- if args[ 1 ..]
11- . iter ( )
12- . any ( |arg| arg. starts_with ( '-' ) || arg. contains ( '/' ) )
13- {
14- return delegate:: run ( args) ;
15- }
18+ let parsed_args = {
19+ let mut result = Args :: default ( ) ;
20+ let mut args_iter = args. iter ( ) ;
21+ args_iter. next ( ) ; // Skip `list`
22+ for arg in args_iter {
23+ match arg. as_str ( ) {
24+ "--formula" | "--formulae" => {
25+ if result. cask {
26+ return Err ( anyhow ! (
27+ "Conflicting flags: `{}` and `{}`" ,
28+ arg,
29+ args. iter( )
30+ . find( |s| s. as_str( ) == "--cask" || s. as_str( ) == "--casks" )
31+ . unwrap( )
32+ ) ) ;
33+ } else {
34+ result. formula = true ;
35+ }
36+ }
37+ "--cask" | "--casks" => {
38+ if result. formula {
39+ return Err ( anyhow ! (
40+ "Conflicting flags: `{}` and `{}`" ,
41+ arg,
42+ args. iter( )
43+ . find( |s| s. as_str( ) == "--formula" || s. as_str( ) == "--formulae" )
44+ . unwrap( )
45+ ) ) ;
46+ } else {
47+ result. cask = true ;
48+ }
49+ }
50+ s if !s. starts_with ( '-' ) && !s. contains ( '/' ) => result. packages . push ( s) ,
51+ _ => return delegate:: run ( args) ,
52+ }
53+ }
54+ if !result. formula && !result. cask {
55+ result. formula = true ;
56+ result. cask = true ;
57+ }
58+ result
59+ } ;
1660
1761 let cellar = homebrew:: cellar_path ( ) ?;
1862 let prefix = homebrew:: prefix_path ( ) ?;
1963 let caskroom = homebrew:: caskroom_path ( ) ?;
2064
21- if args. len ( ) == 1 {
22- let formulae = homebrew:: installed_names ( & cellar) ?;
23- let casks = homebrew:: installed_names ( & caskroom) ?;
65+ if parsed_args. packages . is_empty ( ) {
66+ let formulae = if parsed_args. formula {
67+ homebrew:: installed_names ( & cellar) ?
68+ } else {
69+ Vec :: new ( )
70+ } ;
71+ let casks = if parsed_args. cask {
72+ homebrew:: installed_names ( & caskroom) ?
73+ } else {
74+ Vec :: new ( )
75+ } ;
2476 homebrew:: print_sections ( & formulae, & casks) ;
2577 return Ok ( ExitCode :: SUCCESS ) ;
2678 }
2779
2880 let mut missing = Vec :: new ( ) ;
2981 let mut listed_any = false ;
3082
31- for name in & args[ 1 ..] {
32- match list_formula_paths ( & cellar, & prefix, name) ? {
33- FormulaPaths :: Paths ( paths) => {
34- if listed_any {
35- println ! ( ) ;
83+ for name in parsed_args. packages {
84+ if parsed_args. formula {
85+ match list_formula_paths ( & cellar, & prefix, name) ? {
86+ FormulaPaths :: Paths ( paths) => {
87+ if listed_any {
88+ println ! ( ) ;
89+ }
90+ println ! ( "{}" , paths. join( "\n " ) ) ;
91+ listed_any = true ;
92+ continue ;
3693 }
37- println ! ( "{}" , paths. join( "\n " ) ) ;
38- listed_any = true ;
39- continue ;
94+ FormulaPaths :: Delegate => return delegate:: run ( args) ,
95+ FormulaPaths :: Missing => { }
4096 }
41- FormulaPaths :: Delegate => return delegate:: run ( args) ,
42- FormulaPaths :: Missing => { }
4397 }
4498
45- if let Some ( paths) = list_cask_paths ( & caskroom, name) ? {
99+ if parsed_args. cask
100+ && let Some ( paths) = list_cask_paths ( & caskroom, name) ?
101+ {
46102 if listed_any {
47103 println ! ( ) ;
48104 }
@@ -51,12 +107,20 @@ pub fn run(args: &[String]) -> BrewResult<ExitCode> {
51107 continue ;
52108 }
53109
54- missing. push ( name. clone ( ) ) ;
110+ missing. push ( name) ;
55111 }
56112
113+ let keg_or_cask = if parsed_args. formula && parsed_args. cask {
114+ "keg or cask"
115+ } else if parsed_args. formula {
116+ "keg"
117+ } else {
118+ "cask"
119+ } ;
120+
57121 if !missing. is_empty ( ) {
58122 for name in missing {
59- eprintln ! ( "No such keg or cask : {name}" ) ;
123+ eprintln ! ( "No such {keg_or_cask} : {name}" ) ;
60124 }
61125 return Ok ( ExitCode :: FAILURE ) ;
62126 }
0 commit comments