@@ -141,18 +141,34 @@ pub struct SubmitOptions {
141
141
142
142
/// The result of creating a commit.
143
143
#[ derive( Clone , Debug ) ]
144
- pub struct CreateStatus {
145
- /// The commit OID after carrying out the creation process. Usually, this
146
- /// will be the same as the original commit OID, unless the forge amends it
147
- /// (e.g. to include a change ID).
148
- pub final_commit_oid : NonZeroOid ,
149
-
150
- /// An identifier corresponding to the commit, for display purposes only.
151
- /// This may be a branch name, a change ID, the commit summary, etc.
152
- ///
153
- /// This does not necessarily correspond to the commit's name/identifier in
154
- /// the forge (e.g. not a code review link).
155
- pub local_commit_name : String ,
144
+ pub enum CreateStatus {
145
+ /// The commit was successfully created.
146
+ Created {
147
+ /// The commit OID after carrying out the creation process. Usually, this
148
+ /// will be the same as the original commit OID, unless the forge amends it
149
+ /// (e.g. to include a change ID).
150
+ final_commit_oid : NonZeroOid ,
151
+
152
+ /// An identifier corresponding to the commit, for display purposes only.
153
+ /// This may be a branch name, a change ID, the commit summary, etc.
154
+ ///
155
+ /// This does not necessarily correspond to the commit's name/identifier in
156
+ /// the forge (e.g. not a code review link).
157
+ local_commit_name : String ,
158
+ } ,
159
+
160
+ /// The commit was skipped. This could happen if a previous commit could not
161
+ /// be created due to an error.
162
+ Skipped {
163
+ /// The commit which was skipped.
164
+ commit_oid : NonZeroOid ,
165
+ } ,
166
+
167
+ /// The commit could not be created due to an error.
168
+ Err {
169
+ /// The commit which produced an error.
170
+ commit_oid : NonZeroOid ,
171
+ } ,
156
172
}
157
173
158
174
/// "Forge" refers to a Git hosting provider, such as GitHub, GitLab, etc.
@@ -370,30 +386,49 @@ fn submit(
370
386
( local, unsubmitted, to_update, to_skip)
371
387
} ) ;
372
388
373
- let ( submitted_commit_names, unsubmitted_commit_names) : ( BTreeSet < String > , BTreeSet < String > ) = {
389
+ let ( submitted_commit_names, unsubmitted_commit_names, create_error_commits) : (
390
+ BTreeSet < String > ,
391
+ BTreeSet < String > ,
392
+ BTreeSet < NonZeroOid > ,
393
+ ) = {
374
394
let unsubmitted_commit_names: BTreeSet < String > = unsubmitted_commits
375
395
. values ( )
376
396
. flat_map ( |commit_status| commit_status. local_commit_name . clone ( ) )
377
397
. collect ( ) ;
378
398
if create {
379
- let created_commit_names = if dry_run {
380
- unsubmitted_commit_names. clone ( )
399
+ let ( created_commit_names, error_commits ) = if dry_run {
400
+ ( unsubmitted_commit_names. clone ( ) , Default :: default ( ) )
381
401
} else {
382
402
let create_statuses =
383
403
try_exit_code ! ( forge. create( unsubmitted_commits, & submit_options) ?) ;
384
- create_statuses
385
- . into_values ( )
386
- . map (
387
- |CreateStatus {
388
- final_commit_oid : _,
389
- local_commit_name,
390
- } | local_commit_name,
391
- )
392
- . collect ( )
404
+ let mut created_commit_names = BTreeSet :: new ( ) ;
405
+ let mut error_commits = BTreeSet :: new ( ) ;
406
+ for ( _commit_oid, create_status) in create_statuses {
407
+ match create_status {
408
+ CreateStatus :: Created {
409
+ final_commit_oid : _,
410
+ local_commit_name,
411
+ } => {
412
+ created_commit_names. insert ( local_commit_name) ;
413
+ }
414
+ // For now, treat `Skipped` the same as `Err` as it would be
415
+ // a lot of work to render it differently in the output, and
416
+ // we may want to rethink the data structures before doing
417
+ // that.
418
+ CreateStatus :: Skipped { commit_oid } | CreateStatus :: Err { commit_oid } => {
419
+ error_commits. insert ( commit_oid) ;
420
+ }
421
+ }
422
+ }
423
+ ( created_commit_names, error_commits)
393
424
} ;
394
- ( created_commit_names, Default :: default ( ) )
425
+ ( created_commit_names, Default :: default ( ) , error_commits )
395
426
} else {
396
- ( Default :: default ( ) , unsubmitted_commit_names)
427
+ (
428
+ Default :: default ( ) ,
429
+ unsubmitted_commit_names,
430
+ Default :: default ( ) ,
431
+ )
397
432
}
398
433
} ;
399
434
@@ -513,8 +548,30 @@ repository. To submit them, retry this operation with the --create option.",
513
548
if dry_run { "are" } else { "were" } ,
514
549
) ?;
515
550
}
516
-
517
- Ok ( Ok ( ( ) ) )
551
+ if !create_error_commits. is_empty ( ) {
552
+ writeln ! (
553
+ effects. get_output_stream( ) ,
554
+ "Failed to create {}:" ,
555
+ Pluralize {
556
+ determiner: None ,
557
+ amount: create_error_commits. len( ) ,
558
+ unit: ( "commit" , "commits" )
559
+ } ,
560
+ ) ?;
561
+ for error_commit_oid in & create_error_commits {
562
+ let error_commit = repo. find_commit_or_fail ( * error_commit_oid) ?;
563
+ writeln ! (
564
+ effects. get_output_stream( ) ,
565
+ "{}" ,
566
+ effects
567
+ . get_glyphs( )
568
+ . render( error_commit. friendly_describe( effects. get_glyphs( ) ) ?) ?
569
+ ) ?;
570
+ }
571
+ Ok ( Err ( ExitCode ( 1 ) ) )
572
+ } else {
573
+ Ok ( Ok ( ( ) ) )
574
+ }
518
575
}
519
576
520
577
#[ instrument]
0 commit comments