##// END OF EJS Templates
Added namespace for Redmine specific rake tasks....
Jean-Philippe Lang -
r680:e76d153064ee
parent child
Show More
@@ -0,0 +1,9
1 def deprecated_task(name, new_name)
2 task name=>new_name do
3 $stderr.puts "\nNote: The rake task #{name} has been deprecated, please use the replacement version #{new_name}"
4 end
5 end
6
7 deprecated_task :load_default_data, "redmine:load_default_data"
8 deprecated_task :migrate_from_mantis, "redmine:migrate_from_mantis"
9 deprecated_task :migrate_from_trac, "redmine:migrate_from_trac"
@@ -1,71 +1,71
1 1 == redMine installation
2 2
3 3 redMine - project management software
4 4 Copyright (C) 2006-2007 Jean-Philippe Lang
5 5 http://redmine.rubyforge.org/
6 6
7 7
8 8 == Requirements
9 9
10 10 * Ruby on Rails 1.2.2
11 11 * A database (see compatibility below)
12 12
13 13 Optional:
14 14 * RedCloth (to enable textile formatting)
15 15 * SVN binaries (needed for repository browsing, must be available in PATH)
16 16
17 17 Supported databases:
18 18 * MySQL (tested with MySQL 5)
19 19 * PostgreSQL (tested with PostgreSQL 8.1)
20 20 * Oracle (tested with Oracle 10g)
21 21 * SQL Server (tested with SQL Server 2005)
22 22 * SQLite (tested with SQLite 3)
23 23
24 24
25 25 == Installation
26 26
27 27 1. Uncompress program archive:
28 28 tar zxvf <filename>
29 29
30 30 2. Create an empty database: "redmine" for example
31 31
32 32 3. Configure database parameters in config/database.yml
33 33 for "production" environment (default database is MySQL)
34 34
35 35 4. Create the database structure. Under the application main directory:
36 36 rake db:migrate RAILS_ENV="production"
37 37 It will create tables and an administrator account.
38 38
39 39 5. Insert default configuration data in database:
40 rake load_default_data RAILS_ENV="production"
40 rake redmine:load_default_data RAILS_ENV="production"
41 41 It will load default roles, trackers, statuses, workflows and enumerations.
42 42 This step is optional (but recommended), as you can define your
43 43 own configuration from sratch.
44 44
45 45 6. Test the installation by running WEBrick web server:
46 46 ruby script/server -e production
47 47
48 48 Once WEBrick has started, point your browser to http://localhost:3000/
49 49 You should now see the application welcome page
50 50
51 51 7. Use default administrator account to log in:
52 52 login: admin
53 53 password: admin
54 54
55 55 8. You can go to "Admin -> Settings" to modify application settings.
56 56
57 57 9. Setup Apache or Lighttpd with fastcgi for best performance.
58 58
59 59
60 60 == SMTP server Configuration
61 61
62 62 In config/environment.rb, you can set parameters for your SMTP server:
63 63 config.action_mailer.smtp_settings: SMTP server configuration
64 64 config.action_mailer.perform_deliveries: set to false to disable mail delivering
65 65
66 66 Don't forget to restart the application after any change.
67 67
68 68
69 69 == Upgrading
70 70
71 71 See UPGRADING
@@ -1,166 +1,168
1 desc 'Load default configuration data'
1 desc 'Load Redmine default configuration data'
2 2
3 namespace :redmine do
3 4 task :load_default_data => :environment do
4 5 include GLoc
5 6 set_language_if_valid('en')
6 7 puts
7 8
8 9 while true
9 10 print "Select language: "
10 11 print GLoc.valid_languages.sort {|x,y| x.to_s <=> y.to_s }.join(", ")
11 12 print " [#{GLoc.current_language}] "
12 13 lang = STDIN.gets.chomp!
13 14 break if lang.empty?
14 15 break if set_language_if_valid(lang)
15 16 puts "Unknown language!"
16 17 end
17 18
18 19 puts "===================================="
19 20
20 21 begin
21 22 # check that no data already exists
22 23 if Role.find(:first, :conditions => {:builtin => 0})
23 24 raise "Some roles are already defined."
24 25 end
25 26 if Tracker.find(:first)
26 27 raise "Some trackers are already defined."
27 28 end
28 29 if IssueStatus.find(:first)
29 30 raise "Some statuses are already defined."
30 31 end
31 32 if Enumeration.find(:first)
32 33 raise "Some enumerations are already defined."
33 34 end
34 35
35 36 puts "Loading default configuration data for language: #{current_language}"
36 37
37 38 # roles
38 39 manager = Role.create :name => l(:default_role_manager),
39 40 :position => 1
40 41 manager.permissions = manager.setable_permissions.collect {|p| p.name}
41 42 manager.save
42 43
43 44 developper = Role.create :name => l(:default_role_developper),
44 45 :position => 2,
45 46 :permissions => [:manage_versions,
46 47 :manage_categories,
47 48 :add_issues,
48 49 :edit_issues,
49 50 :manage_issue_relations,
50 51 :add_issue_notes,
51 52 :change_issue_status,
52 53 :save_queries,
53 54 :view_gantt,
54 55 :view_calendar,
55 56 :log_time,
56 57 :view_time_entries,
57 58 :comment_news,
58 59 :view_documents,
59 60 :view_wiki_pages,
60 61 :edit_wiki_pages,
61 62 :delete_wiki_pages,
62 63 :add_messages,
63 64 :view_files,
64 65 :manage_files,
65 66 :browse_repository,
66 67 :view_changesets]
67 68
68 69 reporter = Role.create :name => l(:default_role_reporter),
69 70 :position => 3,
70 71 :permissions => [:add_issues,
71 72 :add_issue_notes,
72 73 :change_issue_status,
73 74 :save_queries,
74 75 :view_gantt,
75 76 :view_calendar,
76 77 :log_time,
77 78 :view_time_entries,
78 79 :comment_news,
79 80 :view_documents,
80 81 :view_wiki_pages,
81 82 :add_messages,
82 83 :view_files,
83 84 :browse_repository,
84 85 :view_changesets]
85 86
86 87 Role.non_member.update_attribute :permissions, [:add_issues,
87 88 :add_issue_notes,
88 89 :change_issue_status,
89 90 :save_queries,
90 91 :view_gantt,
91 92 :view_calendar,
92 93 :view_time_entries,
93 94 :comment_news,
94 95 :view_documents,
95 96 :view_wiki_pages,
96 97 :add_messages,
97 98 :view_files,
98 99 :browse_repository,
99 100 :view_changesets]
100 101
101 102 Role.anonymous.update_attribute :permissions, [:view_gantt,
102 103 :view_calendar,
103 104 :view_time_entries,
104 105 :view_documents,
105 106 :view_wiki_pages,
106 107 :view_files,
107 108 :browse_repository,
108 109 :view_changesets]
109 110
110 111 # trackers
111 112 Tracker.create(:name => l(:default_tracker_bug), :is_in_chlog => true, :is_in_roadmap => false, :position => 1)
112 113 Tracker.create(:name => l(:default_tracker_feature), :is_in_chlog => true, :is_in_roadmap => true, :position => 2)
113 114 Tracker.create(:name => l(:default_tracker_support), :is_in_chlog => false, :is_in_roadmap => false, :position => 3)
114 115
115 116 # issue statuses
116 117 new = IssueStatus.create(:name => l(:default_issue_status_new), :is_closed => false, :is_default => true, :html_color => 'F98787', :position => 1)
117 118 assigned = IssueStatus.create(:name => l(:default_issue_status_assigned), :is_closed => false, :is_default => false, :html_color => 'C0C0FF', :position => 2)
118 119 resolved = IssueStatus.create(:name => l(:default_issue_status_resolved), :is_closed => false, :is_default => false, :html_color => '88E0B3', :position => 3)
119 120 feedback = IssueStatus.create(:name => l(:default_issue_status_feedback), :is_closed => false, :is_default => false, :html_color => 'F3A4F4', :position => 4)
120 121 closed = IssueStatus.create(:name => l(:default_issue_status_closed), :is_closed => true, :is_default => false, :html_color => 'DBDBDB', :position => 5)
121 122 rejected = IssueStatus.create(:name => l(:default_issue_status_rejected), :is_closed => true, :is_default => false, :html_color => 'F5C28B', :position => 6)
122 123
123 124 # workflow
124 125 Tracker.find(:all).each { |t|
125 126 IssueStatus.find(:all).each { |os|
126 127 IssueStatus.find(:all).each { |ns|
127 128 Workflow.create(:tracker_id => t.id, :role_id => manager.id, :old_status_id => os.id, :new_status_id => ns.id) unless os == ns
128 129 }
129 130 }
130 131 }
131 132
132 133 Tracker.find(:all).each { |t|
133 134 [new, assigned, resolved, feedback].each { |os|
134 135 [assigned, resolved, feedback, closed].each { |ns|
135 136 Workflow.create(:tracker_id => t.id, :role_id => developper.id, :old_status_id => os.id, :new_status_id => ns.id) unless os == ns
136 137 }
137 138 }
138 139 }
139 140
140 141 Tracker.find(:all).each { |t|
141 142 [new, assigned, resolved, feedback].each { |os|
142 143 [closed].each { |ns|
143 144 Workflow.create(:tracker_id => t.id, :role_id => reporter.id, :old_status_id => os.id, :new_status_id => ns.id) unless os == ns
144 145 }
145 146 }
146 147 Workflow.create(:tracker_id => t.id, :role_id => reporter.id, :old_status_id => resolved.id, :new_status_id => feedback.id)
147 148 }
148 149
149 150 # enumerations
150 151 Enumeration.create(:opt => "DCAT", :name => l(:default_doc_category_user))
151 152 Enumeration.create(:opt => "DCAT", :name => l(:default_doc_category_tech))
152 153
153 154 Enumeration.create(:opt => "IPRI", :name => l(:default_priority_low))
154 155 Enumeration.create(:opt => "IPRI", :name => l(:default_priority_normal))
155 156 Enumeration.create(:opt => "IPRI", :name => l(:default_priority_high))
156 157 Enumeration.create(:opt => "IPRI", :name => l(:default_priority_urgent))
157 158 Enumeration.create(:opt => "IPRI", :name => l(:default_priority_immediate))
158 159
159 160 Enumeration.create(:opt => "ACTI", :name => l(:default_activity_design))
160 161 Enumeration.create(:opt => "ACTI", :name => l(:default_activity_development))
161 162
162 163 rescue => error
163 164 puts "Error: " + error
164 165 puts "Default configuration data can't be loaded."
165 166 end
166 end No newline at end of file
167 end
168 end
@@ -1,485 +1,487
1 1 # redMine - project management software
2 2 # Copyright (C) 2006-2007 Jean-Philippe Lang
3 3 #
4 4 # This program is free software; you can redistribute it and/or
5 5 # modify it under the terms of the GNU General Public License
6 6 # as published by the Free Software Foundation; either version 2
7 7 # of the License, or (at your option) any later version.
8 8 #
9 9 # This program is distributed in the hope that it will be useful,
10 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 12 # GNU General Public License for more details.
13 13 #
14 14 # You should have received a copy of the GNU General Public License
15 15 # along with this program; if not, write to the Free Software
16 16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 17
18 18 desc 'Mantis migration script'
19 19
20 20 require 'active_record'
21 21 require 'iconv'
22 22 require 'pp'
23 23
24 namespace :redmine do
24 25 task :migrate_from_mantis => :environment do
25 26
26 27 module MantisMigrate
27 28
28 29 DEFAULT_STATUS = IssueStatus.default
29 30 assigned_status = IssueStatus.find_by_position(2)
30 31 resolved_status = IssueStatus.find_by_position(3)
31 32 feedback_status = IssueStatus.find_by_position(4)
32 33 closed_status = IssueStatus.find :first, :conditions => { :is_closed => true }
33 34 STATUS_MAPPING = {10 => DEFAULT_STATUS, # new
34 35 20 => feedback_status, # feedback
35 36 30 => DEFAULT_STATUS, # acknowledged
36 37 40 => DEFAULT_STATUS, # confirmed
37 38 50 => assigned_status, # assigned
38 39 80 => resolved_status, # resolved
39 40 90 => closed_status # closed
40 41 }
41 42
42 43 priorities = Enumeration.get_values('IPRI')
43 44 DEFAULT_PRIORITY = priorities[2]
44 45 PRIORITY_MAPPING = {10 => priorities[1], # none
45 46 20 => priorities[1], # low
46 47 30 => priorities[2], # normal
47 48 40 => priorities[3], # high
48 49 50 => priorities[4], # urgent
49 50 60 => priorities[5] # immediate
50 51 }
51 52
52 53 TRACKER_BUG = Tracker.find_by_position(1)
53 54 TRACKER_FEATURE = Tracker.find_by_position(2)
54 55
55 56 DEFAULT_ROLE = Role.find_by_position(3)
56 57 manager_role = Role.find_by_position(1)
57 58 developer_role = Role.find_by_position(2)
58 59 ROLE_MAPPING = {10 => DEFAULT_ROLE, # viewer
59 60 25 => DEFAULT_ROLE, # reporter
60 61 40 => DEFAULT_ROLE, # updater
61 62 55 => developer_role, # developer
62 63 70 => manager_role, # manager
63 64 90 => manager_role # administrator
64 65 }
65 66
66 67 CUSTOM_FIELD_TYPE_MAPPING = {0 => 'string', # String
67 68 1 => 'int', # Numeric
68 69 2 => 'int', # Float
69 70 3 => 'list', # Enumeration
70 71 4 => 'string', # Email
71 72 5 => 'bool', # Checkbox
72 73 6 => 'list', # List
73 74 7 => 'list', # Multiselection list
74 75 8 => 'date', # Date
75 76 }
76 77
77 78 RELATION_TYPE_MAPPING = {1 => IssueRelation::TYPE_RELATES, # related to
78 79 2 => IssueRelation::TYPE_RELATES, # parent of
79 80 3 => IssueRelation::TYPE_RELATES, # child of
80 81 0 => IssueRelation::TYPE_DUPLICATES, # duplicate of
81 82 4 => IssueRelation::TYPE_DUPLICATES # has duplicate
82 83 }
83 84
84 85 class MantisUser < ActiveRecord::Base
85 86 set_table_name :mantis_user_table
86 87
87 88 def firstname
88 89 realname.blank? ? username : realname.split.first[0..29]
89 90 end
90 91
91 92 def lastname
92 93 realname.blank? ? username : realname.split[1..-1].join(' ')[0..29]
93 94 end
94 95
95 96 def email
96 97 if read_attribute(:email).match(/^([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})$/i)
97 98 read_attribute(:email)
98 99 else
99 100 "#{username}@foo.bar"
100 101 end
101 102 end
102 103
103 104 def username
104 105 read_attribute(:username)[0..29].gsub(/[^a-zA-Z0-9_\-@\.]/, '-')
105 106 end
106 107 end
107 108
108 109 class MantisProject < ActiveRecord::Base
109 110 set_table_name :mantis_project_table
110 111 has_many :versions, :class_name => "MantisVersion", :foreign_key => :project_id
111 112 has_many :categories, :class_name => "MantisCategory", :foreign_key => :project_id
112 113 has_many :news, :class_name => "MantisNews", :foreign_key => :project_id
113 114 has_many :members, :class_name => "MantisProjectUser", :foreign_key => :project_id
114 115
115 116 def name
116 117 read_attribute(:name)[0..29].gsub(/[^\w\s\'\-]/, '-')
117 118 end
118 119
119 120 def description
120 121 read_attribute(:description).blank? ? read_attribute(:name) : read_attribute(:description)[0..254]
121 122 end
122 123
123 124 def identifier
124 125 read_attribute(:name).underscore[0..11].gsub(/[^a-z0-9\-]/, '-')
125 126 end
126 127 end
127 128
128 129 class MantisVersion < ActiveRecord::Base
129 130 set_table_name :mantis_project_version_table
130 131
131 132 def version
132 133 read_attribute(:version)[0..29]
133 134 end
134 135
135 136 def description
136 137 read_attribute(:description)[0..254]
137 138 end
138 139 end
139 140
140 141 class MantisCategory < ActiveRecord::Base
141 142 set_table_name :mantis_project_category_table
142 143 end
143 144
144 145 class MantisProjectUser < ActiveRecord::Base
145 146 set_table_name :mantis_project_user_list_table
146 147 end
147 148
148 149 class MantisBug < ActiveRecord::Base
149 150 set_table_name :mantis_bug_table
150 151 belongs_to :bug_text, :class_name => "MantisBugText", :foreign_key => :bug_text_id
151 152 has_many :bug_notes, :class_name => "MantisBugNote", :foreign_key => :bug_id
152 153 has_many :bug_files, :class_name => "MantisBugFile", :foreign_key => :bug_id
153 154 has_many :bug_monitors, :class_name => "MantisBugMonitor", :foreign_key => :bug_id
154 155 end
155 156
156 157 class MantisBugText < ActiveRecord::Base
157 158 set_table_name :mantis_bug_text_table
158 159
159 160 # Adds Mantis steps_to_reproduce and additional_information fields
160 161 # to description if any
161 162 def full_description
162 163 full_description = description
163 164 full_description += "\n\n*Steps to reproduce:*\n\n#{steps_to_reproduce}" unless steps_to_reproduce.blank?
164 165 full_description += "\n\n*Additional information:*\n\n#{additional_information}" unless additional_information.blank?
165 166 full_description
166 167 end
167 168 end
168 169
169 170 class MantisBugNote < ActiveRecord::Base
170 171 set_table_name :mantis_bugnote_table
171 172 belongs_to :bug, :class_name => "MantisBug", :foreign_key => :bug_id
172 173 belongs_to :bug_note_text, :class_name => "MantisBugNoteText", :foreign_key => :bugnote_text_id
173 174 end
174 175
175 176 class MantisBugNoteText < ActiveRecord::Base
176 177 set_table_name :mantis_bugnote_text_table
177 178 end
178 179
179 180 class MantisBugFile < ActiveRecord::Base
180 181 set_table_name :mantis_bug_file_table
181 182
182 183 def size
183 184 filesize
184 185 end
185 186
186 187 def original_filename
187 188 filename
188 189 end
189 190
190 191 def content_type
191 192 file_type
192 193 end
193 194
194 195 def read
195 196 content
196 197 end
197 198 end
198 199
199 200 class MantisBugRelationship < ActiveRecord::Base
200 201 set_table_name :mantis_bug_relationship_table
201 202 end
202 203
203 204 class MantisBugMonitor < ActiveRecord::Base
204 205 set_table_name :mantis_bug_monitor_table
205 206 end
206 207
207 208 class MantisNews < ActiveRecord::Base
208 209 set_table_name :mantis_news_table
209 210 end
210 211
211 212 class MantisCustomField < ActiveRecord::Base
212 213 set_table_name :mantis_custom_field_table
213 214 set_inheritance_column :none
214 215 has_many :values, :class_name => "MantisCustomFieldString", :foreign_key => :field_id
215 216 has_many :projects, :class_name => "MantisCustomFieldProject", :foreign_key => :field_id
216 217
217 218 def format
218 219 read_attribute :type
219 220 end
220 221
221 222 def name
222 223 read_attribute(:name)[0..29].gsub(/[^\w\s\'\-]/, '-')
223 224 end
224 225 end
225 226
226 227 class MantisCustomFieldProject < ActiveRecord::Base
227 228 set_table_name :mantis_custom_field_project_table
228 229 end
229 230
230 231 class MantisCustomFieldString < ActiveRecord::Base
231 232 set_table_name :mantis_custom_field_string_table
232 233 end
233 234
234 235
235 236 def self.migrate
236 237
237 238 # Users
238 239 print "Migrating users"
239 240 User.delete_all "login <> 'admin'"
240 241 users_map = {}
241 242 users_migrated = 0
242 243 MantisUser.find(:all).each do |user|
243 244 u = User.new :firstname => encode(user.firstname),
244 245 :lastname => encode(user.lastname),
245 246 :mail => user.email,
246 247 :last_login_on => user.last_visit
247 248 u.login = user.username
248 249 u.password = 'mantis'
249 250 u.status = User::STATUS_LOCKED if user.enabled != 1
250 251 u.admin = true if user.access_level == 90
251 252 next unless u.save
252 253 users_migrated += 1
253 254 users_map[user.id] = u.id
254 255 print '.'
255 256 end
256 257 puts
257 258
258 259 # Projects
259 260 print "Migrating projects"
260 261 Project.destroy_all
261 262 projects_map = {}
262 263 versions_map = {}
263 264 categories_map = {}
264 265 MantisProject.find(:all).each do |project|
265 266 p = Project.new :name => encode(project.name),
266 267 :description => encode(project.description)
267 268 p.identifier = project.identifier
268 269 next unless p.save
269 270 projects_map[project.id] = p.id
270 271 print '.'
271 272
272 273 # Project members
273 274 project.members.each do |member|
274 275 m = Member.new :user => User.find_by_id(users_map[member.user_id]),
275 276 :role => ROLE_MAPPING[member.access_level] || DEFAULT_ROLE
276 277 m.project = p
277 278 m.save
278 279 end
279 280
280 281 # Project versions
281 282 project.versions.each do |version|
282 283 v = Version.new :name => encode(version.version),
283 284 :description => encode(version.description),
284 285 :effective_date => version.date_order.to_date
285 286 v.project = p
286 287 v.save
287 288 versions_map[version.id] = v.id
288 289 end
289 290
290 291 # Project categories
291 292 project.categories.each do |category|
292 293 g = IssueCategory.new :name => category.category[0,30]
293 294 g.project = p
294 295 g.save
295 296 categories_map[category.category] = g.id
296 297 end
297 298 end
298 299 puts
299 300
300 301 # Bugs
301 302 print "Migrating bugs"
302 303 Issue.destroy_all
303 304 issues_map = {}
304 305 MantisBug.find(:all).each do |bug|
305 306 next unless projects_map[bug.project_id] && users_map[bug.reporter_id]
306 307 i = Issue.new :project_id => projects_map[bug.project_id],
307 308 :subject => encode(bug.summary),
308 309 :description => encode(bug.bug_text.full_description),
309 310 :priority => PRIORITY_MAPPING[bug.priority] || DEFAULT_PRIORITY,
310 311 :created_on => bug.date_submitted,
311 312 :updated_on => bug.last_updated
312 313 i.author = User.find_by_id(users_map[bug.reporter_id])
313 314 i.category = IssueCategory.find_by_project_id_and_name(i.project_id, bug.category[0,30]) unless bug.category.blank?
314 315 i.fixed_version = Version.find_by_project_id_and_name(i.project_id, bug.fixed_in_version) unless bug.fixed_in_version.blank?
315 316 i.status = STATUS_MAPPING[bug.status] || DEFAULT_STATUS
316 317 i.tracker = (bug.severity == 10 ? TRACKER_FEATURE : TRACKER_BUG)
317 318 next unless i.save
318 319 issues_map[bug.id] = i.id
319 320 print '.'
320 321
321 322 # Assignee
322 323 # Redmine checks that the assignee is a project member
323 324 if (bug.handler_id && users_map[bug.handler_id])
324 325 i.assigned_to = User.find_by_id(users_map[bug.handler_id])
325 326 i.save_with_validation(false)
326 327 end
327 328
328 329 # Bug notes
329 330 bug.bug_notes.each do |note|
330 331 next unless users_map[note.reporter_id]
331 332 n = Journal.new :notes => encode(note.bug_note_text.note),
332 333 :created_on => note.date_submitted
333 334 n.user = User.find_by_id(users_map[note.reporter_id])
334 335 n.journalized = i
335 336 n.save
336 337 end
337 338
338 339 # Bug files
339 340 bug.bug_files.each do |file|
340 341 a = Attachment.new :created_on => file.date_added
341 342 a.file = file
342 343 a.author = User.find :first
343 344 a.container = i
344 345 a.save
345 346 end
346 347
347 348 # Bug monitors
348 349 bug.bug_monitors.each do |monitor|
349 350 next unless users_map[monitor.user_id]
350 351 i.add_watcher(User.find_by_id(users_map[monitor.user_id]))
351 352 end
352 353 end
353 354 puts
354 355
355 356 # Bug relationships
356 357 print "Migrating bug relations"
357 358 MantisBugRelationship.find(:all).each do |relation|
358 359 next unless issues_map[relation.source_bug_id] && issues_map[relation.destination_bug_id]
359 360 r = IssueRelation.new :relation_type => RELATION_TYPE_MAPPING[relation.relationship_type]
360 361 r.issue_from = Issue.find_by_id(issues_map[relation.source_bug_id])
361 362 r.issue_to = Issue.find_by_id(issues_map[relation.destination_bug_id])
362 363 pp r unless r.save
363 364 print '.'
364 365 end
365 366 puts
366 367
367 368 # News
368 369 print "Migrating news"
369 370 News.destroy_all
370 371 MantisNews.find(:all, :conditions => 'project_id > 0').each do |news|
371 372 next unless projects_map[news.project_id]
372 373 n = News.new :project_id => projects_map[news.project_id],
373 374 :title => encode(news.headline[0..59]),
374 375 :description => encode(news.body),
375 376 :created_on => news.date_posted
376 377 n.author = User.find_by_id(users_map[news.poster_id])
377 378 n.save
378 379 print '.'
379 380 end
380 381 puts
381 382
382 383 # Custom fields
383 384 print "Migrating custom fields"
384 385 IssueCustomField.destroy_all
385 386 MantisCustomField.find(:all).each do |field|
386 387 f = IssueCustomField.new :name => field.name[0..29],
387 388 :field_format => CUSTOM_FIELD_TYPE_MAPPING[field.format],
388 389 :min_length => field.length_min,
389 390 :max_length => field.length_max,
390 391 :regexp => field.valid_regexp,
391 392 :possible_values => field.possible_values.split('|'),
392 393 :is_required => field.require_report?
393 394 next unless f.save
394 395 print '.'
395 396
396 397 # Trackers association
397 398 f.trackers = Tracker.find :all
398 399
399 400 # Projects association
400 401 field.projects.each do |project|
401 402 f.projects << Project.find_by_id(projects_map[project.project_id]) if projects_map[project.project_id]
402 403 end
403 404
404 405 # Values
405 406 field.values.each do |value|
406 407 v = CustomValue.new :custom_field_id => f.id,
407 408 :value => value.value
408 409 v.customized = Issue.find_by_id(issues_map[value.bug_id]) if issues_map[value.bug_id]
409 410 v.save
410 411 end unless f.new_record?
411 412 end
412 413 puts
413 414
414 415 puts
415 416 puts "Users: #{users_migrated}/#{MantisUser.count}"
416 417 puts "Projects: #{Project.count}/#{MantisProject.count}"
417 418 puts "Memberships: #{Member.count}/#{MantisProjectUser.count}"
418 419 puts "Versions: #{Version.count}/#{MantisVersion.count}"
419 420 puts "Categories: #{IssueCategory.count}/#{MantisCategory.count}"
420 421 puts "Bugs: #{Issue.count}/#{MantisBug.count}"
421 422 puts "Bug notes: #{Journal.count}/#{MantisBugNote.count}"
422 423 puts "Bug files: #{Attachment.count}/#{MantisBugFile.count}"
423 424 puts "Bug relations: #{IssueRelation.count}/#{MantisBugRelationship.count}"
424 425 puts "Bug monitors: #{Watcher.count}/#{MantisBugMonitor.count}"
425 426 puts "News: #{News.count}/#{MantisNews.count}"
426 427 puts "Custom fields: #{IssueCustomField.count}/#{MantisCustomField.count}"
427 428 end
428 429
429 430 def self.encoding(charset)
430 431 @ic = Iconv.new('UTF-8', charset)
431 432 rescue Iconv::InvalidEncoding
432 433 return false
433 434 end
434 435
435 436 def self.establish_connection(params)
436 437 constants.each do |const|
437 438 klass = const_get(const)
438 439 next unless klass.respond_to? 'establish_connection'
439 440 klass.establish_connection params
440 441 end
441 442 end
442 443
443 444 private
444 445 def self.encode(text)
445 446 @ic.iconv text
446 447 rescue
447 448 text
448 449 end
449 450 end
450 451
451 452 puts
452 453 puts "WARNING: Your Redmine data will be deleted during this process."
453 454 print "Are you sure you want to continue ? [y/N] "
454 455 break unless STDIN.gets.match(/^y$/i)
455 456
456 457 # Default Mantis database settings
457 458 db_params = {:adapter => 'mysql',
458 459 :database => 'bugtracker',
459 460 :host => 'localhost',
460 461 :username => 'root',
461 462 :password => '' }
462 463
463 464 puts
464 465 puts "Please enter settings for your Mantis database"
465 466 [:adapter, :host, :database, :username, :password].each do |param|
466 467 print "#{param} [#{db_params[param]}]: "
467 468 value = STDIN.gets.chomp!
468 469 db_params[param] = value unless value.blank?
469 470 end
470 471
471 472 while true
472 473 print "encoding [UTF-8]: "
473 474 encoding = STDIN.gets.chomp!
474 475 encoding = 'UTF-8' if encoding.blank?
475 476 break if MantisMigrate.encoding encoding
476 477 puts "Invalid encoding!"
477 478 end
478 479 puts
479 480
480 481 # Make sure bugs can refer bugs in other projects
481 482 Setting.cross_project_issue_relations = 1 if Setting.respond_to? 'cross_project_issue_relations'
482 483
483 484 MantisMigrate.establish_connection db_params
484 485 MantisMigrate.migrate
485 486 end
487 end
General Comments 0
You need to be logged in to leave comments. Login now