summaryrefslogtreecommitdiffstats
path: root/scripts/movecomponent.pl
diff options
context:
space:
mode:
authorDavid Lawrence <dkl@mozilla.com>2015-07-06 21:21:04 +0200
committerDavid Lawrence <dkl@mozilla.com>2015-07-06 21:21:04 +0200
commitb758be1d37cb49ced8cb17fca3d5a4cb2dd2e03e (patch)
tree01d7b7c5a5fcd5dddc0ed4adc55a60917ce70bce /scripts/movecomponent.pl
parentf70d4ce7e0a94379bb901559109650874946c84b (diff)
downloadbugzilla-b758be1d37cb49ced8cb17fca3d5a4cb2dd2e03e.tar.gz
bugzilla-b758be1d37cb49ced8cb17fca3d5a4cb2dd2e03e.tar.xz
Bug 1172968: Move the scripts we want to keep from contrib/* and place them in scripts/ directory. Remove contrib from repo
Diffstat (limited to 'scripts/movecomponent.pl')
-rwxr-xr-xscripts/movecomponent.pl154
1 files changed, 154 insertions, 0 deletions
diff --git a/scripts/movecomponent.pl b/scripts/movecomponent.pl
new file mode 100755
index 000000000..cb07b84fc
--- /dev/null
+++ b/scripts/movecomponent.pl
@@ -0,0 +1,154 @@
+#!/usr/bin/perl -w
+# 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 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;
+
+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"
+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.
+
+USAGE
+}
+
+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;
+
+# check versions
+my @missing_versions;
+my $ra_versions = $dbh->selectcol_arrayref(
+ "SELECT DISTINCT version FROM bugs WHERE component_id = ?",
+ undef, $component->id);
+foreach my $version (@$ra_versions) {
+ my $has_version = $dbh->selectrow_array(
+ "SELECT 1 FROM versions WHERE product_id = ? AND value = ?",
+ undef, $new_product->id, $version);
+ push @missing_versions, $version unless $has_version;
+}
+
+# check milestones
+my @missing_milestones;
+my $ra_milestones = $dbh->selectcol_arrayref(
+ "SELECT DISTINCT target_milestone FROM bugs WHERE component_id = ?",
+ undef, $component->id);
+foreach my $milestone (@$ra_milestones) {
+ my $has_milestone = $dbh->selectrow_array(
+ "SELECT 1 FROM milestones WHERE product_id=? AND value=?",
+ undef, $new_product->id, $milestone);
+ push @missing_milestones, $milestone unless $has_milestone;
+}
+
+my $missing_error = '';
+if (@missing_versions) {
+ $missing_error .= "'$new_product_name' is missing the following version(s):\n " .
+ join("\n ", @missing_versions) . "\n";
+}
+if (@missing_milestones) {
+ $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_name'
+From '$old_product_name'
+To '$new_product_name'
+
+Press <Ctrl-C> to stop or <Enter> to continue...
+EOF
+getc();
+
+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, $old_product->id, $component->id);
+
+# Bugs table
+$dbh->do("UPDATE bugs SET product_id = ? WHERE component_id = ?",
+ undef,
+ ($new_product->id, $component->id));
+
+# Flags tables
+fix_flags('flaginclusions', $new_product, $component);
+fix_flags('flagexclusions', $new_product, $component);
+
+# Components
+$dbh->do("UPDATE components SET product_id = ? WHERE id = ?",
+ undef,
+ ($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, $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, ?, ?, ?
+ FROM bugs WHERE component_id = ?",
+ undef,
+ ($userid, $field_id, $old_product_name, $new_product_name, $component->id));
+
+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();
+
+sub fix_flags {
+ my ($table, $new_product, $component) = @_;
+ my $dbh = Bugzilla->dbh;
+
+ my $type_ids = $dbh->selectcol_arrayref("SELECT DISTINCT type_id FROM $table WHERE component_id = ?",
+ undef,
+ $component->id);
+ $dbh->do("DELETE FROM $table WHERE component_id = ?", undef, $component->id);
+ foreach my $type_id (@$type_ids) {
+ $dbh->do("INSERT INTO $table (type_id, product_id, component_id) VALUES (?, ?, ?)",
+ undef, ($type_id, $new_product->id, $component->id));
+ }
+}