diff options
Diffstat (limited to 'contrib')
53 files changed, 0 insertions, 7225 deletions
diff --git a/contrib/README b/contrib/README deleted file mode 100644 index f4e40e4a3..000000000 --- a/contrib/README +++ /dev/null @@ -1,57 +0,0 @@ -This directory contains contributed software related to Bugzilla. -Things in here have not necessarily been tested or tried by anyone -except the original contributor, so tread carefully. But it may still -be useful to you. Read the files themselves for detailed usage information -on any specific script. - -This file is encoded in UTF8 for purposes of contributor names. - -This directory includes: - - bugzilla-submit/ -- A standalone bug submission program. - - bzdbcopy.pl -- A script to copy data from an installation running - on one DB platform to an installation running on - another DB platform. - -bz_webservice_demo.pl -- An example script that demonstrates how to talk to - Bugzilla via XMLRPC. - - cmdline/ -- Various commands for querying your Bugzilla - installation. - - cvs-update.pl -- Script to keep a record of all CVS updates made - from a given directory. The log is useful when - changes need to be backed out. - - jb2bz.py -- Script to import bugs from JitterBug to Bugzilla. - - merge-users.pl -- Script to merge two user accounts. The activities - from one account are moved to the another. Specify - both accounts on the command line. The new account - must already exist. - - mysqld-watcher.pl -- This script can be installed as a frequent Cron - job to clean up stalled/dead queries. - - recode.pl -- Script to convert a database from one encoding - (or multiple encodings) to UTF-8. - - sendbugmail.pl -- This script is a drop-in replacement for the - 'processmail' script which used to be shipped - with Bugzilla, but was replaced by the - Bugzilla/BugMail.pm Perl module. This script can - be used if 'processmail' was previously called - from other scripts external to - Bugzilla. See the comments at the top of - the file for usage information. Contributed - by Nick Barnes of Ravenbrook Limited. - -sendunsentbugmail.pl -- Script to find bugs with un-sent mail and to - send all unsent messages. - - syncLDAP.pl -- Script that can be run via Cron that queries an LDAP - server for users and e-mail addresses and adds - missing users to Bugzilla. Can disable/update - non-existing/changed information. Contributed by - Andreas Höfler <andreas.hoefler@bearingpoint.com>. diff --git a/contrib/addcustomfield.pl b/contrib/addcustomfield.pl deleted file mode 100755 index 4fa6589e4..000000000 --- a/contrib/addcustomfield.pl +++ /dev/null @@ -1,63 +0,0 @@ -#!/usr/bin/perl -wT -# -*- 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. -# -# Contributor(s): Frédéric Buclin <LpSolit@gmail.com> -# David Miller <justdave@mozilla.com> - -use strict; -use lib qw(. lib); - -use Bugzilla; -use Bugzilla::Constants; -use Bugzilla::Field; - -Bugzilla->usage_mode(USAGE_MODE_CMDLINE); - -my %types = ( - 'freetext' => FIELD_TYPE_FREETEXT, - 'single_select' => FIELD_TYPE_SINGLE_SELECT, - 'multi_select' => FIELD_TYPE_MULTI_SELECT, - 'textarea' => FIELD_TYPE_TEXTAREA, - 'datetime' => FIELD_TYPE_DATETIME, - 'date' => FIELD_TYPE_DATE, - 'bug_id' => FIELD_TYPE_BUG_ID, - 'bug_urls' => FIELD_TYPE_BUG_URLS, - 'keywords' => FIELD_TYPE_KEYWORDS, -); - -my $syntax = - "syntax: addcustomfield.pl <field name> [field type]\n\n" . - "valid field types:\n " . join("\n ", sort keys %types) . "\n\n" . - "the default field type is single_select\n"; - -my $name = shift || die $syntax; -my $type = lc(shift || 'single_select'); -exists $types{$type} || die "Invalid field type '$type'.\n\n$syntax"; -$type = $types{$type}; - -Bugzilla::Field->create({ - name => $name, - description => 'Please give me a description!', - type => $type, - mailhead => 0, - enter_bug => 0, - obsolete => 1, - custom => 1, - buglist => 1, -}); -print "Done!\n"; - -my $urlbase = Bugzilla->params->{urlbase}; -print "Please visit ${urlbase}editfields.cgi?action=edit&name=$name to finish setting up this field.\n"; diff --git a/contrib/bugzilla-queue.rhel b/contrib/bugzilla-queue.rhel deleted file mode 100755 index 3e00cce24..000000000 --- a/contrib/bugzilla-queue.rhel +++ /dev/null @@ -1,109 +0,0 @@ -#!/bin/bash -# -# bugzilla-queue This starts, stops, and restarts the Bugzilla jobqueue.pl -# daemon, which manages sending queued mail and possibly -# other queued tasks in the future. -# -# chkconfig: 345 85 15 -# description: Bugzilla queue runner -# -### BEGIN INIT INFO -# Provides: bugzilla-queue -# Required-Start: $local_fs $syslog MTA mysqld -# Required-Stop: $local_fs $syslog MTA mysqld -# Default-Start: 3 5 -# Default-Stop: 0 1 2 6 -# Short-Description: Start and stop the Bugzilla queue runner. -# Description: The Bugzilla queue runner (jobqueue.pl) sends any mail -# that Bugzilla has queued to be sent in the background. If you -# have enabled the use_mailer_queue parameter in Bugzilla, you -# must run this daemon. -### END INIT INFO - -NAME=`basename $0` - -################# -# Configuration # -################# - -# This should be the path to your Bugzilla -BUGZILLA=/var/www/html/bugzilla -# Who owns the Bugzilla directory and files? -USER=root - -# If you want to pass any options to the daemon (like -d for debugging) -# specify it here. -OPTIONS="" - -# You can also override the configuration by creating a -# /etc/sysconfig/bugzilla-queue file so that you don't -# have to edit this script. -if [ -r /etc/sysconfig/$NAME ]; then - . /etc/sysconfig/$NAME -fi - -########## -# Script # -########## - -RETVAL=0 -BIN=$BUGZILLA/jobqueue.pl -PIDFILE=/var/run/$NAME.pid - -# Source function library. -. /etc/rc.d/init.d/functions - -usage () -{ - echo "Usage: service $NAME {start|stop|status|restart|condrestart}" - RETVAL=1 -} - - -start () -{ - if [ -f "$PIDFILE" ]; then - checkpid `cat $PIDFILE` && return 0 - fi - echo -n "Starting $NAME: " - touch $PIDFILE - chown $USER $PIDFILE - daemon --user=$USER \ - "$BIN ${OPTIONS} -p '$PIDFILE' -n $NAME start > /dev/null" - ret=$? - [ $ret -eq "0" ] && touch /var/lock/subsys/$NAME - echo - return $ret -} - -stop () -{ - [ -f /var/lock/subsys/$NAME ] || return 0 - echo -n "Killing $NAME: " - killproc $NAME - echo - rm -f /var/lock/subsys/$NAME -} - -restart () -{ - stop - start -} - -condrestart () -{ - [ -e /var/lock/subsys/$NAME ] && restart || return 0 -} - - -case "$1" in - start) start; RETVAL=$? ;; - stop) stop; RETVAL=$? ;; - status) $BIN -p $PIDFILE -n $NAME check; RETVAL=$?;; - restart) restart; RETVAL=$? ;; - condrestart) condrestart; RETVAL=$? ;; - *) usage ; RETVAL=2 ;; -esac - -exit $RETVAL diff --git a/contrib/bugzilla-queue.suse b/contrib/bugzilla-queue.suse deleted file mode 100755 index 356302058..000000000 --- a/contrib/bugzilla-queue.suse +++ /dev/null @@ -1,174 +0,0 @@ -#!/bin/bash -# -# bugzilla-queue This starts, stops, and restarts the Bugzilla jobqueue.pl -# daemon, which manages sending queued mail and possibly -# other queued tasks in the future. -# -# chkconfig: 345 85 15 -# description: Bugzilla queue runner -# -### BEGIN INIT INFO -# Provides: bugzilla-queue -# Required-Start: $local_fs $syslog -# Required-Stop: $local_fs $syslog -# Default-Start: 3 5 -# Default-Stop: 0 1 2 6 -# Short-Description: Start and stop the Bugzilla queue runner. -# Description: The Bugzilla queue runner (jobqueue.pl) sends any mail -# that Bugzilla has queued to be sent in the background. If you -# have enabled the use_mailer_queue parameter in Bugzilla, you -# must run this daemon. -### END INIT INFO - -NAME=`basename $0` - -################# -# Configuration # -################# - -# This should be the path to your Bugzilla -BUGZILLA=/var/www/html/bugzilla -# Who owns the Bugzilla directory and files? -USER=root - -# If you want to pass any options to the daemon (like -d for debugging) -# specify it here. -OPTIONS="" - -# You can also override the configuration by creating a -# /etc/sysconfig/bugzilla-queue file so that you don't -# have to edit this script. -if [ -r /etc/sysconfig/$NAME ]; then - . /etc/sysconfig/$NAME -fi - -########## -# Script # -########## - -BIN=$BUGZILLA/jobqueue.pl -if [ ! -x $BIN ]; then - echo "$BIN not installed" - if [ "$1" = "stop" ]; then - exit 0 - else - exit 5 - fi -fi - -# Source LSB function library. -. /lib/lsb/init-functions - -# Reset status of this service. -rc_reset - -# Return values for all commands but status: -# 0 - success -# 1 - generic or unspecified error -# 2 - invalid or excess argument(s) -# 3 - unimplemented feature (e.g. "reload") -# 4 - user had insufficient privileges -# 5 - program is not installed -# 6 - program is not configured -# 7 - program is not running -# 8--199 - reserved (8--99 LSB, 100--149 distrib, 150--199 appl) -# -# Note that starting an already running service, stopping -# or restarting a not-running service as well as the restart -# with force-reload (in case signaling is not supported) are -# considered a success. - -case "$1" in - start) - echo -n "Starting $NAME " - # Start daemon with startproc(8). If this fails the return value - # is set appropriately by startproc. - start_daemon -u $USER $BIN ${OPTIONS} start - - # Remember status and be verbose - rc_status -v - ;; - - stop) - echo -n "Shutting down $NAME " - # Stop daemon with killproc(8) and if this fails killproc sets the - # return value according to LSB. - killproc -TERM $BIN - - # Remember status and be verbose - rc_status -v - ;; - - status) - echo -n "Checking for service $NAME " - # Check status with checkproc(8), if process is running checkproc - # will return with exit status 0. - - # Return value is slightly different for the status command: - # 0 - service up and running - # 1 - service dead, but /var/run/ pid file exists - # 2 - service dead, but /var/lock/ lock file exists - # 3 - service not running (unused) - # 4 - service status unknown :-( - # 5--199 reserved (5--99 LSB, 100--149 distro, 150--199 appl.) - - # NOTE: checkproc returns LSB compliant status values. - checkproc $BIN - - # NOTE: rc_status knows that we called this init script with - # "status" option and adapts its messages accordingly. - rc_status -v - - # Run jobqueue's own check function too. - $BIN check - ;; - - restart) - # Stop the service and regardless of whether it was running or not, - # start it again. - $0 stop - $0 start - - # Remember status and be quiet. - rc_status - ;; - - try-restart|condrestart) - # Do a restart only if the service was active before. - # NOTE: try-restart is now part of LSB (as of 1.9). RH has a - # similar command named condrestart. - if [ "$1" = "condrestart" ]; then - echo "${attn} Use try-restart ${done}(LSB)${attn} rather than condrestart ${warn}(RH)${norm}" - fi - $0 status - if [ $? -eq 0 ]; then - $0 restart - else - rc_reset # Not running is not a failure. - fi - - # Remember status and be quiet - rc_status - ;; - - force-reload) - # The jobqueue.pl daemon does not support SIGHUP for reload. Just - # restart the service if it is running. - echo -n "Reload service $NAME " - - $0 try-restart - rc_status - ;; - - reload) - # The jobqueue.pl daemon does not support SIGHUP for reload. - rc_failed 3 - rc_status -v - ;; - - *) - echo "Usage: $0 {start|stop|status|try-restart|restart|force-reload|reload}" - exit 1 -esac - -rc_exit diff --git a/contrib/bugzilla-submit/README b/contrib/bugzilla-submit/README deleted file mode 100644 index f9e74b9d4..000000000 --- a/contrib/bugzilla-submit/README +++ /dev/null @@ -1,46 +0,0 @@ -bugzilla-submit -=============== - -Authors: Christian Reis <kiko@async.com.br> - Eric Raymond <esr@thyrsus.com> - -bugzilla-submit is a simple Python program that creates bugs in a Bugzilla -instance. It takes as input text resembling message headers (RFC-822 -formatted) via standard input, or optionally a number of commandline -parameters. It communicates using HTTP, which allows it to work over a -network. - -Requirements ------------- - -Its only requirement is Python 2.3 or higher; you should have the -"python" executable in your path. - -Usage Notes ------------ - -* Please constrain testing to your own installation of Bugzilla, or use -* http://landfill.bugzilla.org/ for testing purposes -- opening test -* bugs on production instances of Bugzilla is definitely not a good idea - -Run "bugzilla-submit --help" for a description of the possible options. - -An example input file, named bugdata.txt, is provided. You can pipe it -in as standard input to bugzilla-submit, providing a Bugzilla URI through -the command-line. - -Note that you must create a ~/.netrc entry to authenticate against the -Bugzilla instance. The entry's machine field is a *quoted* Bugzilla URI, -the login field is your ID on that host, and the password field is the -your password password. An example entry follows: - - machine "http://bugzilla.mozilla.org/" - login foo@bar.loo - password snarf - -Documentation -------------- - -Documentation for bugzilla-submit is provided in Docbook format; see -bugzilla-submit.xml. - diff --git a/contrib/bugzilla-submit/bugdata.txt b/contrib/bugzilla-submit/bugdata.txt deleted file mode 100755 index fc880165c..000000000 --- a/contrib/bugzilla-submit/bugdata.txt +++ /dev/null @@ -1,13 +0,0 @@ -Product: FoodReplicator -Component: Salt -Version: 1.0 -Priority: P2 -Hardware: PC -OS: Linux -Severity: critical -Summary: Impending electron shortage -Depends-on: 8 -URL: http://www.google.com/ - -We need an emergency supply of electrons. - diff --git a/contrib/bugzilla-submit/bugzilla-submit b/contrib/bugzilla-submit/bugzilla-submit deleted file mode 100755 index d98e7de8d..000000000 --- a/contrib/bugzilla-submit/bugzilla-submit +++ /dev/null @@ -1,301 +0,0 @@ -#!/usr/bin/env python -# -# bugzilla-submit: a command-line script to post bugs to a Bugzilla instance -# -# Authors: Christian Reis <kiko@async.com.br> -# Eric S. Raymond <esr@thyrsus.com> -# -# This is version 0.5. -# -# For a usage hint run bugzilla-submit --help -# -# TODO: use RDF output to pick up valid options, as in -# http://www.async.com.br/~kiko/mybugzilla/config.cgi?ctype=rdf - -import sys, string - -def error(m): - sys.stderr.write("bugzilla-submit: %s\n" % m) - sys.stderr.flush() - sys.exit(1) - -version = string.split(string.split(sys.version)[0], ".")[:2] -if map(int, version) < [2, 3]: - error("you must upgrade to Python 2.3 or higher to use this script.") - -import urllib, re, os, netrc, email.Parser, optparse - -class ErrorURLopener(urllib.URLopener): - """URLopener that handles HTTP 404s""" - def http_error_404(self, url, fp, errcode, errmsg, headers, *extra): - raise ValueError, errmsg # 'File Not Found' - -# Set up some aliases -- partly to hide the less friendly fieldnames -# behind the names actually used for them in the stock web page presentation, -# and partly to provide a place for mappings if the Bugzilla fieldnames -# ever change. -field_aliases = (('hardware', 'rep_platform'), - ('os', 'op_sys'), - ('summary', 'short_desc'), - ('description', 'comment'), - ('depends_on', 'dependson'), - ('status', 'bug_status'), - ('severity', 'bug_severity'), - ('url', 'bug_file_loc'),) - -def header_to_field(hdr): - hdr = hdr.lower().replace("-", "_") - for (alias, name) in field_aliases: - if hdr == alias: - hdr = name - break - return hdr - -def field_to_header(hdr): - hdr = "-".join(map(lambda x: x.capitalize(), hdr.split("_"))) - for (alias, name) in field_aliases: - if hdr == name: - hdr = alias - break - return hdr - -def setup_parser(): - # Take override values from the command line - parser = optparse.OptionParser(usage="usage: %prog [options] bugzilla-url") - parser.add_option('-b', '--status', dest='bug_status', - help='Set the Status field.') - parser.add_option('-u', '--url', dest='bug_file_loc', - help='Set the URL field.') - parser.add_option('-p', '--product', dest='product', - help='Set the Product field.') - parser.add_option('-v', '--version', dest='version', - help='Set the Version field.') - parser.add_option('-c', '--component', dest='component', - help='Set the Component field.') - parser.add_option('-s', '--summary', dest='short_desc', - help='Set the Summary field.') - parser.add_option('-H', '--hardware', dest='rep_platform', - help='Set the Hardware field.') - parser.add_option('-o', '--os', dest='op_sys', - help='Set the Operating System field.') - parser.add_option('-r', '--priority', dest='priority', - help='Set the Priority field.') - parser.add_option('-x', '--severity', dest='bug_severity', - help='Set the Severity field.') - parser.add_option('-d', '--description', dest='comment', - help='Set the Description field.') - parser.add_option('-a', '--assigned-to', dest='assigned_to', - help='Set the Assigned-To field.') - parser.add_option('-C', '--cc', dest='cc', - help='Set the Cc field.') - parser.add_option('-k', '--keywords', dest='keywords', - help='Set the Keywords field.') - parser.add_option('-D', '--depends-on', dest='dependson', - help='Set the Depends-On field.') - parser.add_option('-B', '--blocked', dest='blocked', - help='Set the Blocked field.') - parser.add_option('-n', '--no-stdin', dest='read', - default=True, action='store_false', - help='Suppress reading fields from stdin.') - return parser - -# Fetch user's credential for access to this Bugzilla instance. -def get_credentials(bugzilla): - # Work around a quirk in the Python implementation. - # The URL has to be quoted, otherwise the parser barfs on the colon. - # But the parser doesn't strip the quotes. - authenticate_on = '"' + bugzilla + '"' - try: - credentials = netrc.netrc() - except netrc.NetrcParseError, e: - error("ill-formed .netrc: %s:%s %s" % (e.filename, e.lineno, e.msg)) - except IOError, e: - error("missing .netrc file %s" % str(e).split()[-1]) - ret = credentials.authenticators(authenticate_on) - if not ret: - # Okay, the literal string passed in failed. Just to make sure, - # try adding/removing a slash after the address and looking - # again. We don't know what format was used in .netrc, which is - # why this rather hackish approach is necessary. - if bugzilla[-1] == "/": - authenticate_on = '"' + bugzilla[:-1] + '"' - else: - authenticate_on = '"' + bugzilla + '/"' - ret = credentials.authenticators(authenticate_on) - if not ret: - # Apparently, an invalid machine URL will cause credentials == None - error("no credentials for Bugzilla instance at %s" % bugzilla) - return ret - -def process_options(options): - data = {} - # Initialize bug report fields from message on standard input - if options.read: - message_parser = email.Parser.Parser() - message = message_parser.parse(sys.stdin) - for (key, value) in message.items(): - data.update({header_to_field(key) : value}) - if not 'comment' in data: - data['comment'] = message.get_payload() - - # Merge in options from the command line; they override what's on stdin. - for (key, value) in options.__dict__.items(): - if key != 'read' and value != None: - data[key] = value - return data - -def ensure_defaults(data): - # Provide some defaults if the user did not supply them. - if 'op_sys' not in data: - if sys.platform.startswith('linux'): - data['op_sys'] = 'Linux' - if 'rep_platform' not in data: - data['rep_platform'] = 'PC' - if 'bug_status' not in data: - data['bug_status'] = 'CONFIRMED' - if 'bug_severity' not in data: - data['bug_severity'] = 'normal' - if 'bug_file_loc' not in data: - data['bug_file_loc'] = 'http://' # Yes, Bugzilla needs this - if 'priority' not in data: - data['priority'] = 'Normal' - -def validate_fields(data): - # Fields for validation - required_fields = ( - "bug_status", "bug_file_loc", "product", "version", "component", - "short_desc", "rep_platform", "op_sys", "priority", "bug_severity", - "comment", - ) - legal_fields = required_fields + ( - "assigned_to", "cc", "keywords", "dependson", "blocked", - ) - my_fields = data.keys() - for field in my_fields: - if field not in legal_fields: - error("invalid field: %s" % field_to_header(field)) - for field in required_fields: - if field not in my_fields: - error("required field missing: %s" % field_to_header(field)) - - if not data['short_desc']: - error("summary for bug submission must not be empty") - - if not data['comment']: - error("comment for bug submission must not be empty") - -# -# POST-specific functions -# - -def submit_bug_POST(bugzilla, data): - # Move the request over the wire - postdata = urllib.urlencode(data) - try: - url = ErrorURLopener().open("%s/post_bug.cgi" % bugzilla, postdata) - except ValueError: - error("Bugzilla site at %s not found (HTTP returned 404)" % bugzilla) - ret = url.read() - check_result_POST(ret, data) - -def check_result_POST(ret, data): - # XXX We can move pre-validation out of here as soon as we pick up - # the valid options from config.cgi -- it will become a simple - # assertion and ID-grabbing step. - # - # XXX: We use get() here which may return None, but since the user - # might not have provided these options, we don't want to die on - # them. - version = data.get('version') - product = data.get('product') - component = data.get('component') - priority = data.get('priority') - severity = data.get('bug_severity') - status = data.get('bug_status') - assignee = data.get('assigned_to') - platform = data.get('rep_platform') - opsys = data.get('op_sys') - keywords = data.get('keywords') - deps = data.get('dependson', '') + " " + data.get('blocked', '') - deps = deps.replace(" ", ", ") - # XXX: we should really not be using plain find() here, as it can - # match the bug content inadvertedly - if ret.find("A legal Version was not") != -1: - error("version %r does not exist for component %s:%s" % - (version, product, component)) - if ret.find("A legal Priority was not") != -1: - error("priority %r does not exist in " - "this Bugzilla instance" % priority) - if ret.find("A legal Severity was not") != -1: - error("severity %r does not exist in " - "this Bugzilla instance" % severity) - if ret.find("A legal Status was not") != -1: - error("status %r is not a valid creation status in " - "this Bugzilla instance" % status) - if ret.find("A legal Platform was not") != -1: - error("platform %r is not a valid platform in " - "this Bugzilla instance" % platform) - if ret.find("A legal OS/Version was not") != -1: - error("%r is not a valid OS in " - "this Bugzilla instance" % opsys) - if ret.find("Invalid Username") != -1: - error("invalid credentials submitted") - if ret.find("Component Needed") != -1: - error("the component %r does not exist in " - "this Bugzilla instance" % component) - if ret.find("Unknown Keyword") != -1: - error("keyword(s) %r not registered in " - "this Bugzilla instance" % keywords) - if ret.find("The product name") != -1: - error("product %r does not exist in this " - "Bugzilla instance" % product) - # XXX: this should be smarter - if ret.find("does not exist") != -1: - error("could not mark dependencies for bugs %s: one or " - "more bugs didn't exist in this Bugzilla instance" % deps) - if ret.find("Match Failed") != -1: - # XXX: invalid CC hits on this error too - error("the bug assignee %r isn't registered in " - "this Bugzilla instance" % assignee) - # If all is well, return bug number posted - if ret.find("process_bug.cgi") == -1: - error("could not post bug to %s: are you sure this " - "is Bugzilla instance's top-level directory?" % bugzilla) - m = re.search("Bug ([0-9]+) Submitted", ret) - if not m: - print ret - error("Internal error: bug id not found; please report a bug") - id = m.group(1) - print "Bug %s posted." % id - -# -# -# - -if __name__ == "__main__": - parser = setup_parser() - - # Parser will print help and exit here if we specified --help - (options, args) = parser.parse_args() - - if len(args) != 1: - parser.error("missing Bugzilla host URL") - - bugzilla = args[0] - data = process_options(options) - - login, account, password = get_credentials(bugzilla) - if "@" not in login: # no use even trying to submit - error("login %r is invalid (it should be an email address)" % login) - - ensure_defaults(data) - validate_fields(data) - - # Attach authentication information - data.update({'Bugzilla_login' : login, - 'Bugzilla_password' : password, - 'GoAheadAndLogIn' : 1, - 'form_name' : 'enter_bug'}) - - submit_bug_POST(bugzilla, data) - diff --git a/contrib/bugzilla-submit/bugzilla-submit.xml b/contrib/bugzilla-submit/bugzilla-submit.xml deleted file mode 100755 index 5c818e268..000000000 --- a/contrib/bugzilla-submit/bugzilla-submit.xml +++ /dev/null @@ -1,221 +0,0 @@ -<?xml version="1.0" encoding="ISO-8859-1"?> -<!DOCTYPE refentry PUBLIC - "-//OASIS//DTD DocBook XML V4.1.2//EN" - "docbook/docbookx.dtd"> -<refentry id='bugzilla-submit.1'> -<refmeta> -<refentrytitle>bugzilla-submit</refentrytitle> -<manvolnum>1</manvolnum> -<refmiscinfo class='date'>Oct 30, 2003</refmiscinfo> -</refmeta> -<refnamediv id='name'> -<refname>bugzilla-submit</refname> -<refpurpose>post bugs to a Bugzilla instance</refpurpose> -</refnamediv> -<refsynopsisdiv id='synopsis'> - -<cmdsynopsis> - <command>bugzilla-submit</command> - <arg choice='opt'>--status <replaceable>bug_status</replaceable></arg> - <arg choice='opt'>--url <replaceable>bug_file_loc</replaceable></arg> - <arg choice='opt'>--product <replaceable>product</replaceable></arg> - <arg choice='opt'>--version <replaceable>version</replaceable></arg> - <arg choice='opt'>--component <replaceable>component</replaceable></arg> - <arg choice='opt'>--summary <replaceable>short_desc</replaceable></arg> - <arg choice='opt'>--hardware <replaceable>rep_platform</replaceable></arg> - <arg choice='opt'>--os <replaceable>op_sys</replaceable></arg> - <arg choice='opt'>--priority <replaceable>priority</replaceable></arg> - <arg choice='opt'>--severity <replaceable>bug_severity</replaceable></arg> - <arg choice='opt'>--assigned-to <replaceable>assigned-to</replaceable></arg> - <arg choice='opt'>--cc <replaceable>cc</replaceable></arg> - <arg choice='opt'>--keywords <replaceable>keywords</replaceable></arg> - <arg choice='opt'>--depends-on <replaceable>dependson</replaceable></arg> - <arg choice='opt'>--blocked <replaceable>blocked</replaceable></arg> - <arg choice='opt'>--description <replaceable>comment</replaceable></arg> - <arg choice='opt'>--no-stdin </arg> - <arg choice='plain'><replaceable>bugzilla-url</replaceable></arg> -</cmdsynopsis> - -</refsynopsisdiv> - -<refsect1 id='description'><title>DESCRIPTION</title> - -<para><application>bugzilla-submit</application> is a command-line tool -for posting bug reports to any instance of Bugzilla. It accepts on -standard input text resembling an RFC-822 message. The headers of -that message, and its body, are used to set error-report field values. -More field values are merged in from command-line options. If required -fields have not been set, <application>bugzilla-submit</application> -tries to compute them. Finally, the resulting error report is -validated. If all required fields are present, and there are no -illegal fields or values, the report is shipped off to the Mozilla -instance specified by the single positional argument. Login/password -credentials are read from the calling user's <filename>~/.netrc</filename> -file.</para> - -<para>bugzilla-submit accepts a single argument: -<replaceable>bugzilla-url</replaceable>. Its value must match the -relevant Bugzilla instance's base URL (technically, its -<replaceable>urlbase</replaceable> param). The program also accepts the -following options to set or override fields:</para> -<variablelist> -<varlistentry> -<term>-b, --status</term> -<listitem> -<para>Set the bug_status field, overriding the Status header from -standard input if present. (The stock Bugzilla web presentation -identifies this field as <quote>Status</quote>.)</para> -</listitem> -</varlistentry> -<varlistentry> -<term>-u, --url</term> -<listitem> -<para>Set the bug_file_loc field, overriding the URL header from -standard input if present. (The stock Bugzilla web presentation -identifies this field as <quote>URL</quote>.)</para> -</listitem> -</varlistentry> -<varlistentry> -<term>-p, --product</term> -<listitem> -<para>Set the product field, overriding the Product header from -standard input if necessary.</para> -</listitem> -</varlistentry> -<varlistentry> -<term>-v, --version</term> -<listitem><para>Set the version field, overriding the Version header -from standard input if necessary.</para></listitem> -</varlistentry> -<varlistentry> -<term>-c, --component</term> -<listitem><para>Set the component field, overriding the Component header -from standard input if necessary.</para></listitem> -</varlistentry> -<varlistentry> -<term>-s, --summary</term> -<listitem><para>Set the short_desc field, overriding the Summary header -from standard input if necessary. (The stock Bugzilla web presentation -identifies this field as <quote>Summary</quote>.)</para></listitem> -</varlistentry> -<varlistentry> -<term>-H, --hardware</term> -<listitem><para>Set the rep_platform field, overriding the Hardware header -from standard input if necessary. (The stock Bugzilla web presentation -identifies this field as <quote>Hardware</quote>.)</para></listitem> -</varlistentry> -<varlistentry> -<term>-o, --os</term> -<listitem><para>Set the op_sys field, overriding the OS (Operating -System) header from standard input if necessary. (The stock Bugzilla web -presentation also identifies this field as -<quote>OS</quote>.)</para></listitem> -</varlistentry> -<varlistentry> -<term>-r, --priority</term> -<listitem><para>Set the priority field, overriding the Priority header -from standard input if necessary.</para></listitem> -</varlistentry> -<varlistentry> -<term>-x, --severity</term> -<listitem><para>Set the severity field, overriding the Severity header -from standard input if necessary.</para></listitem> -</varlistentry> -<varlistentry> -<term>-d, --description</term> -<listitem><para>Set the comment field, overriding the Description header -from standard input if necessary. (The stock Bugzilla web presentation -identifies this field as <quote>Description</quote>.) If there is a -message body and no Description field and this option is not -specified, the message body is used as a description. -</para></listitem> -</varlistentry> -<varlistentry> -<term>-a, --assigned-to</term> -<listitem> -<para>Set the optional assigned_to field, overriding the Assigned-To -header from standard input if necessary.</para> -</listitem> -</varlistentry> -<varlistentry> -<term>-C, --cc</term> -<listitem> -<para>Set the optional cc field, overriding the Cc -header from standard input if necessary.</para> -</listitem> -</varlistentry> -<varlistentry> -<term>-k, --keywords</term> -<listitem> -<para>Set the optional keywords field, overriding the Keywords -header from standard input if necessary.</para> -</listitem> -</varlistentry> -<varlistentry> -<term>-D, --depends-on</term> -<listitem> -<para>Set the optional dependson field, overriding the Depends-On -header from standard input if necessary.</para> -</listitem> -</varlistentry> -<varlistentry> -<term>-B, --assigned-to</term> -<listitem> -<para>Set the optional blocked field, overriding the Blocked -header from standard input if necessary.</para> -</listitem> -</varlistentry> -<varlistentry> -<term>-n, --no-stdin</term> -<listitem><para>Suppress reading fields from standard input.</para></listitem> -</varlistentry> -<varlistentry> -<term>-h, --help</term> -<listitem><para>Print usage help and exit.</para></listitem> -</varlistentry> -</variablelist> - -<para>This program will try to deduce OS and Hardware if those are not -specified. If it fails, validation will fail before shipping the -report.</para> - -<para>There is expected to be a single positional argument following -any options. It should be the URL of the Bugzilla instance to which -the bug is to be submitted.</para> - -</refsect1> -<refsect1 id='files'><title>FILES</title> -<variablelist> -<varlistentry> -<term><filename>~/.netrc</filename></term> -<listitem><para>Must contain an entry in which the machine field is -the Bugzilla instance URL, the login field is your ID on that host, and the -password field is the right password. The URL in the machine field -must be enclosed in double quotes.</para> - -<para>For example, if your Bugzilla instance is at -"http://landfill.bugzilla.org/bztest/", and your login and password -there are "john@doe.com" and "foo", respectively, your -<filename>.netrc</filename> entry should look something like:</para> - -<screen> - machine "http://landfill.bugzilla.org/bztest/" - login john@doe.com - password foo - -</screen> - -<para>Note that the machine entry should match exactly the instance URL -specified to <application>bugzilla-submit</application>.</para> - -</listitem> -</varlistentry> -</variablelist> - -</refsect1> -<refsect1 id='author'><title>AUTHORS</title> -<para>Christian Reis <kiko@async.com.br>, Eric S. Raymond -<esr@thyrsus.com>.</para> -</refsect1> -</refentry> - diff --git a/contrib/bz_webservice_demo.pl b/contrib/bz_webservice_demo.pl deleted file mode 100755 index 72ec58a88..000000000 --- a/contrib/bz_webservice_demo.pl +++ /dev/null @@ -1,428 +0,0 @@ -#!/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. -# -# Contributor(s): Marc Schumann <wurblzap@gmail.com> -# Mads Bondo Dydensborg <mbd@dbc.dk> - -=head1 NAME - -bz_webservice_demo.pl - Show how to talk to Bugzilla via XMLRPC - -=head1 SYNOPSIS - -C<bz_webservice_demo.pl [options]> - -C<bz_webservice_demo.pl --help> for detailed help - -=cut - -use strict; -use lib qw(lib); -use Getopt::Long; -use Pod::Usage; -use File::Basename qw(dirname); -use File::Spec; -use HTTP::Cookies; -use XMLRPC::Lite; - -# If you want, say “use Bugzilla::WebService::Constants” here to get access -# to Bugzilla's web service error code constants. -# If you do this, remember to issue a “use lib” pointing to your Bugzilla -# installation directory, too. - -my $help; -my $Bugzilla_uri; -my $Bugzilla_login; -my $Bugzilla_password; -my $Bugzilla_remember; -my $bug_id; -my $product_name; -my $create_file_name; -my $legal_field_values; -my $add_comment; -my $private; -my $work_time; -my $fetch_extension_info = 0; - -GetOptions('help|h|?' => \$help, - 'uri=s' => \$Bugzilla_uri, - 'login:s' => \$Bugzilla_login, - 'password=s' => \$Bugzilla_password, - 'rememberlogin!' => \$Bugzilla_remember, - 'bug_id:s' => \$bug_id, - 'product_name:s' => \$product_name, - 'create:s' => \$create_file_name, - 'field:s' => \$legal_field_values, - 'comment:s' => \$add_comment, - 'private:i' => \$private, - 'worktime:f' => \$work_time, - 'extension_info' => \$fetch_extension_info - ) or pod2usage({'-verbose' => 0, '-exitval' => 1}); - -=head1 OPTIONS - -=over - -=item --help, -h, -? - -Print a short help message and exit. - -=item --uri - -URI to Bugzilla's C<xmlrpc.cgi> script, along the lines of -C<http://your.bugzilla.installation/path/to/bugzilla/xmlrpc.cgi>. - -=item --login - -Bugzilla login name. Specify this together with B<--password> in order to log in. - -Specify this without a value in order to log out. - -=item --password - -Bugzilla password. Specify this together with B<--login> in order to log in. - -=item --rememberlogin - -Gives access to Bugzilla's "Bugzilla_remember" option. -Specify this option while logging in to do the same thing as ticking the -C<Bugzilla_remember> box on Bugilla's log in form. -Don't specify this option to do the same thing as unchecking the box. - -See Bugzilla's rememberlogin parameter for details. - -=item --bug_id - -Pass a bug ID to have C<bz_webservice_demo.pl> do some bug-related test calls. - -=item --product_name - -Pass a product name to have C<bz_webservice_demo.pl> do some product-related -test calls. - -=item --create - -Specify a file that contains settings for the creating of a new bug. - -=item --field - -Pass a field name to get legal values for this field. It must be either a -global select field (such as bug_status, resolution, rep_platform, op_sys, -priority, bug_severity) or a custom select field. - -=item --comment - -A comment to add to a bug identified by B<--bug_id>. You must also pass a B<--login> -and B<--password> to log in to Bugzilla. - -=item --private - -An optional non-zero value to specify B<--comment> as private. - -=item --worktime - -An optional double precision number specifying the work time for B<--comment>. - -=item --extension_info - -If specified on the command line, the script returns the information about the -extensions that are installed. - -=back - -=head1 DESCRIPTION - -=cut - -pod2usage({'-verbose' => 1, '-exitval' => 0}) if $help; -_syntaxhelp('URI unspecified') unless $Bugzilla_uri; - -# We will use this variable for SOAP call results. -my $soapresult; - -# We will use this variable for function call results. -my $result; - -# Open our cookie jar. We save it into a file so that we may re-use cookies -# to avoid the need of logging in every time. You're encouraged, but not -# required, to do this in your applications, too. -# Cookies are only saved if Bugzilla's rememberlogin parameter is set to one of -# - on -# - defaulton (and you didn't pass 0 as third parameter to User.login) -# - defaultoff (and you passed 1 as third parameter to User.login) -my $cookie_jar = - new HTTP::Cookies('file' => File::Spec->catdir(dirname($0), 'cookies.txt'), - 'autosave' => 1); - -=head2 Initialization - -Using the XMLRPC::Lite class, you set up a proxy, as shown in this script. -Bugzilla's XMLRPC URI ends in C<xmlrpc.cgi>, so your URI looks along the lines -of C<http://your.bugzilla.installation/path/to/bugzilla/xmlrpc.cgi>. - -=cut - -my $proxy = XMLRPC::Lite->proxy($Bugzilla_uri, - 'cookie_jar' => $cookie_jar); - -=head2 Checking Bugzilla's version - -To make sure the Bugzilla you're connecting to supports the methods you wish to -call, you may want to compare the result of C<Bugzilla.version> to the -minimum required version your application needs. - -=cut - -$soapresult = $proxy->call('Bugzilla.version'); -_die_on_fault($soapresult); -print 'Connecting to a Bugzilla of version ' . $soapresult->result()->{version} . ".\n"; - -=head2 Checking Bugzilla's timezone - -To make sure that you understand the dates and times that Bugzilla returns to you, you may want to call C<Bugzilla.timezone>. - -=cut - -$soapresult = $proxy->call('Bugzilla.timezone'); -_die_on_fault($soapresult); -print 'Bugzilla\'s timezone is ' . $soapresult->result()->{timezone} . ".\n"; - -=head2 Getting Extension Information - -Returns all the information any extensions have decided to provide to the webservice. - -=cut - -if ($fetch_extension_info) { - $soapresult = $proxy->call('Bugzilla.extensions'); - _die_on_fault($soapresult); - my $extensions = $soapresult->result()->{extensions}; - foreach my $extensionname (keys(%$extensions)) { - print "Extension '$extensionname' information\n"; - my $extension = $extensions->{$extensionname}; - foreach my $data (keys(%$extension)) { - print ' ' . $data . ' => ' . $extension->{$data} . "\n"; - } - } -} - -=head2 Logging In and Out - -=head3 Using Bugzilla's Environment Authentication - -Use a -C<http://login:password@your.bugzilla.installation/path/to/bugzilla/xmlrpc.cgi> -style URI. -You don't log out if you're using this kind of authentication. - -=head3 Using Bugzilla's CGI Variable Authentication - -Use the C<User.login> and C<User.logout> calls to log in and out, as shown -in this script. - -The C<Bugzilla_remember> parameter is optional. -If omitted, Bugzilla's defaults apply (as specified by its C<rememberlogin> -parameter). - -Bugzilla hands back cookies you'll need to pass along during your work calls. - -=cut - -if (defined($Bugzilla_login)) { - if ($Bugzilla_login ne '') { - # Log in. - $soapresult = $proxy->call('User.login', - { login => $Bugzilla_login, - password => $Bugzilla_password, - remember => $Bugzilla_remember } ); - _die_on_fault($soapresult); - print "Login successful.\n"; - } - else { - # Log out. - $soapresult = $proxy->call('User.logout'); - _die_on_fault($soapresult); - print "Logout successful.\n"; - } -} - -=head2 Retrieving Bug Information - -Call C<Bug.get> with the ID of the bug you want to know more of. -The call will return a C<Bugzilla::Bug> object. - -Note: You can also use "Bug.get_bugs" for compatibility with Bugzilla 3.0 API. - -=cut - -if ($bug_id) { - $soapresult = $proxy->call('Bug.get', { ids => [$bug_id] }); - _die_on_fault($soapresult); - $result = $soapresult->result; - my $bug = $result->{bugs}->[0]; - foreach my $field (keys(%$bug)) { - my $value = $bug->{$field}; - if (ref($value) eq 'HASH') { - foreach (keys %$value) { - print "$_: " . $value->{$_} . "\n"; - } - } - else { - print "$field: $value\n"; - } - } -} - -=head2 Retrieving Product Information - -Call C<Product.get> with the name of the product you want to know more of. -The call will return a C<Bugzilla::Product> object. - -=cut - -if ($product_name) { - $soapresult = $proxy->call('Product.get', {'names' => [$product_name]}); - _die_on_fault($soapresult); - $result = $soapresult->result()->{'products'}->[0]; - - # Iterate all entries, the values may be scalars or array refs with hash refs. - foreach my $key (sort(keys %$result)) { - my $value = $result->{$key}; - - if (ref($value)) { - my $counter = 0; - foreach my $hash (@$value) { - while (my ($innerKey, $innerValue) = each %$hash) { - print "$key.$counter.$innerKey: $innerValue\n"; - } - ++$counter; - } - } - else { - print "$key: $value\n" - } - } -} - -=head2 Creating A Bug - -Call C<Bug.create> with the settings read from the file indicated on -the command line. The file must contain a valid anonymous hash to use -as argument for the call to C<Bug.create>. -The call will return a hash with a bug id for the newly created bug. - -=cut - -if ($create_file_name) { - $soapresult = $proxy->call('Bug.create', do "$create_file_name" ); - _die_on_fault($soapresult); - $result = $soapresult->result; - - if (ref($result) eq 'HASH') { - foreach (keys(%$result)) { - print "$_: $$result{$_}\n"; - } - } - else { - print "$result\n"; - } - -} - -=head2 Getting Legal Field Values - -Call C<Bug.legal_values> with the name of the field (including custom -select fields). The call will return a reference to an array with the -list of legal values for this field. - -=cut - -if ($legal_field_values) { - $soapresult = $proxy->call('Bug.legal_values', {field => $legal_field_values} ); - _die_on_fault($soapresult); - $result = $soapresult->result; - - print join("\n", @{$result->{values}}) . "\n"; -} - -=head2 Adding a comment to a bug - -Call C<Bug.add_comment> with the bug id, the comment text, and optionally the number -of hours you worked on the bug, and a boolean indicating if the comment is private -or not. - -=cut - -if ($add_comment) { - if ($bug_id) { - $soapresult = $proxy->call('Bug.add_comment', {id => $bug_id, - comment => $add_comment, private => $private, work_time => $work_time}); - _die_on_fault($soapresult); - print "Comment added.\n"; - } - else { - print "A --bug_id must be supplied to add a comment."; - } -} - -=head1 NOTES - -=head2 Character Set Encoding - -Make sure that your application either uses the same character set -encoding as Bugzilla does, or that it converts correspondingly when using the -web service API. -By default, Bugzilla uses UTF-8 as its character set encoding. - -=head2 Format For Create File - -The create format file is a piece of Perl code, that should look something like -this: - - { - product => "TestProduct", - component => "TestComponent", - summary => "TestBug - created from bz_webservice_demo.pl", - version => "unspecified", - description => "This is a description of the bug... hohoho", - op_sys => "All", - platform => "All", - priority => "P4", - severity => "normal" - }; - -=head1 SEE ALSO - -There are code comments in C<bz_webservice_demo.pl> which might be of further -help to you. - -=cut - -sub _die_on_fault { - my $soapresult = shift; - - if ($soapresult->fault) { - my ($package, $filename, $line) = caller; - die $soapresult->faultcode . ' ' . $soapresult->faultstring . - " in SOAP call near $filename line $line.\n"; - } -} - -sub _syntaxhelp { - my $msg = shift; - - print "Error: $msg\n"; - pod2usage({'-verbose' => 0, '-exitval' => 1}); -} diff --git a/contrib/bzdbcopy.pl b/contrib/bzdbcopy.pl deleted file mode 100755 index 688bc28a2..000000000 --- a/contrib/bzdbcopy.pl +++ /dev/null @@ -1,264 +0,0 @@ -#!/usr/bin/perl -w -# -# 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 Everything Solved. -# Portions created by Everything Solved are Copyright (C) 2006 -# Everything Solved. All Rights Reserved. -# -# Contributor(s): Max Kanat-Alexander <mkanat@bugzilla.org> - -use strict; -use lib qw(. lib); -use Bugzilla; -use Bugzilla::Constants; -use Bugzilla::DB; -use Bugzilla::Install::Util qw(indicate_progress); -use Bugzilla::Util; - -##################################################################### -# User-Configurable Settings -##################################################################### - -# Settings for the 'Source' DB that you are copying from. -use constant SOURCE_DB_TYPE => 'Mysql'; -use constant SOURCE_DB_NAME => 'bugs'; -use constant SOURCE_DB_USER => 'bugs'; -use constant SOURCE_DB_PASSWORD => ''; -use constant SOURCE_DB_HOST => 'localhost'; - -# Settings for the 'Target' DB that you are copying to. -use constant TARGET_DB_TYPE => 'Pg'; -use constant TARGET_DB_NAME => 'bugs'; -use constant TARGET_DB_USER => 'bugs'; -use constant TARGET_DB_PASSWORD => ''; -use constant TARGET_DB_HOST => 'localhost'; - -##################################################################### -# MAIN SCRIPT -##################################################################### - -print "Connecting to the '" . SOURCE_DB_NAME . "' source database on " - . SOURCE_DB_TYPE . "...\n"; -my $source_db = Bugzilla::DB::_connect({ - db_driver => SOURCE_DB_TYPE, - db_host => SOURCE_DB_HOST, - db_name => SOURCE_DB_NAME, - db_user => SOURCE_DB_USER, - db_pass => SOURCE_DB_PASSWORD, -}); -# Don't read entire tables into memory. -if (SOURCE_DB_TYPE eq 'Mysql') { - $source_db->{'mysql_use_result'} = 1; - - # MySQL cannot have two queries running at the same time. Ensure the schema - # is loaded from the database so bz_column_info will not execute a query - $source_db->_bz_real_schema; -} - -print "Connecting to the '" . TARGET_DB_NAME . "' target database on " - . TARGET_DB_TYPE . "...\n"; -my $target_db = Bugzilla::DB::_connect({ - db_driver => TARGET_DB_TYPE, - db_host => TARGET_DB_HOST, - db_name => TARGET_DB_NAME, - db_user => TARGET_DB_USER, - db_pass => TARGET_DB_PASSWORD, -}); -my $ident_char = $target_db->get_info( 29 ); # SQL_IDENTIFIER_QUOTE_CHAR - -# We use the table list from the target DB, because if somebody -# has customized their source DB, we still want the script to work, -# and it may otherwise fail in that situation (that is, the tables -# may not exist in the target DB). -# -# We don't want to copy over the bz_schema table's contents, though. -my @table_list = grep { $_ ne 'bz_schema' } $target_db->bz_table_list_real(); - -# Instead of figuring out some fancy algorithm to insert data in the right -# order and not break FK integrity, we just drop them all. -$target_db->bz_drop_foreign_keys(); -# We start a transaction on the target DB, which helps when we're doing -# so many inserts. -$target_db->bz_start_transaction(); -foreach my $table (@table_list) { - my @serial_cols; - print "Reading data from the source '$table' table on " - . SOURCE_DB_TYPE . "...\n"; - my @table_columns = $target_db->bz_table_columns_real($table); - # The column names could be quoted using the quote identifier char - # Remove these chars as different databases use different quote chars - @table_columns = map { s/^\Q$ident_char\E?(.*?)\Q$ident_char\E?$/$1/; $_ } - @table_columns; - - my ($total) = $source_db->selectrow_array("SELECT COUNT(*) FROM $table"); - my $select_query = "SELECT " . join(',', @table_columns) . " FROM $table"; - my $select_sth = $source_db->prepare($select_query); - $select_sth->execute(); - - my $insert_query = "INSERT INTO $table ( " . join(',', @table_columns) - . " ) VALUES ("; - $insert_query .= '?,' foreach (@table_columns); - # Remove the last comma. - chop($insert_query); - $insert_query .= ")"; - my $insert_sth = $target_db->prepare($insert_query); - - print "Clearing out the target '$table' table on " - . TARGET_DB_TYPE . "...\n"; - $target_db->do("DELETE FROM $table"); - - # Oracle doesn't like us manually inserting into tables that have - # auto-increment PKs set, because of the way we made auto-increment - # fields work. - if ($target_db->isa('Bugzilla::DB::Oracle')) { - foreach my $column (@table_columns) { - my $col_info = $source_db->bz_column_info($table, $column); - if ($col_info && $col_info->{TYPE} =~ /SERIAL/i) { - print "Dropping the sequence + trigger on $table.$column...\n"; - $target_db->do("DROP TRIGGER ${table}_${column}_TR"); - $target_db->do("DROP SEQUENCE ${table}_${column}_SEQ"); - } - } - } - - print "Writing data to the target '$table' table on " - . TARGET_DB_TYPE . "...\n"; - my $count = 0; - while (my $row = $select_sth->fetchrow_arrayref) { - # Each column needs to be bound separately, because - # many columns need to be dealt with specially. - my $colnum = 0; - foreach my $column (@table_columns) { - # bind_param args start at 1, but arrays start at 0. - my $param_num = $colnum + 1; - my $already_bound; - - # Certain types of columns need special handling. - my $col_info = $source_db->bz_column_info($table, $column); - if ($col_info && $col_info->{TYPE} eq 'LONGBLOB') { - $insert_sth->bind_param($param_num, - $row->[$colnum], $target_db->BLOB_TYPE); - $already_bound = 1; - } - elsif ($col_info && $col_info->{TYPE} =~ /decimal/) { - # In MySQL, decimal cols can be too long. - my $col_type = $col_info->{TYPE}; - $col_type =~ /decimal\((\d+),(\d+)\)/; - my ($precision, $decimals) = ($1, $2); - # If it's longer than precision + decimal point - if ( length($row->[$colnum]) > ($precision + 1) ) { - # Truncate it to the highest allowed value. - my $orig_value = $row->[$colnum]; - $row->[$colnum] = ''; - my $non_decimal = $precision - $decimals; - $row->[$colnum] .= '9' while ($non_decimal--); - $row->[$colnum] .= '.'; - $row->[$colnum] .= '9' while ($decimals--); - print "Truncated value $orig_value to " . $row->[$colnum] - . " for $table.$column.\n"; - } - } - elsif ($col_info && $col_info->{TYPE} =~ /DATETIME/i) { - my $date = $row->[$colnum]; - # MySQL can have strange invalid values for Datetimes. - $row->[$colnum] = '1901-01-01 00:00:00' - if $date && $date eq '0000-00-00 00:00:00'; - } - - $insert_sth->bind_param($param_num, $row->[$colnum]) - unless $already_bound; - $colnum++; - } - - $insert_sth->execute(); - $count++; - indicate_progress({ current => $count, total => $total, every => 100 }); - } - - # For some DBs, we have to do clever things with auto-increment fields. - foreach my $column (@table_columns) { - next if $target_db->isa('Bugzilla::DB::Mysql'); - my $col_info = $source_db->bz_column_info($table, $column); - if ($col_info && $col_info->{TYPE} =~ /SERIAL/i) { - my ($max_val) = $target_db->selectrow_array( - "SELECT MAX($column) FROM $table"); - # Set the sequence to the current max value + 1. - $max_val = 0 if !defined $max_val; - $max_val++; - print "\nSetting the next value for $table.$column to $max_val."; - if ($target_db->isa('Bugzilla::DB::Pg')) { - # PostgreSQL doesn't like it when you insert values into - # a serial field; it doesn't increment the counter - # automatically. - $target_db->bz_set_next_serial_value($table, $column); - } - elsif ($target_db->isa('Bugzilla::DB::Oracle')) { - # Oracle increments the counter on every insert, and *always* - # sets the field, even if you gave it a value. So if there - # were already rows in the target DB (like the default rows - # created by checksetup), you'll get crazy values in your - # id columns. So we just dropped the sequences above and - # we re-create them here, starting with the right number. - my @sql = $target_db->_bz_real_schema->_get_create_seq_ddl( - $table, $column, $max_val); - $target_db->do($_) foreach @sql; - } - } - } - - print "\n\n"; -} - -print "Committing changes to the target database...\n"; -$target_db->bz_commit_transaction(); -$target_db->bz_setup_foreign_keys(); - -print "All done! Make sure to run checksetup.pl on the new DB.\n"; -$source_db->disconnect; -$target_db->disconnect; - -1; - -__END__ - -=head1 NAME - -bzdbcopy.pl - Copies data from one Bugzilla database to another. - -=head1 DESCRIPTION - -The intended use of this script is to copy data from an installation -running on one DB platform to an installation running on another -DB platform. - -It must be run from the directory containing your Bugzilla installation. -That means if this script is in the contrib/ directory, you should -be running it as: C<./contrib/bzdbcopy.pl> - -Note: Both schemas must already exist and be B<IDENTICAL>. (That is, -they must have both been created/updated by the same version of -checksetup.pl.) This script will B<DESTROY ALL CURRENT DATA> in the -target database. - -Both Schemas must be at least from Bugzilla 2.19.3, but if you're -running a Bugzilla from before 2.20rc2, you'll need the patch at: -L<http://bugzilla.mozilla.org/show_bug.cgi?id=300311> in order to -be able to run this script. - -Before you using it, you have to correctly set all the variables -in the "User-Configurable Settings" section at the top of the script. -The C<SOURCE> settings are for the database you're copying from, and -the C<TARGET> settings are for the database you're copying to. The -C<DB_TYPE> is the name of a DB driver from the F<Bugzilla/DB/> directory. - diff --git a/contrib/clear-templates.pl b/contrib/clear-templates.pl deleted file mode 100755 index 8b0864d46..000000000 --- a/contrib/clear-templates.pl +++ /dev/null @@ -1,40 +0,0 @@ -#!/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 warnings; -use lib qw(. lib); - -use Bugzilla; -use Bugzilla::Constants; -use Bugzilla::Install::Filesystem qw(fix_dir_permissions); -use File::Path qw(mkpath rmtree); - -Bugzilla->usage_mode(USAGE_MODE_CMDLINE); -$| = 1; - -# rename the current directory and create a new empty one -# the templates will lazy-compile on demand - -my $path = bz_locations()->{'template_cache'}; -my $delete_path = "$path.deleteme"; - -print "clearing $path\n"; - -rmtree("$delete_path") if -e "$delete_path"; -rename($path, $delete_path) - or die "renaming '$path' to '$delete_path' failed: $!\n"; - -mkpath($path) - or die "creating '$path' failed: $!\n"; -fix_dir_permissions($path); - -# delete the temp directory (it's ok if this fails) - -rmtree("$delete_path"); diff --git a/contrib/cmdline/bugcount b/contrib/cmdline/bugcount deleted file mode 100755 index b41412a12..000000000 --- a/contrib/cmdline/bugcount +++ /dev/null @@ -1,7 +0,0 @@ -#!/bin/sh - -thisdir=`dirname "$0"` -bugids=`$thisdir/bugids "$@"` -if test "$?" != "0"; then echo "$bugids" 1>&2; exit 1; fi - -echo "$bugids" | wc -w diff --git a/contrib/cmdline/bugids b/contrib/cmdline/bugids deleted file mode 100755 index 6bb54213a..000000000 --- a/contrib/cmdline/bugids +++ /dev/null @@ -1,32 +0,0 @@ -#!/bin/sh -# 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 -# Andreas Franke <afranke@mathweb.org>. -# Corporation. Portions created by Andreas Franke are -# Copyright (C) 2001,2005 Andreas Franke. All -# Rights Reserved. -# -# Contributor(s): - -thisdir=`dirname "$0"` -buglist="$thisdir/buglist" -csvfile="$thisdir/buglist.csv" - -$thisdir/buglist "$@" 2>&1 1>${csvfile} -if test "$?" != "0"; then cat "$csvfile" 1>&2; exit 1; fi - -# 1. use 'awk' to select the first column (bug_id) -# 2. use 'grep -v' to remove the first line with the column headers -# 3. use backquotes & 'echo' to get all values in one line, space separated -echo `cat ${csvfile} | awk -F, '{printf $1 "\n"}' | grep -v bug_id` diff --git a/contrib/cmdline/buglist b/contrib/cmdline/buglist deleted file mode 100755 index 4bd5f20b5..000000000 --- a/contrib/cmdline/buglist +++ /dev/null @@ -1,31 +0,0 @@ -#!/bin/sh -# 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 -# Andreas Franke <afranke@mathweb.org>. -# Corporation. Portions created by Andreas Franke are -# Copyright (C) 2001,2005 Andreas Franke. All -# Rights Reserved. -# -# Contributor(s): - -defaultcolumnlist="severity priority platform status resolution target_milestone status_whiteboard keywords summaryfull" - -thisdir=`dirname "$0"` -query=`$thisdir/makequery "$@"` -if test "$?" != "0"; then exit 1; fi - -outputfile="/dev/stdout" -#outputfile="buglist.html" -#\rm -f ${outputfile} -wget -q -O ${outputfile} --header="Cookie: COLUMNLIST=${COLUMNLIST-${defaultcolumnlist}}" "${query}" diff --git a/contrib/cmdline/bugs b/contrib/cmdline/bugs deleted file mode 100755 index 2e8655876..000000000 --- a/contrib/cmdline/bugs +++ /dev/null @@ -1,6 +0,0 @@ -#!/bin/sh - -thisdir=`dirname "$0"` -bugids=`$thisdir/bugids "$@"` || echo "$bugids" 1>&2 && exit 1 - -echo "$bugids" | sed -e 's/ /\,/g' diff --git a/contrib/cmdline/bugslink b/contrib/cmdline/bugslink deleted file mode 100755 index ee7d5c588..000000000 --- a/contrib/cmdline/bugslink +++ /dev/null @@ -1,8 +0,0 @@ -#!/bin/sh - -thisdir=`dirname "$0"` -bugids=`$thisdir/bugids "$@"` || echo "$bugids" 1>&2 && exit 1 - -bugids=`echo "$bugids" | sed -e 's/ /\,/g'` -echo "https://bugzilla.mozilla.org/buglist.cgi?ctype=html&bug_id=$bugids" - diff --git a/contrib/cmdline/makequery b/contrib/cmdline/makequery deleted file mode 100755 index b34efb841..000000000 --- a/contrib/cmdline/makequery +++ /dev/null @@ -1,108 +0,0 @@ -#!/bin/sh -# 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 -# Andreas Franke <afranke@mathweb.org>. -# Corporation. Portions created by Andreas Franke are -# Copyright (C) 2001,2005 Andreas Franke. All -# Rights Reserved. -# -# Contributor(s): - -conf="`dirname $0`/query.conf" - -query="https://bugzilla.mozilla.org/buglist.cgi?ctype=csv" - -chart=0 -and=0 -while test "X$1" != "X"; do - arg="$1" - shift - if test 0 != `expr "X$arg" : 'X--[^=]*\$'`; then - # long option: --name val (without '=') - name=`expr "X$arg" : 'X--\(.*\)'` - val="$1" - shift - elif test 0 != `expr "X$arg" : 'X--[^=][^=]*='`; then - # long option: --name=val - name=`expr "X$arg" : 'X--\([^=]*\)'` - val=`expr "X$arg" : 'X--[^=]*=\(.*\)'` - elif test 0 != `expr "X$arg" : 'X-[a-zA-Z]\$'`; then - # short option like -X foo (with space in between) - name=`expr "X$arg" : 'X-\(.\)'` - val="$1" - shift - elif test 0 != `expr "X$arg" : 'X-[a-zA-Z]='`; then - # reject things like -X=foo - echo "Unrecognized option $arg" 1>&2 - echo "Use -Xfoo or -X foo instead of -X=foo" 1>&2 - exit 1 - elif test 0 != `expr "X$arg" : 'X-[a-zA-Z]'`; then - # short option like -Xfoo (without space) - name=`expr "X$arg" : 'X-\(.\)'` - val=`expr "X$arg" : 'X-.\(.*\)'` - else - name="default" - val="$arg" - #echo "Unrecognized option $arg" 1>&2 - #exit 1 - fi - - # plausibility check: val must not be empty, nor start with '-' - if test "X$val" = "X"; then - echo "No value found for '$name'!" 1>&2 - exit 1 - elif test 0 != `expr "X$val" : "X-"` && \ - test 0 = `expr "X$val" : "X---"`; then - echo "Suspicious value for '$name': '$val' looks like an option!" 1>&2 - exit 1 - fi - - # find field and comparison type for option ${name} - field=`grep "\"$name\"" "$conf" | awk '{printf $1}'` - type=`grep "\"$name\"" "$conf" | awk '{printf $2}'` - if test "X$field" = "X" || test "X$type" = "X"; then - if test "X$name" = "Xdefault"; then - echo 1>&2 "Error: unexpected argument '$arg'" - cat 1>&2 <<EOF -Use short options like -P1 or long options like --priority=1 , -or enable the 'default' behaviour in the 'query.conf' file. -EOF - else - echo "Unknown field name '$name'." 1>&2 - fi - exit 1 - fi - - # split val into comma-separated alternative values - or=0 - while test "X$val" != "X"; do - # val1 gets everything before the first comma; val gets the rest - if test 0 != `expr "X$val" : 'X[^,]*,'`; then - val1=`expr "X$val" : 'X\([^,]*\),'` - val=`expr "X$val" : 'X[^,]*,\(.*\)'` - else - val1="$val" - val="" - fi - # append to query - query="${query}&field${chart}-${and}-${or}=${field}" - query="${query}&type${chart}-${and}-${or}=${type}" - query="${query}&value${chart}-${and}-${or}=${val1}" - #echo "----- ${name} : ${field} : ${type} : ${val1} -----" 1>&2 - or=`expr ${or} + 1` - done - chart=`expr ${chart} + 1` -done - -echo "${query}" diff --git a/contrib/cmdline/query.conf b/contrib/cmdline/query.conf deleted file mode 100755 index 87390cd3f..000000000 --- a/contrib/cmdline/query.conf +++ /dev/null @@ -1,49 +0,0 @@ -# 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 -# Andreas Franke <afranke@mathweb.org>. -# Corporation. Portions created by Andreas Franke are -# Copyright (C) 2001 Andreas Franke. All -# Rights Reserved. -# -# Contributor(s): - -# -# This is `query.conf', the config file for `buglist'. -# -# Columns: 1: field_name, 2: comparison_type, 3: cmd-line options -# -bug_status substring "s","status" -resolution substring "r","resolution" -rep_platform substring "p","platform" -op_sys substring "o","os","opsys" -priority substring "P","priority" -bug_severity substring "S","severity" -assigned_to substring "A","O","owner","assignedto" -reporter substring "R","reporter" -qa_contact substring "Q","qa","qacontact" -cc substring "C","cc" -product substring "product" -version substring "V","version" -component substring "c","component" -target_milestone substring "M","milestone" -short_desc substring "summary","defaultREMOVEME" -longdesc substring "d","description","longdesc" -bug_file_loc substring "u","url" -status_whiteboard substring "w","whiteboard" -keywords substring "k","K","keywords" -attachments.description substring "attachdesc" -attach_data.thedata substring "attachdata" -attachments.mimetype substring "attachmime" -dependson substring # bug 30823 -blocked substring # bug 30823 diff --git a/contrib/console.pl b/contrib/console.pl deleted file mode 100755 index 408fdef61..000000000 --- a/contrib/console.pl +++ /dev/null @@ -1,186 +0,0 @@ -#!/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 the National Aeronautics -# and Space Administration of the United States Government. -# Portions created by the Initial Developer are Copyright (C) 2010 -# the Initial Developer. All Rights Reserved. -# -# Contributor(s): Jesse Clark <jjclark1982@gmail.com> - -use File::Basename; -BEGIN { chdir dirname($0) . "/.."; } -use lib qw(. lib); - -use Bugzilla; -use Bugzilla::Constants; -use Bugzilla::Util; -use Bugzilla::Bug; - -use Term::ReadLine; -use Data::Dumper; -$Data::Dumper::Sortkeys = 1; -$Data::Dumper::Terse = 1; -$Data::Dumper::Indent = 1; -$Data::Dumper::Useqq = 1; -$Data::Dumper::Maxdepth = 1; -$Data::Dumper::Deparse = 0; - -my $sysname = get_text('term', {term => 'Bugzilla'}); -my $term = new Term::ReadLine "$sysname Console"; -read_history($term); -END { write_history($term) } - -while ( defined (my $input = $term->readline("$sysname> ")) ) { - my @res = eval($input); - if ($@) { - warn $@; - } - else { - print Dumper(@res); - } -} -print STDERR "\n"; -exit 0; - -# d: full dump (normal behavior is limited to depth of 1) -sub d { - local $Data::Dumper::Maxdepth = 0; - local $Data::Dumper::Deparse = 1; - print Dumper(@_); - return (); -} - -# p: print as a single string (normal behavior puts list items on separate lines) -sub p { - local $^W=0; # suppress possible undefined var message - print(@_, "\n"); - return (); -} - -sub filter { - my $name = shift; - my $filter = Bugzilla->template->{SERVICE}->{CONTEXT}->{CONFIG}->{FILTERS}->{$name}; - if (scalar @_) { - return $filter->(@_); - } - else { - return $filter; - } -} - -sub b { get_object('Bugzilla::Bug', @_) } -sub u { get_object('Bugzilla::User', @_) } -sub f { get_object('Bugzilla::Field', @_) } - -sub get_object { - my $class = shift; - $_ = shift; - my @results = (); - - if (ref $_ eq 'HASH' && keys %$_) { - @results = @{$class->match($_)}; - } - elsif (m/^\d+$/) { - @results = ($class->new($_)); - } - elsif (m/\w/i && grep {$_ eq 'name'} ($class->_get_db_columns)) { - @results = @{$class->match({name => $_})}; - } - else { - @results = (); - } - - if (wantarray) { - return @results; - } - else { - return shift @results; - } -} - -sub read_history { - my ($term) = @_; - - if (open HIST, "<$ENV{HOME}/.bugzilla_console_history") { - foreach (<HIST>) { - chomp; - $term->addhistory($_); - } - close HIST; - } -} - -sub write_history { - my ($term) = @_; - - if ($term->can('GetHistory') && open HIST, ">$ENV{HOME}/.bugzilla_console_history") { - my %seen_hist = (); - my @hist = (); - foreach my $line (reverse $term->GetHistory()) { - next unless $line =~ m/\S/; - next if $seen_hist{$line}; - $seen_hist{$line} = 1; - push @hist, $line; - last if (scalar @hist > 500); - } - foreach (reverse @hist) { - print HIST $_, "\n"; - } - close HIST; - } -} - -__END__ - -=head1 NAME - -B<console.pl> - command-line interface to Bugzilla API - -=head1 SYNOPSIS - -$ B<contrib/console.pl> - -Bugzilla> B<b(5)-E<gt>short_desc> - -=over 8 - -"Misplaced Widget" - -=back - -Bugzilla> B<$f = f "cf_subsystem"; scalar @{$f-E<gt>legal_values}> - -=over 8 - -177 - -=back - -Bugzilla> B<p filter html_light, "1 E<lt> 2 E<lt>bE<gt>3E<lt>/bE<gt>"> - -=over 8 - -1 < 2 E<lt>bE<gt>3E<lt>/bE<gt> - -=back - -Bugzilla> B<$u = u 5; $u-E<gt>groups; d $u> - -=head1 DESCRIPTION - -Loads Bugzilla packages and prints expressions with Data::Dumper. -Useful for checking results of Bugzilla API calls without opening -a debug file from a cgi. diff --git a/contrib/convert-workflow.pl b/contrib/convert-workflow.pl deleted file mode 100755 index e4baf18d6..000000000 --- a/contrib/convert-workflow.pl +++ /dev/null @@ -1,179 +0,0 @@ -#!/usr/bin/perl -w -# -# 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 Everything Solved, Inc. -# Portions created by the Initial Developer are Copyright (C) 2009 the -# Initial Developer. All Rights Reserved. -# -# Contributor(s): -# Max Kanat-Alexander <mkanat@bugzilla.org> - -use strict; -use lib qw(. lib); - -use Bugzilla; -use Bugzilla::Config qw(:admin); -use Bugzilla::Search::Saved; -use Bugzilla::Status; -use Getopt::Long; - -my $confirmed = new Bugzilla::Status({ name => 'CONFIRMED' }); -my $in_progress = new Bugzilla::Status({ name => 'IN_PROGRESS' }); - -if ($confirmed and $in_progress) { - print "You are already using the new workflow.\n"; - exit 1; -} -my $enable_unconfirmed = 0; -my $result = GetOptions("enable-unconfirmed" => \$enable_unconfirmed); - -print <<END; -WARNING: This will convert the status of all bugs using the following -system: - - "NEW" will become "CONFIRMED" - "ASSIGNED" will become "IN_PROGRESS" - "REOPENED" will become "CONFIRMED" (and the "REOPENED" status will be removed) - "CLOSED" will become "VERIFIED" (and the "CLOSED" status will be removed) - -This change will be immediate. The history of each bug will also be changed -so that it appears that these statuses were always in existence. - -Emails will not be sent for the change. - -END -if ($enable_unconfirmed) { - print "UNCONFIRMED will be enabled in all products.\n"; -} else { - print <<END; -If you also want to enable the UNCONFIRMED status in every product, -restart this script with the --enable-unconfirmed option. -END -} -print "\nTo continue, press any key, or press Ctrl-C to stop this program..."; -getc; - -my $dbh = Bugzilla->dbh; -# This is an array instead of a hash so that we can be sure that -# the translation happens in the right order. In particular, we -# want NEW to be renamed to CONFIRMED, instead of having REOPENED -# be the one that gets renamed. -my @translation = ( - [NEW => 'CONFIRMED'], - [ASSIGNED => 'IN_PROGRESS'], - [REOPENED => 'CONFIRMED'], - [CLOSED => 'VERIFIED'], -); - -my $status_field = Bugzilla::Field->check('bug_status'); -$dbh->bz_start_transaction(); -foreach my $pair (@translation) { - my ($from, $to) = @$pair; - print "Converting $from to $to...\n"; - # There is no FK on bugs.bug_status pointing to bug_status.value, - # so it's fine to update the bugs table first. - $dbh->do('UPDATE bugs SET bug_status = ? WHERE bug_status = ?', - undef, $to, $from); - - if (Bugzilla->params->{'duplicate_or_move_bug_status'} eq $from) { - SetParam('duplicate_or_move_bug_status', $to); - write_params(); - } - - foreach my $what (qw(added removed)) { - $dbh->do("UPDATE bugs_activity SET $what = ? - WHERE fieldid = ? AND $what = ?", - undef, $to, $status_field->id, $from); - } - - # Delete any transitions where it now appears that - # a bug moved from a status to itself. - $dbh->do('DELETE FROM bugs_activity WHERE fieldid = ? AND added = removed', - undef, $status_field->id); - - # If the new status already exists, just delete the old one, but retain - # the workflow items from it. - my $new_status = new Bugzilla::Status({ name => $to }); - my $old_status = new Bugzilla::Status({ name => $from }); - - if ($new_status && $old_status) { - my $to_id = $new_status->id; - my $from_id = $old_status->id; - # The subselect collects existing transitions from the target bug status. - # The main select collects existing transitions from the renamed bug status. - # The diff tells us which transitions are missing from the target bug status. - my $missing_transitions = - $dbh->selectcol_arrayref('SELECT sw1.new_status - FROM status_workflow sw1 - WHERE sw1.old_status = ? - AND sw1.new_status NOT IN (SELECT sw2.new_status - FROM status_workflow sw2 - WHERE sw2.old_status = ?)', - undef, ($from_id, $to_id)); - - $dbh->do('UPDATE status_workflow SET old_status = ? WHERE old_status = ? AND ' - . $dbh->sql_in('new_status', $missing_transitions), - undef, ($to_id, $from_id)) if @$missing_transitions; - - # The subselect collects existing transitions to the target bug status. - # The main select collects existing transitions to the renamed bug status. - # The diff tells us which transitions are missing to the target bug status. - # We have to explicitly exclude NULL from the subselect, because NOT IN - # doesn't know what to do with it (neither true nor false) and no data is returned. - $missing_transitions = - $dbh->selectcol_arrayref('SELECT sw1.old_status - FROM status_workflow sw1 - WHERE sw1.new_status = ? - AND sw1.old_status NOT IN (SELECT sw2.old_status - FROM status_workflow sw2 - WHERE sw2.new_status = ? - AND sw2.old_status IS NOT NULL)', - undef, ($from_id, $to_id)); - - $dbh->do('UPDATE status_workflow SET new_status = ? WHERE new_status = ? AND ' - . $dbh->sql_in('old_status', $missing_transitions), - undef, ($to_id, $from_id)) if @$missing_transitions; - - # Delete rows where old_status = new_status, and then the old status itself. - $dbh->do('DELETE FROM status_workflow WHERE old_status = new_status'); - $dbh->do('DELETE FROM bug_status WHERE value = ?', undef, $from); - } - # Otherwise, rename the old status to the new one. - elsif ($old_status) { - $dbh->do('UPDATE bug_status SET value = ? WHERE value = ?', - undef, $to, $from); - } - - Bugzilla::Search::Saved->rename_field_value('bug_status', $from, $to); - Bugzilla::Series->Bugzilla::Search::Saved::rename_field_value('bug_status', - $from, $to); -} -if ($enable_unconfirmed) { - print "Enabling UNCONFIRMED in all products...\n"; - $dbh->do('UPDATE products SET allows_unconfirmed = 1'); -} -$dbh->bz_commit_transaction(); -Bugzilla->memcached->clear_all(); - -print <<END; -Done. There are some things you may want to fix, now: - - * You may want to run ./collectstats.pl --regenerate to regenerate - data for the Old Charts system. - * You may have to fix the Status Workflow using the Status Workflow - panel in "Administration". - * You will probably want to update the "mybugstemplate" and "defaultquery" - parameters using the Parameters panel in "Administration". (Just - resetting them to the default will work.) -END diff --git a/contrib/cvs-update.pl b/contrib/cvs-update.pl deleted file mode 100755 index 32cb5861b..000000000 --- a/contrib/cvs-update.pl +++ /dev/null @@ -1,51 +0,0 @@ -#!/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): Dawn Endico <endico@mozilla.org> -# Jacob Steenhagen <jake@bugzilla.org> -# Jouni Heikniemi <jouni@heikniemi.net> - -# Keep a record of all cvs updates made from a given directory. -# -# Later, if changes need to be backed out, look at the log file -# and run the cvs command with the date that you want to back -# out to. (Probably the second to last entry). - -# Because this script lives in contrib, you may want to -# ln -s contrib/cvs-update.pl cvs-update.pl -# from your bugzilla install directory so you can run -# the script easily from there (./cvs-update.pl) - -#DATE=`date +%e/%m/%Y\ %k:%M:%S\ %Z` - -my ($second, $minute, $hour, $day, $month, $year) = gmtime; -my $date = sprintf("%04d-%02d-%02d %d:%02d:%02dZ", - $year+1900, $month+1, $day, $hour, $minute, $second); -my $cmd = "cvs -q update -dP"; -open LOG, ">>cvs-update.log" or die("Couldn't open cvs update log!"); -print LOG "$cmd -D \"$date\"\n"; -close LOG; -system("$cmd -A"); - -# sample log file -#cvs update -P -D "11/04/2000 20:22:08 PDT" -#cvs update -P -D "11/05/2000 20:22:22 PDT" -#cvs update -P -D "11/07/2000 20:26:29 PDT" -#cvs update -P -D "11/08/2000 20:27:10 PDT" diff --git a/contrib/extension-convert.pl b/contrib/extension-convert.pl deleted file mode 100755 index 88718cf83..000000000 --- a/contrib/extension-convert.pl +++ /dev/null @@ -1,303 +0,0 @@ -#!/usr/bin/perl -w -# -# 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 Everything Solved, Inc. -# Portions created by the Initial Developer are Copyright (C) 2009 the -# Initial Developer. All Rights Reserved. -# -# Contributor(s): -# Max Kanat-Alexander <mkanat@bugzilla.org> - -use strict; -use warnings; -use lib qw(. lib); - -use Bugzilla; -use Bugzilla::Constants; -use Bugzilla::Util qw(trim); - -use File::Basename; -use File::Copy qw(move); -use File::Find; -use File::Path qw(mkpath rmtree); - -my $from = $ARGV[0] - or die <<END; -You must specify the name of the extension you are converting from, -as the first argument. -END -my $extension_name = ucfirst($from); - -my $extdir = bz_locations()->{'extensionsdir'}; - -my $from_dir = "$extdir/$from"; -if (!-d $from_dir) { - die "$from_dir does not exist.\n"; -} - -my $to_dir = "$extdir/$extension_name"; -if (-d $to_dir) { - die "$to_dir already exists, not converting.\n"; -} - -if (ON_WINDOWS) { - # There's no easy way to recursively copy a directory on Windows. - print "WARNING: This will modify the contents of $from_dir.\n", - "Press Ctrl-C to stop or any other key to continue...\n"; - getc; - move($from_dir, $to_dir) - || die "rename of $from_dir to $to_dir failed: $!"; -} -else { - print "Copying $from_dir to $to_dir...\n"; - system("cp", "-r", $from_dir, $to_dir); -} - -# Make sure we don't accidentally modify the $from_dir anywhere else -# in this script. -undef $from_dir; - -if (!-d $to_dir) { - die "$to_dir was not created.\n"; -} - -my $version = get_version($to_dir); -move_template_hooks($to_dir); -rename_module_packages($to_dir, $extension_name); -my $install_requirements = get_install_requirements($to_dir); -my ($modules, $subs) = code_files_to_subroutines($to_dir); - -my $config_pm = <<END; -package Bugzilla::Extension::$extension_name; -use strict; -use constant NAME => '$extension_name'; -$install_requirements -__PACKAGE__->NAME; -END - -my $extension_pm = <<END; -package Bugzilla::Extension::$extension_name; -use strict; -use base qw(Bugzilla::Extension); - -$modules - -our \$VERSION = '$version'; - -$subs - -__PACKAGE__->NAME; -END - -open(my $config_fh, '>', "$to_dir/Config.pm") || die "$to_dir/Config.pm: $!"; -print $config_fh $config_pm; -close($config_fh); -open(my $extension_fh, '>', "$to_dir/Extension.pm") - || die "$to_dir/Extension.pm: $!"; -print $extension_fh $extension_pm; -close($extension_fh); - -rmtree("$to_dir/code"); -unlink("$to_dir/info.pl"); - -############### -# Subroutines # -############### - -sub rename_module_packages { - my ($dir, $name) = @_; - my $lib_dir = "$dir/lib"; - - # We don't want things like Bugzilla::Extension::Testopia::Testopia. - if (-d "$lib_dir/$name") { - print "Moving contents of $lib_dir/$name into $lib_dir...\n"; - foreach my $file (glob("$lib_dir/$name/*")) { - my $dirname = dirname($file); - my $basename = basename($file); - rename($file, "$dirname/../$basename") || warn "$file: $!\n"; - } - } - - my @modules; - find({ wanted => sub { $_ =~ /\.pm$/i and push(@modules, $_) }, - no_chdir => 1 }, $lib_dir); - my %module_rename; - foreach my $file (@modules) { - open(my $fh, '<', $file) || die "$file: $!"; - my $content = do { local $/ = undef; <$fh> }; - close($fh); - if ($content =~ /^package (\S+);/m) { - my $package = $1; - my $new_name = $file; - $new_name =~ s/^$lib_dir\///; - $new_name =~ s/\.pm$//; - $new_name = join('::', File::Spec->splitdir($new_name)); - $new_name = "Bugzilla::Extension::${name}::$new_name"; - print "Renaming $package to $new_name...\n"; - $content =~ s/^package \Q$package\E;/package \Q$new_name\E;/; - open(my $write_fh, '>', $file) || die "$file: $!"; - print $write_fh $content; - close($write_fh); - $module_rename{$package} = $new_name; - } - } - - print "Renaming module names inside of library and code files...\n"; - my @code_files = glob("$dir/code/*.pl"); - rename_modules_internally(\%module_rename, [@modules, @code_files]); -} - -sub rename_modules_internally { - my ($rename, $files) = @_; - - # We can't use \b because :: matches \b. - my $break = qr/^|[^\w:]|$/; - foreach my $file (@$files) { - open(my $fh, '<', $file) || die "$file: $!"; - my $content = do { local $/ = undef; <$fh> }; - close($fh); - foreach my $old_name (keys %$rename) { - my $new_name = $rename->{$old_name}; - $content =~ s/($break)\Q$old_name\E($break)/$1$new_name$2/gms; - } - open(my $write_fh, '>', $file) || die "$file: $!"; - print $write_fh $content; - close($write_fh); - } -} - -sub get_version { - my ($dir) = @_; - print "Getting version info from info.pl...\n"; - my $info; - { - local @INC = ("$dir/lib", @INC); - $info = do "$dir/info.pl"; die $@ if $@; - } - return $info->{version}; -} - -sub get_install_requirements { - my ($dir) = @_; - my $file = "$dir/code/install-requirements.pl"; - return '' if !-f $file; - - print "Moving install-requirements.pl code into Config.pm...\n"; - my ($modules, $code) = process_code_file($file); - $modules = join('', @$modules); - $code = join('', @$code); - if ($modules) { - return "$modules\n\n$code"; - } - return $code; -} - -sub process_code_file { - my ($file) = @_; - open(my $fh, '<', $file) || die "$file: $!"; - my $stuff_started; - my (@modules, @code); - foreach my $line (<$fh>) { - $stuff_started = 1 if $line !~ /^#/; - next if !$stuff_started; - next if $line =~ /^use (warnings|strict|lib|Bugzilla)[^\w:]/; - if ($line =~ /^(?:use|require)\b/) { - push(@modules, $line); - } - else { - push(@code, $line); - } - } - close $fh; - return (\@modules, \@code); -} - -sub code_files_to_subroutines { - my ($dir) = @_; - - my @dir_files = glob("$dir/code/*.pl"); - my (@all_modules, @subroutines); - foreach my $file (@dir_files) { - next if $file =~ /install-requirements/; - print "Moving $file code into Extension.pm...\n"; - my ($modules, $code) = process_code_file($file); - my @code_lines = map { " $_" } @$code; - my $code_string = join('', @code_lines); - $code_string =~ s/Bugzilla->hook_args/\$args/g; - $code_string =~ s/my\s+\$args\s+=\s+\$args;//gs; - chomp($code_string); - push(@all_modules, @$modules); - my $name = basename($file); - $name =~ s/-/_/; - $name =~ s/\.pl$//; - - my $subroutine = <<END; -sub $name { - my (\$self, \$args) = \@_; -$code_string -} -END - push(@subroutines, $subroutine); - } - - my %seen_modules = map { trim($_) => 1 } @all_modules; - my $module_string = join("\n", sort keys %seen_modules); - my $subroutine_string = join("\n", @subroutines); - return ($module_string, $subroutine_string); -} - -sub move_template_hooks { - my ($dir) = @_; - foreach my $lang (glob("$dir/template/*")) { - next if !_file_matters($lang); - my $hook_container = "$lang/default/hook"; - mkpath($hook_container) || warn "$hook_container: $!"; - # Hooks can be in all sorts of weird places, including - # template/default/hook. - foreach my $file (glob("$lang/*")) { - next if !_file_matters($file, 1); - my $dirname = basename($file); - print "Moving $file to $hook_container/$dirname...\n"; - rename($file, "$hook_container/$dirname") || die "move failed: $!"; - } - } -} - -sub _file_matters { - my ($path, $tmpl) = @_; - my @ignore = qw(default custom CVS); - my $file = basename($path); - return 0 if grep(lc($_) eq lc($file), @ignore); - # Hidden files - return 0 if $file =~ /^\./; - if ($tmpl) { - return 1 if $file =~ /\.tmpl$/; - } - return 0 if !-d $path; - return 1; -} - -__END__ - -=head1 NAME - -extension-convert.pl - Convert extensions from the pre-3.6 format to the -3.6 format. - -=head1 SYNOPSIS - - contrib/extension-convert.pl name - - Converts an extension in the F<extensions/> directory into the new - extension layout for Bugzilla 3.6. diff --git a/contrib/fix_comment_text.pl b/contrib/fix_comment_text.pl deleted file mode 100755 index f17bbc3d4..000000000 --- a/contrib/fix_comment_text.pl +++ /dev/null @@ -1,75 +0,0 @@ -#!/usr/bin/perl -# -*- 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 Initial Developer of the Original Code is Mozilla Foundation -# Portions created by the Initial Developer are Copyright (C) 2011 the -# Initial Developer. All Rights Reserved. -# -#=============================================================================== -# -# FILE: fix_comment_text.pl -# -# USAGE: ./fix_comment_text.pl <comment_id> -# -# DESCRIPTION: Updates a comment in Bugzilla with the text after __DATA__ -# -# OPTIONS: <comment_id> - The comment id from longdescs with the comment -# to be replaced. -# REQUIREMENTS: --- -# BUGS: --- -# NOTES: --- -# AUTHOR: David Lawrence (:dkl), dkl@mozilla.com -# COMPANY: Mozilla Foundation -# VERSION: 1.0 -# CREATED: 06/20/2011 03:40:22 PM -# REVISION: --- -#=============================================================================== - -use strict; -use warnings; - -use lib "."; - -use Bugzilla; -use Bugzilla::Util qw(detaint_natural); - -my $comment_id = shift; - -if (!detaint_natural($comment_id)) { - print "Error: invalid comment id or comment id not provided.\n" . - "Usage: ./fix_comment_text.pl <comment_id>\n"; - exit(1); -} - -my $dbh = Bugzilla->dbh; - -my $comment = join("", <DATA>); - -if ($comment =~ /ENTER NEW COMMENT TEXT HERE/) { - print "Please enter the new comment text in the script " . - "after the __DATA__ marker.\n"; - exit(1); -} - -$dbh->bz_start_transaction; - -Bugzilla->dbh->do( - "UPDATE longdescs SET thetext = ? WHERE comment_id = ?", - undef, $comment, $comment_id); - -$dbh->bz_commit_transaction; - -exit(0); - -__DATA__ -ENTER NEW COMMENT TEXT HERE BELOW THE __DATA__ MARKER! diff --git a/contrib/issue-api-key.pl b/contrib/issue-api-key.pl deleted file mode 100755 index fe24f59df..000000000 --- a/contrib/issue-api-key.pl +++ /dev/null @@ -1,25 +0,0 @@ -#!/usr/bin/perl -w -use strict; -use feature 'say'; - -use FindBin qw( $RealBin ); -use lib "$RealBin/.."; -use lib "$RealBin/../lib"; - -use Bugzilla; -use Bugzilla::Constants; -use Bugzilla::User; -use Bugzilla::User::APIKey; - -Bugzilla->usage_mode(USAGE_MODE_CMDLINE); - -my $login = shift - or die "syntax: $0 bugzilla-login [description]\n"; -my $description = shift; - -my $user = Bugzilla::User->check({ name => $login }); -my $api_key = Bugzilla::User::APIKey->create({ - user_id => $user->id, - description => $description, -}); -say $api_key->api_key; diff --git a/contrib/jb2bz.py b/contrib/jb2bz.py deleted file mode 100755 index 55cb056b5..000000000 --- a/contrib/jb2bz.py +++ /dev/null @@ -1,308 +0,0 @@ -#!/usr/local/bin/python -# -*- mode: python -*- - -""" -jb2bz.py - a nonce script to import bugs from JitterBug to Bugzilla -Written by Tom Emerson, tree@basistech.com - -This script is provided in the hopes that it will be useful. No -rights reserved. No guarantees expressed or implied. Use at your own -risk. May be dangerous if swallowed. If it doesn't work for you, don't -blame me. It did what I needed it to do. - -This code requires a recent version of Andy Dustman's MySQLdb interface, - - http://sourceforge.net/projects/mysql-python - -Share and enjoy. -""" - -import rfc822, mimetools, multifile, mimetypes -import sys, re, glob, StringIO, os, stat, time -import MySQLdb, getopt - -# mimetypes doesn't include everything we might encounter, yet. -if not mimetypes.types_map.has_key('.doc'): - mimetypes.types_map['.doc'] = 'application/msword' - -if not mimetypes.encodings_map.has_key('.bz2'): - mimetypes.encodings_map['.bz2'] = "bzip2" - -bug_status='CONFIRMED' -component="default" -version="" -product="" # this is required, the rest of these are defaulted as above - -""" -Each bug in JitterBug is stored as a text file named by the bug number. -Additions to the bug are indicated by suffixes to this: - -<bug> -<bug>.followup.* -<bug>.reply.* -<bug>.notes - -The dates on the files represent the respective dates they were created/added. - -All <bug>s and <bug>.reply.*s include RFC 822 mail headers. These could include -MIME file attachments as well that would need to be extracted. - -There are other additions to the file names, such as - -<bug>.notify - -which are ignored. - -Bugs in JitterBug are organized into directories. At Basis we used the following -naming conventions: - -<product>-bugs Open bugs -<product>-requests Open Feature Requests -<product>-resolved Bugs/Features marked fixed by engineering, but not verified -<product>-verified Resolved defects that have been verified by QA - -where <product> is either: - -<product-name> - -or - -<product-name>-<version> -""" - -def process_notes_file(current, fname): - try: - new_note = {} - notes = open(fname, "r") - s = os.fstat(notes.fileno()) - - new_note['text'] = notes.read() - new_note['timestamp'] = time.gmtime(s[stat.ST_MTIME]) - - notes.close() - - current['notes'].append(new_note) - - except IOError: - pass - -def process_reply_file(current, fname): - new_note = {} - reply = open(fname, "r") - msg = rfc822.Message(reply) - new_note['text'] = "%s\n%s" % (msg['From'], msg.fp.read()) - new_note['timestamp'] = rfc822.parsedate_tz(msg['Date']) - current["notes"].append(new_note) - -def add_notes(current): - """Add any notes that have been recorded for the current bug.""" - process_notes_file(current, "%d.notes" % current['number']) - - for f in glob.glob("%d.reply.*" % current['number']): - process_reply_file(current, f) - - for f in glob.glob("%d.followup.*" % current['number']): - process_reply_file(current, f) - -def maybe_add_attachment(current, file, submsg): - """Adds the attachment to the current record""" - cd = submsg["Content-Disposition"] - m = re.search(r'filename="([^"]+)"', cd) - if m == None: - return - attachment_filename = m.group(1) - if (submsg.gettype() == 'application/octet-stream'): - # try get a more specific content-type for this attachment - type, encoding = mimetypes.guess_type(m.group(1)) - if type == None: - type = submsg.gettype() - else: - type = submsg.gettype() - - try: - data = StringIO.StringIO() - mimetools.decode(file, data, submsg.getencoding()) - except: - return - - current['attachments'].append( ( attachment_filename, type, data.getvalue() ) ) - -def process_mime_body(current, file, submsg): - data = StringIO.StringIO() - mimetools.decode(file, data, submsg.getencoding()) - current['description'] = data.getvalue() - - - -def process_text_plain(msg, current): - print "Processing: %d" % current['number'] - current['description'] = msg.fp.read() - -def process_multi_part(file, msg, current): - print "Processing: %d" % current['number'] - mf = multifile.MultiFile(file) - mf.push(msg.getparam("boundary")) - while mf.next(): - submsg = mimetools.Message(file) - if submsg.has_key("Content-Disposition"): - maybe_add_attachment(current, mf, submsg) - else: - # This is the message body itself (always?), so process - # accordingly - process_mime_body(current, mf, submsg) - -def process_jitterbug(filename): - current = {} - current['number'] = int(filename) - current['notes'] = [] - current['attachments'] = [] - current['description'] = '' - current['date-reported'] = () - current['short-description'] = '' - - file = open(filename, "r") - msg = mimetools.Message(file) - - msgtype = msg.gettype() - - add_notes(current) - current['date-reported'] = rfc822.parsedate_tz(msg['Date']) - current['short-description'] = msg['Subject'] - - if msgtype[:5] == 'text/': - process_text_plain(msg, current) - elif msgtype[:10] == "multipart/": - process_multi_part(file, msg, current) - else: - # Huh? This should never happen. - print "Unknown content-type: %s" % msgtype - sys.exit(1) - - # At this point we have processed the message: we have all of the notes and - # attachments stored, so it's time to add things to the database. - # The schema for JitterBug 2.14 can be found at: - # - # http://www.trilobyte.net/barnsons/html/dbschema.html - # - # The following fields need to be provided by the user: - # - # bug_status - # product - # version - # reporter - # component - # resolution - - # change this to the user_id of the Bugzilla user who is blessed with the - # imported defects - reporter=6 - - # the resolution will need to be set manually - resolution="" - - db = MySQLdb.connect(db='bugs',user='root',host='localhost') - cursor = db.cursor() - - cursor.execute( "INSERT INTO bugs SET " \ - "bug_id=%s," \ - "bug_severity='normal'," \ - "bug_status=%s," \ - "creation_ts=%s," \ - "delta_ts=%s," \ - "short_desc=%s," \ - "product=%s," \ - "rep_platform='All'," \ - "assigned_to=%s," - "reporter=%s," \ - "version=%s," \ - "component=%s," \ - "resolution=%s", - [ current['number'], - bug_status, - time.strftime("%Y-%m-%d %H:%M:%S", current['date-reported'][:9]), - time.strftime("%Y-%m-%d %H:%M:%S", current['date-reported'][:9]), - current['short-description'], - product, - reporter, - reporter, - version, - component, - resolution] ) - - # This is the initial long description associated with the bug report - cursor.execute( "INSERT INTO longdescs VALUES (%s,%s,%s,%s)", - [ current['number'], - reporter, - time.strftime("%Y-%m-%d %H:%M:%S", current['date-reported'][:9]), - current['description'] ] ) - - # Add whatever notes are associated with this defect - for n in current['notes']: - cursor.execute( "INSERT INTO longdescs VALUES (%s,%s,%s,%s)", - [current['number'], - reporter, - time.strftime("%Y-%m-%d %H:%M:%S", n['timestamp'][:9]), - n['text']]) - - # add attachments associated with this defect - for a in current['attachments']: - cursor.execute( "INSERT INTO attachments SET " \ - "bug_id=%s, creation_ts=%s, description='', mimetype=%s," \ - "filename=%s, submitter_id=%s", - [ current['number'], - time.strftime("%Y-%m-%d %H:%M:%S", current['date-reported'][:9]), - a[1], a[0], reporter ]) - cursor.execute( "INSERT INTO attach_data SET " \ - "id=LAST_INSERT_ID(), thedata=%s", - [ a[2] ]) - - cursor.close() - db.close() - -def usage(): - print """Usage: jb2bz.py [OPTIONS] Product - -Where OPTIONS are one or more of the following: - - -h This help information. - -s STATUS One of UNCONFIRMED, CONFIRMED, IN_PROGRESS, RESOLVED, VERIFIED - (default is CONFIRMED) - -c COMPONENT The component to attach to each bug as it is important. This should be - valid component for the Product. - -v VERSION Version to assign to these defects. - -Product is the Product to assign these defects to. - -All of the JitterBugs in the current directory are imported, including replies, notes, -attachments, and similar noise. -""" - sys.exit(1) - - -def main(): - global bug_status, component, version, product - opts, args = getopt.getopt(sys.argv[1:], "hs:c:v:") - - for o,a in opts: - if o == "-s": - if a in ('UNCONFIRMED','CONFIRMED','IN_PROGRESS','RESOLVED','VERIFIED'): - bug_status = a - elif o == '-c': - component = a - elif o == '-v': - version = a - elif o == '-h': - usage() - - if len(args) != 1: - sys.stderr.write("Must specify the Product.\n") - sys.exit(1) - - product = args[0] - - for bug in filter(lambda x: re.match(r"\d+$", x), glob.glob("*")): - process_jitterbug(bug) - - -if __name__ == "__main__": - main() diff --git a/contrib/merge-users.pl b/contrib/merge-users.pl deleted file mode 100755 index aeb8156ad..000000000 --- a/contrib/merge-users.pl +++ /dev/null @@ -1,271 +0,0 @@ -#!/usr/bin/perl -wT -# -*- 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): Myk Melez <myk@mozilla.org> -# Frédéric Buclin <LpSolit@gmail.com> - -use strict; - -=head1 NAME - -merge-users.pl - Merge two user accounts. - -=head1 SYNOPSIS - - This script moves activity from one user account to another. - Specify the two accounts on the command line, e.g.: - - ./merge-users.pl old_account@foo.com new_account@bar.com - or: - ./merge-users.pl id:old_userid id:new_userid - or: - ./merge-users.pl id:old_userid new_account@bar.com - - Notes: - the new account must already exist. - - the id:old_userid syntax permits you to migrate - activity from a deleted account to an existing one. - -=cut - -use lib qw(. lib); - -use Bugzilla; -use Bugzilla::Constants; -use Bugzilla::Util; -use Bugzilla::User; -use Bugzilla::Hook; - -use Getopt::Long; -use Pod::Usage; - -my $dbh = Bugzilla->dbh; - -# Display the help if called with --help or -?. -my $help = 0; -my $result = GetOptions("help|?" => \$help); -pod2usage(0) if $help; - - -# Make sure accounts were specified on the command line and exist. -my $old = $ARGV[0] || die "You must specify an old user account.\n"; -my $old_id; -if ($old =~ /^id:(\d+)$/) { - # As the old user account may be a deleted one, we don't - # check whether this user ID is valid or not. - # If it never existed, no damage will be done. - $old_id = $1; -} -else { - trick_taint($old); - $old_id = $dbh->selectrow_array('SELECT userid FROM profiles - WHERE login_name = ?', - undef, $old); -} -if ($old_id) { - print "OK, old user account $old found; user ID: $old_id.\n"; -} -else { - die "The old user account $old does not exist.\n"; -} - -my $new = $ARGV[1] || die "You must specify a new user account.\n"; -my $new_id; -if ($new =~ /^id:(\d+)$/) { - $new_id = $1; - # Make sure this user ID exists. - $new_id = $dbh->selectrow_array('SELECT userid FROM profiles - WHERE userid = ?', - undef, $new_id); -} -else { - trick_taint($new); - $new_id = $dbh->selectrow_array('SELECT userid FROM profiles - WHERE login_name = ?', - undef, $new); -} -if ($new_id) { - print "OK, new user account $new found; user ID: $new_id.\n"; -} -else { - die "The new user account $new does not exist.\n"; -} - -# Make sure the old and new accounts are different. -if ($old_id == $new_id) { - die "\nBoth accounts are identical. There is nothing to migrate.\n"; -} - - -# A list of tables and columns to be changed: -# - keys of the hash are table names to be locked/altered; -# - values of the hash contain column names to be updated -# as well as the columns they depend on: -# = each array is of the form: -# ['foo1 bar11 bar12 bar13', 'foo2 bar21 bar22', 'foo3 bar31 bar32'] -# where fooN is the column to update, and barN1, barN2, ... are -# the columns to take into account to avoid duplicated entries. -# Note that the barNM columns are optional. -# -# We set the tables that require custom stuff (multiple columns to check) -# here, but the simple stuff is all handled below by bz_get_related_fks. -my %changes = ( - cc => ['who bug_id'], - # Tables affecting global behavior / other users. - component_cc => ['user_id component_id'], - watch => ['watcher watched', 'watched watcher'], - # Tables affecting the user directly. - namedqueries => ['userid name'], - namedqueries_link_in_footer => ['user_id namedquery_id'], - user_group_map => ['user_id group_id isbless grant_type'], - email_setting => ['user_id relationship event'], - profile_setting => ['user_id setting_name'], - - # Only do it if mailto_type = 0, i.e is pointing to a user account! - # This requires to be done separately due to this condition. - whine_schedules => [], # ['mailto'], -); - -my $userid_fks = $dbh->bz_get_related_fks('profiles', 'userid'); -foreach my $item (@$userid_fks) { - my ($table, $column) = @$item; - $changes{$table} ||= []; - push(@{ $changes{$table} }, $column); -} - -# Delete all old records for these tables; no migration. -foreach my $table (qw(logincookies tokens profiles)) { - $changes{$table} = []; -} - -# Start the transaction -$dbh->bz_start_transaction(); - -# BMO - pre-work hook -Bugzilla::Hook::process('merge_users_before', { old_id => $old_id, new_id => $new_id }); - -# Delete old records from logincookies and tokens tables. -$dbh->do('DELETE FROM logincookies WHERE userid = ?', undef, $old_id); -$dbh->do('DELETE FROM tokens WHERE userid = ?', undef, $old_id); - -# Special care needs to be done with bug_user_last_visit table as the -# source user and destination user may have visited the same bug id at one time. -# In this case we remove the one with the oldest timestamp. -my $dupe_ids = $dbh->selectcol_arrayref(" - SELECT earlier.id - FROM bug_user_last_visit as earlier - INNER JOIN bug_user_last_visit as later - ON (earlier.user_id != later.user_id - AND earlier.last_visit_ts < later.last_visit_ts - AND earlier.bug_id = later.bug_id) - WHERE (earlier.user_id = ? OR earlier.user_id = ?) - AND (later.user_id = ? OR later.user_id = ?)", - undef, $old_id, $new_id, $old_id, $new_id); - -if (@$dupe_ids) { - $dbh->do("DELETE FROM bug_user_last_visit WHERE " . - $dbh->sql_in('id', $dupe_ids)); -} - -# Migrate records from old user to new user. -foreach my $table (keys %changes) { - foreach my $column_list (@{ $changes{$table} }) { - # Get all columns to consider. There is always at least - # one column given: the one to update. - my @columns = split(/[\s]+/, $column_list); - my $cols_to_check = join(' AND ', map {"$_ = ?"} @columns); - # The first column of the list is the one to update. - my $col_to_update = shift @columns; - - # Will be used to migrate the old user account to the new one. - my $sth_update = $dbh->prepare("UPDATE $table - SET $col_to_update = ? - WHERE $cols_to_check"); - - # Do we have additional columns to take care of? - if (scalar(@columns)) { - my $cols_to_query = join(', ', @columns); - - # Get existing entries for the old user account. - my $old_entries = - $dbh->selectall_arrayref("SELECT $cols_to_query - FROM $table - WHERE $col_to_update = ?", - undef, $old_id); - - # Will be used to check whether the same entry exists - # for the new user account. - my $sth_select = $dbh->prepare("SELECT COUNT(*) - FROM $table - WHERE $cols_to_check"); - - # Will be used to delete duplicated entries. - my $sth_delete = $dbh->prepare("DELETE FROM $table - WHERE $cols_to_check"); - - foreach my $entry (@$old_entries) { - my $exists = $dbh->selectrow_array($sth_select, undef, - ($new_id, @$entry)); - - if ($exists) { - $sth_delete->execute($old_id, @$entry); - } - else { - $sth_update->execute($new_id, $old_id, @$entry); - } - } - } - # No check required. Update the column directly. - else { - $sth_update->execute($new_id, $old_id); - } - print "OK, records in the '$col_to_update' column of the '$table' table\n" . - "have been migrated to the new user account.\n"; - } -} - -# Only update 'whine_schedules' if mailto_type = 0. -# (i.e. is pointing to a user ID). -$dbh->do('UPDATE whine_schedules SET mailto = ? - WHERE mailto = ? AND mailto_type = ?', - undef, ($new_id, $old_id, 0)); -print "OK, records in the 'mailto' column of the 'whine_schedules' table\n" . - "have been migrated to the new user account.\n"; - -# Delete the old record from the profiles table. -$dbh->do('DELETE FROM profiles WHERE userid = ?', undef, $old_id); - -# rederive regexp-based group memberships, because we merged all memberships -# from all of the accounts, and since the email address isn't the same on -# them, some of them may no longer match the regexps. -my $user = new Bugzilla::User($new_id); -$user->derive_regexp_groups(); - -# BMO - post-work hook -Bugzilla::Hook::process('merge_users_after', { old_id => $old_id, new_id => $new_id }); - -# Commit the transaction -$dbh->bz_commit_transaction(); - -# It's complex to determine which items now need to be flushed from memcached. -# As user merge is expected to be a rare event, we just flush the entire cache -# when users are merged. -Bugzilla->memcached->clear_all(); - -print "Done.\n"; diff --git a/contrib/moco-ldap-check.pl b/contrib/moco-ldap-check.pl deleted file mode 100755 index 7a3a6ca8c..000000000 --- a/contrib/moco-ldap-check.pl +++ /dev/null @@ -1,542 +0,0 @@ -#!/usr/bin/perl - -# 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 warnings; - -use FindBin qw($Bin); -use lib "$Bin/.."; -use lib "$Bin/../lib"; - -use Bugzilla; -use Bugzilla::Constants; -use Bugzilla::Group; -use Bugzilla::Mailer; -use Data::Dumper; -use File::Slurp; -use Getopt::Long; -use Net::LDAP; -use Safe; - -# - -use constant BUGZILLA_IGNORE => <<'EOF'; - infra+bot@mozilla.com # Mozilla Infrastructure Bot - qa-auto@mozilla.com # QA Desktop Automation - qualys@mozilla.com # Qualys Security Scanner - recruiting@mozilla.com # Recruiting - release@mozilla.com # Mozilla RelEng Bot - sumo-dev@mozilla.com # SUMOdev [:sumodev] - airmozilla@mozilla.com # Air Mozilla - ux-review@mozilla.com - release-mgmt@mozilla.com - reps@mozilla.com - moz_bug_r_a4@mozilla.com # Security contractor - nightwatch@mozilla.com # Security distribution list for whines -EOF - -use constant LDAP_IGNORE => <<'EOF'; - airmozilla@mozilla.com # Air Mozilla -EOF - -# REPORT_SENDER has to be a valid @mozilla.com LDAP account -use constant REPORT_SENDER => 'bjones@mozilla.com'; - -use constant BMO_RECIPIENTS => qw( - glob@mozilla.com - dkl@mozilla.com -); - -use constant SUPPORT_RECIPIENTS => qw( - desktop@mozilla.com -); - -# - -my ($ldap_host, $ldap_user, $ldap_pass, $debug, $no_update); -GetOptions('h=s' => \$ldap_host, - 'u=s' => \$ldap_user, - 'p=s' => \$ldap_pass, - 'd' => \$debug, - 'n' => \$no_update); -die "syntax: -h ldap_host -u ldap_user -p ldap_pass\n" - unless $ldap_host && $ldap_user && $ldap_pass; - -my $data_dir = bz_locations()->{'datadir'} . '/moco-ldap-check'; -mkdir($data_dir) unless -d $data_dir; - -if ($ldap_user !~ /,/) { - $ldap_user = "mail=$ldap_user,o=com,dc=mozilla"; -} - -# -# group members -# - -my @bugzilla_ignore; -foreach my $line (split(/\n/, BUGZILLA_IGNORE)) { - $line =~ s/^([^#]+)#.*$/$1/; - $line =~ s/(^\s+|\s+$)//g; - push @bugzilla_ignore, clean_email($line); -} - -my @bugzilla_moco; -if ($no_update && -s "$data_dir/bugzilla_moco.last") { - $debug && print "Using cached user list from Bugzilla...\n"; - my $ra = deserialise("$data_dir/bugzilla_moco.last"); - @bugzilla_moco = @$ra; -} else { - $debug && print "Getting user list from Bugzilla...\n"; - - my $group = Bugzilla::Group->new({ name => 'mozilla-corporation' }) - or die "Failed to find group mozilla-corporation\n"; - - foreach my $user (@{ $group->members_non_inherited }) { - next unless $user->is_enabled; - my $mail = clean_email($user->login); - my $name = trim($user->name); - $name =~ s/\s+/ /g; - next if grep { $mail eq $_ } @bugzilla_ignore; - push @bugzilla_moco, { - mail => $user->login, - canon => $mail, - name => $name, - }; - } - - @bugzilla_moco = sort { $a->{mail} cmp $b->{mail} } @bugzilla_moco; - serialise("$data_dir/bugzilla_moco.last", \@bugzilla_moco); -} - -# -# build list of current mo-co bugmail accounts -# - -my @ldap_ignore; -foreach my $line (split(/\n/, LDAP_IGNORE)) { - $line =~ s/^([^#]+)#.*$/$1/; - $line =~ s/(^\s+|\s+$)//g; - push @ldap_ignore, canon_email($line); -} - -my %ldap; -if ($no_update && -s "$data_dir/ldap.last") { - $debug && print "Using cached user list from LDAP...\n"; - my $rh = deserialise("$data_dir/ldap.last"); - %ldap = %$rh; -} else { - $debug && print "Logging into LDAP as $ldap_user...\n"; - my $ldap = Net::LDAP->new($ldap_host, - scheme => 'ldaps', onerror => 'die') or die "$@"; - $ldap->bind($ldap_user, password => $ldap_pass); - foreach my $ldap_base ('o=com,dc=mozilla', 'o=org,dc=mozilla') { - $debug && print "Getting user list from LDAP $ldap_base...\n"; - my $result = $ldap->search( - base => $ldap_base, - scope => 'sub', - filter => '(mail=*)', - attrs => ['mail', 'bugzillaEmail', 'emailAlias', 'cn', 'employeeType'], - ); - foreach my $entry ($result->entries) { - my ($name, $bugMail, $mail, $type) = - map { $entry->get_value($_) || '' } - qw(cn bugzillaEmail mail employeeType); - next if $type eq 'DISABLED'; - $mail = lc $mail; - next if grep { $_ eq canon_email($mail) } @ldap_ignore; - $bugMail = '' if $bugMail !~ /\@/; - $bugMail =~ s/(^\s+|\s+$)//g; - if ($bugMail =~ / /) { - $bugMail = (grep { /\@/ } split / /, $bugMail)[0]; - } - $name =~ s/\s+/ /g; - $ldap{$mail}{name} = trim($name); - $ldap{$mail}{bugmail} = $bugMail; - $ldap{$mail}{bugmail_canon} = canon_email($bugMail); - $ldap{$mail}{aliases} = []; - foreach my $alias ( - @{$entry->get_value('emailAlias', asref => 1) || []} - ) { - push @{$ldap{$mail}{aliases}}, canon_email($alias); - } - } - $debug && printf "Found %s entries\n", scalar($result->entries); - } - serialise("$data_dir/ldap.last", \%ldap); -} - -# -# validate all bugmail entries from the phonebook -# - -my %bugzilla_login; -if ($no_update && -s "$data_dir/bugzilla_login.last") { - $debug && print "Using cached bugzilla checks...\n"; - my $rh = deserialise("$data_dir/bugzilla_login.last"); - %bugzilla_login = %$rh; -} else { - my %logins; - foreach my $mail (keys %ldap) { - $logins{$mail} = 1; - $logins{$ldap{$mail}{bugmail}} = 1 if $ldap{$mail}{bugmail}; - } - my @logins = sort keys %logins; - $debug && print "Checking " . scalar(@logins) . " bugmail accounts...\n"; - - foreach my $login (@logins) { - if (Bugzilla::User->new({ name => $login })) { - $bugzilla_login{$login} = 1; - } - } - serialise("$data_dir/bugzilla_login.last", \%bugzilla_login); -} - -# -# load previous ldap list -# - -my %ldap_old; -{ - my $rh = deserialise("$data_dir/ldap.data"); - %ldap_old = %$rh if $rh; -} - -# -# save current ldap list -# - -{ - serialise("$data_dir/ldap.data", \%ldap); -} - -# -# new ldap accounts -# - -my @new_ldap; -{ - foreach my $mail (sort keys %ldap) { - next if exists $ldap_old{$mail}; - push @new_ldap, { - mail => $mail, - name => $ldap{$mail}{name}, - bugmail => $ldap{$mail}{bugmail}, - }; - } -} - -# -# deleted ldap accounts -# - -my @gone_ldap_bmo; -my @gone_ldap_no_bmo; -{ - foreach my $mail (sort keys %ldap_old) { - next if exists $ldap{$mail}; - if ($ldap_old{$mail}{bugmail}) { - push @gone_ldap_bmo, { - mail => $mail, - name => $ldap_old{$mail}{name}, - bugmail => $ldap_old{$mail}{bugmail}, - } - } else { - push @gone_ldap_no_bmo, { - mail => $mail, - name => $ldap_old{$mail}{name}, - } - } - } -} - -# -# check bugmail entry for all users in bmo/moco group -# - -my @suspect_bugzilla; -my @invalid_bugzilla; -foreach my $rh (@bugzilla_moco) { - my @check = ($rh->{mail}, $rh->{canon}); - if ($rh->{mail} =~ /^([^\@]+)\@mozilla\.org$/) { - push @check, "$1\@mozilla.com"; - } - - my $exists; - foreach my $check (@check) { - $exists = 0; - - # don't complain about deleted accounts - if (grep { $_->{mail} eq $check } (@gone_ldap_bmo, @gone_ldap_no_bmo)) { - $exists = 1; - last; - } - - # check for matching bugmail entry - foreach my $mail (sort keys %ldap) { - next unless $ldap{$mail}{bugmail_canon} eq $check; - $exists = 1; - last; - } - last if $exists; - - # check for matching mail - $exists = 0; - foreach my $mail (sort keys %ldap) { - next unless $mail eq $check; - $exists = 1; - last; - } - last if $exists; - - # check for matching email alias - $exists = 0; - foreach my $mail (sort keys %ldap) { - next unless grep { $check eq $_ } @{$ldap{$mail}{aliases}}; - $exists = 1; - last; - } - last if $exists; - } - - if (!$exists) { - # flag the account - if ($rh->{mail} =~ /\@mozilla\.(com|org)$/i) { - push @invalid_bugzilla, { - mail => $rh->{mail}, - name => $rh->{name}, - }; - } else { - push @suspect_bugzilla, { - mail => $rh->{mail}, - name => $rh->{name}, - }; - } - } -} - -# -# check bugmail entry for ldap users -# - -my @ldap_unblessed; -my @invalid_ldap; -my @invalid_bugmail; -foreach my $mail (sort keys %ldap) { - # try to find the bmo account - my $found; - foreach my $address ($ldap{$mail}{bugmail}, $ldap{$mail}{bugmail_canon}, $mail, @{$ldap{$mail}{aliases}}) { - if (exists $bugzilla_login{$address}) { - $found = $address; - last; - } - } - - # not on bmo - if (!$found) { - # if they have specified a bugmail account, warn, otherwise ignore - if ($ldap{$mail}{bugmail}) { - if (grep { $_->{canon} eq $ldap{$mail}{bugmail_canon} } @bugzilla_moco) { - push @invalid_bugmail, { - mail => $mail, - name => $ldap{$mail}{name}, - bugmail => $ldap{$mail}{bugmail}, - }; - } else { - push @invalid_ldap, { - mail => $mail, - name => $ldap{$mail}{name}, - bugmail => $ldap{$mail}{bugmail}, - }; - } - } - next; - } - - # warn about mismatches - if ($ldap{$mail}{bugmail} && $found ne $ldap{$mail}{bugmail}) { - push @invalid_bugmail, { - mail => $mail, - name => $ldap{$mail}{name}, - bugmail => $ldap{$mail}{bugmail}, - }; - } - - # warn about unblessed accounts - if ($mail =~ /\@mozilla\.com$/) { - unless (grep { $_->{mail} eq $found || $_->{canon} eq canon_email($found) } @bugzilla_moco) { - push @ldap_unblessed, { - mail => $mail, - name => $ldap{$mail}{name}, - bugmail => $ldap{$mail}{bugmail} || $mail, - }; - } - } -} - -# -# reports -# - -my @bmo_report; -push @bmo_report, generate_report( - 'new ldap accounts', - 'no action required', - @new_ldap); - -push @bmo_report, generate_report( - 'deleted ldap accounts', - 'disable bmo account', - @gone_ldap_bmo); - -push @bmo_report, generate_report( - 'deleted ldap accounts', - 'no action required (no bmo account)', - @gone_ldap_no_bmo); - -push @bmo_report, generate_report( - 'suspect bugzilla accounts', - 'remove from mo-co if required', - @suspect_bugzilla); - -push @bmo_report, generate_report( - 'miss-configured bugzilla accounts', - 'ask owner to update phonebook, disable if not on phonebook', - @invalid_bugzilla); - -push @bmo_report, generate_report( - 'ldap accounts without mo-co group', - 'verify, and add mo-co group to bmo account', - @ldap_unblessed); - -push @bmo_report, generate_report( - 'missmatched bugmail entries on ldap accounts', - 'ask owner to update phonebook', - @invalid_bugmail); - -push @bmo_report, generate_report( - 'invalid bugmail entries on ldap accounts', - 'ask owner to update phonebook', - @invalid_ldap); - -if (!scalar @bmo_report) { - push @bmo_report, '**'; - push @bmo_report, '** nothing to report \o/'; - push @bmo_report, '**'; -} - -email_report(\@bmo_report, 'moco-ldap-check', BMO_RECIPIENTS); - -my @support_report; - -push @support_report, generate_report( - 'Missmatched "Bugzilla Email" entries on LDAP accounts', - 'Ask owner to update phonebook, or update directly', - @invalid_bugmail); - -push @support_report, generate_report( - 'Invalid "Bugzilla Email" entries on LDAP accounts', - 'Ask owner to update phonebook', - @invalid_ldap); - -if (scalar @support_report) { - email_report(\@support_report, 'Invalid "Bugzilla Email" entries in LDAP', SUPPORT_RECIPIENTS); -} - -# -# -# - -sub generate_report { - my ($title, $action, @lines) = @_; - - my $count = scalar @lines; - return unless $count; - - my @report; - push @report, ''; - push @report, '**'; - push @report, "** $title ($count)"; - push @report, "** [ $action ]"; - push @report, '**'; - push @report, ''; - - my $max_length = 0; - foreach my $rh (@lines) { - $max_length = length($rh->{mail}) if length($rh->{mail}) > $max_length; - } - - foreach my $rh (@lines) { - my $template = "%-${max_length}s %s"; - my @fields = ($rh->{mail}, $rh->{name}); - - if ($rh->{bugmail}) { - $template .= ' (%s)'; - push @fields, $rh->{bugmail}; - }; - - push @report, sprintf($template, @fields); - } - - return @report; -} - -sub email_report { - my ($report, $subject, @recipients) = @_; - unshift @$report, ( - "Subject: $subject", - 'X-Bugzilla-Type: moco-ldap-check', - 'From: ' . REPORT_SENDER, - 'To: ' . join(',', @recipients), - ); - if ($debug) { - print "\n", join("\n", @$report), "\n"; - } else { - MessageToMTA(join("\n", @$report)); - } -} - -sub clean_email { - my $email = shift; - $email = trim($email); - $email = $1 if $email =~ /^(\S+)/; - $email =~ s/@/@/; - $email = lc $email; - return $email; -} - -sub canon_email { - my $email = shift; - $email = clean_email($email); - $email =~ s/^([^\+]+)\+[^\@]+(\@.+)$/$1$2/; - return $email; -} - -sub trim { - my $value = shift; - $value =~ s/(^\s+|\s+$)//g; - return $value; -} - -sub serialise { - my ($filename, $ref) = @_; - local $Data::Dumper::Purity = 1; - local $Data::Dumper::Deepcopy = 1; - local $Data::Dumper::Sortkeys = 1; - write_file($filename, Dumper($ref)); -} - -sub deserialise { - my ($filename) = @_; - return unless -s $filename; - my $cpt = Safe->new(); - $cpt->reval('our ' . read_file($filename)) - || die "$!"; - return ${$cpt->varglob('VAR1')}; -} - diff --git a/contrib/mysqld-watcher.pl b/contrib/mysqld-watcher.pl deleted file mode 100755 index a70e2250a..000000000 --- a/contrib/mysqld-watcher.pl +++ /dev/null @@ -1,117 +0,0 @@ -#!/usr/bin/perl -w -# -# 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) 2000 Netscape Communications Corporation. All -# Rights Reserved. -# -# Contributor(s): Dan Mosedale <dmose@mozilla.org> -# - -# mysqld-watcher.pl - a script that watches the running instance of -# mysqld and kills off any long-running SELECTs against the shadow_db -# -use strict; - -# some configurables: - -# length of time before a thread is eligible to be killed, in seconds -# -my $long_query_time = 180; -# -# the From header for any messages sent out -# -my $mail_from = "root\@mothra.mozilla.org"; -# -# the To header for any messages sent out -# -my $mail_to = "root"; -# -# mail transfer agent. this should probably really be converted to a Param(). -# -my $mta_program = "/usr/lib/sendmail -t -ODeliveryMode=deferred"; - -# The array of long-running queries -# -my $long = {}; - -# Run mysqladmin processlist twice, the first time getting complete queries -# and the second time getting just abbreviated queries. We want complete -# queries so we know which queries are taking too long to run, but complete -# queries with line breaks get missed by this script, so we get abbreviated -# queries as well to make sure we don't miss any. -foreach my $command ("/opt/mysql/bin/mysqladmin --verbose processlist", - "/opt/mysql/bin/mysqladmin processlist") -{ - close(STDIN); - open(STDIN, "$command |"); - - # iterate through the running threads - # - while ( <STDIN> ) { - my @F = split(/\|/); - - # if this line is not the correct number of fields, or if the thread-id - # field contains Id, skip this line. both these cases indicate that this - # line contains pretty-printing gunk and not thread info. - # - next if ( $#F != 9 || $F[1] =~ /Id/); - - if ( $F[4] =~ /shadow_bugs/ # shadowbugs database in use - && $F[5] =~ /Query/ # this is actually a query - && $F[6] > $long_query_time # this query has taken too long - && $F[8] =~ /(select|SELECT)/ # only kill a select - && !defined($long->{$F[1]}) ) # haven't seen this one already - { - $long->{$F[1]} = \@F; - system("/opt/mysql/bin/mysqladmin", "kill", $F[1]); - } - } -} - -# send an email message -# -# should perhaps be moved to somewhere more global for use in bugzilla as a -# whole; should also do more error-checking -# -sub sendEmail($$$$) { - ($#_ == 3) || die("sendEmail: invalid number of arguments"); - my ($from, $to, $subject, $body) = @_; - - open(MTA, "|$mta_program"); - print MTA "From: $from\n"; - print MTA "To: $to\n"; - print MTA "Subject: $subject\n"; - print MTA "\n"; - print MTA $body; - print MTA "\n"; - close(MTA); - -} - -# if we found anything, kill the database thread and send mail about it -# -if (scalar(keys(%$long))) { - my $message = ""; - foreach my $process_id (keys(%$long)) { - my $qry = $long->{$process_id}; - $message .= join(" ", @$qry) . "\n\n"; - } - - # fire off an email telling the maintainer that we had to kill some threads - # - sendEmail($mail_from, $mail_to, "long running MySQL thread(s) killed", $message); -} - diff --git a/contrib/new-yui.sh b/contrib/new-yui.sh deleted file mode 100755 index 6199c2a46..000000000 --- a/contrib/new-yui.sh +++ /dev/null @@ -1,17 +0,0 @@ -#!/bin/sh -# -# Updates the version of YUI used by Bugzilla. Just pass the path to -# an unzipped yui release directory, like: -# -# contrib/new-yui.sh /path/to/yui-2.8.1/ -# -rsync -av --delete $1/build/ js/yui/ -cd js/yui -rm -rf editor/ yuiloader-dom-event/ -find -name '*.js' -not -name '*-min.js' -not -name '*-dom-event.js' \ - -exec rm -f {} \; -find -name '*-skin.css' -exec rm -f {} \; -find -depth -path '*/assets' -not -path './assets' -exec rm -rf {} \; -rm assets/skins/sam/sprite.psd -rm assets/skins/sam/skin.css -rmdir utilities diff --git a/contrib/new-yui3.pl b/contrib/new-yui3.pl deleted file mode 100755 index 2d1eeddc2..000000000 --- a/contrib/new-yui3.pl +++ /dev/null @@ -1,80 +0,0 @@ -#!/usr/bin/perl -w -# -# Updates the version of YUI3 used by Bugzilla. Just pass the path to -# an unzipped yui release directory, like: -# -# contrib/new-yui3.pl /path/to/yui3/ -# - -use strict; - -use FindBin; -use File::Find; -use File::Basename; - -use constant EXCLUDES => qw( - gallery-* -); - -sub usage { - my $error = shift; - print "$error\n"; - print <<USAGE; -Usage: contrib/new-yui3.pl /path/to/yui3/files - -Eg. contrib/new-yui3.pl /home/dkl/downloads/yui3 -The yui3 directory should contain the 'build' directory -from the downloaded YUI3 tarball containing the module -related files. -USAGE - exit(1); -} - -############# -# Main Code # -############# - -my $SOURCE_PATH = shift; -my $DEST_PATH = "$FindBin::Bin/../js/yui3"; - -if (!$SOURCE_PATH || !-d "$SOURCE_PATH/build") { - usage("Source path not found!"); -} - -mkdir($DEST_PATH) unless -d $DEST_PATH; - -my $exclude_string = join(" ", map { "--exclude $_" } EXCLUDES); -my $command = "rsync -av --delete $exclude_string " . - "$SOURCE_PATH/build/ $DEST_PATH/"; -system($command) == 0 or usage("system '$command' failed: $?"); - -find( - sub { - my $delete = 0; - my $filename = basename $File::Find::name; - if ($filename =~ /-debug\.js$/ - || $filename =~ /-coverage\.js$/) - { - $delete = 1; - } - elsif ($filename =~ /-skin\.css$/) { - my $temp_filename = $filename; - $temp_filename =~ s/-skin//; - if (-e $temp_filename) { - $delete = 1; - } - } - elsif ($filename =~ /-min\.js/) { - $filename =~ s/-min//; - if (-e $filename) { - $delete = 1; - } - } - return if !$delete; - print "deleting $filename\n"; - unlink($filename) || usage($!); - }, - $DEST_PATH -); - -exit(0); diff --git a/contrib/nuke-bugs.pl b/contrib/nuke-bugs.pl deleted file mode 100755 index 0226c1726..000000000 --- a/contrib/nuke-bugs.pl +++ /dev/null @@ -1,69 +0,0 @@ -#!/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 lib qw(.); - -use Bugzilla; -use Bugzilla::Constants; - -use Getopt::Long; - -# This SQL is designed to delete the bugs and other activity in a Bugzilla database -# so that one can use for development purposes or to start using it as a fresh installation. -# Other data will be retained such as products, versions, flags, profiles, etc. - -$| = 1; -my $trace = 0; - -GetOptions("trace" => \$trace) || exit; - -my $dbh = Bugzilla->dbh; - -$dbh->{TraceLevel} = 1 if $trace; - -print <<EOF; -WARNING - This will delete all bugs, hit <enter> to continue or <ctrl-c> to cancel - WARNING -EOF -getc(); - -Bugzilla->usage_mode(USAGE_MODE_CMDLINE); - -$dbh->bz_start_transaction(); - -print "Deleting all bug data...\n"; - -delete_from_table('bug_group_map'); -delete_from_table('bugs_activity'); -delete_from_table('cc'); -delete_from_table('dependencies'); -delete_from_table('duplicates'); -delete_from_table('flags'); -delete_from_table('keywords'); -delete_from_table('attach_data'); -delete_from_table('attachments'); -delete_from_table('bug_group_map'); -delete_from_table('bugs'); -delete_from_table('longdescs'); - -$dbh->do($dbh->_bz_real_schema->get_set_serial_sql('bugs', 'bug_id', 1)); - -$dbh->bz_commit_transaction(); - -# This has to happen outside of the transaction -$dbh->do("DELETE FROM bugs_fulltext"); - -print "All done!\n"; - -sub delete_from_table { - my $table = shift; - print "Deleting from $table..."; - $dbh->do("DELETE FROM $table"); - print "done.\n"; -} diff --git a/contrib/recode.pl b/contrib/recode.pl deleted file mode 100755 index e74e06c07..000000000 --- a/contrib/recode.pl +++ /dev/null @@ -1,331 +0,0 @@ -#!/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 Everything Solved. -# Portions created by Everything Solved are Copyright (C) 2006 -# Everything Solved. All Rights Reserved. -# -# Contributor(s): Max Kanat-Alexander <mkanat@bugzilla.org> - -use strict; -use lib qw(. lib); - -use Bugzilla; -use Bugzilla::Constants; -use Bugzilla::Util qw(detect_encoding); - -use Digest::MD5 qw(md5_base64); -use Encode qw(encode decode resolve_alias is_utf8); -use Getopt::Long; -use Pod::Usage; - -############# -# Constants # -############# - -use constant IGNORE_ENCODINGS => qw(utf8 ascii iso-8859-1); - -use constant MAX_STRING_LEN => 25; - -# For certain tables, we can't automatically determine their Primary Key. -# So, we specify it here as a string. -use constant SPECIAL_KEYS => { - # bugs_activity since 4.4 has a unique primary key added - bugs_activity => 'bug_id,bug_when,fieldid', - profile_setting => 'user_id,setting_name', - # profiles_activity since 4.4 has a unique primary key added - profiles_activity => 'userid,profiles_when,fieldid', - setting_value => 'name,value', - # longdescs didn't used to have a PK, before 2.20. - longdescs => 'bug_id,bug_when', - # The 2.16 versions table lacked a PK - versions => 'product_id,value', - # These are all for earlier versions of Bugzilla. On a modern - # version of Bugzilla, this script will ignore these (thanks to - # code further down). - components => 'program,value', - products => 'product', -}; - -############### -# Subroutines # -############### - -# "truncate" is a file operation in perl, so we can't use that name. -sub trunc { - my ($str) = @_; - my $truncated = substr($str, 0, MAX_STRING_LEN); - if (length($truncated) ne length($str)) { - $truncated .= '...'; - } - return $truncated; -} - -sub is_valid_utf8 { - my ($str) = @_; - Encode::_utf8_on($str); - return is_utf8($str, 1); -} - -############### -# Main Script # -############### - -my %switch; -GetOptions(\%switch, 'dry-run', 'guess', 'charset=s', 'show-failures', - 'overrides=s', 'help|h'); - -pod2usage({ -verbose => 1 }) if $switch{'help'}; - -# You have to specify at least one of these switches. -pod2usage({ -verbose => 0 }) if (!$switch{'charset'} && !$switch{'guess'}); - -if (exists $switch{'charset'}) { - $switch{'charset'} = resolve_alias($switch{'charset'}) - || die "'$switch{charset}' is not a valid charset."; -} - -if ($switch{'guess'}) { - if (!eval { require Encode::Detect::Detector }) { - my $root = ROOT_USER; - print STDERR <<EOT; -Using --guess requires that Encode::Detect be installed. To install -Encode::Detect, run the following command: - - $^X install-module.pl Encode::Detect - -EOT - exit; - } -} - -my %overrides; -if (exists $switch{'overrides'}) { - my $file = new IO::File($switch{'overrides'}, 'r') - || die "$switch{overrides}: $!"; - my @lines = $file->getlines(); - $file->close(); - foreach my $line (@lines) { - chomp($line); - my ($digest, $encoding) = split(' ', $line); - $overrides{$digest} = $encoding; - } -} - -my $dbh = Bugzilla->dbh; - -if ($dbh->isa('Bugzilla::DB::Mysql')) { - # Get the actual current encoding of the DB. - my $collation_data = $dbh->selectrow_arrayref( - "SHOW VARIABLES LIKE 'character_set_database'"); - my $db_charset = $collation_data->[1]; - # Set our connection encoding to *that* encoding, so that MySQL - # correctly accepts our changes. - $dbh->do("SET NAMES $db_charset"); - # Make the database give us raw bytes. - $dbh->do('SET character_set_results = NULL') -} - -$dbh->begin_work; - -foreach my $table ($dbh->bz_table_list_real) { - my @columns = $dbh->bz_table_columns($table); - - my $pk = SPECIAL_KEYS->{$table}; - if ($pk) { - # Assure that we're on a version of Bugzilla where those keys - # actually exist. - foreach my $column (split ',', $pk) { - $pk = undef if !$dbh->bz_column_info($table, $column); - } - } - - # Figure out the primary key. - foreach my $column (@columns) { - my $def = $dbh->bz_column_info($table, $column); - $pk = $column if $def->{PRIMARYKEY}; - } - # If there's no PK, it's defined by a UNIQUE index. - if (!$pk) { - foreach my $column (@columns) { - my $index = $dbh->bz_index_info($table, "${table}_${column}_idx"); - if ($index && ref($index) eq 'HASH') { - $pk = join(',', @{$index->{FIELDS}}) - if $index->{TYPE} eq 'UNIQUE'; - } - } - } - - foreach my $column (@columns) { - my $def = $dbh->bz_column_info($table, $column); - # If this is a text column, it may need work. - if ($def->{TYPE} =~ /text|char/i) { - # If there's still no PK, we're upgrading from 2.14 or earlier. - # We can't reliably determine the PK (or at least, I don't want to - # maintain code to record what the PK was at all points in history). - # So instead we just use the field itself. - $pk = $column if !$pk; - - print "Converting $table.$column...\n"; - my $sth = $dbh->prepare("SELECT $column, $pk FROM $table - WHERE $column IS NOT NULL - AND $column != ''"); - - my @pk_array = map {"$_ = ?"} split(',', $pk); - my $pk_where = join(' AND ', @pk_array); - my $update_sth = $dbh->prepare( - "UPDATE $table SET $column = ? WHERE $pk_where"); - - $sth->execute(); - - while (my @result = $sth->fetchrow_array) { - my $data = shift @result; - # Wide characters cause md5_base64() to die. - my $digest_data = utf8::is_utf8($data) - ? Encode::encode_utf8($data) : $data; - my $digest = md5_base64($digest_data); - - my @primary_keys = reverse split(',', $pk); - # We copy the array so that we can pop things from it without - # affecting the original. - my @pk_data = @result; - my $pk_line = join (', ', - map { "$_ = " . pop @pk_data } @primary_keys); - - my $encoding; - if ($switch{'guess'}) { - $encoding = detect_encoding($data); - - # We only show failures if they don't appear to be - # ASCII. - if ($switch{'show-failures'} && !$encoding - && !is_valid_utf8($data)) - { - my $truncated = trunc($data); - print "Row: [$pk_line]\n", - "Failed to guess: Key: $digest", - " DATA: $truncated\n"; - } - - # If we fail a guess, and the data is valid UTF-8, - # just assume we failed because it's UTF-8. - next if is_valid_utf8($data); - } - - # If we couldn't detect the charset (or were instructed - # not to try), we fall back to --charset. If there's no - # fallback, we just do nothing. - if (!$encoding && $switch{'charset'}) { - $encoding = $switch{'charset'}; - } - - $encoding = $overrides{$digest} if $overrides{$digest}; - - # We only fix it if it's not ASCII or UTF-8 already. - if ($encoding && !grep($_ eq $encoding, IGNORE_ENCODINGS)) { - my $decoded = encode('utf8', decode($encoding, $data)); - if ($switch{'dry-run'} && $data ne $decoded) { - print "Row: [$pk_line]\n", - "From: [" . trunc($data) . "] Key: $digest\n", - "To: [" . trunc($decoded) . "]", - " Encoding : $encoding\n"; - } - else { - $update_sth->execute($decoded, @result); - } - } - } # while (my @result = $sth->fetchrow_array) - } # if ($column->{TYPE} =~ /text|char/i) - } # foreach my $column (@columns) -} - -$dbh->commit; - -__END__ - -=head1 NAME - -recode.pl - Converts a database from one encoding (or multiple encodings) -to UTF-8. - -=head1 SYNOPSIS - - contrib/recode.pl [--guess [--show-failures]] [--charset=iso-8859-2] - [--overrides=file_name] - - --dry-run Don't modify the database. - - --charset Primary charset your data is currently in. This can be - optionally omitted if you do --guess. - - --guess Try to guess the charset of the data. - - --show-failures If we fail to guess, show where we failed. - - --overrides Specify a file containing overrides. See --help - for more info. - - --help Display detailed help. - - If you aren't sure what to do, try: - - contrib/recode.pl --guess --charset=cp1252 - -=head1 OPTIONS - -=over - -=item --dry-run - -Don't modify the database, just print out what the conversions will be. - -recode.pl will print out a Key for each item. You can use this in the -overrides file, described below. - -=item --guess - -If your database is in multiple different encodings, specify this switch -and recode.pl will do its best to determine the original charset of the data. -The detection is usually very reliable. - -If recode.pl cannot guess the charset, it will leave the data alone, unless -you've specified --charset. - -=item --charset=charset-name - -If you do not specify --guess, then your database is converted -from this character set into the UTF-8. - -If you have specified --guess, recode.pl will use this charset as -a fallback--when it cannot guess the charset of a particular piece -of data, it will guess that the data is in this charset and convert -it from this charset to UTF-8. - -charset-name must be a charset that is known to perl's Encode -module. To see a list of available charsets, do: - -C<perl -MEncode -e 'print join("\n", Encode-E<gt>encodings(":all"))'> - -=item --show-failures - -If --guess fails to guess a charset, print out the data it failed on. - -=item --overrides=file_name - -This is a way of specifying certain encodings to override the encodings of ---guess. The file is a series of lines. The line should start with the Key -from --dry-run, and then a space, and then the encoding you'd like to use. - -=back diff --git a/contrib/reorg-tools/README b/contrib/reorg-tools/README deleted file mode 100644 index 4e5d6eb4d..000000000 --- a/contrib/reorg-tools/README +++ /dev/null @@ -1,9 +0,0 @@ -Upstreaming attempt: https://bugzilla.mozilla.org/show_bug.cgi?id=616499 - -Included in this directory is a group of tools we've used for moving components -around in a Bugzilla 3.2 install on bugzilla.mozilla.org. - -They may require tweaking if you use them on your own install. Putting them -here to make it easier to collaborate on them and keep them up-to-date. -Hopefully Bugzilla upstream will be able to just do this from the web UI -eventually. diff --git a/contrib/reorg-tools/convert_date_time_date.pl b/contrib/reorg-tools/convert_date_time_date.pl deleted file mode 100755 index a2e9bfffc..000000000 --- a/contrib/reorg-tools/convert_date_time_date.pl +++ /dev/null @@ -1,62 +0,0 @@ -#!/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 Cwd 'abs_path'; -use File::Basename; -use FindBin; -use lib "$FindBin::Bin/../.."; -use lib "$FindBin::Bin/../../lib"; - -use Bugzilla; -use Bugzilla::Constants; - -sub usage() { - print <<USAGE; -Usage: convert_date_time_date.pl <column> - -E.g.: convert_date_time_date.pl cf_due_date -Converts a datetime field (FIELD_TYPE_DATETIME) to a date field type -(FIELD_TYPE_DATE). - -Note: Any time portion will be lost but the date portion will be preserved. -USAGE -} - -############################################################################# -# MAIN CODE -############################################################################# - -Bugzilla->usage_mode(USAGE_MODE_CMDLINE); - -if (scalar @ARGV < 1) { - usage(); - exit(); -} - -my $column = shift; - -print <<EOF; -Converting bugs.${column} from FIELD_TYPE_DATETIME to FIELD_TYPE_DATE. - -Note: Any time portion will be lost but the date portion will be preserved. - -Press <Ctrl-C> to stop or <Enter> to continue... -EOF -getc(); - -Bugzilla->dbh->bz_alter_column('bugs', $column, { TYPE => 'DATE' }); -Bugzilla->dbh->do("UPDATE fielddefs SET type = ? WHERE name = ?", - undef, FIELD_TYPE_DATE, $column); - -# 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(); - -print "\ndone.\n"; diff --git a/contrib/reorg-tools/fix_all_open_status_queries.pl b/contrib/reorg-tools/fix_all_open_status_queries.pl deleted file mode 100755 index 7c8d8be68..000000000 --- a/contrib/reorg-tools/fix_all_open_status_queries.pl +++ /dev/null @@ -1,144 +0,0 @@ -#!/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 lib qw(. lib); - -use Bugzilla; -use Bugzilla::Constants; -use Bugzilla::Status; -use Bugzilla::Util; - -sub usage() { - print <<USAGE; -Usage: fix_all_open_status_queries.pl <new_open_status> - -E.g.: fix_all_open_status_queries.pl READY -This will add a new open state to user queries which currently look for -all open bugs by listing every open status in their query criteria. -For users who only look for bug_status=__open__, they will get the new -open status automatically. -USAGE -} - -sub do_namedqueries { - my ($new_status) = @_; - my $dbh = Bugzilla->dbh; - my $replace_count = 0; - - my $query = $dbh->selectall_arrayref("SELECT id, query FROM namedqueries"); - - if ($query) { - $dbh->bz_start_transaction(); - - my $sth = $dbh->prepare("UPDATE namedqueries SET query = ? WHERE id = ?"); - - foreach my $row (@$query) { - my ($id, $old_query) = @$row; - my $new_query = all_open_states($new_status, $old_query); - if ($new_query) { - trick_taint($new_query); - $sth->execute($new_query, $id); - $replace_count++; - } - } - - $dbh->bz_commit_transaction(); - } - - print "namedqueries: $replace_count replacements made.\n"; -} - -# series -sub do_series { - my ($new_status) = @_; - my $dbh = Bugzilla->dbh; - my $replace_count = 0; - - my $query = $dbh->selectall_arrayref("SELECT series_id, query FROM series"); - - if ($query) { - $dbh->bz_start_transaction(); - - my $sth = $dbh->prepare("UPDATE series SET query = ? WHERE series_id = ?"); - - foreach my $row (@$query) { - my ($series_id, $old_query) = @$row; - my $new_query = all_open_states($new_status, $old_query); - if ($new_query) { - trick_taint($new_query); - $sth->execute($new_query, $series_id); - $replace_count++; - } - } - - $dbh->bz_commit_transaction(); - } - - print "series: $replace_count replacements made.\n"; -} - -sub all_open_states { - my ($new_status, $query) = @_; - - my @open_states = Bugzilla::Status::BUG_STATE_OPEN(); - my $cgi = Bugzilla::CGI->new($query); - my @query_states = $cgi->param('bug_status'); - - my ($removed, $added) = diff_arrays(\@query_states, \@open_states); - - if (scalar @$added == 1 && $added->[0] eq $new_status) { - push(@query_states, $new_status); - $cgi->param('bug_status', @query_states); - return $cgi->canonicalise_query(); - } - - return ''; -} - -sub validate_status { - my ($status) = @_; - my $dbh = Bugzilla->dbh; - my $exists = $dbh->selectrow_array("SELECT 1 FROM bug_status - WHERE value = ?", - undef, $status); - return $exists ? 1 : 0; -} - -############################################################################# -# MAIN CODE -############################################################################# -# This is a pure command line script. -Bugzilla->usage_mode(USAGE_MODE_CMDLINE); - -if (scalar @ARGV < 1) { - usage(); - exit(1); -} - -my ($new_status) = @ARGV; - -$new_status = uc($new_status); - -if (!validate_status($new_status)) { - print "Invalid status: $new_status\n\n"; - usage(); - exit(1); -} - -print "Adding new status '$new_status'.\n\n"; - -do_namedqueries($new_status); -do_series($new_status); - -# 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(); - -exit(0); diff --git a/contrib/reorg-tools/fixgroupqueries.pl b/contrib/reorg-tools/fixgroupqueries.pl deleted file mode 100755 index 0bd64cd40..000000000 --- a/contrib/reorg-tools/fixgroupqueries.pl +++ /dev/null @@ -1,123 +0,0 @@ -#!/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> - -use strict; - -use lib qw(. lib); - -use Bugzilla; -use Bugzilla::Constants; -use Bugzilla::Util; - -sub usage() { - print <<USAGE; -Usage: fixgroupqueries.pl <oldvalue> <newvalue> - -E.g.: fixgroupqueries.pl w-security webtools-security -will change all occurrences of "w-security" to "webtools-security" in the -appropriate places in the namedqueries. - -Note that all parameters are case-sensitive. -USAGE -} - -sub do_namedqueries($$) { - my ($old, $new) = @_; - $old = url_quote($old); - $new = url_quote($new); - - my $dbh = Bugzilla->dbh; - - my $replace_count = 0; - my $query = $dbh->selectall_arrayref("SELECT id, query FROM namedqueries"); - if ($query) { - my $sth = $dbh->prepare("UPDATE namedqueries SET query = ? - WHERE id = ?"); - - foreach my $row (@$query) { - my ($id, $query) = @$row; - if (($query =~ /field\d+-\d+-\d+=bug_group/) && - ($query =~ /(?:^|&|;)value\d+-\d+-\d+=$old(?:;|&|$)/)) { - $query =~ s/((?:^|&|;)value\d+-\d+-\d+=)$old(;|&|$)/$1$new$2/; - $sth->execute($query, $id); - $replace_count++; - } - } - } - - print "namedqueries: $replace_count replacements made.\n"; -} - -# series -sub do_series($$) { - my ($old, $new) = @_; - $old = url_quote($old); - $new = url_quote($new); - - my $dbh = Bugzilla->dbh; - #$dbh->bz_start_transaction(); - - my $replace_count = 0; - my $query = $dbh->selectall_arrayref("SELECT series_id, query - FROM series"); - if ($query) { - my $sth = $dbh->prepare("UPDATE series SET query = ? - WHERE series_id = ?"); - foreach my $row (@$query) { - my ($series_id, $query) = @$row; - - if (($query =~ /field\d+-\d+-\d+=bug_group/) && - ($query =~ /(?:^|&|;)value\d+-\d+-\d+=$old(?:;|&|$)/)) { - $query =~ s/((?:^|&|;)value\d+-\d+-\d+=)$old(;|&|$)/$1$new$2/; - $sth->execute($query, $series_id); - $replace_count++; - } - } - } - - #$dbh->bz_commit_transaction(); - print "series: $replace_count replacements made.\n"; -} - -############################################################################# -# MAIN CODE -############################################################################# -# This is a pure command line script. -Bugzilla->usage_mode(USAGE_MODE_CMDLINE); - -if (scalar @ARGV < 2) { - usage(); - exit(); -} - -my ($old, $new) = @ARGV; - -print "Changing all instances of '$old' to '$new'.\n\n"; - -#do_namedqueries($old, $new); -do_series($old, $new); - -# 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(); - -exit(0); diff --git a/contrib/reorg-tools/fixqueries.pl b/contrib/reorg-tools/fixqueries.pl deleted file mode 100755 index 221213058..000000000 --- a/contrib/reorg-tools/fixqueries.pl +++ /dev/null @@ -1,136 +0,0 @@ -#!/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> - -use strict; - -use lib qw(. lib); - -use Bugzilla; -use Bugzilla::Constants; -use Bugzilla::Util; - -sub usage() { - print <<USAGE; -Usage: fixqueries.pl <parameter> <oldvalue> <newvalue> - -E.g.: fixqueries.pl product FoodReplicator SeaMonkey -will change all occurrences of "FoodReplicator" to "Seamonkey" in the -appropriate places in the namedqueries, series and series_categories tables. - -Note that all parameters are case-sensitive. -USAGE -} - -sub do_namedqueries($$$) { - my ($field, $old, $new) = @_; - $old = url_quote($old); - $new = url_quote($new); - - my $dbh = Bugzilla->dbh; - #$dbh->bz_start_transaction(); - - my $replace_count = 0; - my $query = $dbh->selectall_arrayref("SELECT id, query FROM namedqueries"); - if ($query) { - my $sth = $dbh->prepare("UPDATE namedqueries SET query = ? - WHERE id = ?"); - - foreach my $row (@$query) { - my ($id, $query) = @$row; - if ($query =~ /(?:^|&|;)$field=$old(?:&|$|;)/) { - $query =~ s/((?:^|&|;)$field=)$old(;|&|$)/$1$new$2/; - $sth->execute($query, $id); - $replace_count++; - } - } - } - - #$dbh->bz_commit_transaction(); - print "namedqueries: $replace_count replacements made.\n"; -} - -# series -sub do_series($$$) { - my ($field, $old, $new) = @_; - $old = url_quote($old); - $new = url_quote($new); - - my $dbh = Bugzilla->dbh; - #$dbh->bz_start_transaction(); - - my $replace_count = 0; - my $query = $dbh->selectall_arrayref("SELECT series_id, query - FROM series"); - if ($query) { - my $sth = $dbh->prepare("UPDATE series SET query = ? - WHERE series_id = ?"); - foreach my $row (@$query) { - my ($series_id, $query) = @$row; - - if ($query =~ /(?:^|&|;)$field=$old(?:&|$|;)/) { - $query =~ s/((?:^|&|;)$field=)$old(;|&|$)/$1$new$2/; - $replace_count++; - } - - $sth->execute($query, $series_id); - } - } - - #$dbh->bz_commit_transaction(); - print "series: $replace_count replacements made.\n"; -} - -# series_categories -sub do_series_categories($$) { - my ($old, $new) = @_; - my $dbh = Bugzilla->dbh; - - $dbh->do("UPDATE series_categories SET name = ? WHERE name = ?", - undef, - ($new, $old)); -} - -############################################################################# -# MAIN CODE -############################################################################# -# This is a pure command line script. -Bugzilla->usage_mode(USAGE_MODE_CMDLINE); - -if (scalar @ARGV < 3) { - usage(); - exit(); -} - -my ($field, $old, $new) = @ARGV; - -print "Changing all instances of '$old' to '$new'.\n\n"; - -do_namedqueries($field, $old, $new); -do_series($field, $old, $new); -do_series_categories($old, $new); - -# 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(); - -exit(0); - diff --git a/contrib/reorg-tools/migrate_crash_signatures.pl b/contrib/reorg-tools/migrate_crash_signatures.pl deleted file mode 100755 index 4323c1d01..000000000 --- a/contrib/reorg-tools/migrate_crash_signatures.pl +++ /dev/null @@ -1,132 +0,0 @@ -#!/usr/bin/perl -# -*- 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 Initial Developer of the Original Code is Mozilla Foundation. -# Portions created by the Initial Developer are Copyright (C) 2011 the -# Initial Developer. All Rights Reserved. -# -#=============================================================================== -# -# FILE: migrate_crash_signatures.pl -# -# USAGE: ./migrate_crash_signatures.pl -# -# DESCRIPTION: Migrate current summary data on matched bugs to the -# new cf_crash_signature custom fields. -# -# OPTIONS: No params, then performs dry-run without updating the database. -# If a true value is passed as single argument, then the database -# is updated. -# REQUIREMENTS: None -# BUGS: 577724 -# NOTES: None -# AUTHOR: David Lawrence (dkl@mozilla.com), -# COMPANY: Mozilla Corproation -# VERSION: 1.0 -# CREATED: 05/31/2011 03:57:52 PM -# REVISION: 1 -#=============================================================================== - -use strict; -use warnings; - -use lib qw(. lib); - -use Bugzilla; -use Bugzilla::Constants; -use Bugzilla::Util; - -use Data::Dumper; - -Bugzilla->usage_mode(USAGE_MODE_CMDLINE); - -my $UPDATE_DB = shift; # Pass true value as single argument to perform database update - -my $dbh = Bugzilla->dbh; - -# User to make changes as -my $user_id = $dbh->selectrow_array( - "SELECT userid FROM profiles WHERE login_name='nobody\@mozilla.org'"); -$user_id or die "Can't find user ID for 'nobody\@mozilla.org'\n"; - -my $field_id = $dbh->selectrow_array( - "SELECT id FROM fielddefs WHERE name = 'cf_crash_signature'"); -$field_id or die "Can't find field ID for 'cf_crash_signature' field\n"; - -# Search criteria -# a) crash or topcrash keyword, -# b) not have [notacrash] in whiteboard, -# c) have a properly formulated [@ ...] - -# crash and topcrash keyword ids -my $crash_keyword_id = $dbh->selectrow_array( - "SELECT id FROM keyworddefs WHERE name = 'crash'"); -$crash_keyword_id or die "Can't find keyword id for 'crash'\n"; - -my $topcrash_keyword_id = $dbh->selectrow_array( - "SELECT id FROM keyworddefs WHERE name = 'topcrash'"); -$topcrash_keyword_id or die "Can't find keyword id for 'topcrash'\n"; - -# main search query -my $bugs = $dbh->selectall_arrayref(" - SELECT bugs.bug_id, bugs.short_desc - FROM bugs LEFT JOIN keywords ON bugs.bug_id = keywords.bug_id - WHERE (keywords.keywordid = ? OR keywords.keywordid = ?) - AND bugs.status_whiteboard NOT REGEXP '\\\\[notacrash\\\\]' - AND bugs.short_desc REGEXP '\\\\[@.+\\\\]' - AND (bugs.cf_crash_signature IS NULL OR bugs.cf_crash_signature = '') - ORDER BY bugs.bug_id", - {'Slice' => {}}, $crash_keyword_id, $topcrash_keyword_id); - -my $bug_count = scalar @$bugs; -$bug_count or die "No bugs were found in matching search criteria.\n"; - -print "Migrating $bug_count bugs to new crash signature field\n"; - -$dbh->bz_start_transaction() if $UPDATE_DB; - -foreach my $bug (@$bugs) { - my $bug_id = $bug->{'bug_id'}; - my $summary = $bug->{'short_desc'}; - - print "Updating bug $bug_id ..."; - - my @signatures; - while ($summary =~ /(\[\@(?:\[.*\]|[^\[])*\])/g) { - push(@signatures, $1); - } - - if (@signatures && $UPDATE_DB) { - my $timestamp = $dbh->selectrow_array('SELECT LOCALTIMESTAMP(0)'); - $dbh->do("UPDATE bugs SET cf_crash_signature = ? WHERE bug_id = ?", - undef, join("\n", @signatures), $bug_id); - $dbh->do("INSERT INTO bugs_activity(bug_id, who, bug_when, fieldid, removed, added) " . - "VALUES (?, ?, ?, ?, '', ?)", - undef, $bug_id, $user_id, $timestamp, $field_id, join("\n", @signatures)); - $dbh->do("UPDATE bugs SET delta_ts = ?, lastdiffed = ? WHERE bug_id = ?", - undef, $timestamp, $timestamp, $bug_id); - } - elsif (@signatures) { - print Dumper(\@signatures); - } - - print "done.\n"; -} - -if ($UPDATE_DB) { - $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/contrib/reorg-tools/migrate_orange_bugs.pl b/contrib/reorg-tools/migrate_orange_bugs.pl deleted file mode 100755 index 4902464a3..000000000 --- a/contrib/reorg-tools/migrate_orange_bugs.pl +++ /dev/null @@ -1,158 +0,0 @@ -#!/usr/bin/perl -wT -# 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. -#=============================================================================== -# -# FILE: migrate_orange_bugs.pl -# -# USAGE: ./migrate_orange_bugs.pl [--remove] -# -# DESCRIPTION: Add intermittent-keyword to bugs with [orange] stored in -# whiteboard field. If --remove, then also remove the [orange] -# value from whiteboard. -# -# OPTIONS: Without --doit, does a dry-run without updating the database. -# If --doit is passed, then the database is updated. -# --remove will remove [orange] from the whiteboard. -# REQUIREMENTS: None -# BUGS: 791758 -# NOTES: None -# AUTHOR: David Lawrence (dkl@mozilla.com), -# COMPANY: Mozilla Corproation -# VERSION: 1.0 -# CREATED: 10/31/2012 -# REVISION: 1 -#=============================================================================== - -use strict; - -use lib qw(. lib); - -use Bugzilla; -use Bugzilla::Constants; -use Bugzilla::Field; -use Bugzilla::User; -use Bugzilla::Keyword; - -use Getopt::Long; -use Term::ANSIColor qw(colored); - -Bugzilla->usage_mode(USAGE_MODE_CMDLINE); - -my ($remove_whiteboard, $help, $doit); -GetOptions("r|remove" => \$remove_whiteboard, - "h|help" => \$help, 'doit' => \$doit); - -sub usage { - my $error = shift || ""; - print colored(['red'], $error) if $error; - print <<USAGE; -Usage: migrate_orange_bugs.pl [--remove|-r] [--help|-h] [--doit] - -E.g.: migrate_orange_bugs.pl --remove --doit -This script will add the intermittent-failure keyword to any bugs that -contant [orange] in the status whiteboard. If the --remove option is -given, then [orange] will be removed from the whiteboard as well. - -Pass --doit to make the database changes permanent. -USAGE - exit(1); -} - -# Exit if help was requested -usage() if $help; - -# User to make changes as -my $user_id = login_to_id('nobody@mozilla.org'); -$user_id or usage("Can't find user ID for 'nobody\@mozilla.org'\n"); - -my $keywords_field_id = get_field_id('keywords'); -$keywords_field_id or usage("Can't find field ID for 'keywords' field\n"); - -my $whiteboard_field_id = get_field_id('status_whiteboard'); -$whiteboard_field_id or usage("Can't find field ID for 'whiteboard' field\n"); - -# intermittent-keyword id (assumes already created) -my $keyword_obj = Bugzilla::Keyword->new({ name => 'intermittent-failure' }); -$keyword_obj or usage("Can't find keyword id for 'intermittent-failure'\n"); -my $keyword_id = $keyword_obj->id; - -my $dbh = Bugzilla->dbh; - -my $bugs = $dbh->selectall_arrayref(" - SELECT DISTINCT bugs.bug_id, bugs.status_whiteboard - FROM bugs WHERE bugs.status_whiteboard LIKE '%[orange]%' - OR bugs.status_whiteboard LIKE '%[tb-orange]%'", - {'Slice' => {}}); - -my $bug_count = scalar @$bugs; -$bug_count or usage("No bugs were found in matching search criteria.\n"); - -print colored(['green'], "Processing $bug_count [orange] bugs\n"); - -$dbh->bz_start_transaction() if $doit; - -foreach my $bug (@$bugs) { - my $bug_id = $bug->{'bug_id'}; - my $whiteboard = $bug->{'status_whiteboard'}; - - print "Checking bug $bug_id ... "; - - my $timestamp = $dbh->selectrow_array('SELECT LOCALTIMESTAMP(0)'); - - my $keyword_present = $dbh->selectrow_array(" - SELECT bug_id FROM keywords WHERE bug_id = ? AND keywordid = ?", - undef, $bug_id, $keyword_id); - - if (!$keyword_present) { - print "adding keyword ... "; - - if ($doit) { - $dbh->do("INSERT INTO keywords (bug_id, keywordid) VALUES (?, ?)", - undef, $bug_id, $keyword_id); - $dbh->do("INSERT INTO bugs_activity(bug_id, who, bug_when, fieldid, removed, added) " . - "VALUES (?, ?, ?, ?, '', 'intermittent-failure')", - undef, $bug_id, $user_id, $timestamp, $keywords_field_id); - $dbh->do("UPDATE bugs SET delta_ts = ?, lastdiffed = ? WHERE bug_id = ?", - undef, $timestamp, $timestamp, $bug_id); - } - } - - if ($remove_whiteboard) { - print "removing whiteboard ... "; - - if ($doit) { - my $old_whiteboard = $whiteboard; - $whiteboard =~ s/\[(tb-)?orange\]//ig; - - $dbh->do("UPDATE bugs SET status_whiteboard = ? WHERE bug_id = ?", - undef, $whiteboard, $bug_id); - $dbh->do("INSERT INTO bugs_activity(bug_id, who, bug_when, fieldid, removed, added) " . - "VALUES (?, ?, ?, ?, ?, ?)", - undef, $bug_id, $user_id, $timestamp, $whiteboard_field_id, $old_whiteboard, $whiteboard); - $dbh->do("UPDATE bugs SET delta_ts = ?, lastdiffed = ? WHERE bug_id = ?", - undef, $timestamp, $timestamp, $bug_id); - } - } - - print "done.\n"; -} - -$dbh->bz_commit_transaction() if $doit; - -if ($doit) { - # 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(); - - print colored(['green'], "DATABASE WAS UPDATED\n"); -} -else { - print colored(['red'], "DATABASE WAS NOT UPDATED\n"); -} - -exit(0); diff --git a/contrib/reorg-tools/move_dupes_to_invalid.pl b/contrib/reorg-tools/move_dupes_to_invalid.pl deleted file mode 100755 index 25106ce9c..000000000 --- a/contrib/reorg-tools/move_dupes_to_invalid.pl +++ /dev/null @@ -1,101 +0,0 @@ -#!/usr/bin/perl -# 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 warnings; - -use FindBin '$RealBin'; -use lib "$RealBin/../..", "$RealBin/../../lib"; - -use Bugzilla; -use Bugzilla::User; -use Bugzilla::Constants; -use Bugzilla::Util qw(detaint_natural); -use Bugzilla::Install::Util qw(indicate_progress); - -use Pod::Usage; - -BEGIN { Bugzilla->extensions(); } - -Bugzilla->usage_mode(USAGE_MODE_CMDLINE); - -pod2usage(1) unless @ARGV; - -my $dbh = Bugzilla->dbh; - -# Allow nobody@mozilla.org to edit bugs -my $user = Bugzilla::User->check({ name => 'nobody@mozilla.org' }); -Bugzilla->set_user($user); -$user->{'groups'} = [ Bugzilla::Group->new({ name => 'editbugs' }) ]; - -my $timestamp = $dbh->selectrow_array('SELECT LOCALTIMESTAMP(0)'); - -foreach my $dupe_of_bug (@ARGV) { - detaint_natural($dupe_of_bug) || pod2usage(1); - my $duped_bugs = $dbh->selectcol_arrayref(" - SELECT DISTINCT dupe FROM duplicates WHERE dupe_of = ?", - undef, $dupe_of_bug); - my $bug_count = @$duped_bugs; - - die "There are no duplicate bugs to move for bug $dupe_of_bug.\n" - if $bug_count == 0; - - print STDERR <<EOF; -Moving $bug_count duplicate bugs from bug $dupe_of_bug to the 'Invalid Bugs' product. - -Press <Ctrl-C> to stop or <Enter> to continue... -EOF - getc(); - - $dbh->bz_start_transaction; - my $count = 0; - foreach my $duped_bug_id (@$duped_bugs) { - # Change product to "Invalid Bugs" and component to "General" - # Change resolution to "INVALID" instead of duplicate - # Change version to "unspecified" and milestone to "---" - # Reset assignee to default - # Reset QA contact to default - my $bug_obj = Bugzilla::Bug->new($duped_bug_id); - my $params = { - product => 'Invalid Bugs', - component => 'General', - resolution => 'INVALID', - version => 'unspecified', - target_milestone => '---', - reset_assigned_to => 1, - reset_qa_contact => 1 - }; - $params->{bug_status} = 'RESOLVED' if $bug_obj->status->is_open; - $bug_obj->set_all($params); - $bug_obj->update($timestamp); - - $dbh->do("UPDATE bugs SET delta_ts = ?, lastdiffed = ? WHERE bug_id = ?", - undef, $timestamp, $timestamp, $duped_bug_id); - - $count++; - indicate_progress({ current => $count, total => $bug_count, every => 1 }); - } - - Bugzilla::Hook::process('reorg_move_bugs', { bug_ids => [ $dupe_of_bug, @$duped_bugs ] }); - - $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(); - -__END__ - -=head1 NAME - -move_dupes_to_invalid.pl - Script used to move dupes of a given bug to the 'Invalid Bugs' product. - -=head1 SYNOPSIS - - move_dupes_to_invalid.pl <bug_id> [<bug_id> ...] diff --git a/contrib/reorg-tools/move_flag_types.pl b/contrib/reorg-tools/move_flag_types.pl deleted file mode 100755 index 7b7fe2081..000000000 --- a/contrib/reorg-tools/move_flag_types.pl +++ /dev/null @@ -1,172 +0,0 @@ -#!/usr/bin/perl -# -*- 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 Initial Developer of the Original Code is Mozilla Foundation -# Portions created by the Initial Developer are Copyright (C) 2011 the -# Initial Developer. All Rights Reserved. -# -#=============================================================================== -# -# FILE: move_flag_types.pl -# -# USAGE: ./move_flag_types.pl -# -# DESCRIPTION: Move current set flag from one type_id to another -# based on product and optionally component. -# -# OPTIONS: --- -# REQUIREMENTS: --- -# BUGS: --- -# NOTES: --- -# AUTHOR: David Lawrence (:dkl), dkl@mozilla.com -# COMPANY: Mozilla Foundation -# VERSION: 1.0 -# CREATED: 08/22/2011 05:18:06 PM -# REVISION: --- -#=============================================================================== - -=head1 NAME - -move_flag_types.pl - Move currently set flags from one type id to another based -on product and optionally component. - -=head1 SYNOPSIS - -This script will move bugs matching a specific product (and optionally a component) -from one flag type id to another if the bug has the flag set to either +, -, or ?. - -./move_flag_types.pl --old-id 4 --new-id 720 --product Firefox --component Installer - -=head1 OPTIONS - -=over - -=item B<--help|-h|?> - -Print a brief help message and exits. - -=item B<--oldid|-o> - -Old flag type id. Use editflagtypes.cgi to determine the type id from the URL. - -=item B<--newid|-n> - -New flag type id. Use editflagtypes.cgi to determine the type id from the URL. - -=item B<--product|-p> - -The product that the bugs most be assigned to. - -=item B<--component|-c> - -Optional: The component of the given product that the bugs must be assigned to. - -=item B<--doit|-d> - -Without this argument, changes are not actually committed to the database. - -=back - -=cut - -use strict; -use warnings; - -use lib '.'; - -use Bugzilla; -use Getopt::Long; -use Pod::Usage; - -my %params; -GetOptions(\%params, 'help|h|?', 'oldid|o=s', 'newid|n=s', - 'product|p=s', 'component|c:s', 'doit|d') or pod2usage(1); - -if ($params{'help'} || !$params{'oldid'} - || !$params{'newid'} || !$params{'product'}) { - pod2usage({ -message => "Missing required argument", - -exitval => 1 }); -} - -# Set defaults -$params{'doit'} ||= 0; -$params{'component'} ||= ''; - -my $dbh = Bugzilla->dbh; - -# Get the flag names -my $old_flag_name = $dbh->selectrow_array( - "SELECT name FROM flagtypes WHERE id = ?", - undef, $params{'oldid'}); -my $new_flag_name = $dbh->selectrow_array( - "SELECT name FROM flagtypes WHERE id = ?", - undef, $params{'newid'}); - -# Find the product id -my $product_id = $dbh->selectrow_array( - "SELECT id FROM products WHERE name = ?", - undef, $params{'product'}); - -# Find the component id if not __ANY__ -my $component_id; -if ($params{'component'}) { - $component_id = $dbh->selectrow_array( - "SELECT id FROM components WHERE name = ? AND product_id = ?", - undef, $params{'component'}, $product_id); -} - -my @query_args = ($params{'oldid'}); - -my $flag_query = "SELECT flags.id AS flag_id, flags.bug_id AS bug_id - FROM flags JOIN bugs ON flags.bug_id = bugs.bug_id - WHERE flags.type_id = ? "; - -if ($component_id) { - # No need to compare against product_id as component_id is already - # tied to a specific product - $flag_query .= "AND bugs.component_id = ?"; - push(@query_args, $component_id); -} -else { - # All bugs for a product regardless of component - $flag_query .= "AND bugs.product_id = ?"; - push(@query_args, $product_id); -} - -my $flags = $dbh->selectall_arrayref($flag_query, undef, @query_args); - -if (@$flags) { - print "Moving '" . scalar @$flags . "' flags " . - "from $old_flag_name (" . $params{'oldid'} . ") " . - "to $new_flag_name (" . $params{'newid'} . ")...\n"; - - if (!$params{'doit'}) { - print "Pass the argument --doit or -d to permanently make changes to the database.\n"; - } - else { - my $flag_update_sth = $dbh->prepare("UPDATE flags SET type_id = ? WHERE id = ?"); - - foreach my $flag (@$flags) { - my ($flag_id, $bug_id) = @$flag; - print "Bug: $bug_id Flag: $flag_id\n"; - $flag_update_sth->execute($params{'newid'}, $flag_id); - } - } - - # 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(); -} -else { - print "No flags to move\n"; -} diff --git a/contrib/reorg-tools/move_os.pl b/contrib/reorg-tools/move_os.pl deleted file mode 100755 index 96b58d616..000000000 --- a/contrib/reorg-tools/move_os.pl +++ /dev/null @@ -1,81 +0,0 @@ -#!/usr/bin/perl -# 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 5.10.1; -use strict; -use warnings; - -use FindBin '$RealBin'; -use lib "$RealBin/../..", "$RealBin/../../lib"; - -use Bugzilla; -use Bugzilla::Field; -use Bugzilla::Constants; - -use Getopt::Long qw( :config gnu_getopt ); -use Pod::Usage; - -Bugzilla->usage_mode(USAGE_MODE_CMDLINE); - -my ($from_os, $to_os); -GetOptions('from=s' => \$from_os, 'to=s' => \$to_os); - -pod2usage(1) unless defined $from_os && defined $to_os; - - -my $check_from_os = Bugzilla::Field::Choice->type('op_sys')->match({ value => $from_os }); -my $check_to_os = Bugzilla::Field::Choice->type('op_sys')->match({ value => $to_os }); -die "Cannot move $from_os because it does not exist\n" - unless @$check_from_os == 1; -die "Cannot move $from_os because $to_os doesn't exist.\n" - unless @$check_to_os == 1; - -my $dbh = Bugzilla->dbh; -my $timestamp = $dbh->selectrow_array('SELECT LOCALTIMESTAMP(0)'); -my $bug_ids = $dbh->selectcol_arrayref(q{SELECT bug_id FROM bugs WHERE bugs.op_sys = ?}, undef, $from_os); -my $field = Bugzilla::Field->check({ name => 'op_sys', cache => 1 }); -my $nobody = Bugzilla::User->check({ name => 'nobody@mozilla.org', cache => 1 }); - -my $bug_count = @$bug_ids; -if ($bug_count == 0) { - warn "There are no bugs to move.\n"; - exit 1; -} - -print STDERR <<EOF; -About to move $bug_count bugs from $from_os to $to_os. - -Press <Ctrl-C> to stop or <Enter> to continue... -EOF -getc(); - -$dbh->bz_start_transaction; -foreach my $bug_id (@$bug_ids) { - warn "Moving $bug_id...\n"; - - $dbh->do(q{INSERT INTO bugs_activity(bug_id, who, bug_when, fieldid, removed, added) - VALUES (?, ?, ?, ?, ?, ?)}, - undef, $bug_id, $nobody->id, $timestamp, $field->id, $from_os, $to_os); - $dbh->do(q{UPDATE bugs SET op_sys = ?, delta_ts = ?, lastdiffed = ? WHERE bug_id = ?}, - undef, $to_os, $timestamp, $timestamp, $bug_id); -} -$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(); - -__END__ - -=head1 NAME - -move_os.pl - move the os on all bugs with a particular os to a new os - -=head1 SYNOPSIS - - move_os.pl --from 'Windows 8 Metro' --to 'Windows 8.1' diff --git a/contrib/reorg-tools/movebugs.pl b/contrib/reorg-tools/movebugs.pl deleted file mode 100755 index 7ffca3615..000000000 --- a/contrib/reorg-tools/movebugs.pl +++ /dev/null @@ -1,182 +0,0 @@ -#!/usr/bin/perl -w -use strict; - -use Cwd 'abs_path'; -use File::Basename; -use FindBin; -use lib "$FindBin::Bin/../.."; -use lib "$FindBin::Bin/../../lib"; - -use Bugzilla; -use Bugzilla::Constants; -use Bugzilla::FlagType; -use Bugzilla::Hook; -use Bugzilla::Util; - -Bugzilla->usage_mode(USAGE_MODE_CMDLINE); - -if (scalar @ARGV < 4) { - die <<USAGE; -Usage: movebugs.pl <old-product> <old-component> <new-product> <new-component> - -Eg. movebugs.pl mozilla.org bmo bugzilla.mozilla.org admin -Will move all bugs in the mozilla.org:bmo component to the -bugzilla.mozilla.org:admin component. - -The new product must have matching versions, milestones, and flags from the old -product (will be validated by this script). -USAGE -} - -my ($old_product, $old_component, $new_product, $new_component) = @ARGV; - -my $dbh = Bugzilla->dbh; - -my $old_product_id = $dbh->selectrow_array( - "SELECT id FROM products WHERE name=?", - undef, $old_product); -$old_product_id - or die "Can't find product ID for '$old_product'.\n"; - -my $old_component_id = $dbh->selectrow_array( - "SELECT id FROM components WHERE name=? AND product_id=?", - undef, $old_component, $old_product_id); -$old_component_id - or die "Can't find component ID for '$old_component'.\n"; - -my $new_product_id = $dbh->selectrow_array( - "SELECT id FROM products WHERE name=?", - undef, $new_product); -$new_product_id - or die "Can't find product ID for '$new_product'.\n"; - -my $new_component_id = $dbh->selectrow_array( - "SELECT id FROM components WHERE name=? AND product_id=?", - undef, $new_component, $new_product_id); -$new_component_id - or die "Can't find component ID for '$new_component'.\n"; - -my $product_field_id = $dbh->selectrow_array( - "SELECT id FROM fielddefs WHERE name = 'product'"); -$product_field_id - or die "Can't find field ID for 'product' field\n"; -my $component_field_id = $dbh->selectrow_array( - "SELECT id FROM fielddefs WHERE name = 'component'"); -$component_field_id - or die "Can't find field ID for 'component' field\n"; - -my $user_id = $dbh->selectrow_array( - "SELECT userid FROM profiles WHERE login_name='nobody\@mozilla.org'"); -$user_id - or die "Can't find user ID for 'nobody\@mozilla.org'\n"; - -$dbh->bz_start_transaction(); - -# build list of bugs -my $ra_ids = $dbh->selectcol_arrayref( - "SELECT bug_id FROM bugs WHERE product_id=? AND component_id=?", - undef, $old_product_id, $old_component_id); -my $bug_count = scalar @$ra_ids; -$bug_count - or die "No bugs were found in '$old_component'\n"; -my $where_sql = 'bug_id IN (' . join(',', @$ra_ids) . ')'; - -# check versions -my @missing_versions; -my $ra_versions = $dbh->selectcol_arrayref( - "SELECT DISTINCT version FROM bugs WHERE $where_sql"); -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 $where_sql"); -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; -} - -# check flags -my @missing_flags; -my $ra_old_types = $dbh->selectcol_arrayref( - "SELECT DISTINCT type_id - FROM flags - INNER JOIN flagtypes ON flagtypes.id = flags.type_id - WHERE $where_sql"); -my $ra_new_types = - Bugzilla::FlagType::match({ product_id => $new_product_id, - component_id => $new_component_id }); -foreach my $old_type (@$ra_old_types) { - unless (grep { $_->id == $old_type } @$ra_new_types) { - my $flagtype = Bugzilla::FlagType->new($old_type); - push @missing_flags, $flagtype->name . ' (' . $flagtype->target_type . ')'; - } -} - -# show missing -my $missing_error = ''; -if (@missing_versions) { - $missing_error .= "'$new_product' is missing the following version(s):\n " . - join("\n ", @missing_versions) . "\n"; -} -if (@missing_milestones) { - $missing_error .= "'$new_product' is missing the following milestone(s):\n " . - join("\n ", @missing_milestones) . "\n"; -} -if (@missing_flags) { - $missing_error .= "'$new_product'::'$new_component' is missing the following flag(s):\n " . - join("\n ", @missing_flags) . "\n"; -} -die $missing_error if $missing_error; - -# confirmation -print <<EOF; -About to move $bug_count bugs -From '$old_product' : '$old_component' -To '$new_product' : '$new_component' - -Press <Ctrl-C> to stop or <Enter> to continue... -EOF -getc(); - -print "Moving $bug_count bugs from $old_product:$old_component to $new_product:$new_component\n"; - -# update bugs -$dbh->do( - "UPDATE bugs SET product_id=?, component_id=? WHERE $where_sql", - undef, $new_product_id, $new_component_id); - -# touch bugs -$dbh->do("UPDATE bugs SET delta_ts=NOW() WHERE $where_sql"); -$dbh->do("UPDATE bugs SET lastdiffed=NOW() WHERE $where_sql"); - -# update bugs_activity -$dbh->do( - "INSERT INTO bugs_activity(bug_id, who, bug_when, fieldid, removed, added) - SELECT bug_id, ?, delta_ts, ?, ?, ? FROM bugs WHERE $where_sql", - undef, - $user_id, $product_field_id, $old_product, $new_product); -$dbh->do( - "INSERT INTO bugs_activity(bug_id, who, bug_when, fieldid, removed, added) - SELECT bug_id, ?, delta_ts, ?, ?, ? FROM bugs WHERE $where_sql", - undef, - $user_id, $component_field_id, $old_component, $new_component); - -Bugzilla::Hook::process('reorg_move_bugs', { bug_ids => $ra_ids } ); - -$dbh->bz_commit_transaction(); - -foreach my $bug_id (@$ra_ids) { - Bugzilla->memcached->clear({ table => 'bugs', id => $bug_id }); -} - -# 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/contrib/reorg-tools/movecomponent.pl b/contrib/reorg-tools/movecomponent.pl deleted file mode 100755 index cb07b84fc..000000000 --- a/contrib/reorg-tools/movecomponent.pl +++ /dev/null @@ -1,154 +0,0 @@ -#!/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)); - } -} diff --git a/contrib/reorg-tools/reassign_open_bugs.pl b/contrib/reorg-tools/reassign_open_bugs.pl deleted file mode 100755 index 6496f9a95..000000000 --- a/contrib/reorg-tools/reassign_open_bugs.pl +++ /dev/null @@ -1,87 +0,0 @@ -#!/usr/bin/perl -# 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 5.10.1; -use strict; -use warnings; - -use FindBin '$RealBin'; -use lib "$RealBin/../..", "$RealBin/../../lib"; - -use Bugzilla; -use Bugzilla::User; -use Bugzilla::Constants; - -use Getopt::Long qw( :config gnu_getopt ); -use Pod::Usage; - -# Load extensions for monkeypatched $user->clear_last_statistics_ts() -BEGIN { Bugzilla->extensions(); } - -Bugzilla->usage_mode(USAGE_MODE_CMDLINE); - -my ($from, $to); -GetOptions( - "from|f=s" => \$from, - "to|t=s" => \$to, -); - -pod2usage(1) unless defined $from && defined $to; - -my $dbh = Bugzilla->dbh; - -my $timestamp = $dbh->selectrow_array('SELECT LOCALTIMESTAMP(0)'); -my $field = Bugzilla::Field->check({ name => 'assigned_to', cache => 1 }); -my $from_user = Bugzilla::User->check({ name => $from, cache => 1 }); -my $to_user = Bugzilla::User->check({ name => $to, cache => 1 }); - -my $bugs = $dbh->selectcol_arrayref(q{SELECT bug_id - FROM bugs - LEFT JOIN bug_status - ON bug_status.value = bugs.bug_status - WHERE bug_status.is_open = 1 - AND bugs.assigned_to = ?}, undef, $from_user->id); -my $bug_count = @$bugs; -if ($bug_count == 0) { - warn "There are no bugs to move.\n"; - exit 1; -} - -print STDERR <<EOF; -About to move $bug_count bugs from $from to $to. - -Press <Ctrl-C> to stop or <Enter> to continue... -EOF -getc(); - -$dbh->bz_start_transaction; -foreach my $bug_id (@$bugs) { - warn "Updating bug $bug_id\n"; - $dbh->do(q{INSERT INTO bugs_activity(bug_id, who, bug_when, fieldid, removed, added) - VALUES (?, ?, ?, ?, ?, ?)}, - undef, $bug_id, $to_user->id, $timestamp, $field->id, $from_user->login, $to_user->login); - $dbh->do(q{UPDATE bugs SET assigned_to = ?, delta_ts = ?, lastdiffed = ? WHERE bug_id = ?}, - undef, $to_user->id, $timestamp, $timestamp, $bug_id); -} -$from_user->clear_last_statistics_ts(); -$to_user->clear_last_statistics_ts(); -$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(); - -__END__ - -=head1 NAME - -reassign-open-bugs.pl - reassign all open bugs from one user to another. - -=head1 SYNOPSIS - - reassign-open-bugs.pl --from general@js.bugs --to nobody@mozilla.org diff --git a/contrib/reorg-tools/reset_default_user.pl b/contrib/reorg-tools/reset_default_user.pl deleted file mode 100755 index 173d03849..000000000 --- a/contrib/reorg-tools/reset_default_user.pl +++ /dev/null @@ -1,145 +0,0 @@ -#!/usr/bin/perl -wT -# 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 lib '.'; - -use Bugzilla; -use Bugzilla::Constants; -use Bugzilla::User; -use Bugzilla::Field; -use Bugzilla::Util qw(trick_taint); - -use Getopt::Long; - -Bugzilla->usage_mode(USAGE_MODE_CMDLINE); - -my $dbh = Bugzilla->dbh; - -my $field_name = ""; -my $product = ""; -my $component = ""; -my $help = ""; -my %user_cache = (); - -my $result = GetOptions('field=s' => \$field_name, - 'product=s' => \$product, - 'component=s' => \$component, - 'help|h' => \$help); - -sub usage { - print <<USAGE; -Usage: reset_default_user.pl --field <fieldname> --product <product> [--component <component>] [--help] - -This script will load all bugs matching the product, and optionally component, -and reset the default user value back to the default value for the component. -Valid field names are assigned_to and qa_contact. -USAGE -} - -if (!$product || $help - || ($field_name ne 'assigned_to' && $field_name ne 'qa_contact')) -{ - usage(); - exit(1); -} - -# We will need these for entering into bugs_activity -my $who = Bugzilla::User->new({ name => 'nobody@mozilla.org' }); -my $field = Bugzilla::Field->new({ name => $field_name }); - -trick_taint($product); -my $product_id = $dbh->selectrow_array( - "SELECT id FROM products WHERE name = ?", - undef, $product); -$product_id or die "Can't find product ID for '$product'.\n"; - -my $component_id; -my $default_user_id; -if ($component) { - trick_taint($component); - my $colname = $field->name eq 'qa_contact' - ? 'initialqacontact' - : 'initialowner'; - ($component_id, $default_user_id) = $dbh->selectrow_array( - "SELECT id, $colname FROM components " . - "WHERE name = ? AND product_id = ?", - undef, $component, $product_id); - $component_id or die "Can't find component ID for '$component'.\n"; - $user_cache{$default_user_id} ||= Bugzilla::User->new($default_user_id); -} - -# build list of bugs -my $bugs_query = "SELECT bug_id, qa_contact, component_id " . - "FROM bugs WHERE product_id = ?"; -my @args = ($product_id); - -if ($component_id) { - $bugs_query .= " AND component_id = ? AND qa_contact != ?"; - push(@args, $component_id, $default_user_id); -} - -my $bugs = $dbh->selectall_arrayref($bugs_query, {Slice => {}}, @args); -my $bug_count = scalar @$bugs; -$bug_count - or die "No bugs were found.\n"; - -# confirmation -print <<EOF; -About to reset $field_name for $bug_count bugs. - -Press <Ctrl-C> to stop or <Enter> to continue... -EOF -getc(); - -$dbh->bz_start_transaction(); - -foreach my $bug (@$bugs) { - my $bug_id = $bug->{bug_id}; - my $old_user_id = $bug->{$field->name}; - my $old_comp_id = $bug->{component_id}; - - # If only changing one component, we already have the default user id - my $new_user_id; - if ($default_user_id) { - $new_user_id = $default_user_id; - } - else { - my $colname = $field->name eq 'qa_contact' - ? 'initialqacontact' - : 'initialowner'; - $new_user_id = $dbh->selectrow_array( - "SELECT $colname FROM components WHERE id = ?", - undef, $old_comp_id); - } - - if ($old_user_id != $new_user_id) { - print "Resetting " . $field->name . " for bug $bug_id ..."; - - # Use the cached version if already exists - my $old_user = $user_cache{$old_user_id} ||= Bugzilla::User->new($old_user_id); - my $new_user = $user_cache{$new_user_id} ||= Bugzilla::User->new($new_user_id); - - my $timestamp = $dbh->selectrow_array('SELECT LOCALTIMESTAMP(0)'); - - $dbh->do("UPDATE bugs SET " . $field->name . " = ? WHERE bug_id = ?", - undef, $new_user_id, $bug_id); - $dbh->do("INSERT INTO bugs_activity(bug_id, who, bug_when, fieldid, removed, added) " . - "VALUES (?, ?, ?, ?, ?, ?)", - undef, $bug_id, $who->id, $timestamp, $field->id, $old_user->login, $new_user->login); - $dbh->do("UPDATE bugs SET delta_ts = ?, lastdiffed = ? WHERE bug_id = ?", - undef, $timestamp, $timestamp, $bug_id); - - Bugzilla->memcached->clear({ table => 'bugs', id => $bug_id }); - - print "done.\n"; - } -} - -$dbh->bz_commit_transaction(); diff --git a/contrib/reorg-tools/syncflags.pl b/contrib/reorg-tools/syncflags.pl deleted file mode 100755 index 8e039f7bb..000000000 --- a/contrib/reorg-tools/syncflags.pl +++ /dev/null @@ -1,88 +0,0 @@ -#!/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 - -use strict; - -use lib qw(. lib); - -use Bugzilla; -use Bugzilla::Constants; - -sub usage() { - print <<USAGE; -Usage: syncflags.pl <srcproduct> <tgtproduct> - -E.g.: syncflags.pl FoodReplicator SeaMonkey -will copy any flag inclusions (only) for the product "FoodReplicator" -so matching inclusions exist for the product "SeaMonkey". This script is -normally used prior to moving components from srcproduct to tgtproduct. -USAGE - - exit(1); -} - -############################################################################# -# MAIN CODE -############################################################################# - -# This is a pure command line script. -Bugzilla->usage_mode(USAGE_MODE_CMDLINE); - -if (scalar @ARGV < 2) { - usage(); - exit(); -} - -my ($srcproduct, $tgtproduct) = @ARGV; - -my $dbh = Bugzilla->dbh; - -# Find product IDs -my $srcprodid = $dbh->selectrow_array("SELECT id FROM products WHERE name = ?", - undef, $srcproduct); -if (!$srcprodid) { - print "Can't find product ID for '$srcproduct'.\n"; - exit(1); -} - -my $tgtprodid = $dbh->selectrow_array("SELECT id FROM products WHERE name = ?", - undef, $tgtproduct); -if (!$tgtprodid) { - print "Can't find product ID for '$tgtproduct'.\n"; - exit(1); -} - -$dbh->do("INSERT INTO flaginclusions(component_id, type_id, product_id) - SELECT fi1.component_id, fi1.type_id, ? FROM flaginclusions fi1 - LEFT JOIN flaginclusions fi2 - ON fi1.type_id = fi2.type_id - AND fi2.product_id = ? - WHERE fi1.product_id = ? - AND fi2.type_id IS NULL", - undef, - $tgtprodid, $tgtprodid, $srcprodid); - -# 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/contrib/reorg-tools/syncmsandversions.pl b/contrib/reorg-tools/syncmsandversions.pl deleted file mode 100755 index 20e88252e..000000000 --- a/contrib/reorg-tools/syncmsandversions.pl +++ /dev/null @@ -1,122 +0,0 @@ -#!/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 - -use strict; - -use lib qw(. lib); - -use Bugzilla; -use Bugzilla::Constants; - -sub usage() { - print <<USAGE; -Usage: syncmsandversions.pl <srcproduct> <tgtproduct> - -E.g.: syncmsandversions.pl FoodReplicator SeaMonkey -will copy any versions and milstones in the product "FoodReplicator" -which do not exist in product "SeaMonkey" into it. This script is normally -used prior to moving components from srcproduct to tgtproduct. -USAGE - - exit(1); -} - -############################################################################# -# MAIN CODE -############################################################################# - -# This is a pure command line script. -Bugzilla->usage_mode(USAGE_MODE_CMDLINE); - -if (scalar @ARGV < 2) { - usage(); - exit(); -} - -my ($srcproduct, $tgtproduct) = @ARGV; - -my $dbh = Bugzilla->dbh; - -# Find product IDs -my $srcprodid = $dbh->selectrow_array("SELECT id FROM products WHERE name = ?", - undef, $srcproduct); -if (!$srcprodid) { - print "Can't find product ID for '$srcproduct'.\n"; - exit(1); -} - -my $tgtprodid = $dbh->selectrow_array("SELECT id FROM products WHERE name = ?", - undef, $tgtproduct); -if (!$tgtprodid) { - print "Can't find product ID for '$tgtproduct'.\n"; - exit(1); -} - -$dbh->bz_start_transaction(); - -$dbh->do(" - INSERT INTO milestones(value, sortkey, isactive, product_id) - SELECT m1.value, m1.sortkey, m1.isactive, ? - FROM milestones m1 - LEFT JOIN milestones m2 ON m1.value = m2.value - AND m2.product_id = ? - WHERE m1.product_id = ? - AND m2.value IS NULL - ", - undef, - $tgtprodid, $tgtprodid, $srcprodid); - -$dbh->do(" - INSERT INTO versions(value, isactive, product_id) - SELECT v1.value, v1.isactive, ? - FROM versions v1 - LEFT JOIN versions v2 ON v1.value = v2.value - AND v2.product_id = ? - WHERE v1.product_id = ? - AND v2.value IS NULL - ", - undef, - $tgtprodid, $tgtprodid, $srcprodid); - -$dbh->do(" - INSERT INTO group_control_map (group_id, product_id, entry, membercontrol, - othercontrol, canedit, editcomponents, - editbugs, canconfirm) - SELECT g1.group_id, ?, g1.entry, g1.membercontrol, g1.othercontrol, - g1.canedit, g1.editcomponents, g1.editbugs, g1.canconfirm - FROM group_control_map g1 - LEFT JOIN group_control_map g2 ON g1.product_id = ? - AND g2.product_id = ? - AND g1.group_id = g2.group_id - WHERE g1.product_id = ? - AND g2.group_id IS NULL - ", - undef, - $tgtprodid, $srcprodid, $tgtprodid, $srcprodid); - -$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/contrib/sanitizeme.pl b/contrib/sanitizeme.pl deleted file mode 100755 index af0c167bf..000000000 --- a/contrib/sanitizeme.pl +++ /dev/null @@ -1,230 +0,0 @@ -#!/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 the Mozilla -# Corporation. Portions created by Mozilla are -# Copyright (C) 2006 Mozilla Foundation. All Rights Reserved. -# -# Contributor(s): Myk Melez <myk@mozilla.org> -# Alex Brugh <alex@cs.umn.edu> -# Dave Miller <justdave@mozilla.com> -# Byron Jones <glob@mozilla.com> - -use strict; - -use FindBin '$RealBin'; -use lib "$RealBin/..", "$RealBin/lib"; - -use Bugzilla; -use Bugzilla::Bug; -use Bugzilla::Constants; -use Bugzilla::Hook; -use Bugzilla::Util; -use Getopt::Long; -use List::MoreUtils qw(uniq); -$| = 1; - -my $dbh = Bugzilla->dbh; - -# This SQL is designed to sanitize a copy of a Bugzilla database so that it -# doesn't contain any information that can't be viewed from a web browser by -# a user who is not logged in. - -my ($dry_run, $from_cron, $keep_attachments, $keep_group_bugs, $keep_groups, $execute, - $keep_passwords, $keep_insider, $trace, $enable_email) = (0, 0, 0, '', 0, 0, 0, 0, 0, 0); -my $keep_group_bugs_sql = ''; - -my $syntax = <<EOF; -options: ---execute perform database sanitization ---keep-attachments disable removal of attachment content ---keep-passwords disable resetting of passwords ---keep-insider disable removal of insider comments and attachments ---keep-group-bugs disable removal of the specified groups and associated bugs ---keep-groups disable removal of group definitions ---enable-email do not disable email for all users ---dry-run do not update the database, just output what will be deleted ---from-cron quite mode - suppress non-warning/error output ---trace output sql statements -EOF -GetOptions( - "execute" => \$execute, - "dry-run" => \$dry_run, - "from-cron" => \$from_cron, - "keep-attachments" => \$keep_attachments, - "keep-passwords" => \$keep_passwords, - "keep-insider" => \$keep_insider, - "keep-group-bugs:s" => \$keep_group_bugs, - "keep-groups" => \$keep_groups, - "trace" => \$trace, - "enable-email" => \$enable_email, -) or die $syntax; -die "--execute switch required to perform database sanitization.\n\n$syntax" - unless $execute or $dry_run; - -if ($keep_group_bugs ne '') { - my @groups; - foreach my $group_id (split(/\s*,\s*/, $keep_group_bugs)) { - my $group; - if ($group_id =~ /\D/) { - $group = Bugzilla::Group->new({ name => $group_id }); - } else { - $group = Bugzilla::Group->new($group_id); - } - die "Invalid group '$group_id'\n" unless $group; - push @groups, $group->id; - } - $keep_group_bugs_sql = "NOT IN (" . join(",", @groups) . ")"; -} - -$dbh->{TraceLevel} = 1 if $trace; - -if ($dry_run) { - print "** dry run : no changes to the database will be made **\n"; - $dbh->bz_start_transaction(); -} -eval { - delete_non_public_products(); - delete_secure_bugs(); - delete_deleted_comments(); - delete_insider_comments() unless $keep_insider; - delete_security_groups() unless $keep_groups; - delete_sensitive_user_data(); - delete_attachment_data() unless $keep_attachments; - delete_bug_user_last_visit(); - Bugzilla::Hook::process('db_sanitize'); - disable_email_delivery() unless $enable_email; - print "All done!\n"; - $dbh->bz_rollback_transaction() if $dry_run; -}; -if ($@) { - $dbh->bz_rollback_transaction() if $dry_run; - die "$@" if $@; -} - -sub delete_non_public_products { - # Delete all non-public products, and all data associated with them - my @products = Bugzilla::Product->get_all(); - my $mandatory = CONTROLMAPMANDATORY; - foreach my $product (@products) { - # if there are any mandatory groups on the product, nuke it and - # everything associated with it (including the bugs) - Bugzilla->params->{'allowbugdeletion'} = 1; # override this in memory for now - my $mandatorygroups = $dbh->selectcol_arrayref("SELECT group_id FROM group_control_map WHERE product_id = ? AND (membercontrol = $mandatory)", undef, $product->id); - if (0 < scalar(@$mandatorygroups)) { - print "Deleting product '" . $product->name . "'...\n"; - $product->remove_from_db(); - } - } -} - -sub delete_secure_bugs { - # Delete all data for bugs in security groups. - my $buglist = $dbh->selectall_arrayref( - $keep_group_bugs - ? "SELECT DISTINCT bug_id FROM bug_group_map WHERE group_id $keep_group_bugs_sql" - : "SELECT DISTINCT bug_id FROM bug_group_map" - ); - my $numbugs = scalar(@$buglist); - my $bugnum = 0; - print "Deleting $numbugs bugs in " . ($keep_group_bugs ? 'non-' : '') . "security groups...\n"; - foreach my $row (@$buglist) { - my $bug_id = $row->[0]; - $bugnum++; - print "\r$bugnum/$numbugs" unless $from_cron; - my $bug = new Bugzilla::Bug($bug_id); - $bug->remove_from_db(); - } - print "\rDone \n" unless $from_cron; -} - -sub delete_deleted_comments { - # Delete all comments tagged as 'deleted' - my $comment_ids = $dbh->selectcol_arrayref("SELECT comment_id FROM longdescs_tags WHERE tag='deleted'"); - return unless @$comment_ids; - print "Deleting 'deleted' comments...\n"; - my @bug_ids = uniq @{ - $dbh->selectcol_arrayref("SELECT bug_id FROM longdescs WHERE comment_id IN (" . join(',', @$comment_ids) . ")") - }; - $dbh->do("DELETE FROM longdescs WHERE comment_id IN (" . join(',', @$comment_ids) . ")"); - foreach my $bug_id (@bug_ids) { - Bugzilla::Bug->new($bug_id)->_sync_fulltext(update_comments => 1); - } -} - -sub delete_insider_comments { - # Delete all 'insidergroup' comments and attachments - print "Deleting 'insidergroup' comments and attachments...\n"; - $dbh->do("DELETE FROM longdescs WHERE isprivate = 1"); - $dbh->do("DELETE attach_data FROM attachments JOIN attach_data ON attachments.attach_id = attach_data.id WHERE attachments.isprivate = 1"); - $dbh->do("DELETE FROM attachments WHERE isprivate = 1"); - $dbh->do("UPDATE bugs_fulltext SET comments = comments_noprivate"); -} - -sub delete_security_groups { - # Delete all security groups. - print "Deleting " . ($keep_group_bugs ? 'non-' : '') . "security groups...\n"; - $dbh->do("DELETE user_group_map FROM groups JOIN user_group_map ON groups.id = user_group_map.group_id WHERE groups.isbuggroup = 1"); - $dbh->do("DELETE group_group_map FROM groups JOIN group_group_map ON (groups.id = group_group_map.member_id OR groups.id = group_group_map.grantor_id) WHERE groups.isbuggroup = 1"); - $dbh->do("DELETE group_control_map FROM groups JOIN group_control_map ON groups.id = group_control_map.group_id WHERE groups.isbuggroup = 1"); - $dbh->do("UPDATE flagtypes LEFT JOIN groups ON flagtypes.grant_group_id = groups.id SET grant_group_id = NULL WHERE groups.isbuggroup = 1"); - $dbh->do("UPDATE flagtypes LEFT JOIN groups ON flagtypes.request_group_id = groups.id SET request_group_id = NULL WHERE groups.isbuggroup = 1"); - if ($keep_group_bugs) { - $dbh->do("DELETE FROM groups WHERE isbuggroup = 1 AND id $keep_group_bugs_sql"); - } else { - $dbh->do("DELETE FROM groups WHERE isbuggroup = 1"); - } -} - -sub delete_sensitive_user_data { - # Remove sensitive user account data. - print "Deleting sensitive user account data...\n"; - $dbh->do("UPDATE profiles SET cryptpassword = 'deleted'") unless $keep_passwords; - $dbh->do("DELETE FROM user_api_keys"); - $dbh->do("DELETE FROM profiles_activity"); - $dbh->do("DELETE FROM profile_search"); - $dbh->do("DELETE FROM namedqueries"); - $dbh->do("DELETE FROM tokens"); - $dbh->do("DELETE FROM logincookies"); - $dbh->do("DELETE FROM login_failure"); - $dbh->do("DELETE FROM audit_log"); - # queued bugmail - $dbh->do("DELETE FROM ts_error"); - $dbh->do("DELETE FROM ts_exitstatus"); - $dbh->do("DELETE FROM ts_funcmap"); - $dbh->do("DELETE FROM ts_job"); - $dbh->do("DELETE FROM ts_note"); -} - -sub delete_attachment_data { - # Delete unnecessary attachment data. - print "Removing attachment data to preserve disk space...\n"; - $dbh->do("UPDATE attach_data SET thedata = ''"); -} - -sub delete_bug_user_last_visit { - print "Removing all entries from bug_user_last_visit...\n"; - $dbh->do('TRUNCATE TABLE bug_user_last_visit'); -} - -sub disable_email_delivery { - # turn off email delivery for all users. - print "Turning off email delivery...\n"; - $dbh->do("UPDATE profiles SET disable_mail = 1"); - - # Also clear out the default flag cc as well since they do not - # have to be in the profiles table - $dbh->do("UPDATE flagtypes SET cc_list = NULL"); -} diff --git a/contrib/sendbugmail.pl b/contrib/sendbugmail.pl deleted file mode 100755 index d0c7d63b7..000000000 --- a/contrib/sendbugmail.pl +++ /dev/null @@ -1,101 +0,0 @@ -#!/usr/bin/perl -wT -# -# sendbugmail.pl -# -# Nick Barnes, Ravenbrook Limited, 2004-04-01. -# -# Bugzilla email script for Bugzilla 2.17.4 and later. Invoke this to send -# bugmail for a bug which has been changed directly in the database. -# This uses Bugzilla's own BugMail facility, and will email the -# users associated with the bug. Replaces the old "processmail" -# script. -# -# Usage: perl -T contrib/sendbugmail.pl bug_id user_email - -use 5.10.1; -use strict; -use lib qw(. lib); - -use Bugzilla; -use Bugzilla::Util; -use Bugzilla::BugMail; -use Bugzilla::User; - -my $dbh = Bugzilla->dbh; - -sub usage { - say STDERR "Usage: $0 bug_id user_email"; - exit; -} - -if (($#ARGV < 1) || ($#ARGV > 2)) { - usage(); -} - -# Get the arguments. -my $bugnum = $ARGV[0]; -my $changer = $ARGV[1]; - -# Validate the bug number. -if (!($bugnum =~ /^(\d+)$/)) { - say STDERR "Bug number \"$bugnum\" not numeric."; - usage(); -} - -detaint_natural($bugnum); - -my ($id) = $dbh->selectrow_array("SELECT bug_id FROM bugs WHERE bug_id = ?", - undef, $bugnum); - -if (!$id) { - say STDERR "Bug number $bugnum does not exist."; - usage(); -} - -# Validate the changer address. -my $match = Bugzilla->params->{'emailregexp'}; -if ($changer !~ /$match/) { - say STDERR "Changer \"$changer\" doesn't match email regular expression."; - usage(); -} -my $changer_user = new Bugzilla::User({ name => $changer }); -unless ($changer_user) { - say STDERR "\"$changer\" is not a valid user."; - usage(); -} - -# Send the email. -my $outputref = Bugzilla::BugMail::Send($bugnum, {'changer' => $changer_user }); - -# Report the results. -my $sent = scalar(@{$outputref->{sent}}); - -if ($sent) { - say "email sent to $sent recipients:"; -} else { - say "No email sent."; -} - -foreach my $sent (@{$outputref->{sent}}) { - say " $sent"; -} - -# This document is copyright (C) 2004 Perforce Software, Inc. All rights -# reserved. -# -# Redistribution and use of this document in any form, with or without -# modification, is permitted provided that redistributions of this -# document retain the above copyright notice, this condition and the -# following disclaimer. -# -# THIS DOCUMENT IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS -# IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED -# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A -# PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# HOLDERS AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED -# TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR -# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -# DOCUMENT, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/contrib/sendunsentbugmail.pl b/contrib/sendunsentbugmail.pl deleted file mode 100755 index 7771cfeff..000000000 --- a/contrib/sendunsentbugmail.pl +++ /dev/null @@ -1,60 +0,0 @@ -#!/usr/bin/perl -wT -# -*- 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): Dave Miller <justdave@bugzilla.org> -# Myk Melez <myk@mozilla.org> - -use 5.10.1; -use strict; -use lib qw(. lib); - -use Bugzilla; -use Bugzilla::Constants; -use Bugzilla::BugMail; - -my $dbh = Bugzilla->dbh; - -my $list = $dbh->selectcol_arrayref( - 'SELECT bug_id FROM bugs - WHERE lastdiffed IS NULL - OR lastdiffed < delta_ts - AND delta_ts < ' - . $dbh->sql_date_math('NOW()', '-', 30, 'MINUTE') . - ' ORDER BY bug_id'); - -if (scalar(@$list) > 0) { - say "OK, now attempting to send unsent mail"; - say scalar(@$list) . " bugs found with possibly unsent mail.\n"; - foreach my $bugid (@$list) { - my $start_time = time; - say "Sending mail for bug $bugid..."; - my $outputref = Bugzilla::BugMail::Send($bugid); - if ($ARGV[0] && $ARGV[0] eq "--report") { - say "Mail sent to:"; - say $_ foreach (sort @{$outputref->{sent}}); - } - else { - my $sent = scalar @{$outputref->{sent}}; - say "$sent mails sent."; - say "Took " . (time - $start_time) . " seconds.\n"; - } - } - say "Unsent mail has been sent."; -} diff --git a/contrib/syncLDAP.pl b/contrib/syncLDAP.pl deleted file mode 100755 index 3da25a656..000000000 --- a/contrib/syncLDAP.pl +++ /dev/null @@ -1,298 +0,0 @@ -#!/usr/bin/perl -wT -# -*- 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 LDAP to Bugzilla User Sync Tool. -# -# The Initial Developer of the Original Code is Andreas Höfler. -# Portions created by Andreas Höfler are Copyright (C) 2003 -# Andreas Höfler. All Rights Reserved. -# -# Contributor(s): Andreas Höfler <andreas.hoefler@bearingpoint.com> -# - -use strict; - -use lib qw(. lib); - -use Net::LDAP; -use Bugzilla; -use Bugzilla::User; - -my $cgi = Bugzilla->cgi; -my $dbh = Bugzilla->dbh; - -my $readonly = 0; -my $nodisable = 0; -my $noupdate = 0; -my $nocreate = 0; -my $quiet = 0; - -### -# Do some preparations -### -foreach my $arg (@ARGV) -{ - if($arg eq '-r') { - $readonly = 1; - } - elsif($arg eq '-d') { - $nodisable = 1; - } - elsif($arg eq '-u') { - $noupdate = 1; - } - elsif($arg eq '-c') { - $nocreate = 1; - } - elsif($arg eq '-q') { - $quiet = 1; - } - else { - print "LDAP Sync Script\n"; - print "Syncronizes the users table from the LDAP server with the Bugzilla users.\n"; - print "Takes mail-attribute from preferences and description from 'cn' or,\n"; - print "if not available, from the uid-attribute.\n\n"; - print "usage:\n syncLDAP.pl [options]\n\n"; - print "options:\n"; - print " -r Readonly, do not make changes to Bugzilla tables\n"; - print " -d No disable, don't disable users, which are not in LDAP\n"; - print " -u No update, don't update users, which have different description in LDAP\n"; - print " -c No create, don't create users, which are in LDAP but not in Bugzilla\n"; - print " -q Quiet mode, give less output\n"; - print "\n"; - exit; - } -} - -my %ldap_users; - -### -# Get current bugzilla users -### -my %bugzilla_users = %{ $dbh->selectall_hashref( - 'SELECT login_name AS new_login_name, realname, disabledtext ' . - 'FROM profiles', 'new_login_name') }; - -foreach my $login_name (keys %bugzilla_users) { - # remove whitespaces - $bugzilla_users{$login_name}{'realname'} =~ s/^\s+|\s+$//g; -} - -### -# Get current LDAP users -### -my $LDAPserver = Bugzilla->params->{"LDAPserver"}; -if ($LDAPserver eq "") { - print "No LDAP server defined in bugzilla preferences.\n"; - exit; -} - -my $LDAPconn; -if($LDAPserver =~ /:\/\//) { - # if the "LDAPserver" parameter is in uri scheme - $LDAPconn = Net::LDAP->new($LDAPserver, version => 3); -} else { - my $LDAPport = "389"; # default LDAP port - if($LDAPserver =~ /:/) { - ($LDAPserver, $LDAPport) = split(":",$LDAPserver); - } - $LDAPconn = Net::LDAP->new($LDAPserver, port => $LDAPport, version => 3); -} - -if(!$LDAPconn) { - print "Connecting to LDAP server failed. Check LDAPserver setting.\n"; - exit; -} -my $mesg; -if (Bugzilla->params->{"LDAPbinddn"}) { - my ($LDAPbinddn,$LDAPbindpass) = split(":",Bugzilla->params->{"LDAPbinddn"}); - $mesg = $LDAPconn->bind($LDAPbinddn, password => $LDAPbindpass); -} -else { - $mesg = $LDAPconn->bind(); -} -if($mesg->code) { - print "Binding to LDAP server failed: " . $mesg->error . "\nCheck LDAPbinddn setting.\n"; - exit; -} - -# We've got our anonymous bind; let's look up the users. -$mesg = $LDAPconn->search( base => Bugzilla->params->{"LDAPBaseDN"}, - scope => "sub", - filter => '(&(' . Bugzilla->params->{"LDAPuidattribute"} . "=*)" . Bugzilla->params->{"LDAPfilter"} . ')', - ); - - -if(! $mesg->count) { - print "LDAP lookup failure. Check LDAPBaseDN setting.\n"; - exit; -} - -my %val = %{ $mesg->as_struct }; - -while( my ($key, $value) = each(%val) ) { - - my @login_name = @{ $value->{Bugzilla->params->{"LDAPmailattribute"}} }; - my @realname = @{ $value->{"cn"} }; - - # no mail entered? go to next - if(! @login_name) { - print "$key has no valid mail address\n"; - next; - } - - # no cn entered? use uid instead - if(! @realname) { - @realname = @{ $value->{Bugzilla->params->{"LDAPuidattribute"}} }; - } - - my $login = shift @login_name; - my $real = shift @realname; - $ldap_users{$login} = { realname => $real }; -} - -print "\n" unless $quiet; - -### -# Sort the users into disable/update/create-Lists and display everything -### -my %disable_users; -my %update_users; -my %create_users; - -print "Bugzilla-Users: \n" unless $quiet; -while( my ($key, $value) = each(%bugzilla_users) ) { - print " " . $key . " '" . $value->{'realname'} . "' " . $value->{'disabledtext'} ."\n" unless $quiet==1; - if(!exists $ldap_users{$key}){ - if($value->{'disabledtext'} eq '') { - $disable_users{$key} = $value; - } - } -} - -print "\nLDAP-Users: \n" unless $quiet; -while( my ($key, $value) = each(%ldap_users) ) { - print " " . $key . " '" . $value->{'realname'} . "'\n" unless $quiet==1; - if(!defined $bugzilla_users{$key}){ - $create_users{$key} = $value; - } - else { - my $bugzilla_user_value = $bugzilla_users{$key}; - if($bugzilla_user_value->{'realname'} ne $value->{'realname'}) { - $update_users{$key} = $value; - } - } -} - -print "\nDetecting email changes: \n" unless $quiet; -while( my ($create_key, $create_value) = each(%create_users) ) { - while( my ($disable_key, $disable_value) = each(%disable_users) ) { - if($create_value->{'realname'} eq $disable_value->{'realname'}) { - print " " . $disable_key . " => " . $create_key ."'\n" unless $quiet==1; - $update_users{$disable_key} = { realname => $create_value->{'realname'}, - new_login_name => $create_key }; - delete $create_users{$create_key}; - delete $disable_users{$disable_key}; - } - } -} - -if($quiet == 0) { - print "\nUsers to disable: \n"; - while( my ($key, $value) = each(%disable_users) ) { - print " " . $key . " '" . $value->{'realname'} . "'\n"; - } - - print "\nUsers to update: \n"; - while( my ($key, $value) = each(%update_users) ) { - print " " . $key . " '" . $value->{'realname'} . "' "; - if(defined $value->{'new_login_name'}) { - print "has changed email to " . $value->{'new_login_name'}; - } - print "\n"; - } - - print "\nUsers to create: \n"; - while( my ($key, $value) = each(%create_users) ) { - print " " . $key . " '" . $value->{'realname'} . "'\n"; - } - - print "\n\n"; -} - - -### -# now do the DB-Update -### -if($readonly == 0) { - print "Performing DB update:\nPhase 1: disabling not-existing users... " unless $quiet; - - my $sth_disable = $dbh->prepare( - 'UPDATE profiles - SET disabledtext = ? - WHERE ' . $dbh->sql_istrcmp('login_name', '?')); - - if($nodisable == 0) { - while( my ($key, $value) = each(%disable_users) ) { - $sth_disable->execute('auto-disabled by ldap sync', $key); - } - print "done!\n" unless $quiet; - } - else { - print "disabled!\n" unless $quiet; - } - - print "Phase 2: updating existing users... " unless $quiet; - - my $sth_update_login = $dbh->prepare( - 'UPDATE profiles - SET login_name = ? - WHERE ' . $dbh->sql_istrcmp('login_name', '?')); - my $sth_update_realname = $dbh->prepare( - 'UPDATE profiles - SET realname = ? - WHERE ' . $dbh->sql_istrcmp('login_name', '?')); - - if($noupdate == 0) { - while( my ($key, $value) = each(%update_users) ) { - if(defined $value->{'new_login_name'}) { - $sth_update_login->execute($value->{'new_login_name'}, $key); - } else { - $sth_update_realname->execute($value->{'realname'}, $key); - } - } - print "done!\n" unless $quiet; - } - else { - print "disabled!\n" unless $quiet; - } - - print "Phase 3: creating new users... " unless $quiet; - if($nocreate == 0) { - while( my ($key, $value) = each(%create_users) ) { - Bugzilla::User->create({ - login_name => $key, - realname => $value->{'realname'}, - cryptpassword => '*'}); - } - print "done!\n" unless $quiet; - } - else { - print "disabled!\n" unless $quiet; - } -} -else -{ - print "No changes to DB because readonly mode\n" unless $quiet; -} - diff --git a/contrib/verify-user.pl b/contrib/verify-user.pl deleted file mode 100755 index d12cd745f..000000000 --- a/contrib/verify-user.pl +++ /dev/null @@ -1,129 +0,0 @@ -#!/usr/bin/perl -wT -# -*- 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): Myk Melez <myk@mozilla.org> -# Dave Miller <justdave@bugzilla.org> - -# See if a user account has ever done anything - -# ./verify-user.pl foo@baz.com - -use strict; - -use lib qw(.); - -use Bugzilla; -use Bugzilla::Util; -use Bugzilla::DB; -use Bugzilla::Constants; - -# Make sure accounts were specified on the command line and exist. -my $user = $ARGV[0] || die "You must specify an user.\n"; -my $dbh = Bugzilla->dbh; -my $sth; - -#$sth = $dbh->prepare("SELECT name, count(*) as qty from bugs, products where reporter=198524 and product_id=products.id group by name order by qty desc"); -#$sth->execute(); -#my $results = $sth->fetchall_arrayref(); -#use Data::Dumper; -#print Data::Dumper::Dumper($results); -#exit; - -trick_taint($user); -if ($user =~ /^\d+$/) { # user ID passed instead of email - $sth = $dbh->prepare('SELECT login_name FROM profiles WHERE userid = ?'); - $sth->execute($user); - ($user) = $sth->fetchrow_array || die "The user with ID $ARGV[0] does not exist.\n"; - print "User $ARGV[0]'s login name is $user.\n"; -} -$sth = $dbh->prepare("SELECT userid FROM profiles WHERE login_name = ?"); -$sth->execute($user); -my ($user_id) = $sth->fetchrow_array || die "The user $user does not exist.\n"; - -print "${user}'s ID is $user_id.\n"; - -$sth = $dbh->prepare("SELECT DISTINCT ipaddr FROM logincookies WHERE userid = ?"); -$sth->execute($user_id); -my $iplist = $sth->fetchall_arrayref; -if (@$iplist > 0) { - print "This user has recently connected from the following IP addresses:\n"; - foreach my $ip (@$iplist) { - print $$ip[0] . "\n"; - } -} - - -# A list of tables and columns to be checked. -my $columns = { - attachments => ['submitter_id'] , - bugs => ['assigned_to', 'reporter', 'qa_contact'] , - bugs_activity => ['who'] , - cc => ['who'] , - components => ['initialowner', 'initialqacontact'] , - flags => ['setter_id', 'requestee_id'] , - logincookies => ['userid'] , - longdescs => ['who'] , - namedqueries => ['userid'] , - profiles_activity => ['userid', 'who'] , - quips => ['userid'] , - series => ['creator'] , - tokens => ['userid'] , - user_group_map => ['user_id'] , - votes => ['who'] , - watch => ['watcher', 'watched'] , - -}; - -my $fields = 0; -# Check records for user. -foreach my $table (keys(%$columns)) { - foreach my $column (@{$columns->{$table}}) { - $sth = $dbh->prepare("SELECT COUNT(*) FROM $table WHERE $column = ?"); - if ($table eq 'user_group_map') { - $sth = $dbh->prepare("SELECT COUNT(*) FROM $table WHERE $column = ? AND grant_type = " . GRANT_DIRECT); - } - $sth->execute($user_id); - my ($val) = $sth->fetchrow_array; - $fields++ if $val; - print "$table.$column: $val\n" if $val; - } -} - -print "The user is mentioned in $fields fields.\n"; - -if ($::ARGV[1] && $::ARGV[1] eq '-r') { - if ($fields == 0) { - $sth = $dbh->prepare("SELECT login_name FROM profiles WHERE login_name = ?"); - my $count = 0; - print "Finding an unused recycle ID"; - do { - $count++; - $sth->execute(sprintf("reuseme%03d\@bugzilla.org", $count)); - print "."; - } while (my ($match) = $sth->fetchrow_array()); - printf "\nUsing reuseme%03d\@bugzilla.org.\n", $count; - $dbh->do("DELETE FROM user_group_map WHERE user_id=?",undef,$user_id); - $dbh->do("UPDATE profiles SET realname='', cryptpassword='randomgarbage' WHERE userid=?",undef,$user_id); - $dbh->do("UPDATE profiles SET login_name=? WHERE userid=?",undef,sprintf("reuseme%03d\@bugzilla.org",$count),$user_id); - } - else { - print "Account has been used, so not recycling.\n"; - } -} |