@@ -28,6 +28,7 @@ use tar::{Archive, Builder, EntryType, Header, HeaderMode};
28
28
use tracing:: debug;
29
29
use unicase:: Ascii as UncasedAscii ;
30
30
31
+ #[ derive( Clone ) ]
31
32
pub struct PackageOpts < ' gctx > {
32
33
pub gctx : & ' gctx GlobalContext ,
33
34
pub list : bool ,
@@ -82,48 +83,33 @@ struct GitVcsInfo {
82
83
sha1 : String ,
83
84
}
84
85
86
+ /// Packages a single package in a workspace, returning the resulting tar file.
87
+ ///
88
+ /// Ignores `opts.list`.
85
89
pub fn package_one (
86
90
ws : & Workspace < ' _ > ,
87
91
pkg : & Package ,
88
92
opts : & PackageOpts < ' _ > ,
89
- ) -> CargoResult < Option < FileLock > > {
90
- let gctx = ws. gctx ( ) ;
91
- let mut src = PathSource :: new ( pkg. root ( ) , pkg. package_id ( ) . source_id ( ) , gctx) ;
92
- src. update ( ) ?;
93
+ ) -> CargoResult < FileLock > {
94
+ let ar_files = build_ar_list ( ws, pkg, opts) ?;
95
+ let tarball = create_package ( ws, pkg, ar_files) ?;
93
96
94
- if opts. check_metadata {
95
- check_metadata ( pkg, gctx) ?;
96
- }
97
-
98
- if !pkg. manifest ( ) . exclude ( ) . is_empty ( ) && !pkg. manifest ( ) . include ( ) . is_empty ( ) {
99
- gctx. shell ( ) . warn (
100
- "both package.include and package.exclude are specified; \
101
- the exclude list will be ignored",
102
- ) ?;
97
+ if opts. verify {
98
+ run_verify ( ws, pkg, & tarball, opts) ?;
103
99
}
104
- let src_files = src. list_files ( pkg) ?;
105
-
106
- // Check (git) repository state, getting the current commit hash if not
107
- // dirty.
108
- let vcs_info = if !opts. allow_dirty {
109
- // This will error if a dirty repo is found.
110
- check_repo_state ( pkg, & src_files, gctx) ?
111
- } else {
112
- None
113
- } ;
114
100
115
- let ar_files = build_ar_list ( ws, pkg, src_files, vcs_info) ?;
101
+ Ok ( tarball)
102
+ }
116
103
104
+ // Builds a tarball and places it in the output directory.
105
+ fn create_package (
106
+ ws : & Workspace < ' _ > ,
107
+ pkg : & Package ,
108
+ ar_files : Vec < ArchiveFile > ,
109
+ ) -> CargoResult < FileLock > {
110
+ let gctx = ws. gctx ( ) ;
117
111
let filecount = ar_files. len ( ) ;
118
112
119
- if opts. list {
120
- for ar_file in ar_files {
121
- drop_println ! ( gctx, "{}" , ar_file. rel_str) ;
122
- }
123
-
124
- return Ok ( None ) ;
125
- }
126
-
127
113
// Check that the package dependencies are safe to deploy.
128
114
for dep in pkg. dependencies ( ) {
129
115
super :: check_dep_has_version ( dep, false ) ?;
@@ -145,10 +131,6 @@ pub fn package_one(
145
131
dst. file ( ) . set_len ( 0 ) ?;
146
132
let uncompressed_size = tar ( ws, pkg, ar_files, dst. file ( ) , & filename)
147
133
. with_context ( || "failed to prepare local package for uploading" ) ?;
148
- if opts. verify {
149
- dst. seek ( SeekFrom :: Start ( 0 ) ) ?;
150
- run_verify ( ws, pkg, & dst, opts) . with_context ( || "failed to verify package tarball" ) ?
151
- }
152
134
153
135
dst. seek ( SeekFrom :: Start ( 0 ) ) ?;
154
136
let src_path = dst. path ( ) ;
@@ -172,7 +154,7 @@ pub fn package_one(
172
154
// It doesn't really matter if this fails.
173
155
drop ( gctx. shell ( ) . status ( "Packaged" , message) ) ;
174
156
175
- return Ok ( Some ( dst) ) ;
157
+ return Ok ( dst) ;
176
158
}
177
159
178
160
pub fn package ( ws : & Workspace < ' _ > , opts : & PackageOpts < ' _ > ) -> CargoResult < Option < Vec < FileLock > > > {
@@ -197,25 +179,24 @@ pub fn package(ws: &Workspace<'_>, opts: &PackageOpts<'_>) -> CargoResult<Option
197
179
}
198
180
199
181
for ( pkg, cli_features) in pkgs {
200
- let result = package_one (
201
- ws,
202
- pkg,
203
- & PackageOpts {
204
- gctx : opts. gctx ,
205
- list : opts. list ,
206
- check_metadata : opts. check_metadata ,
207
- allow_dirty : opts. allow_dirty ,
208
- verify : opts. verify ,
209
- jobs : opts. jobs . clone ( ) ,
210
- keep_going : opts. keep_going ,
211
- to_package : ops:: Packages :: Default ,
212
- targets : opts. targets . clone ( ) ,
213
- cli_features : cli_features,
214
- } ,
215
- ) ?;
182
+ let opts = PackageOpts {
183
+ to_package : ops:: Packages :: Default ,
184
+ cli_features,
185
+ ..opts. clone ( )
186
+ } ;
187
+ let ar_files = build_ar_list ( ws, pkg, & opts) ?;
216
188
217
- if !opts. list {
218
- dsts. push ( result. unwrap ( ) ) ;
189
+ if opts. list {
190
+ for ar_file in ar_files {
191
+ drop_println ! ( ws. gctx( ) , "{}" , ar_file. rel_str) ;
192
+ }
193
+ } else {
194
+ let tarball = create_package ( ws, pkg, ar_files) ?;
195
+ if opts. verify {
196
+ run_verify ( ws, pkg, & tarball, & opts)
197
+ . with_context ( || "failed to verify package tarball" ) ?;
198
+ }
199
+ dsts. push ( tarball) ;
219
200
}
220
201
}
221
202
@@ -231,9 +212,33 @@ pub fn package(ws: &Workspace<'_>, opts: &PackageOpts<'_>) -> CargoResult<Option
231
212
fn build_ar_list (
232
213
ws : & Workspace < ' _ > ,
233
214
pkg : & Package ,
234
- src_files : Vec < PathBuf > ,
235
- vcs_info : Option < VcsInfo > ,
215
+ opts : & PackageOpts < ' _ > ,
236
216
) -> CargoResult < Vec < ArchiveFile > > {
217
+ let gctx = ws. gctx ( ) ;
218
+ let mut src = PathSource :: new ( pkg. root ( ) , pkg. package_id ( ) . source_id ( ) , gctx) ;
219
+ src. update ( ) ?;
220
+
221
+ if opts. check_metadata {
222
+ check_metadata ( pkg, gctx) ?;
223
+ }
224
+
225
+ if !pkg. manifest ( ) . exclude ( ) . is_empty ( ) && !pkg. manifest ( ) . include ( ) . is_empty ( ) {
226
+ gctx. shell ( ) . warn (
227
+ "both package.include and package.exclude are specified; \
228
+ the exclude list will be ignored",
229
+ ) ?;
230
+ }
231
+ let src_files = src. list_files ( pkg) ?;
232
+
233
+ // Check (git) repository state, getting the current commit hash if not
234
+ // dirty.
235
+ let vcs_info = if !opts. allow_dirty {
236
+ // This will error if a dirty repo is found.
237
+ check_repo_state ( pkg, & src_files, gctx) ?
238
+ } else {
239
+ None
240
+ } ;
241
+
237
242
let mut result = HashMap :: new ( ) ;
238
243
let root = pkg. root ( ) ;
239
244
0 commit comments