@@ -81,36 +81,6 namespace :redmine do | |||||
81 | set_table_name :ticket_custom |
|
81 | set_table_name :ticket_custom | |
82 | end |
|
82 | end | |
83 |
|
83 | |||
84 | class TracTicket < ActiveRecord::Base |
|
|||
85 | set_table_name :ticket |
|
|||
86 | set_inheritance_column :none |
|
|||
87 |
|
||||
88 | # ticket changes: only migrate status changes and comments |
|
|||
89 | has_many :changes, :class_name => "TracTicketChange", :foreign_key => :ticket, :conditions => "field = 'comment' OR field='status'" |
|
|||
90 | has_many :attachments, :class_name => "TracAttachment", :foreign_key => :id, :conditions => "type = 'ticket'" |
|
|||
91 | has_many :customs, :class_name => "TracTicketCustom", :foreign_key => :ticket |
|
|||
92 |
|
||||
93 | def ticket_type |
|
|||
94 | read_attribute(:type) |
|
|||
95 | end |
|
|||
96 |
|
||||
97 | def summary |
|
|||
98 | read_attribute(:summary).blank? ? "(no subject)" : read_attribute(:summary) |
|
|||
99 | end |
|
|||
100 |
|
||||
101 | def description |
|
|||
102 | read_attribute(:description).blank? ? summary : read_attribute(:description) |
|
|||
103 | end |
|
|||
104 |
|
||||
105 | def time; Time.at(read_attribute(:time)) end |
|
|||
106 | end |
|
|||
107 |
|
||||
108 | class TracTicketChange < ActiveRecord::Base |
|
|||
109 | set_table_name :ticket_change |
|
|||
110 |
|
||||
111 | def time; Time.at(read_attribute(:time)) end |
|
|||
112 | end |
|
|||
113 |
|
||||
114 | class TracAttachment < ActiveRecord::Base |
|
84 | class TracAttachment < ActiveRecord::Base | |
115 | set_table_name :attachment |
|
85 | set_table_name :attachment | |
116 | set_inheritance_column :none |
|
86 | set_inheritance_column :none | |
@@ -141,6 +111,36 namespace :redmine do | |||||
141 | end |
|
111 | end | |
142 | end |
|
112 | end | |
143 |
|
113 | |||
|
114 | class TracTicket < ActiveRecord::Base | |||
|
115 | set_table_name :ticket | |||
|
116 | set_inheritance_column :none | |||
|
117 | ||||
|
118 | # ticket changes: only migrate status changes and comments | |||
|
119 | has_many :changes, :class_name => "TracTicketChange", :foreign_key => :ticket | |||
|
120 | has_many :attachments, :class_name => "TracAttachment", :foreign_key => :id, :conditions => "#{TracMigrate::TracAttachment.table_name}.type = 'ticket'" | |||
|
121 | has_many :customs, :class_name => "TracTicketCustom", :foreign_key => :ticket | |||
|
122 | ||||
|
123 | def ticket_type | |||
|
124 | read_attribute(:type) | |||
|
125 | end | |||
|
126 | ||||
|
127 | def summary | |||
|
128 | read_attribute(:summary).blank? ? "(no subject)" : read_attribute(:summary) | |||
|
129 | end | |||
|
130 | ||||
|
131 | def description | |||
|
132 | read_attribute(:description).blank? ? summary : read_attribute(:description) | |||
|
133 | end | |||
|
134 | ||||
|
135 | def time; Time.at(read_attribute(:time)) end | |||
|
136 | end | |||
|
137 | ||||
|
138 | class TracTicketChange < ActiveRecord::Base | |||
|
139 | set_table_name :ticket_change | |||
|
140 | ||||
|
141 | def time; Time.at(read_attribute(:time)) end | |||
|
142 | end | |||
|
143 | ||||
144 | class TracWikiPage < ActiveRecord::Base |
|
144 | class TracWikiPage < ActiveRecord::Base | |
145 | set_table_name :wiki |
|
145 | set_table_name :wiki | |
146 | end |
|
146 | end | |
@@ -250,6 +250,15 namespace :redmine do | |||||
250 | end |
|
250 | end | |
251 | puts |
|
251 | puts | |
252 |
|
|
252 | ||
|
253 | # Trac 'resolution' field as a Redmine custom field | |||
|
254 | r = IssueCustomField.new :name => 'Resolution', | |||
|
255 | :field_format => 'list', | |||
|
256 | :is_filter => true | |||
|
257 | r.trackers = Tracker.find(:all) | |||
|
258 | r.projects << @target_project | |||
|
259 | r.possible_values = %w(fixed invalid wontfix duplicate worksforme) | |||
|
260 | custom_field_map['resolution'] = r if r.save | |||
|
261 | ||||
253 | # Tickets |
|
262 | # Tickets | |
254 | print "Migrating tickets" |
|
263 | print "Migrating tickets" | |
255 | TracTicket.find(:all).each do |ticket| |
|
264 | TracTicket.find(:all).each do |ticket| | |
@@ -265,6 +274,7 namespace :redmine do | |||||
265 | i.status = STATUS_MAPPING[ticket.status] || DEFAULT_STATUS |
|
274 | i.status = STATUS_MAPPING[ticket.status] || DEFAULT_STATUS | |
266 | i.tracker = TRACKER_MAPPING[ticket.ticket_type] || DEFAULT_TRACKER |
|
275 | i.tracker = TRACKER_MAPPING[ticket.ticket_type] || DEFAULT_TRACKER | |
267 | i.id = ticket.id |
|
276 | i.id = ticket.id | |
|
277 | i.custom_values << CustomValue.new(:custom_field => custom_field_map['resolution'], :value => ticket.resolution) unless ticket.resolution.blank? | |||
268 | next unless i.save |
|
278 | next unless i.save | |
269 | migrated_tickets += 1 |
|
279 | migrated_tickets += 1 | |
270 |
|
280 | |||
@@ -274,9 +284,10 namespace :redmine do | |||||
274 | i.save |
|
284 | i.save | |
275 | end |
|
285 | end | |
276 |
|
286 | |||
277 | # Comments and status changes |
|
287 | # Comments and status/resolution changes | |
278 | ticket.changes.group_by(&:time).each do |time, changeset| |
|
288 | ticket.changes.group_by(&:time).each do |time, changeset| | |
279 | status_change = changeset.select {|change| change.field == 'status'}.first |
|
289 | status_change = changeset.select {|change| change.field == 'status'}.first | |
|
290 | resolution_change = changeset.select {|change| change.field == 'resolution'}.first | |||
280 | comment_change = changeset.select {|change| change.field == 'comment'}.first |
|
291 | comment_change = changeset.select {|change| change.field == 'comment'}.first | |
281 |
|
292 | |||
282 | n = Journal.new :notes => (comment_change ? convert_wiki_text(encode(comment_change.newvalue)) : ''), |
|
293 | n = Journal.new :notes => (comment_change ? convert_wiki_text(encode(comment_change.newvalue)) : ''), | |
@@ -292,7 +303,13 namespace :redmine do | |||||
292 | :old_value => STATUS_MAPPING[status_change.oldvalue].id, |
|
303 | :old_value => STATUS_MAPPING[status_change.oldvalue].id, | |
293 | :value => STATUS_MAPPING[status_change.newvalue].id) |
|
304 | :value => STATUS_MAPPING[status_change.newvalue].id) | |
294 | end |
|
305 | end | |
295 |
|
|
306 | if resolution_change | |
|
307 | n.details << JournalDetail.new(:property => 'cf', | |||
|
308 | :prop_key => custom_field_map['resolution'].id, | |||
|
309 | :old_value => resolution_change.oldvalue, | |||
|
310 | :value => resolution_change.newvalue) | |||
|
311 | end | |||
|
312 | n.save unless n.details.empty? && n.notes.blank? | |||
296 | end |
|
313 | end | |
297 |
|
314 | |||
298 | # Attachments |
|
315 | # Attachments | |
@@ -424,7 +441,7 namespace :redmine do | |||||
424 | end |
|
441 | end | |
425 |
|
442 | |||
426 | prompt('Trac directory') {|directory| TracMigrate.set_trac_directory directory} |
|
443 | prompt('Trac directory') {|directory| TracMigrate.set_trac_directory directory} | |
427 |
prompt(' |
|
444 | prompt('Trac database encoding', :default => 'UTF-8') {|encoding| TracMigrate.encoding encoding} | |
428 | prompt('Target project identifier') {|identifier| TracMigrate.target_project_identifier identifier} |
|
445 | prompt('Target project identifier') {|identifier| TracMigrate.target_project_identifier identifier} | |
429 | puts |
|
446 | puts | |
430 |
|
447 |
General Comments 0
You need to be logged in to leave comments.
Login now