summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorByron Jones <glob@mozilla.com>2014-06-10 07:47:32 +0200
committerByron Jones <glob@mozilla.com>2014-06-10 07:47:46 +0200
commitd9b38fd554ae02a645746c13d1f2ca5d743026f3 (patch)
tree628f2e58ef18f86fb9f943c11aeecce271748f5e
parentf0cab2479e25ab0ed36a8bf256406d80b21ddb19 (diff)
downloadbugzilla-d9b38fd554ae02a645746c13d1f2ca5d743026f3.tar.gz
bugzilla-d9b38fd554ae02a645746c13d1f2ca5d743026f3.tar.xz
Bug 1022500: cloning a firefox tracking flags throws "The component named 'Template::Document=HASH(0x7f7ffacdb4c8)' does not exist. "
-rwxr-xr-xcontrib/reorg-tools/movecomponent.pl176
-rw-r--r--extensions/ComponentWatching/Extension.pm61
-rw-r--r--extensions/ComponentWatching/template/en/default/hook/admin/sanitycheck/messages-statuses.html.tmpl23
-rw-r--r--extensions/TrackingFlags/Extension.pm61
-rw-r--r--extensions/TrackingFlags/lib/Admin.pm5
-rw-r--r--extensions/TrackingFlags/template/en/default/hook/admin/sanitycheck/messages-statuses.html.tmpl23
-rw-r--r--extensions/TrackingFlags/template/en/default/hook/global/code-error-errors.html.tmpl3
7 files changed, 232 insertions, 120 deletions
diff --git a/contrib/reorg-tools/movecomponent.pl b/contrib/reorg-tools/movecomponent.pl
index 162942627..bdbfdc976 100755
--- a/contrib/reorg-tools/movecomponent.pl
+++ b/contrib/reorg-tools/movecomponent.pl
@@ -1,46 +1,29 @@
#!/usr/bin/perl -w
-# -*- Mode: perl; indent-tabs-mode: nil -*-
-#
-# The contents of this file are subject to the Mozilla Public
-# License Version 1.1 (the "License"); you may not use this file
-# except in compliance with the License. You may obtain a copy of
-# the License at http://www.mozilla.org/MPL/
-#
-# Software distributed under the License is distributed on an "AS
-# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
-# implied. See the License for the specific language governing
-# rights and limitations under the License.
-#
-# The Original Code is the Bugzilla Bug Tracking System.
-#
-# The Initial Developer of the Original Code is Netscape Communications
-# Corporation. Portions created by Netscape are
-# Copyright (C) 1998 Netscape Communications Corporation. All
-# Rights Reserved.
-#
-# Contributor(s): Gervase Markham <gerv@gerv.net>
-
-# See also https://bugzilla.mozilla.org/show_bug.cgi?id=119569
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
#
+# This Source Code Form is "Incompatible With Secondary Licenses", as
+# defined by the Mozilla Public License, v. 2.0.
use strict;
-use Cwd 'abs_path';
-use File::Basename;
-BEGIN {
- my $root = abs_path(dirname(__FILE__) . '/../..');
- chdir($root);
-}
-use lib qw(. lib);
+use FindBin '$RealBin';
+use lib "$RealBin/../..", "$RealBin/../../lib";
use Bugzilla;
+use Bugzilla::Component;
use Bugzilla::Constants;
+use Bugzilla::Field;
use Bugzilla::Hook;
+use Bugzilla::Product;
use Bugzilla::Util;
-sub usage() {
- print <<USAGE;
-Usage: movecomponent.pl <oldproduct> <newproduct> <component> <doit>
+Bugzilla->usage_mode(USAGE_MODE_CMDLINE);
+
+if (scalar @ARGV < 3) {
+ die <<USAGE;
+Usage: movecomponent.pl <oldproduct> <newproduct> <component>
E.g.: movecomponent.pl ReplicationEngine FoodReplicator SeaMonkey
will move the component "SeaMonkey" from the product "ReplicationEngine"
@@ -49,71 +32,26 @@ to the product "FoodReplicator".
Important: You must make sure the milestones and versions of the bugs in the
component are available in the new product. See syncmsandversions.pl.
-Pass in a true value for "doit" to make the database changes permament.
USAGE
-
- exit(1);
-}
-
-#############################################################################
-# MAIN CODE
-#############################################################################
-
-# This is a pure command line script.
-Bugzilla->usage_mode(USAGE_MODE_CMDLINE);
-
-if (scalar @ARGV < 3) {
- usage();
- exit();
}
-my ($oldproduct, $newproduct, $component, $doit) = @ARGV;
+my ($old_product_name, $new_product_name, $component_name) = @ARGV;
+my $old_product = Bugzilla::Product->check({ name => $old_product_name });
+my $new_product = Bugzilla::Product->check({ name => $new_product_name });
+my $component = Bugzilla::Component->check({ product => $old_product, name => $component_name });
+my $field_id = get_field_id('product');
my $dbh = Bugzilla->dbh;
-$dbh->{'AutoCommit'} = 0 unless $doit; # Turn off autocommit by default
-
-# Find product IDs
-my $oldprodid = $dbh->selectrow_array("SELECT id FROM products WHERE name = ?",
- undef, $oldproduct);
-if (!$oldprodid) {
- print "Can't find product ID for '$oldproduct'.\n";
- exit(1);
-}
-
-my $newprodid = $dbh->selectrow_array("SELECT id FROM products WHERE name = ?",
- undef, $newproduct);
-if (!$newprodid) {
- print "Can't find product ID for '$newproduct'.\n";
- exit(1);
-}
-
-# Find component ID
-my $compid = $dbh->selectrow_array("SELECT id FROM components
- WHERE name = ? AND product_id = ?",
- undef, $component, $oldprodid);
-if (!$compid) {
- print "Can't find component ID for '$component' in product " .
- "'$oldproduct'.\n";
- exit(1);
-}
-
-my $fieldid = $dbh->selectrow_array("SELECT id FROM fielddefs
- WHERE name = 'product'");
-if (!$fieldid) {
- print "Can't find field ID for 'product' field!\n";
- exit(1);
-}
-
# check versions
my @missing_versions;
my $ra_versions = $dbh->selectcol_arrayref(
"SELECT DISTINCT version FROM bugs WHERE component_id = ?",
- undef, $compid);
+ undef, $component->id);
foreach my $version (@$ra_versions) {
my $has_version = $dbh->selectrow_array(
"SELECT 1 FROM versions WHERE product_id = ? AND value = ?",
- undef, $newprodid, $version);
+ undef, $new_product->id, $version);
push @missing_versions, $version unless $has_version;
}
@@ -121,85 +59,87 @@ foreach my $version (@$ra_versions) {
my @missing_milestones;
my $ra_milestones = $dbh->selectcol_arrayref(
"SELECT DISTINCT target_milestone FROM bugs WHERE component_id = ?",
- undef, $compid);
+ undef, $component->id);
foreach my $milestone (@$ra_milestones) {
my $has_milestone = $dbh->selectrow_array(
"SELECT 1 FROM milestones WHERE product_id=? AND value=?",
- undef, $newprodid, $milestone);
+ undef, $new_product->id, $milestone);
push @missing_milestones, $milestone unless $has_milestone;
}
my $missing_error = '';
if (@missing_versions) {
- $missing_error .= "'$newproduct' is missing the following version(s):\n " .
+ $missing_error .= "'$new_product_name' is missing the following version(s):\n " .
join("\n ", @missing_versions) . "\n";
}
if (@missing_milestones) {
- $missing_error .= "'$newproduct' is missing the following milestone(s):\n " .
+ $missing_error .= "'$new_product_name' is missing the following milestone(s):\n " .
join("\n ", @missing_milestones) . "\n";
}
die $missing_error if $missing_error;
# confirmation
print <<EOF;
-About to move the component '$component'
-From '$oldproduct'
-To '$newproduct'
+About to move the component '$component_name'
+From '$old_product_name'
+To '$new_product_name'
Press <Ctrl-C> to stop or <Enter> to continue...
EOF
getc();
-print "Moving '$component' from '$oldproduct' to '$newproduct'...\n\n";
-$dbh->bz_start_transaction() if $doit;
+print "Moving '$component_name' from '$old_product_name' to '$new_product_name'...\n\n";
+$dbh->bz_start_transaction();
my $ra_ids = $dbh->selectcol_arrayref(
"SELECT bug_id FROM bugs WHERE product_id=? AND component_id=?",
- undef, $oldprodid, $compid);
+ undef, $old_product->id, $component->id);
# Bugs table
-$dbh->do("UPDATE bugs SET product_id = ? WHERE component_id = ?",
+$dbh->do("UPDATE bugs SET product_id = ? WHERE component_id = ?",
undef,
- ($newprodid, $compid));
+ ($new_product->id, $component->id));
# Flags tables
-$dbh->do("UPDATE flaginclusions SET product_id = ? WHERE component_id = ?",
+$dbh->do("UPDATE flaginclusions SET product_id = ? WHERE component_id = ?",
undef,
- ($newprodid, $compid));
+ ($new_product->id, $component->id));
-$dbh->do("UPDATE flagexclusions SET product_id = ? WHERE component_id = ?",
+$dbh->do("UPDATE flagexclusions SET product_id = ? WHERE component_id = ?",
undef,
- ($newprodid, $compid));
+ ($new_product->id, $component->id));
# Components
-$dbh->do("UPDATE components SET product_id = ? WHERE id = ?",
+$dbh->do("UPDATE components SET product_id = ? WHERE id = ?",
undef,
- ($newprodid, $compid));
+ ($new_product->id, $component->id));
+
+Bugzilla::Hook::process('reorg_move_component', {
+ old_product => $old_product,
+ new_product => $new_product,
+ component => $component,
+} );
# Mark bugs as touched
-$dbh->do("UPDATE bugs SET delta_ts = NOW()
- WHERE component_id = ?", undef, $compid);
-$dbh->do("UPDATE bugs SET lastdiffed = NOW()
- WHERE component_id = ?", undef, $compid);
+$dbh->do("UPDATE bugs SET delta_ts = NOW()
+ WHERE component_id = ?", undef, $component->id);
+$dbh->do("UPDATE bugs SET lastdiffed = NOW()
+ WHERE component_id = ?", undef, $component->id);
# Update bugs_activity
my $userid = 1; # nobody@mozilla.org
$dbh->do("INSERT INTO bugs_activity(bug_id, who, bug_when, fieldid, removed,
- added)
- SELECT bug_id, ?, delta_ts, ?, ?, ?
+ added)
+ SELECT bug_id, ?, delta_ts, ?, ?, ?
FROM bugs WHERE component_id = ?",
undef,
- ($userid, $fieldid, $oldproduct, $newproduct, $compid));
+ ($userid, $field_id, $old_product_name, $new_product_name, $component->id));
-Bugzilla::Hook::process('reorg_move_bugs', { bug_ids => $ra_ids } ) if $doit;
-
-if ($doit) {
- $dbh->bz_commit_transaction();
-
- # It's complex to determine which items now need to be flushed from memcached.
- # As this is expected to be a rare event, we just flush the entire cache.
- Bugzilla->memcached->clear_all();
-}
+Bugzilla::Hook::process('reorg_move_bugs', { bug_ids => $ra_ids } );
+$dbh->bz_commit_transaction();
+# It's complex to determine which items now need to be flushed from memcached.
+# As this is expected to be a rare event, we just flush the entire cache.
+Bugzilla->memcached->clear_all();
diff --git a/extensions/ComponentWatching/Extension.pm b/extensions/ComponentWatching/Extension.pm
index addbaba70..f85e0010c 100644
--- a/extensions/ComponentWatching/Extension.pm
+++ b/extensions/ComponentWatching/Extension.pm
@@ -530,4 +530,65 @@ sub _addDefaultSettings {
}
}
+sub reorg_move_component {
+ my ($self, $args) = @_;
+ my $new_product = $args->{new_product};
+ my $component = $args->{component};
+
+ Bugzilla->dbh->do(
+ "UPDATE component_watch SET product_id=? WHERE component_id=?",
+ undef,
+ $new_product->id, $component->id,
+ );
+}
+
+sub sanitycheck_check {
+ my ($self, $args) = @_;
+ my $status = $args->{status};
+
+ $status->('component_watching_check');
+
+ my ($count) = Bugzilla->dbh->selectrow_array("
+ SELECT COUNT(*)
+ FROM component_watch
+ INNER JOIN components ON components.id = component_watch.component_id
+ WHERE component_watch.product_id <> components.product_id
+ ");
+ if ($count) {
+ $status->('component_watching_alert', undef, 'alert');
+ $status->('component_watching_repair');
+ }
+}
+
+sub sanitycheck_repair {
+ my ($self, $args) = @_;
+ return unless Bugzilla->cgi->param('component_watching_repair');
+
+ my $status = $args->{'status'};
+ my $dbh = Bugzilla->dbh;
+ $status->('component_watching_repairing');
+
+ my $rows = $dbh->selectall_arrayref("
+ SELECT DISTINCT component_watch.product_id AS bad_product_id,
+ components.product_id AS good_product_id,
+ component_watch.component_id
+ FROM component_watch
+ INNER JOIN components ON components.id = component_watch.component_id
+ WHERE component_watch.product_id <> components.product_id
+ ",
+ { Slice => {} }
+ );
+ foreach my $row (@$rows) {
+ $dbh->do("
+ UPDATE component_watch
+ SET product_id=?
+ WHERE product_id=? AND component_id=?
+ ", undef,
+ $row->{good_product_id},
+ $row->{bad_product_id},
+ $row->{component_id},
+ );
+ }
+}
+
__PACKAGE__->NAME;
diff --git a/extensions/ComponentWatching/template/en/default/hook/admin/sanitycheck/messages-statuses.html.tmpl b/extensions/ComponentWatching/template/en/default/hook/admin/sanitycheck/messages-statuses.html.tmpl
new file mode 100644
index 000000000..c22ffacaa
--- /dev/null
+++ b/extensions/ComponentWatching/template/en/default/hook/admin/sanitycheck/messages-statuses.html.tmpl
@@ -0,0 +1,23 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+
+[% IF san_tag == "component_watching_repair" %]
+ <a href="sanitycheck.cgi?component_watching_repair=1&amp;token=
+ [%- issue_hash_token(['sanitycheck']) FILTER uri %]"
+ >Repair invalid product_id values in the component_watch table</a>
+
+[% ELSIF san_tag == "component_watching_check" %]
+ Checking component_watch table for bad values of product_id.
+
+[% ELSIF san_tag == "component_watching_alert" %]
+ Bad values for product_id found in the component_watch table.
+
+[% ELSIF san_tag == "component_watching_repairing" %]
+ OK, now fixing bad product_id values in the component_watch table.
+
+[% END %]
diff --git a/extensions/TrackingFlags/Extension.pm b/extensions/TrackingFlags/Extension.pm
index 7d8f8c401..3ba9e768b 100644
--- a/extensions/TrackingFlags/Extension.pm
+++ b/extensions/TrackingFlags/Extension.pm
@@ -657,4 +657,65 @@ sub quicksearch_map {
}
}
+sub reorg_move_component {
+ my ($self, $args) = @_;
+ my $new_product = $args->{new_product};
+ my $component = $args->{component};
+
+ Bugzilla->dbh->do(
+ "UPDATE tracking_flags_visibility SET product_id=? WHERE component_id=?",
+ undef,
+ $new_product->id, $component->id,
+ );
+}
+
+sub sanitycheck_check {
+ my ($self, $args) = @_;
+ my $status = $args->{status};
+
+ $status->('tracking_flags_check');
+
+ my ($count) = Bugzilla->dbh->selectrow_array("
+ SELECT COUNT(*)
+ FROM tracking_flags_visibility
+ INNER JOIN components ON components.id = tracking_flags_visibility.component_id
+ WHERE tracking_flags_visibility.product_id <> components.product_id
+ ");
+ if ($count) {
+ $status->('tracking_flags_alert', undef, 'alert');
+ $status->('tracking_flags_repair');
+ }
+}
+
+sub sanitycheck_repair {
+ my ($self, $args) = @_;
+ return unless Bugzilla->cgi->param('tracking_flags_repair');
+
+ my $status = $args->{'status'};
+ my $dbh = Bugzilla->dbh;
+ $status->('tracking_flags_repairing');
+
+ my $rows = $dbh->selectall_arrayref("
+ SELECT DISTINCT tracking_flags_visibility.product_id AS bad_product_id,
+ components.product_id AS good_product_id,
+ tracking_flags_visibility.component_id
+ FROM tracking_flags_visibility
+ INNER JOIN components ON components.id = tracking_flags_visibility.component_id
+ WHERE tracking_flags_visibility.product_id <> components.product_id
+ ",
+ { Slice => {} }
+ );
+ foreach my $row (@$rows) {
+ $dbh->do("
+ UPDATE tracking_flags_visibility
+ SET product_id=?
+ WHERE product_id=? AND component_id=?
+ ", undef,
+ $row->{good_product_id},
+ $row->{bad_product_id},
+ $row->{component_id},
+ );
+ }
+}
+
__PACKAGE__->NAME;
diff --git a/extensions/TrackingFlags/lib/Admin.pm b/extensions/TrackingFlags/lib/Admin.pm
index b72416819..389acde2c 100644
--- a/extensions/TrackingFlags/lib/Admin.pm
+++ b/extensions/TrackingFlags/lib/Admin.pm
@@ -263,7 +263,10 @@ sub _validate {
if ($visibility->{component} ne '') {
$visibility->{component_obj} = Bugzilla::Component->new({ product => $visibility->{product_obj},
name => $visibility->{component} })
- || ThrowCodeError('tracking_flags_invalid_component', { component => $visibility->{component} });
+ || ThrowCodeError('tracking_flags_invalid_component', {
+ product => $visibility->{product},
+ component_name => $visibility->{component},
+ });
}
}
diff --git a/extensions/TrackingFlags/template/en/default/hook/admin/sanitycheck/messages-statuses.html.tmpl b/extensions/TrackingFlags/template/en/default/hook/admin/sanitycheck/messages-statuses.html.tmpl
new file mode 100644
index 000000000..71ef63c11
--- /dev/null
+++ b/extensions/TrackingFlags/template/en/default/hook/admin/sanitycheck/messages-statuses.html.tmpl
@@ -0,0 +1,23 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+
+[% IF san_tag == "tracking_flags_repair" %]
+ <a href="sanitycheck.cgi?tracking_flags_repair=1&amp;token=
+ [%- issue_hash_token(['sanitycheck']) FILTER uri %]"
+ >Repair invalid product_id values in the tracking_flags_visibility table</a>
+
+[% ELSIF san_tag == "tracking_flags_check" %]
+ Checking tracking_flags_visibility table for bad values of product_id.
+
+[% ELSIF san_tag == "tracking_flags_alert" %]
+ Bad values for product_id found in the tracking_flags_visibility table.
+
+[% ELSIF san_tag == "tracking_flags_repairing" %]
+ OK, now fixing bad product_id values in the tracking_flags_visibility table.
+
+[% END %]
diff --git a/extensions/TrackingFlags/template/en/default/hook/global/code-error-errors.html.tmpl b/extensions/TrackingFlags/template/en/default/hook/global/code-error-errors.html.tmpl
index 2d462ebaf..d656aac92 100644
--- a/extensions/TrackingFlags/template/en/default/hook/global/code-error-errors.html.tmpl
+++ b/extensions/TrackingFlags/template/en/default/hook/global/code-error-errors.html.tmpl
@@ -12,7 +12,8 @@
[% ELSIF error == "tracking_flags_invalid_component" %]
[% title = "Invalid Component" %]
- The component named '[% component FILTER html %]' does not exist.
+ The component named '[% component_name FILTER html %]' does not exist in the
+ product '[% product FILTER html %]'.
[% ELSIF error == "tracking_flags_invalid_item_id" %]
[% title = "Invalid " _ item _ " ID" %]