View | Details | Raw Unified | Return to bug 6473
Collapse All | Expand All

(-)a/lib/GitBz/Commands/Attach.pm (-2 / +129 lines)
Lines 406-413 sub attach_patches { Link Here
406
        # Apply updates with spinner
406
        # Apply updates with spinner
407
        if (%bug_updates) {
407
        if (%bug_updates) {
408
            my $spinner = GitBz::Progress::start_spinner("Updating bug fields");
408
            my $spinner = GitBz::Progress::start_spinner("Updating bug fields");
409
            $bug->apply_updates();
409
410
            GitBz::Progress::stop_spinner( $spinner, 'success', "Bug fields updated" );
410
            my $update_success = eval {
411
                $bug->apply_updates();
412
                1;
413
            };
414
415
            if ($@) {
416
                my $error = $@;
417
                GitBz::Progress::stop_spinner( $spinner, 'error' );
418
419
                # Check if it's a 404 error related to QA contact
420
                if ( exists $bug_updates{qa_contact} && $error =~ /404|not found/i ) {
421
                    print "\n";
422
                    GitBz::Progress::print_error("QA contact '$bug_updates{qa_contact}' not found");
423
424
                    # Iteratively search and retry until success or user cancels
425
                    my $attempted_email = $bug_updates{qa_contact};
426
                    my $retry_success   = 0;
427
428
                    while ( !$retry_success ) {
429
                        # Offer to search for similar users
430
                        my $selected_email = $self->select_qa_contact( $client, $attempted_email );
431
432
                        if ( !$selected_email ) {
433
                            die "Update cancelled by user\n";
434
                        }
435
436
                        # Retry with the selected user
437
                        $bug->set_field( 'qa_contact', $selected_email );
438
                        print "\nRetrying with QA contact: $selected_email\n";
439
                        $spinner = GitBz::Progress::start_spinner("Updating bug fields");
440
441
                        my $retry_eval = eval {
442
                            $bug->apply_updates();
443
                            1;
444
                        };
445
446
                        if ($@) {
447
                            my $retry_error = $@;
448
                            GitBz::Progress::stop_spinner( $spinner, 'error' );
449
450
                            # Check if it's another 404 error
451
                            if ( $retry_error =~ /404|not found/i ) {
452
                                GitBz::Progress::print_error("QA contact '$selected_email' not found");
453
                                $attempted_email = $selected_email;    # Use this as the next search term
454
                                # Loop continues
455
                            } else {
456
                                # Different error, rethrow
457
                                die $retry_error;
458
                            }
459
                        } else {
460
                            # Success!
461
                            GitBz::Progress::stop_spinner( $spinner, 'success', "Bug fields updated" );
462
                            $retry_success = 1;
463
                        }
464
                    }
465
                } else {
466
                    die $error;
467
                }
468
            } else {
469
                GitBz::Progress::stop_spinner( $spinner, 'success', "Bug fields updated" );
470
            }
411
        }
471
        }
412
472
413
        # Perform obsoletes with real-time feedback
473
        # Perform obsoletes with real-time feedback
Lines 659-662 sub parse_bug_updates { Link Here
659
    return ( $bug_comment, \@obsoletes, $bug_updates );
719
    return ( $bug_comment, \@obsoletes, $bug_updates );
660
}
720
}
661
721
722
=head2 select_qa_contact
723
724
    my $email = $attach->select_qa_contact($client, $invalid_email);
725
726
Searches for users matching the invalid email and presents a selection menu.
727
Returns the selected email, or undef if cancelled.
728
729
=cut
730
731
sub select_qa_contact {
732
    my ( $self, $client, $invalid_email ) = @_;
733
734
    # Extract the local part (before @) from the invalid email
735
    my $search_term;
736
    if ( $invalid_email =~ /^([^@]+)@/ ) {
737
        $search_term = $1;
738
    } else {
739
        $search_term = $invalid_email;
740
    }
741
742
    # Search for users whose email begins with the local part
743
    print "\nSearching for similar users (begins with '$search_term')...\n";
744
    my $users = GitBz::Progress::with_spinner(
745
        "Searching users",
746
        sub {
747
            return $client->search_users($search_term);
748
        },
749
        1
750
    );
751
752
    if ( !@$users ) {
753
        print "No similar users found.\n";
754
        print "Would you like to enter a different QA contact? [y/N]: ";
755
        my $response = <STDIN>;
756
        chomp $response;
757
758
        if ( $response =~ /^[yY]/ ) {
759
            print "Enter QA contact email: ";
760
            my $new_email = <STDIN>;
761
            chomp $new_email;
762
            $new_email =~ s/^\s+|\s+$//g;
763
            return $new_email if $new_email;
764
        }
765
766
        return;
767
    }
768
769
    # Present users for selection
770
    print "\nFound " . scalar(@$users) . " similar user(s):\n\n";
771
772
    for my $i ( 0 .. $#$users ) {
773
        my $user = $users->[$i];
774
        my $display_name = $user->{real_name} ? "$user->{real_name} <$user->{email}>" : $user->{email};
775
        print "  [$i] $display_name\n";
776
    }
777
778
    print "\nSelect a user by number, or press Enter to cancel: ";
779
    my $selection = <STDIN>;
780
    chomp $selection;
781
782
    if ( $selection =~ /^\d+$/ && $selection >= 0 && $selection <= $#$users ) {
783
        return $users->[$selection]{email};
784
    }
785
786
    return;
787
}
788
662
1;
789
1;
(-)a/lib/GitBz/Commands/Edit.pm (-3 / +131 lines)
Lines 393-401 sub update_bug { Link Here
393
393
394
        $bug->_display_changes();
394
        $bug->_display_changes();
395
        my $spinner = GitBz::Progress::start_spinner("Updating bug fields");
395
        my $spinner = GitBz::Progress::start_spinner("Updating bug fields");
396
        $bug->apply_updates();
396
397
        GitBz::Progress::stop_spinner( $spinner, 'success', "Bug fields updated" );
397
        my $update_success = eval {
398
        $changed = 1;
398
            $bug->apply_updates();
399
            1;
400
        };
401
402
        if ($@) {
403
            my $error = $@;
404
            GitBz::Progress::stop_spinner( $spinner, 'error' );
405
406
            # Check if it's a 404 error related to QA contact
407
            if ( exists $actual_changes{qa_contact} && $error =~ /404|not found/i ) {
408
                print "\n";
409
                GitBz::Progress::print_error("QA contact '$actual_changes{qa_contact}' not found");
410
411
                # Iteratively search and retry until success or user cancels
412
                my $attempted_email = $actual_changes{qa_contact};
413
                my $retry_success   = 0;
414
415
                while ( !$retry_success ) {
416
                    # Offer to search for similar users
417
                    my $selected_email = $self->select_qa_contact( $client, $attempted_email );
418
419
                    if ( !$selected_email ) {
420
                        die "Update cancelled by user\n";
421
                    }
422
423
                    # Retry with the selected user
424
                    $bug->set_field( 'qa_contact', $selected_email );
425
                    print "\nRetrying with QA contact: $selected_email\n";
426
                    $spinner = GitBz::Progress::start_spinner("Updating bug fields");
427
428
                    my $retry_eval = eval {
429
                        $bug->apply_updates();
430
                        1;
431
                    };
432
433
                    if ($@) {
434
                        my $retry_error = $@;
435
                        GitBz::Progress::stop_spinner( $spinner, 'error' );
436
437
                        # Check if it's another 404 error
438
                        if ( $retry_error =~ /404|not found/i ) {
439
                            GitBz::Progress::print_error("QA contact '$selected_email' not found");
440
                            $attempted_email = $selected_email;    # Use this as the next search term
441
                            # Loop continues
442
                        } else {
443
                            # Different error, rethrow
444
                            die $retry_error;
445
                        }
446
                    } else {
447
                        # Success!
448
                        GitBz::Progress::stop_spinner( $spinner, 'success', "Bug fields updated" );
449
                        $changed       = 1;
450
                        $retry_success = 1;
451
                    }
452
                }
453
            } else {
454
                die $error;
455
            }
456
        } else {
457
            GitBz::Progress::stop_spinner( $spinner, 'success', "Bug fields updated" );
458
            $changed = 1;
459
        }
399
    }
460
    }
400
461
401
    # Handle obsoleting attachments
462
    # Handle obsoleting attachments
Lines 445-448 sub extract_bug_ref { Link Here
445
    return;
506
    return;
446
}
507
}
447
508
509
=head2 select_qa_contact
510
511
    my $email = $edit->select_qa_contact($client, $invalid_email);
512
513
Searches for users matching the invalid email and presents a selection menu.
514
Returns the selected email, or undef if cancelled.
515
516
=cut
517
518
sub select_qa_contact {
519
    my ( $self, $client, $invalid_email ) = @_;
520
521
    # Extract the local part (before @) from the invalid email
522
    my $search_term;
523
    if ( $invalid_email =~ /^([^@]+)@/ ) {
524
        $search_term = $1;
525
    } else {
526
        $search_term = $invalid_email;
527
    }
528
529
    # Search for users whose email begins with the local part
530
    print "\nSearching for similar users (begins with '$search_term')...\n";
531
    my $users = GitBz::Progress::with_spinner(
532
        "Searching users",
533
        sub {
534
            return $client->search_users($search_term);
535
        },
536
        1
537
    );
538
539
    if ( !@$users ) {
540
        print "No similar users found.\n";
541
        print "Would you like to enter a different QA contact? [y/N]: ";
542
        my $response = <STDIN>;
543
        chomp $response;
544
545
        if ( $response =~ /^[yY]/ ) {
546
            print "Enter QA contact email: ";
547
            my $new_email = <STDIN>;
548
            chomp $new_email;
549
            $new_email =~ s/^\s+|\s+$//g;
550
            return $new_email if $new_email;
551
        }
552
553
        return;
554
    }
555
556
    # Present users for selection
557
    print "\nFound " . scalar(@$users) . " similar user(s):\n\n";
558
559
    for my $i ( 0 .. $#$users ) {
560
        my $user = $users->[$i];
561
        my $display_name = $user->{real_name} ? "$user->{real_name} <$user->{email}>" : $user->{email};
562
        print "  [$i] $display_name\n";
563
    }
564
565
    print "\nSelect a user by number, or press Enter to cancel: ";
566
    my $selection = <STDIN>;
567
    chomp $selection;
568
569
    if ( $selection =~ /^\d+$/ && $selection >= 0 && $selection <= $#$users ) {
570
        return $users->[$selection]{email};
571
    }
572
573
    return;
574
}
575
448
1;
576
1;
(-)a/lib/GitBz/RestClient.pm (-2 / +40 lines)
Lines 274-279 sub get_field_values { Link Here
274
    return [];
274
    return [];
275
}
275
}
276
276
277
=head2 search_users
278
279
    my $users = $client->search_users($search_term);
280
281
Searches for users matching the given search term.
282
Returns arrayref of user hashes with 'email', 'real_name', and 'id' keys.
283
284
=cut
285
286
sub search_users {
287
    my ( $self, $search_term ) = @_;
288
289
    return [] unless $search_term;
290
291
    # Get authentication token
292
    my $token = $self->get_token();
293
294
    # Build URL with token for authentication
295
    my $url = sprintf( "%s/user?match=%s", $self->{base_url}, $search_term );
296
    $url .= "&token=$token" if $token;
297
298
    my $response = $self->{ua}->get($url);
299
300
    if ( !$response->is_success ) {
301
        return [];
302
    }
303
304
    my $data = decode_json( $response->content );
305
306
    # Return users array with relevant fields
307
    return [ map {
308
        {
309
            email     => $_->{email},
310
            real_name => $_->{real_name} || '',
311
            id        => $_->{id}
312
        }
313
    } @{ $data->{users} || [] } ];
314
}
315
277
=head2 obsolete_attachment
316
=head2 obsolete_attachment
278
317
279
    $client->obsolete_attachment($attachment_id);
318
    $client->obsolete_attachment($attachment_id);
Lines 353-356 sub get_bug_url { Link Here
353
    return "$web_url/show_bug.cgi?id=$bug_id";
392
    return "$web_url/show_bug.cgi?id=$bug_id";
354
}
393
}
355
394
356
1;
395
1;
357
- 

Return to bug 6473