@@ -40,8 +40,16 @@ pub fn cargo_fetch(curdir: &Path, manifest: &str, respect_lockfile: bool) -> io:
40
40
info ! ( "⤵️ Running `cargo fetch`..." ) ;
41
41
let mut default_options: Vec < String > = vec ! [ ] ;
42
42
let manifest_path = PathBuf :: from ( & manifest) ;
43
- let manifest_path_parent = manifest_path. parent ( ) . unwrap_or ( curdir) ;
44
- let possible_lockfile = manifest_path_parent. join ( "Cargo.lock" ) ;
43
+ if !manifest_path. is_file ( ) {
44
+ let msg = format ! (
45
+ "There seems to be no manifest at this path `{}`." ,
46
+ manifest_path. display( )
47
+ ) ;
48
+ error ! ( msg, ?manifest_path) ;
49
+ return Err ( io:: Error :: new ( io:: ErrorKind :: NotFound , msg) ) ;
50
+ }
51
+ let manifest_path_parent = manifest_path. parent ( ) . unwrap_or ( curdir) . canonicalize ( ) ?;
52
+ let possible_lockfile = manifest_path_parent. join ( "Cargo.lock" ) . canonicalize ( ) ?;
45
53
if possible_lockfile. is_file ( ) {
46
54
if respect_lockfile {
47
55
default_options. push ( "--locked" . to_string ( ) ) ;
@@ -51,10 +59,6 @@ pub fn cargo_fetch(curdir: &Path, manifest: &str, respect_lockfile: bool) -> io:
51
59
cargo_generate_lockfile ( curdir, manifest) ?;
52
60
info ! ( "🔒Regenerated lockfile." ) ;
53
61
}
54
- if !manifest. is_empty ( ) {
55
- default_options. push ( "--manifest-path" . to_string ( ) ) ;
56
- default_options. push ( manifest. to_string ( ) ) ;
57
- }
58
62
TARGET_TRIPLES . iter ( ) . for_each ( |target| {
59
63
default_options. push ( "--target" . to_string ( ) ) ;
60
64
default_options. push ( target. to_string ( ) ) ;
@@ -109,13 +113,20 @@ pub fn cargo_vendor(
109
113
) ) ;
110
114
}
111
115
} else {
112
- return Err ( io:: Error :: new (
113
- io:: ErrorKind :: NotFound ,
114
- "Failed to vendor as their are no manifest files to use." ,
115
- ) ) ;
116
+ let msg = "Failed to vendor as their are no manifest files to use." ;
117
+ error ! ( msg, ?manifest_paths) ;
118
+ return Err ( io:: Error :: new ( io:: ErrorKind :: NotFound , msg) ) ;
116
119
} ;
120
+ } else {
121
+ let msg = format ! (
122
+ "There seems to be no manifest at this path `{}`." ,
123
+ first_manifest. display( )
124
+ ) ;
125
+ error ! ( msg, ?first_manifest) ;
126
+ return Err ( io:: Error :: new ( io:: ErrorKind :: NotFound , msg) ) ;
117
127
}
118
- let first_manifest_parent = first_manifest. parent ( ) . unwrap_or ( curdir) ;
128
+
129
+ let first_manifest_parent = first_manifest. parent ( ) . unwrap_or ( curdir) . canonicalize ( ) ?;
119
130
let possible_lockfile = first_manifest_parent. join ( "Cargo.lock" ) ;
120
131
let is_manifest_workspace = is_workspace ( & first_manifest) ?;
121
132
let has_deps = has_dependencies ( & first_manifest) ?;
@@ -174,7 +185,7 @@ pub fn cargo_vendor(
174
185
false to true."
175
186
) ;
176
187
info ! ( "🔓Attempting to regenerate lockfile..." ) ;
177
- cargo_generate_lockfile ( curdir , & first_manifest. to_string_lossy ( ) ) ?;
188
+ cargo_generate_lockfile ( & first_manifest_parent , & first_manifest. to_string_lossy ( ) ) ?;
178
189
info ! ( "🔒Regenerated lockfile." ) ;
179
190
}
180
191
@@ -194,21 +205,23 @@ pub fn cargo_vendor(
194
205
if !update {
195
206
warn ! ( "😥 Disabled update of dependencies. You should enable this for security updates." ) ;
196
207
}
208
+
197
209
cargo_update (
198
210
update,
199
211
crates,
200
- curdir ,
212
+ & first_manifest_parent ,
201
213
& first_manifest. to_string_lossy ( ) ,
202
214
respect_lockfile,
203
215
) ?;
216
+
204
217
info ! ( "🚝 Attempting to fetch dependencies." ) ;
205
218
cargo_fetch ( curdir, & first_manifest. to_string_lossy ( ) , respect_lockfile) ?;
206
219
info ! ( "💼 Fetched dependencies." ) ;
207
220
208
221
// NOTE: Vendor filterer's default output format is directory so we
209
222
// don't need to set that ourselves.
210
223
info ! ( "🏪 Running `cargo {}`..." , & which_subcommand) ;
211
- let res = cargo_command ( which_subcommand, & default_options, curdir ) ;
224
+ let res = cargo_command ( which_subcommand, & default_options, first_manifest_parent ) ;
212
225
213
226
if possible_lockfile. is_file ( ) {
214
227
info ! ( ?possible_lockfile, "🔓 Adding lockfile." ) ;
@@ -223,10 +236,12 @@ pub fn cargo_vendor(
223
236
} ) ?;
224
237
}
225
238
info ! ( "🛡️🙂 All lockfiles are audited" ) ;
239
+
226
240
if !global_has_deps {
227
241
info ! ( "🎉 Nothing to vendor." ) ;
228
242
return Ok ( None ) ;
229
243
}
244
+
230
245
match res {
231
246
Ok ( output_cargo_configuration) => {
232
247
info ! ( "🏪 `cargo {}` finished." , & which_subcommand) ;
@@ -289,9 +304,9 @@ pub fn cargo_update(
289
304
let mut default_options = vec ! [ ] ;
290
305
if global_update {
291
306
info ! ( "⏫ Updating dependencies..." ) ;
292
- let manifest_path = PathBuf :: from ( & manifest) ;
307
+ let manifest_path = PathBuf :: from ( & manifest) . canonicalize ( ) ? ;
293
308
let manifest_path_parent = manifest_path. parent ( ) . unwrap_or ( curdir) ;
294
- let possible_lockfile = manifest_path_parent. join ( "Cargo.lock" ) ;
309
+ let possible_lockfile = manifest_path_parent. join ( "Cargo.lock" ) . canonicalize ( ) ? ;
295
310
if !manifest. is_empty ( ) {
296
311
default_options. push ( "--manifest-path" . to_string ( ) ) ;
297
312
default_options. push ( manifest. to_string ( ) ) ;
@@ -311,55 +326,123 @@ pub fn cargo_update(
311
326
// and user might have specified specific crates to update
312
327
if !crates. is_empty ( ) {
313
328
for crate_ in crates. iter ( ) {
314
- if let Some ( ( crate_name, crate_ver) ) = crate_. split_once ( "@" ) {
329
+ let mut new_cur_dir = curdir. to_path_buf ( ) ;
330
+ if let Some ( ( crate_name, string_tail) ) = crate_. split_once ( "@" ) {
315
331
default_options. push ( crate_name. to_string ( ) ) ;
316
- if !crate_ver. trim ( ) . is_empty ( ) {
317
- if * crate_ver == * "recursive" {
318
- info ! (
319
- "📦🔄 Applying recursive update for crate dependency {}" ,
320
- crate_name
321
- ) ;
322
- default_options. push ( "--recursive" . to_string ( ) ) ;
323
- } else if semver:: Version :: parse ( crate_ver)
324
- . map_err ( |err| {
325
- error ! ( ?err) ;
326
- let msg = format ! ( "Expected a valid version string. Got {}" , crate_ver) ;
327
- io:: Error :: new ( io:: ErrorKind :: InvalidInput , msg)
328
- } )
329
- . is_ok ( )
330
- {
331
- info ! (
332
+ if let Some ( ( crate_ver, dependent) ) = string_tail. split_once ( "+" ) {
333
+ if !crate_ver. trim ( ) . is_empty ( ) {
334
+ if * crate_ver == * "recursive" {
335
+ info ! (
336
+ "📦🔄 Applying recursive update for crate dependency {}" ,
337
+ crate_name
338
+ ) ;
339
+ default_options. push ( "--recursive" . to_string ( ) ) ;
340
+ } else if semver:: Version :: parse ( crate_ver)
341
+ . map_err ( |err| {
342
+ error ! ( ?err) ;
343
+ let msg =
344
+ format ! ( "Expected a valid version string. Got {}" , crate_ver) ;
345
+ io:: Error :: new ( io:: ErrorKind :: InvalidInput , msg)
346
+ } )
347
+ . is_ok ( )
348
+ {
349
+ info ! (
332
350
"📦🥄 Applying precise update for crate dependency {} to version {}" ,
333
351
crate_name, crate_ver
334
352
) ;
335
- default_options. push ( "--precise" . to_string ( ) ) ;
336
- default_options. push ( crate_ver. to_string ( ) ) ;
337
- } else {
338
- let msg = format ! (
339
- "Expected a valid `cargo update` option for {}. Got {}" ,
353
+ default_options. push ( "--precise" . to_string ( ) ) ;
354
+ default_options. push ( crate_ver. to_string ( ) ) ;
355
+ } else {
356
+ let msg = format ! (
357
+ "Expected a valid `cargo update` option for {}. Got {}" ,
358
+ crate_name, crate_ver
359
+ ) ;
360
+ return Err ( io:: Error :: new ( io:: ErrorKind :: InvalidInput , msg) ) ;
361
+ }
362
+ }
363
+
364
+ if !dependent. trim ( ) . is_empty ( ) {
365
+ info ! ( "🏗️ Updating {} at {}." , crate_name, dependent) ;
366
+ let dependent_manifest_path = curdir. join ( dependent) . canonicalize ( ) ?;
367
+ default_options. push ( "--manifest-path" . to_string ( ) ) ;
368
+ default_options. push ( dependent_manifest_path. to_string_lossy ( ) . to_string ( ) ) ;
369
+ let manifest_path_parent =
370
+ dependent_manifest_path. parent ( ) . unwrap_or ( curdir) ;
371
+ new_cur_dir = manifest_path_parent. to_path_buf ( ) ;
372
+ let possible_lockfile = manifest_path_parent. join ( "Cargo.lock" ) ;
373
+ if possible_lockfile. is_file ( ) && respect_lockfile {
374
+ default_options. push ( "--locked" . to_string ( ) ) ;
375
+ }
376
+ }
377
+ }
378
+ // NOTE: `+` can be first then `@` second.
379
+ } else if let Some ( ( crate_name, string_tail) ) = crate_. split_once ( "+" ) {
380
+ default_options. push ( crate_name. to_string ( ) ) ;
381
+ if let Some ( ( dependent, crate_ver) ) = string_tail. split_once ( "@" ) {
382
+ if !crate_ver. trim ( ) . is_empty ( ) {
383
+ if * crate_ver == * "recursive" {
384
+ info ! (
385
+ "📦🔄 Applying recursive update for crate dependency {}" ,
386
+ crate_name
387
+ ) ;
388
+ default_options. push ( "--recursive" . to_string ( ) ) ;
389
+ } else if semver:: Version :: parse ( crate_ver)
390
+ . map_err ( |err| {
391
+ error ! ( ?err) ;
392
+ let msg =
393
+ format ! ( "Expected a valid version string. Got {}" , crate_ver) ;
394
+ io:: Error :: new ( io:: ErrorKind :: InvalidInput , msg)
395
+ } )
396
+ . is_ok ( )
397
+ {
398
+ info ! (
399
+ "📦🥄 Applying precise update for crate dependency {} to version {}" ,
340
400
crate_name, crate_ver
341
401
) ;
342
- return Err ( io:: Error :: new ( io:: ErrorKind :: InvalidInput , msg) ) ;
402
+ default_options. push ( "--precise" . to_string ( ) ) ;
403
+ default_options. push ( crate_ver. to_string ( ) ) ;
404
+ } else {
405
+ let msg = format ! (
406
+ "Expected a valid `cargo update` option for {}. Got {}" ,
407
+ crate_name, crate_ver
408
+ ) ;
409
+ return Err ( io:: Error :: new ( io:: ErrorKind :: InvalidInput , msg) ) ;
410
+ }
411
+ }
412
+
413
+ if !dependent. trim ( ) . is_empty ( ) {
414
+ info ! ( "🏗️ Updating {} at {}." , crate_name, dependent) ;
415
+ let dependent_manifest_path = curdir. join ( dependent) . canonicalize ( ) ?;
416
+ default_options. push ( "--manifest-path" . to_string ( ) ) ;
417
+ default_options. push ( dependent_manifest_path. to_string_lossy ( ) . to_string ( ) ) ;
418
+ let manifest_path_parent =
419
+ dependent_manifest_path. parent ( ) . unwrap_or ( curdir) ;
420
+ let possible_lockfile = manifest_path_parent. join ( "Cargo.lock" ) ;
421
+ new_cur_dir = manifest_path_parent. to_path_buf ( ) ;
422
+ if possible_lockfile. is_file ( ) && respect_lockfile {
423
+ default_options. push ( "--locked" . to_string ( ) ) ;
424
+ }
343
425
}
344
426
}
345
427
}
428
+ cargo_command ( "update" , & default_options, new_cur_dir)
429
+ . inspect ( |_| {
430
+ info ! ( "✅ Updated dependencies." ) ;
431
+ } )
432
+ . inspect_err ( |err| {
433
+ error ! ( ?err) ;
434
+ // There is no point of handling error if a PKGID or crate does not exist for a particular manifest path
435
+ // because at the end of the day, if two manifest paths do have the same crate that was specified to update
436
+ // then the one in the registry or vendor gets updated with the same version as well.
437
+ // NOTE: Maybe in the future we can add ways to be specific on each manifest path
438
+ warn ! ( "This error will be ignored." ) ;
439
+ } ) ?;
346
440
}
347
- let _ = cargo_command ( "update" , & default_options, curdir)
348
- . inspect ( |_| {
349
- info ! ( "✅ Updated dependencies." ) ;
350
- } )
351
- . inspect_err ( |err| {
352
- error ! ( ?err) ;
353
- // There is no point of handling error if a PKGID or crate does not exist for a particular manifest path
354
- // because at the end of the day, if two manifest paths do have the same crate that was specified to update
355
- // then the one in the registry or vendor gets updated with the same version as well.
356
- // NOTE: Maybe in the future we can add ways to be specific on each manifest path
357
- warn ! ( "This error will be ignored." ) ;
358
- } ) ;
359
- Ok ( "" . to_string ( ) )
441
+ let success_msg = "ℹ️ Finished updating specified crate dependencies." . to_string ( ) ;
442
+ Ok ( success_msg)
360
443
} else {
361
444
let msg = "🫠 Nothing to update." . to_string ( ) ;
362
445
info ! ( "{}" , & msg) ;
363
- Ok ( msg)
446
+ return Ok ( msg) ;
364
447
}
365
448
}
0 commit comments