annotate lib/tasks/migrate_from_mantis.rake @ 8:0c83d98252d9 yuya

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