3
3
4
4
//! The `packages` subcommand.
5
5
6
+ use std:: io:: Write ;
7
+
6
8
use clap:: { Arg , ArgAction , ArgMatches , Command } ;
9
+ use indexmap:: IndexSet ;
10
+ use tabwriter:: TabWriter ;
11
+ use tokio:: runtime:: Runtime ;
7
12
8
13
use crate :: error:: * ;
9
- use crate :: sess:: Session ;
14
+ use crate :: sess:: { DependencySource , Session , SessionIo } ;
15
+ use crate :: src:: SourceGroup ;
16
+ use crate :: target:: TargetSpec ;
10
17
11
18
/// Assemble the `packages` subcommand.
12
19
pub fn new ( ) -> Command {
@@ -27,38 +34,132 @@ pub fn new() -> Command {
27
34
. help ( "Do not group packages by topological rank" )
28
35
. long_help ( "Do not group packages by topological rank. If the `--graph` option is specified, print multiple lines per package, one for each dependency." )
29
36
)
37
+ . arg ( Arg :: new ( "version" )
38
+ . long ( "version" )
39
+ . num_args ( 0 )
40
+ . action ( ArgAction :: SetTrue )
41
+ . help ( "Print the version of each package" )
42
+ . long_help ( "Print the version of each package. Implies --flat. More detailed information is available per dependency using the `parents` subcommand." )
43
+ )
44
+ . arg ( Arg :: new ( "targets" )
45
+ . long ( "targets" )
46
+ . num_args ( 0 )
47
+ . action ( ArgAction :: SetTrue )
48
+ . help ( "Print the targets available for each package" )
49
+ )
30
50
}
31
51
32
52
/// Execute the `packages` subcommand.
33
53
pub fn run ( sess : & Session , matches : & ArgMatches ) -> Result < ( ) > {
34
54
let graph = matches. get_flag ( "graph" ) ;
35
55
let flat = matches. get_flag ( "flat" ) ;
36
- if graph {
56
+ let version = matches. get_flag ( "version" ) ;
57
+ if graph && version {
58
+ return Err ( Error :: new ( "cannot specify both --graph and --version" ) ) ;
59
+ }
60
+ let targets = matches. get_flag ( "targets" ) ;
61
+ if targets {
62
+ if graph {
63
+ return Err ( Error :: new ( "cannot specify both --graph and --targets" ) ) ;
64
+ }
65
+ let rt = Runtime :: new ( ) ?;
66
+ let io = SessionIo :: new ( sess) ;
67
+ let srcs = rt. block_on ( io. sources ( false , & [ ] ) ) ?;
68
+ let mut target_str = String :: from ( "" ) ;
69
+ for pkgs in sess. packages ( ) . iter ( ) {
70
+ let pkg_names = pkgs. iter ( ) . map ( |& id| sess. dependency_name ( id) ) ;
71
+ for pkg_name in pkg_names {
72
+ target_str. push_str ( & format ! (
73
+ "{}:\t {:?}\n " ,
74
+ pkg_name,
75
+ srcs. filter_packages( & IndexSet :: from( [ pkg_name. into( ) ] ) )
76
+ . unwrap_or_else( || SourceGroup {
77
+ package: Default :: default ( ) ,
78
+ independent: true ,
79
+ target: TargetSpec :: Wildcard ,
80
+ include_dirs: Default :: default ( ) ,
81
+ export_incdirs: Default :: default ( ) ,
82
+ defines: Default :: default ( ) ,
83
+ files: Default :: default ( ) ,
84
+ dependencies: Default :: default ( ) ,
85
+ version: None ,
86
+ } )
87
+ . get_avail_targets( )
88
+ ) ) ;
89
+ }
90
+ }
91
+ target_str. push_str ( & format ! (
92
+ "{}:\t {:?}\n " ,
93
+ & sess. manifest. package. name,
94
+ srcs. filter_packages( & IndexSet :: from( [ sess. manifest. package. name. clone( ) ] ) )
95
+ . unwrap_or_else( || SourceGroup {
96
+ package: Default :: default ( ) ,
97
+ independent: true ,
98
+ target: TargetSpec :: Wildcard ,
99
+ include_dirs: Default :: default ( ) ,
100
+ export_incdirs: Default :: default ( ) ,
101
+ defines: Default :: default ( ) ,
102
+ files: Default :: default ( ) ,
103
+ dependencies: Default :: default ( ) ,
104
+ version: None ,
105
+ } )
106
+ . get_avail_targets( )
107
+ ) ) ;
108
+ let mut tw = TabWriter :: new ( vec ! [ ] ) ;
109
+ write ! ( & mut tw, "{}" , target_str) . unwrap ( ) ;
110
+ tw. flush ( ) . unwrap ( ) ;
111
+ print ! ( "{}" , String :: from_utf8( tw. into_inner( ) . unwrap( ) ) . unwrap( ) ) ;
112
+ } else if graph {
113
+ let mut graph_str = String :: from ( "" ) ;
37
114
for ( & pkg, deps) in sess. graph ( ) . iter ( ) {
38
115
let pkg_name = sess. dependency_name ( pkg) ;
39
116
let dep_names = deps. iter ( ) . map ( |& id| sess. dependency_name ( id) ) ;
40
117
if flat {
41
118
// Print one line per dependency.
42
119
for dep_name in dep_names {
43
- println ! ( "{}\t {}" , pkg_name, dep_name) ;
120
+ graph_str . push_str ( & format ! ( "{}\t {}\n " , pkg_name, dep_name) ) ;
44
121
}
45
122
} else {
46
123
// Print all dependencies on one line.
47
- print ! ( "{}\t " , pkg_name) ;
124
+ graph_str . push_str ( & format ! ( "{}\t " , pkg_name) ) ;
48
125
for ( i, dep_name) in dep_names. enumerate ( ) {
49
126
if i > 0 {
50
- print ! ( " {}" , dep_name) ;
127
+ graph_str . push_str ( & format ! ( " {}" , dep_name) ) ;
51
128
} else {
52
- print ! ( "{}" , dep_name) ;
129
+ graph_str . push_str ( dep_name) ;
53
130
}
54
131
}
55
- println ! ( ) ;
132
+ graph_str . push ( '\n' ) ;
56
133
}
57
134
}
135
+ let mut tw = TabWriter :: new ( vec ! [ ] ) ;
136
+ write ! ( & mut tw, "{}" , graph_str) . unwrap ( ) ;
137
+ tw. flush ( ) . unwrap ( ) ;
138
+ print ! ( "{}" , String :: from_utf8( tw. into_inner( ) . unwrap( ) ) . unwrap( ) ) ;
58
139
} else {
140
+ let mut version_str = String :: from ( "" ) ;
59
141
for pkgs in sess. packages ( ) . iter ( ) {
60
142
let pkg_names = pkgs. iter ( ) . map ( |& id| sess. dependency_name ( id) ) ;
61
- if flat {
143
+ let pkg_sources = pkgs. iter ( ) . map ( |& id| sess. dependency ( id) ) ;
144
+ if version {
145
+ for pkg_source in pkg_sources {
146
+ version_str. push_str ( & format ! (
147
+ "{}:\t {}\t at {}\t {}\n " ,
148
+ pkg_source. name,
149
+ match pkg_source. version {
150
+ Some ( ref v) => format!( "v{}" , v) ,
151
+ None => "" . to_string( ) ,
152
+ } ,
153
+ pkg_source. source,
154
+ match pkg_source. source {
155
+ DependencySource :: Path { .. } => " as path" . to_string( ) ,
156
+ DependencySource :: Git ( _) =>
157
+ format!( " with hash {}" , pkg_source. version( ) ) ,
158
+ _ => "" . to_string( ) ,
159
+ }
160
+ ) ) ;
161
+ }
162
+ } else if flat {
62
163
// Print one line per package.
63
164
for pkg_name in pkg_names {
64
165
println ! ( "{}" , pkg_name) ;
@@ -75,6 +176,12 @@ pub fn run(sess: &Session, matches: &ArgMatches) -> Result<()> {
75
176
println ! ( ) ;
76
177
}
77
178
}
179
+ if version {
180
+ let mut tw = TabWriter :: new ( vec ! [ ] ) ;
181
+ write ! ( & mut tw, "{}" , version_str) . unwrap ( ) ;
182
+ tw. flush ( ) . unwrap ( ) ;
183
+ print ! ( "{}" , String :: from_utf8( tw. into_inner( ) . unwrap( ) ) . unwrap( ) ) ;
184
+ }
78
185
}
79
186
Ok ( ( ) )
80
187
}
0 commit comments