To check out this repository please hg clone the following URL, or open the URL using EasyMercurial or your preferred Mercurial client.
root / lib / tasks / migrate_from_mantis.rake @ 1568:bc47b68a9487
History | View | Annotate | Download (18.4 KB)
| 1 |
# Redmine - project management software
|
|---|---|
| 2 |
# Copyright (C) 2006-2014 Jean-Philippe Lang
|
| 3 |
#
|
| 4 |
# This program is free software; you can redistribute it and/or
|
| 5 |
# modify it under the terms of the GNU General Public License
|
| 6 |
# as published by the Free Software Foundation; either version 2
|
| 7 |
# of the License, or (at your option) any later version.
|
| 8 |
#
|
| 9 |
# This program is distributed in the hope that it will be useful,
|
| 10 |
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
| 11 |
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
| 12 |
# GNU General Public License for more details.
|
| 13 |
#
|
| 14 |
# You should have received a copy of the GNU General Public License
|
| 15 |
# along with this program; if not, write to the Free Software
|
| 16 |
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
| 17 |
|
| 18 |
desc 'Mantis migration script'
|
| 19 |
|
| 20 |
require 'active_record'
|
| 21 |
require 'iconv' if RUBY_VERSION < '1.9' |
| 22 |
require 'pp'
|
| 23 |
|
| 24 |
namespace :redmine do |
| 25 |
task :migrate_from_mantis => :environment do |
| 26 |
|
| 27 |
module MantisMigrate |
| 28 |
|
| 29 |
DEFAULT_STATUS = IssueStatus.default |
| 30 |
assigned_status = IssueStatus.find_by_position(2) |
| 31 |
resolved_status = IssueStatus.find_by_position(3) |
| 32 |
feedback_status = IssueStatus.find_by_position(4) |
| 33 |
closed_status = IssueStatus.where(:is_closed => true).first |
| 34 |
STATUS_MAPPING = {10 => DEFAULT_STATUS, # new |
| 35 |
20 => feedback_status, # feedback |
| 36 |
30 => DEFAULT_STATUS, # acknowledged |
| 37 |
40 => DEFAULT_STATUS, # confirmed |
| 38 |
50 => assigned_status, # assigned |
| 39 |
80 => resolved_status, # resolved |
| 40 |
90 => closed_status # closed |
| 41 |
} |
| 42 |
|
| 43 |
priorities = IssuePriority.all
|
| 44 |
DEFAULT_PRIORITY = priorities[2] |
| 45 |
PRIORITY_MAPPING = {10 => priorities[1], # none |
| 46 |
20 => priorities[1], # low |
| 47 |
30 => priorities[2], # normal |
| 48 |
40 => priorities[3], # high |
| 49 |
50 => priorities[4], # urgent |
| 50 |
60 => priorities[5] # immediate |
| 51 |
} |
| 52 |
|
| 53 |
TRACKER_BUG = Tracker.find_by_position(1) |
| 54 |
TRACKER_FEATURE = Tracker.find_by_position(2) |
| 55 |
|
| 56 |
roles = Role.where(:builtin => 0).order('position ASC').all |
| 57 |
manager_role = roles[0]
|
| 58 |
developer_role = roles[1]
|
| 59 |
DEFAULT_ROLE = roles.last
|
| 60 |
ROLE_MAPPING = {10 => DEFAULT_ROLE, # viewer |
| 61 |
25 => DEFAULT_ROLE, # reporter |
| 62 |
40 => DEFAULT_ROLE, # updater |
| 63 |
55 => developer_role, # developer |
| 64 |
70 => manager_role, # manager |
| 65 |
90 => manager_role # administrator |
| 66 |
} |
| 67 |
|
| 68 |
CUSTOM_FIELD_TYPE_MAPPING = {0 => 'string', # String |
| 69 |
1 => 'int', # Numeric |
| 70 |
2 => 'int', # Float |
| 71 |
3 => 'list', # Enumeration |
| 72 |
4 => 'string', # Email |
| 73 |
5 => 'bool', # Checkbox |
| 74 |
6 => 'list', # List |
| 75 |
7 => 'list', # Multiselection list |
| 76 |
8 => 'date', # Date |
| 77 |
} |
| 78 |
|
| 79 |
RELATION_TYPE_MAPPING = {1 => IssueRelation::TYPE_RELATES, # related to |
| 80 |
2 => IssueRelation::TYPE_RELATES, # parent of |
| 81 |
3 => IssueRelation::TYPE_RELATES, # child of |
| 82 |
0 => IssueRelation::TYPE_DUPLICATES, # duplicate of |
| 83 |
4 => IssueRelation::TYPE_DUPLICATES # has duplicate |
| 84 |
} |
| 85 |
|
| 86 |
class MantisUser < ActiveRecord::Base |
| 87 |
self.table_name = :mantis_user_table |
| 88 |
|
| 89 |
def firstname |
| 90 |
@firstname = realname.blank? ? username : realname.split.first[0..29] |
| 91 |
@firstname
|
| 92 |
end
|
| 93 |
|
| 94 |
def lastname |
| 95 |
@lastname = realname.blank? ? '-' : realname.split[1..-1].join(' ')[0..29] |
| 96 |
@lastname = '-' if @lastname.blank? |
| 97 |
@lastname
|
| 98 |
end
|
| 99 |
|
| 100 |
def email |
| 101 |
if read_attribute(:email).match(/^([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})$/i) && |
| 102 |
!User.find_by_mail(read_attribute(:email)) |
| 103 |
@email = read_attribute(:email) |
| 104 |
else
|
| 105 |
@email = "#{username}@foo.bar" |
| 106 |
end
|
| 107 |
end
|
| 108 |
|
| 109 |
def username |
| 110 |
read_attribute(:username)[0..29].gsub(/[^a-zA-Z0-9_\-@\.]/, '-') |
| 111 |
end
|
| 112 |
end
|
| 113 |
|
| 114 |
class MantisProject < ActiveRecord::Base |
| 115 |
self.table_name = :mantis_project_table |
| 116 |
has_many :versions, :class_name => "MantisVersion", :foreign_key => :project_id |
| 117 |
has_many :categories, :class_name => "MantisCategory", :foreign_key => :project_id |
| 118 |
has_many :news, :class_name => "MantisNews", :foreign_key => :project_id |
| 119 |
has_many :members, :class_name => "MantisProjectUser", :foreign_key => :project_id |
| 120 |
|
| 121 |
def identifier |
| 122 |
read_attribute(:name).downcase.gsub(/[^a-z0-9\-]+/, '-').slice(0, Project::IDENTIFIER_MAX_LENGTH) |
| 123 |
end
|
| 124 |
end
|
| 125 |
|
| 126 |
class MantisVersion < ActiveRecord::Base |
| 127 |
self.table_name = :mantis_project_version_table |
| 128 |
|
| 129 |
def version |
| 130 |
read_attribute(:version)[0..29] |
| 131 |
end
|
| 132 |
|
| 133 |
def description |
| 134 |
read_attribute(:description)[0..254] |
| 135 |
end
|
| 136 |
end
|
| 137 |
|
| 138 |
class MantisCategory < ActiveRecord::Base |
| 139 |
self.table_name = :mantis_project_category_table |
| 140 |
end
|
| 141 |
|
| 142 |
class MantisProjectUser < ActiveRecord::Base |
| 143 |
self.table_name = :mantis_project_user_list_table |
| 144 |
end
|
| 145 |
|
| 146 |
class MantisBug < ActiveRecord::Base |
| 147 |
self.table_name = :mantis_bug_table |
| 148 |
belongs_to :bug_text, :class_name => "MantisBugText", :foreign_key => :bug_text_id |
| 149 |
has_many :bug_notes, :class_name => "MantisBugNote", :foreign_key => :bug_id |
| 150 |
has_many :bug_files, :class_name => "MantisBugFile", :foreign_key => :bug_id |
| 151 |
has_many :bug_monitors, :class_name => "MantisBugMonitor", :foreign_key => :bug_id |
| 152 |
end
|
| 153 |
|
| 154 |
class MantisBugText < ActiveRecord::Base |
| 155 |
self.table_name = :mantis_bug_text_table |
| 156 |
|
| 157 |
# Adds Mantis steps_to_reproduce and additional_information fields
|
| 158 |
# to description if any
|
| 159 |
def full_description |
| 160 |
full_description = description |
| 161 |
full_description += "\n\n*Steps to reproduce:*\n\n#{steps_to_reproduce}" unless steps_to_reproduce.blank? |
| 162 |
full_description += "\n\n*Additional information:*\n\n#{additional_information}" unless additional_information.blank? |
| 163 |
full_description |
| 164 |
end
|
| 165 |
end
|
| 166 |
|
| 167 |
class MantisBugNote < ActiveRecord::Base |
| 168 |
self.table_name = :mantis_bugnote_table |
| 169 |
belongs_to :bug, :class_name => "MantisBug", :foreign_key => :bug_id |
| 170 |
belongs_to :bug_note_text, :class_name => "MantisBugNoteText", :foreign_key => :bugnote_text_id |
| 171 |
end
|
| 172 |
|
| 173 |
class MantisBugNoteText < ActiveRecord::Base |
| 174 |
self.table_name = :mantis_bugnote_text_table |
| 175 |
end
|
| 176 |
|
| 177 |
class MantisBugFile < ActiveRecord::Base |
| 178 |
self.table_name = :mantis_bug_file_table |
| 179 |
|
| 180 |
def size |
| 181 |
filesize |
| 182 |
end
|
| 183 |
|
| 184 |
def original_filename |
| 185 |
MantisMigrate.encode(filename)
|
| 186 |
end
|
| 187 |
|
| 188 |
def content_type |
| 189 |
file_type |
| 190 |
end
|
| 191 |
|
| 192 |
def read(*args) |
| 193 |
if @read_finished |
| 194 |
nil
|
| 195 |
else
|
| 196 |
@read_finished = true |
| 197 |
content |
| 198 |
end
|
| 199 |
end
|
| 200 |
end
|
| 201 |
|
| 202 |
class MantisBugRelationship < ActiveRecord::Base |
| 203 |
self.table_name = :mantis_bug_relationship_table |
| 204 |
end
|
| 205 |
|
| 206 |
class MantisBugMonitor < ActiveRecord::Base |
| 207 |
self.table_name = :mantis_bug_monitor_table |
| 208 |
end
|
| 209 |
|
| 210 |
class MantisNews < ActiveRecord::Base |
| 211 |
self.table_name = :mantis_news_table |
| 212 |
end
|
| 213 |
|
| 214 |
class MantisCustomField < ActiveRecord::Base |
| 215 |
self.table_name = :mantis_custom_field_table |
| 216 |
set_inheritance_column :none
|
| 217 |
has_many :values, :class_name => "MantisCustomFieldString", :foreign_key => :field_id |
| 218 |
has_many :projects, :class_name => "MantisCustomFieldProject", :foreign_key => :field_id |
| 219 |
|
| 220 |
def format |
| 221 |
read_attribute :type
|
| 222 |
end
|
| 223 |
|
| 224 |
def name |
| 225 |
read_attribute(:name)[0..29] |
| 226 |
end
|
| 227 |
end
|
| 228 |
|
| 229 |
class MantisCustomFieldProject < ActiveRecord::Base |
| 230 |
self.table_name = :mantis_custom_field_project_table |
| 231 |
end
|
| 232 |
|
| 233 |
class MantisCustomFieldString < ActiveRecord::Base |
| 234 |
self.table_name = :mantis_custom_field_string_table |
| 235 |
end
|
| 236 |
|
| 237 |
def self.migrate |
| 238 |
|
| 239 |
# Users
|
| 240 |
print "Migrating users"
|
| 241 |
User.delete_all "login <> 'admin'" |
| 242 |
users_map = {}
|
| 243 |
users_migrated = 0
|
| 244 |
MantisUser.all.each do |user| |
| 245 |
u = User.new :firstname => encode(user.firstname), |
| 246 |
:lastname => encode(user.lastname),
|
| 247 |
:mail => user.email,
|
| 248 |
:last_login_on => user.last_visit
|
| 249 |
u.login = user.username |
| 250 |
u.password = 'mantis'
|
| 251 |
u.status = User::STATUS_LOCKED if user.enabled != 1 |
| 252 |
u.admin = true if user.access_level == 90 |
| 253 |
next unless u.save! |
| 254 |
users_migrated += 1
|
| 255 |
users_map[user.id] = u.id |
| 256 |
print '.'
|
| 257 |
end
|
| 258 |
puts |
| 259 |
|
| 260 |
# Projects
|
| 261 |
print "Migrating projects"
|
| 262 |
Project.destroy_all
|
| 263 |
projects_map = {}
|
| 264 |
versions_map = {}
|
| 265 |
categories_map = {}
|
| 266 |
MantisProject.all.each do |project| |
| 267 |
p = Project.new :name => encode(project.name), |
| 268 |
:description => encode(project.description)
|
| 269 |
p.identifier = project.identifier |
| 270 |
next unless p.save |
| 271 |
projects_map[project.id] = p.id |
| 272 |
p.enabled_module_names = ['issue_tracking', 'news', 'wiki'] |
| 273 |
p.trackers << TRACKER_BUG unless p.trackers.include?(TRACKER_BUG) |
| 274 |
p.trackers << TRACKER_FEATURE unless p.trackers.include?(TRACKER_FEATURE) |
| 275 |
print '.'
|
| 276 |
|
| 277 |
# Project members
|
| 278 |
project.members.each do |member|
|
| 279 |
m = Member.new :user => User.find_by_id(users_map[member.user_id]), |
| 280 |
:roles => [ROLE_MAPPING[member.access_level] || DEFAULT_ROLE] |
| 281 |
m.project = p |
| 282 |
m.save |
| 283 |
end
|
| 284 |
|
| 285 |
# Project versions
|
| 286 |
project.versions.each do |version|
|
| 287 |
v = Version.new :name => encode(version.version), |
| 288 |
:description => encode(version.description),
|
| 289 |
:effective_date => (version.date_order ? version.date_order.to_date : nil) |
| 290 |
v.project = p |
| 291 |
v.save |
| 292 |
versions_map[version.id] = v.id |
| 293 |
end
|
| 294 |
|
| 295 |
# Project categories
|
| 296 |
project.categories.each do |category|
|
| 297 |
g = IssueCategory.new :name => category.category[0,30] |
| 298 |
g.project = p |
| 299 |
g.save |
| 300 |
categories_map[category.category] = g.id |
| 301 |
end
|
| 302 |
end
|
| 303 |
puts |
| 304 |
|
| 305 |
# Bugs
|
| 306 |
print "Migrating bugs"
|
| 307 |
Issue.destroy_all
|
| 308 |
issues_map = {}
|
| 309 |
keep_bug_ids = (Issue.count == 0) |
| 310 |
MantisBug.find_each(:batch_size => 200) do |bug| |
| 311 |
next unless projects_map[bug.project_id] && users_map[bug.reporter_id] |
| 312 |
i = Issue.new :project_id => projects_map[bug.project_id], |
| 313 |
:subject => encode(bug.summary),
|
| 314 |
:description => encode(bug.bug_text.full_description),
|
| 315 |
:priority => PRIORITY_MAPPING[bug.priority] || DEFAULT_PRIORITY, |
| 316 |
:created_on => bug.date_submitted,
|
| 317 |
:updated_on => bug.last_updated
|
| 318 |
i.author = User.find_by_id(users_map[bug.reporter_id])
|
| 319 |
i.category = IssueCategory.find_by_project_id_and_name(i.project_id, bug.category[0,30]) unless bug.category.blank? |
| 320 |
i.fixed_version = Version.find_by_project_id_and_name(i.project_id, bug.fixed_in_version) unless bug.fixed_in_version.blank? |
| 321 |
i.status = STATUS_MAPPING[bug.status] || DEFAULT_STATUS |
| 322 |
i.tracker = (bug.severity == 10 ? TRACKER_FEATURE : TRACKER_BUG) |
| 323 |
i.id = bug.id if keep_bug_ids
|
| 324 |
next unless i.save |
| 325 |
issues_map[bug.id] = i.id |
| 326 |
print '.'
|
| 327 |
STDOUT.flush
|
| 328 |
|
| 329 |
# Assignee
|
| 330 |
# Redmine checks that the assignee is a project member
|
| 331 |
if (bug.handler_id && users_map[bug.handler_id])
|
| 332 |
i.assigned_to = User.find_by_id(users_map[bug.handler_id])
|
| 333 |
i.save(:validate => false) |
| 334 |
end
|
| 335 |
|
| 336 |
# Bug notes
|
| 337 |
bug.bug_notes.each do |note|
|
| 338 |
next unless users_map[note.reporter_id] |
| 339 |
n = Journal.new :notes => encode(note.bug_note_text.note), |
| 340 |
:created_on => note.date_submitted
|
| 341 |
n.user = User.find_by_id(users_map[note.reporter_id])
|
| 342 |
n.journalized = i |
| 343 |
n.save |
| 344 |
end
|
| 345 |
|
| 346 |
# Bug files
|
| 347 |
bug.bug_files.each do |file|
|
| 348 |
a = Attachment.new :created_on => file.date_added |
| 349 |
a.file = file |
| 350 |
a.author = User.first
|
| 351 |
a.container = i |
| 352 |
a.save |
| 353 |
end
|
| 354 |
|
| 355 |
# Bug monitors
|
| 356 |
bug.bug_monitors.each do |monitor|
|
| 357 |
next unless users_map[monitor.user_id] |
| 358 |
i.add_watcher(User.find_by_id(users_map[monitor.user_id]))
|
| 359 |
end
|
| 360 |
end
|
| 361 |
|
| 362 |
# update issue id sequence if needed (postgresql)
|
| 363 |
Issue.connection.reset_pk_sequence!(Issue.table_name) if Issue.connection.respond_to?('reset_pk_sequence!') |
| 364 |
puts |
| 365 |
|
| 366 |
# Bug relationships
|
| 367 |
print "Migrating bug relations"
|
| 368 |
MantisBugRelationship.all.each do |relation| |
| 369 |
next unless issues_map[relation.source_bug_id] && issues_map[relation.destination_bug_id] |
| 370 |
r = IssueRelation.new :relation_type => RELATION_TYPE_MAPPING[relation.relationship_type] |
| 371 |
r.issue_from = Issue.find_by_id(issues_map[relation.source_bug_id])
|
| 372 |
r.issue_to = Issue.find_by_id(issues_map[relation.destination_bug_id])
|
| 373 |
pp r unless r.save
|
| 374 |
print '.'
|
| 375 |
STDOUT.flush
|
| 376 |
end
|
| 377 |
puts |
| 378 |
|
| 379 |
# News
|
| 380 |
print "Migrating news"
|
| 381 |
News.destroy_all
|
| 382 |
MantisNews.where('project_id > 0').all.each do |news| |
| 383 |
next unless projects_map[news.project_id] |
| 384 |
n = News.new :project_id => projects_map[news.project_id], |
| 385 |
:title => encode(news.headline[0..59]), |
| 386 |
:description => encode(news.body),
|
| 387 |
:created_on => news.date_posted
|
| 388 |
n.author = User.find_by_id(users_map[news.poster_id])
|
| 389 |
n.save |
| 390 |
print '.'
|
| 391 |
STDOUT.flush
|
| 392 |
end
|
| 393 |
puts |
| 394 |
|
| 395 |
# Custom fields
|
| 396 |
print "Migrating custom fields"
|
| 397 |
IssueCustomField.destroy_all
|
| 398 |
MantisCustomField.all.each do |field| |
| 399 |
f = IssueCustomField.new :name => field.name[0..29], |
| 400 |
:field_format => CUSTOM_FIELD_TYPE_MAPPING[field.format], |
| 401 |
:min_length => field.length_min,
|
| 402 |
:max_length => field.length_max,
|
| 403 |
:regexp => field.valid_regexp,
|
| 404 |
:possible_values => field.possible_values.split('|'), |
| 405 |
:is_required => field.require_report?
|
| 406 |
next unless f.save |
| 407 |
print '.'
|
| 408 |
STDOUT.flush
|
| 409 |
# Trackers association
|
| 410 |
f.trackers = Tracker.all
|
| 411 |
|
| 412 |
# Projects association
|
| 413 |
field.projects.each do |project|
|
| 414 |
f.projects << Project.find_by_id(projects_map[project.project_id]) if projects_map[project.project_id] |
| 415 |
end
|
| 416 |
|
| 417 |
# Values
|
| 418 |
field.values.each do |value|
|
| 419 |
v = CustomValue.new :custom_field_id => f.id, |
| 420 |
:value => value.value
|
| 421 |
v.customized = Issue.find_by_id(issues_map[value.bug_id]) if issues_map[value.bug_id] |
| 422 |
v.save |
| 423 |
end unless f.new_record? |
| 424 |
end
|
| 425 |
puts |
| 426 |
|
| 427 |
puts |
| 428 |
puts "Users: #{users_migrated}/#{MantisUser.count}"
|
| 429 |
puts "Projects: #{Project.count}/#{MantisProject.count}"
|
| 430 |
puts "Memberships: #{Member.count}/#{MantisProjectUser.count}"
|
| 431 |
puts "Versions: #{Version.count}/#{MantisVersion.count}"
|
| 432 |
puts "Categories: #{IssueCategory.count}/#{MantisCategory.count}"
|
| 433 |
puts "Bugs: #{Issue.count}/#{MantisBug.count}"
|
| 434 |
puts "Bug notes: #{Journal.count}/#{MantisBugNote.count}"
|
| 435 |
puts "Bug files: #{Attachment.count}/#{MantisBugFile.count}"
|
| 436 |
puts "Bug relations: #{IssueRelation.count}/#{MantisBugRelationship.count}"
|
| 437 |
puts "Bug monitors: #{Watcher.count}/#{MantisBugMonitor.count}"
|
| 438 |
puts "News: #{News.count}/#{MantisNews.count}"
|
| 439 |
puts "Custom fields: #{IssueCustomField.count}/#{MantisCustomField.count}"
|
| 440 |
end
|
| 441 |
|
| 442 |
def self.encoding(charset) |
| 443 |
@charset = charset
|
| 444 |
end
|
| 445 |
|
| 446 |
def self.establish_connection(params) |
| 447 |
constants.each do |const|
|
| 448 |
klass = const_get(const) |
| 449 |
next unless klass.respond_to? 'establish_connection' |
| 450 |
klass.establish_connection params |
| 451 |
end
|
| 452 |
end
|
| 453 |
|
| 454 |
def self.encode(text) |
| 455 |
if RUBY_VERSION < '1.9' |
| 456 |
@ic ||= Iconv.new('UTF-8', @charset) |
| 457 |
@ic.iconv text
|
| 458 |
else
|
| 459 |
text.to_s.force_encoding(@charset).encode('UTF-8') |
| 460 |
end
|
| 461 |
end
|
| 462 |
end
|
| 463 |
|
| 464 |
puts |
| 465 |
if Redmine::DefaultData::Loader.no_data? |
| 466 |
puts "Redmine configuration need to be loaded before importing data."
|
| 467 |
puts "Please, run this first:"
|
| 468 |
puts |
| 469 |
puts " rake redmine:load_default_data RAILS_ENV=\"#{ENV['RAILS_ENV']}\""
|
| 470 |
exit |
| 471 |
end
|
| 472 |
|
| 473 |
puts "WARNING: Your Redmine data will be deleted during this process."
|
| 474 |
print "Are you sure you want to continue ? [y/N] "
|
| 475 |
STDOUT.flush
|
| 476 |
break unless STDIN.gets.match(/^y$/i) |
| 477 |
|
| 478 |
# Default Mantis database settings
|
| 479 |
db_params = {:adapter => 'mysql2',
|
| 480 |
:database => 'bugtracker', |
| 481 |
:host => 'localhost', |
| 482 |
:username => 'root', |
| 483 |
:password => '' } |
| 484 |
|
| 485 |
puts |
| 486 |
puts "Please enter settings for your Mantis database"
|
| 487 |
[:adapter, :host, :database, :username, :password].each do |param| |
| 488 |
print "#{param} [#{db_params[param]}]: "
|
| 489 |
value = STDIN.gets.chomp!
|
| 490 |
db_params[param] = value unless value.blank?
|
| 491 |
end
|
| 492 |
|
| 493 |
while true |
| 494 |
print "encoding [UTF-8]: "
|
| 495 |
STDOUT.flush
|
| 496 |
encoding = STDIN.gets.chomp!
|
| 497 |
encoding = 'UTF-8' if encoding.blank? |
| 498 |
break if MantisMigrate.encoding encoding |
| 499 |
puts "Invalid encoding!"
|
| 500 |
end
|
| 501 |
puts |
| 502 |
|
| 503 |
# Make sure bugs can refer bugs in other projects
|
| 504 |
Setting.cross_project_issue_relations = 1 if Setting.respond_to? 'cross_project_issue_relations' |
| 505 |
|
| 506 |
old_notified_events = Setting.notified_events
|
| 507 |
old_password_min_length = Setting.password_min_length
|
| 508 |
begin
|
| 509 |
# Turn off email notifications temporarily
|
| 510 |
Setting.notified_events = []
|
| 511 |
Setting.password_min_length = 4 |
| 512 |
# Run the migration
|
| 513 |
MantisMigrate.establish_connection db_params
|
| 514 |
MantisMigrate.migrate
|
| 515 |
ensure
|
| 516 |
# Restore previous settings
|
| 517 |
Setting.notified_events = old_notified_events
|
| 518 |
Setting.password_min_length = old_password_min_length
|
| 519 |
end
|
| 520 |
|
| 521 |
end
|
| 522 |
end
|