Hi Kristis,
I'm sharing my current cumulative patch on top of scmbug 0.26.17 which we're
using on our environment with Bugzilla 3.6 (final) and 3.4.6.
- Added support for Bugzilla 3.6 version number
- Same fix for status & resolution with Bugzilla 3.2+ (a bit reformatted
and simplified)
- Same fix with eval block around comment adding (a bit reformatted and a
bit simplified as per Max's comments)
- A bit extended revision of my old patch for Bugzilla e-mail notification
(http://bugzilla.mkgnu.net/show_bug.cgi?id=832). I've bee using that since
an year with no problems. Following daemon.conf -- bugtracker parameters
should be added to enable it:
notification_enabled => 1 # bugtracker e-mail notification enabled
changer_notification_enabled => 1 # notify bug changer too
Regards,
Yavor
On Thu, Apr 15, 2010 at 09:24, Yavor Nikolov <[email protected]>wrote:
> Bugzilla does throw exceptions (in a "die" way) on certain places: e.g.
> - on calling Bug::check(), when providing bad user
> - Invalid duplicate bug id
> ... etc.
>
> I.e. - more often Bugzilla throws exception when error is encountered (bad
> parameter, lack of permissions, etc.) than returning an error code. Actually
> - exception handling is in general a cleaner approach to manage error
> situations than dealing with return codes. Just the die/eval/$@/.. is some
> kind of limited workaround since older versions of Perl didn't have
> exceptions.
>
> So what happens if we don't catch these exceptions: scmbug dies, error
> message is logged in scmbug log. However end user gets a general purpose
> error which doesn't explain the root cause of the problem (i.e. user
> receives something like "scmbug died for unknown reason" than duplicate bug
> id is bad; or we don't have permissions to edit the bug).
>
> Regards,
> Yavor
>
>
> On Thu, Apr 15, 2010 at 02:18, Kristis Makris <[email protected]> wrote:
>
>>
>> > If there is a possibility for Bugzilla to raise exceptions
>> > inside the
>> > eval {} blocks, is there another way of eliminating that
>> > possibility ?
>> > I think If we use the WebService API error would be signalled in a bit
>> > different manner. Another approach would be to patch Bugzilla.
>>
>> I suppose my question is, why are we so fearful that something bad will
>> happen that will throw an exception ? Can't we simply check the return
>> values of function calls to see if the calls succeeded ?
>>
>>
>>
>
diff -Naur Scmbug.orig.0.26.17/Daemon/Bugtracker.pm Scmbug.patched.20100418/Daemon/Bugtracker.pm
--- Scmbug.orig.0.26.17/Daemon/Bugtracker.pm 2010-03-26 21:53:38.000000000 +0200
+++ Scmbug.patched.20100418/Daemon/Bugtracker.pm 2010-04-16 23:12:09.000000000 +0300
@@ -115,6 +115,8 @@
$self->username ( $data->{ database_username } );
$self->password ( $data->{ database_password } );
$self->bug_url_prefix ( $data->{ bug_url_prefix } );
+ $self->notification_enabled ( $data->{ notification_enabled } );
+ $self->changer_notification_enabled ( $data->{ changer_notification_enabled } );
}
@@ -294,6 +296,29 @@
}
+sub changer_notification_enabled {
+ my $self = shift;
+ my $data = shift;
+
+ if ( $data ) {
+ $self->{ changer_notification_enabled } = $data;
+ } else {
+ return $self->{ changer_notification_enabled };
+ }
+}
+
+
+sub notification_enabled {
+ my $self = shift;
+ my $data = shift;
+
+ if ( $data ) {
+ $self->{ notification_enabled } = $data;
+ } else {
+ return $self->{ notification_enabled };
+ }
+}
+
sub active_states_list {
my $self = shift;
@@ -633,6 +658,10 @@
return @comment_sets;
}
+#
+# Send notification
+sub integration_send_notification {
+}
1;
diff -Naur Scmbug.orig.0.26.17/Daemon/Bugzilla.pm Scmbug.patched.20100418/Daemon/Bugzilla.pm
--- Scmbug.orig.0.26.17/Daemon/Bugzilla.pm 2010-03-26 21:53:38.000000000 +0200
+++ Scmbug.patched.20100418/Daemon/Bugzilla.pm 2010-04-18 17:44:44.000000000 +0300
@@ -234,6 +234,7 @@
# Must load the Bugzilla package before any of its functions are used.
eval "use Bugzilla";
+ eval "use Bugzilla::BugMail";
}
# This is direct modification to bugzilla's internal variables
@@ -480,7 +481,7 @@
# Thus they function like Bugzilla 3.2
$self->{ version_type } = "up_to_3_1_2";
} elsif ( $major == 3 &&
- ($minor == 2 || $minor == 4)) {
+ ($minor == 2 || $minor == 4 || $minor == 6)) {
$self->{ version_type } = $BUGTRACKER_VERSION_LATEST;
} else {
$self->{ version_type } = $BUGTRACKER_VERSION_NOT_SUPPORTED;
@@ -565,18 +566,27 @@
}
} else {
# Since Bugzilla 3.1.3 AppendComment has been replaced by add_comment
- my $userid = Bugzilla::User::login_to_id( $username );
- if ( $userid > 0 ) {
- my $bug = Bugzilla::Bug->check($bugid);
- my $user = new Bugzilla::User($userid);
- Bugzilla->set_user($user);
- $bug->add_comment($comment, {isprivate => 0, work_time => 0, type => Bugzilla::Constants->CMT_NORMAL, extra_data => ""} );
+
+ my $dbh = Bugzilla->dbh;
+ my @ret_list = eval {
+ my $user = Bugzilla::User->check( $username );
+ Bugzilla->set_user( $user );
+ my $bug = Bugzilla::Bug->check( $bugid );
+ $dbh->bz_start_transaction();
+ $bug->add_comment( $comment );
$bug->update();
- return 0;
- } else {
- # This should never happen. Each user should have a
- # corresponding userid in the database schema
- return 1, "Login '$username' could not be converted to an id in Bugzilla. Is username mapping setup correctly in daemon.conf ?\n" ;
+ $dbh->bz_commit_transaction();
+
+ return 0;
+ }; # eval
+ if ( $@ ) {
+ my $err = $@;
+ log_daemon_warn( undef, $err );
+ $dbh->bz_rollback_transaction() if $dbh->bz_in_transaction();
+ return 1, "Error while adding bug comment: $err";
+ }
+ else {
+ return @ret_list;
}
}
}
@@ -606,7 +616,7 @@
$self->is_version_up_to_2_22() ) {
# Changing bug resolutions is not supported for earlier versions of Bugzilla
return ( 1, "Changing bug resolution is not implemented in this version of Bugzilla.\n");
- } elsif ( $self->is_version_up_to_3_1_2() || $self->is_version_latest() ) {
+ } elsif ( $self->is_version_up_to_3_1_2() ) {
my $privileges_are_required = 0; #Set within check_can_change_field, not used at the moment
my $bug = new Bugzilla::Bug($bugid);
@@ -784,9 +794,90 @@
} else {
return ( 1, "Changing bug resolution for bug '$bugid' wasn't successful. Nothing changed.\n");
}
+ } elsif ( $self->is_version_latest() ) {
+ # Bugzilla 3.2+
+ my $dbh = Bugzilla->dbh;
+
+ # Run in eval block to catch bugzilla exceptions
+ my @ret_list = eval {
+ my $user = Bugzilla::User->check( $username );
+ Bugzilla->set_user( $user );
+ my $bug = Bugzilla::Bug->check( $bugid );
+
+ my $has_changed = 0;
+
+ if( !defined $status ) {
+ $status = "none";
+ } else {
+ $status = lc $status;
+ }
+
+ my $new_status = uc $status; # Default status. May be changed later
+ my $resolution_params = {};
+
+ if ( $status =~ /^none$/ ) {
+ return ( 1, "Undefined status '$status' for bug '$bugid'.\n" );
+ } elsif ( $status =~ /^assigned$/ ) {
+ if ( defined( $resolution ) && ( '' ne $resolution ) ) {
+ # Reassign to given assignee
+ my $assignee_user = new Bugzilla::User( { name => $resolution } );
+ if( !defined( $assignee_user ) ) {
+ return ( 1, "Unknown assignee '$resolution'.\n" );
+ }
+
+ $bug->set_assigned_to( $assignee_user );
+ $new_status = "NEW";
+ } else {
+ # Accepting bug
+ if( $bug->assigned_to->id != $user->id ) {
+ return ( 1, "You cannot accept a bug if you aren't the assignee. Bug '$bugid' is assigned to '" . $bug->assigned_to->login . "'\n" );
+ }
+ }
+
+ $has_changed = 1;
+ } elsif ( $status =~ /^reopened$/ ) {
+ $has_changed = 1;
+ } elsif ( $status =~ /^resolved$/ ) {
+ $resolution = lc $resolution;
+
+ if( $resolution eq "moved" ) {
+ # Should never happen, anyway leave it here
+ return ( 1, "Movement of bugs isn't supported.\n" );
+ }
+ elsif ( $resolution eq "duplicate" ) {
+ $resolution_params->{ dupe_of } = $resolution_data;
+ }
+
+ $resolution_params->{ resolution } = uc $resolution;
+ $has_changed = 1;
+ } else {
+ return ( 1, "Unknown status '$status' for bug '$bugid'.\n" );
+ }
+
+ if( $has_changed == 1 ) {
+ $dbh->bz_start_transaction();
+ $bug->set_status( $new_status, $resolution_params );
+ $bug->update();
+ $dbh->bz_commit_transaction();
+
+ return 0;
+ } else {
+ return ( 1, "Changing bug resolution for bug '$bugid' wasn't successful. Nothing changed.\n" );
+ }
+ }; # eval
+ if ( $@ ) {
+ my $err = $@;
+ log_daemon_warn( undef, $err );
+ $dbh->bz_rollback_transaction() if $dbh->bz_in_transaction();
+ return 1, "Error while changing bug resolution: $err";
+ }
+ else {
+ return @ret_list;
+ }
+
} else {
# Changing bug resolutions is not supported for earlier versions of Bugzilla
- return ( 1, "Changing bug resolution is not yet implemented in this version of Bugzilla.\n");
+ return ( 1, "Changing bug resolution is not yet implemented in this version of Bugzilla.\n" );
}
}
@@ -1586,5 +1677,19 @@
return 1;
}
+#
+# Send notification
+sub integration_send_notification {
+ my $self = shift;
+ my ( $bugid, $vars ) = ( @_ );
+
+ # If vars changer is not defined then changer is also notified (from Bugzilla).
+ if ( $self->changer_notification_enabled ) {
+ $vars = {};
+ }
+
+ return Bugzilla::BugMail::Send( $bugid, $vars );
+}
+
1;
diff -Naur Scmbug.orig.0.26.17/Daemon/Integration.pm Scmbug.patched.20100418/Daemon/Integration.pm
--- Scmbug.orig.0.26.17/Daemon/Integration.pm 2010-03-26 21:53:38.000000000 +0200
+++ Scmbug.patched.20100418/Daemon/Integration.pm 2010-04-16 23:03:03.000000000 +0300
@@ -100,10 +100,30 @@
$self->bugtracker()->integration_disconnect_database();
+ # Trigger mailing.
+ if ( $self->bugtracker()->notification_enabled ) {
+ $self->send_bugtracker_notification_to_all();
+ }
+
return $retval;
}
+#
+# Send bugtracker notifications.
+#
+sub send_bugtracker_notification_to_all {
+ my $self = shift;
+
+ my $vars = {};
+ $vars->{ 'changer' } = $self->request()->{ translated_username };
+ my @bugs = $self->get_all_related_bug_ids();
+
+ foreach my $bugid ( @bugs ) {
+ my $ret_message = $self->bugtracker()->integration_send_notification( $bugid, $vars );
+ # could log result here
+ }
+}
#
# Processes a verify activity
@@ -647,6 +667,23 @@
return ( $matched_owner, $case_sensitive_username_verification_who );
}
+# Get union of all bug id-s and resolution ids
+sub get_all_related_bug_ids {
+ my $self = shift;
+ my @bug_ids = @{ $self->request()->{ ids } };
+ my @res_ids = keys %{ $self->request()->{ resolution_ids } };
+
+ my @res = ();
+ my %res = ();
+
+ foreach my $e ( @bug_ids, @res_ids ) {
+ $res{ $e }++;
+ }
+
+ @res = sort { $a <=> $b } keys %res;
+
+ return @res;
+}
1;
_______________________________________________
scmbug-users mailing list
[email protected]
http://lists.mkgnu.net/cgi-bin/mailman/listinfo/scmbug-users