migrate_jira.rake
| 1 |
require 'rexml/document'
|
|---|---|
| 2 |
require 'active_record'
|
| 3 |
require 'yaml'
|
| 4 |
require 'config/environment'
|
| 5 |
|
| 6 |
|
| 7 |
|
| 8 |
module JiraMigration |
| 9 |
include REXML
|
| 10 |
|
| 11 |
file = File.new('backup_jira.xml') |
| 12 |
doc = Document.new file
|
| 13 |
$doc = doc
|
| 14 |
|
| 15 |
CONF_FILE = "map_jira_to_redmine.yml" |
| 16 |
|
| 17 |
$MIGRATED_USERS_BY_NAME = {} # Maps the Jira username to the Redmine Rails User object |
| 18 |
$MIGRATED_ISSUE_TYPES = {}
|
| 19 |
$MIGRATED_ISSUE_STATUS = {}
|
| 20 |
$MIGRATED_ISSUE_PRIORITIES = {}
|
| 21 |
|
| 22 |
$MIGRATED_ISSUE_TYPES_BY_ID = {}
|
| 23 |
$MIGRATED_ISSUE_STATUS_BY_ID = {}
|
| 24 |
$MIGRATED_ISSUE_PRIORITIES_BY_ID = {}
|
| 25 |
|
| 26 |
def self.get_all_options() |
| 27 |
# return all options
|
| 28 |
# Issue Type, Issue Status, Issue Priority
|
| 29 |
ret = {}
|
| 30 |
ret["types"] = self.get_jira_issue_types() |
| 31 |
ret["status"] = self.get_jira_status() |
| 32 |
ret["priorities"] = self.get_jira_priorities() |
| 33 |
|
| 34 |
return ret
|
| 35 |
end
|
| 36 |
def self.get_list_from_tag(xpath_query) |
| 37 |
# Get a tag node and get all attributes as a hash
|
| 38 |
ret = [] |
| 39 |
$doc.elements.each(xpath_query) {|node| ret.push(node.attributes.rehash)}
|
| 40 |
|
| 41 |
return ret
|
| 42 |
end
|
| 43 |
|
| 44 |
class BaseJira |
| 45 |
attr_reader :tag
|
| 46 |
attr_accessor :new_record
|
| 47 |
MAP = {}
|
| 48 |
|
| 49 |
def map |
| 50 |
self.class::MAP |
| 51 |
end
|
| 52 |
|
| 53 |
def initialize(node) |
| 54 |
@tag = node
|
| 55 |
end
|
| 56 |
|
| 57 |
def method_missing(key, *args) |
| 58 |
if key.to_s.start_with?("jira_") |
| 59 |
attr = key.to_s.sub("jira_", "") |
| 60 |
return @tag.attributes[attr] |
| 61 |
end
|
| 62 |
puts "Method missing: #{key}"
|
| 63 |
raise NoMethodError key
|
| 64 |
end
|
| 65 |
|
| 66 |
def run_all_redmine_fields |
| 67 |
ret = {}
|
| 68 |
self.methods.each do |method_name| |
| 69 |
m = method_name.to_s |
| 70 |
if m.start_with?("red_") |
| 71 |
mm = m.to_s.sub("red_", "") |
| 72 |
ret[mm] = self.send(m)
|
| 73 |
end
|
| 74 |
end
|
| 75 |
return ret
|
| 76 |
end
|
| 77 |
def migrate |
| 78 |
all_fields = self.run_all_redmine_fields()
|
| 79 |
pp("Saving:", all_fields)
|
| 80 |
record = self.retrieve
|
| 81 |
if record
|
| 82 |
record.update_attributes(all_fields) |
| 83 |
else
|
| 84 |
record = self.class::DEST_MODEL.new all_fields |
| 85 |
end
|
| 86 |
if self.respond_to?("before_save") |
| 87 |
self.before_save(record)
|
| 88 |
end
|
| 89 |
record.save! |
| 90 |
record.reload |
| 91 |
self.map[self.jira_id] = record |
| 92 |
self.new_record = record
|
| 93 |
if self.respond_to?("post_migrate") |
| 94 |
self.post_migrate(record)
|
| 95 |
end
|
| 96 |
return record
|
| 97 |
end
|
| 98 |
def retrieve |
| 99 |
self.class::DEST_MODEL.find_by_name(self.jira_id) |
| 100 |
end
|
| 101 |
end
|
| 102 |
|
| 103 |
class JiraProject < BaseJira |
| 104 |
DEST_MODEL = Project |
| 105 |
MAP = {}
|
| 106 |
|
| 107 |
def retrieve |
| 108 |
self.class::DEST_MODEL.find_by_identifier(self.red_identifier) |
| 109 |
end
|
| 110 |
def post_migrate(new_record) |
| 111 |
if !new_record.module_enabled?('issue_tracking') |
| 112 |
new_record.enabled_modules << EnabledModule.new(:name => 'issue_tracking') |
| 113 |
end
|
| 114 |
$MIGRATED_ISSUE_TYPES.values.uniq.each do |issue_type| |
| 115 |
if !new_record.trackers.include?(issue_type)
|
| 116 |
new_record.trackers << issue_type |
| 117 |
end
|
| 118 |
end
|
| 119 |
end
|
| 120 |
|
| 121 |
# here is the tranformation of Jira attributes in Redmine attribues
|
| 122 |
def red_name |
| 123 |
self.jira_name
|
| 124 |
end
|
| 125 |
def red_description |
| 126 |
self.jira_name
|
| 127 |
end
|
| 128 |
def red_identifier |
| 129 |
ret = self.jira_key.downcase
|
| 130 |
return ret
|
| 131 |
end
|
| 132 |
end
|
| 133 |
|
| 134 |
class JiraUser < BaseJira |
| 135 |
DEST_MODEL = User |
| 136 |
MAP = {}
|
| 137 |
#attr_reader :jira_fullname, :jira_email
|
| 138 |
|
| 139 |
#def initialize(node)
|
| 140 |
# super
|
| 141 |
# # parsing specific things of each user
|
| 142 |
# @jira_fullname = get_property("fullName")
|
| 143 |
# @jira_email = get_property("email")
|
| 144 |
#end
|
| 145 |
def retrieve |
| 146 |
user = self.class::DEST_MODEL.find_by_login(self.red_login) |
| 147 |
if !user
|
| 148 |
user = self.class::DEST_MODEL.find_by_mail(self.jira_email) |
| 149 |
end
|
| 150 |
|
| 151 |
return user
|
| 152 |
end
|
| 153 |
|
| 154 |
def jira_fullname |
| 155 |
get_property("fullName")
|
| 156 |
end
|
| 157 |
def jira_email |
| 158 |
get_property("email")
|
| 159 |
end
|
| 160 |
|
| 161 |
def get_property(property) |
| 162 |
# User properties (like fullname and email)
|
| 163 |
# Wow... we need to find 2 things to reach the desired property
|
| 164 |
entityId = self.jira_id
|
| 165 |
query = "/entity-engine-xml/OSPropertyEntry[@entityId='#{entityId}' and @propertyKey='#{property}']/@id"
|
| 166 |
prop = $doc.elements.each(query).first()
|
| 167 |
prop = prop.value |
| 168 |
|
| 169 |
query = "/entity-engine-xml/OSPropertyString[@id='#{prop}']/@value"
|
| 170 |
prop = $doc.elements.each(query).first()
|
| 171 |
return prop.value
|
| 172 |
end
|
| 173 |
|
| 174 |
def get_first_name() |
| 175 |
firstname, lastname = self.jira_fullname.split ' ', 2 |
| 176 |
return firstname
|
| 177 |
end
|
| 178 |
def get_last_name() |
| 179 |
firstname, lastname = self.jira_fullname.split ' ', 2 |
| 180 |
return lastname
|
| 181 |
end
|
| 182 |
def migrate |
| 183 |
super
|
| 184 |
$MIGRATED_USERS_BY_NAME[self.jira_name] = self.new_record |
| 185 |
end
|
| 186 |
|
| 187 |
# First Name, Last Name, E-mail, Password
|
| 188 |
# here is the tranformation of Jira attributes in Redmine attribues
|
| 189 |
def red_firstname() |
| 190 |
self.get_first_name
|
| 191 |
end
|
| 192 |
def red_lastname |
| 193 |
self.get_last_name.sub("(", "").sub(")", "") |
| 194 |
end
|
| 195 |
def red_mail |
| 196 |
self.jira_email
|
| 197 |
end
|
| 198 |
def red_password |
| 199 |
self.jira_name
|
| 200 |
end
|
| 201 |
def red_login |
| 202 |
self.jira_name
|
| 203 |
end
|
| 204 |
def before_save(new_record) |
| 205 |
new_record.login = red_login |
| 206 |
end
|
| 207 |
#def red_username
|
| 208 |
# self.jira_name
|
| 209 |
#end
|
| 210 |
end
|
| 211 |
|
| 212 |
class JiraComment < BaseJira |
| 213 |
DEST_MODEL = Journal |
| 214 |
MAP = {}
|
| 215 |
|
| 216 |
def initialize(node) |
| 217 |
super
|
| 218 |
# get a body from a comment
|
| 219 |
# comment can have the comment body as a attribute or as a child tag
|
| 220 |
@jira_body = @tag.attributes["body"] || @tag.elements["body"].text |
| 221 |
end
|
| 222 |
|
| 223 |
def jira_marker |
| 224 |
return "FROM JIRA: #{self.jira_id}\n" |
| 225 |
end
|
| 226 |
def retrieve |
| 227 |
Journal.first(:conditions => "notes LIKE '#{self.jira_marker}%'") |
| 228 |
end
|
| 229 |
|
| 230 |
# here is the tranformation of Jira attributes in Redmine attribues
|
| 231 |
def red_notes |
| 232 |
self.jira_marker + "\n" + @jira_body |
| 233 |
end
|
| 234 |
def red_created_on |
| 235 |
DateTime.parse(self.jira_created) |
| 236 |
end
|
| 237 |
def red_user |
| 238 |
# retrieving the Rails object
|
| 239 |
$MIGRATED_USERS_BY_NAME[self.jira_author] |
| 240 |
end
|
| 241 |
def red_journalized |
| 242 |
# retrieving the Rails object
|
| 243 |
JiraIssue::MAP[self.jira_issue] |
| 244 |
end
|
| 245 |
end
|
| 246 |
|
| 247 |
class JiraIssue < BaseJira |
| 248 |
DEST_MODEL = Issue |
| 249 |
MAP = {}
|
| 250 |
#attr_reader :jira_id, :jira_key, :jira_project, :jira_reporter,
|
| 251 |
# :jira_type, :jira_summary, :jira_assignee, :jira_priority
|
| 252 |
# :jira_resolution, :jira_status, :jira_created, :jira_resolutiondate
|
| 253 |
attr_reader :jira_description
|
| 254 |
|
| 255 |
|
| 256 |
def initialize(node_tag) |
| 257 |
super
|
| 258 |
@jira_description = @tag.elements["description"].text if @tag.elements["description"] |
| 259 |
end
|
| 260 |
def jira_marker |
| 261 |
return "FROM JIRA: #{self.jira_key}\n" |
| 262 |
end
|
| 263 |
def retrieve |
| 264 |
Issue.first(:conditions => "description LIKE '#{self.jira_marker}%'") |
| 265 |
end
|
| 266 |
|
| 267 |
def red_project |
| 268 |
# needs to return the Rails Project object
|
| 269 |
proj = self.jira_project
|
| 270 |
JiraProject::MAP[proj] |
| 271 |
end
|
| 272 |
def red_subject |
| 273 |
#:subject => encode(issue.title[0, limit_for(Issue, 'subject')]),
|
| 274 |
self.jira_summary
|
| 275 |
end
|
| 276 |
def red_description |
| 277 |
dsc = self.jira_marker + "\n" |
| 278 |
if @jira_description |
| 279 |
dsc += @jira_description
|
| 280 |
else
|
| 281 |
dsc += self.red_subject
|
| 282 |
end
|
| 283 |
return dsc
|
| 284 |
end
|
| 285 |
def red_priority |
| 286 |
name = $MIGRATED_ISSUE_PRIORITIES_BY_ID[self.jira_priority] |
| 287 |
return $MIGRATED_ISSUE_PRIORITIES[name] |
| 288 |
end
|
| 289 |
def red_created_on |
| 290 |
Time.parse(self.jira_created) |
| 291 |
end
|
| 292 |
def red_updated_on |
| 293 |
Time.parse(self.jira_updated) |
| 294 |
end
|
| 295 |
def red_status |
| 296 |
name = $MIGRATED_ISSUE_STATUS_BY_ID[self.jira_status] |
| 297 |
return $MIGRATED_ISSUE_STATUS[name] |
| 298 |
end
|
| 299 |
def red_tracker |
| 300 |
type_name = $MIGRATED_ISSUE_TYPES_BY_ID[self.jira_type] |
| 301 |
return $MIGRATED_ISSUE_TYPES[type_name] |
| 302 |
end
|
| 303 |
def red_author |
| 304 |
$MIGRATED_USERS_BY_NAME[self.jira_reporter] |
| 305 |
end
|
| 306 |
def red_assigned_to |
| 307 |
$MIGRATED_USERS_BY_NAME[self.jira_assignee] |
| 308 |
end
|
| 309 |
|
| 310 |
end
|
| 311 |
|
| 312 |
class JiraAttachment < BaseJira |
| 313 |
DEST_MODEL = Attachment |
| 314 |
MAP = {}
|
| 315 |
|
| 316 |
def retrieve |
| 317 |
self.class::DEST_MODEL.find_by_disk_filename(self.red_filename) |
| 318 |
end
|
| 319 |
def before_save(new_record) |
| 320 |
new_record.container = self.red_container
|
| 321 |
pp(new_record) |
| 322 |
end
|
| 323 |
|
| 324 |
# here is the tranformation of Jira attributes in Redmine attribues
|
| 325 |
#<FileAttachment id="10084" issue="10255" mimetype="image/jpeg" filename="Landing_Template.jpg"
|
| 326 |
# created="2011-05-05 15:54:59.411" filesize="236515" author="emiliano"/>
|
| 327 |
def red_filename |
| 328 |
self.jira_filename.gsub(/[^\w\.\-]/,'_') # stole from Redmine: app/model/attachment (methods sanitize_filenanme) |
| 329 |
end
|
| 330 |
def red_disk_filename |
| 331 |
Attachment.disk_filename(self.jira_filename) |
| 332 |
end
|
| 333 |
def red_content_type |
| 334 |
self.jira_mimetype.to_s.chomp
|
| 335 |
end
|
| 336 |
def red_filesize |
| 337 |
self.jira_filesize
|
| 338 |
end
|
| 339 |
|
| 340 |
def red_created_on |
| 341 |
DateTime.parse(self.jira_created) |
| 342 |
end
|
| 343 |
def red_author |
| 344 |
$MIGRATED_USERS_BY_NAME[self.jira_author] |
| 345 |
end
|
| 346 |
def red_container |
| 347 |
JiraIssue::MAP[self.jira_issue] |
| 348 |
end
|
| 349 |
end
|
| 350 |
|
| 351 |
|
| 352 |
def self.parse_projects() |
| 353 |
# PROJECTS:
|
| 354 |
# for project we need (identifies, name and description)
|
| 355 |
# in exported data we have name and key, in Redmine name and descr. will be equal
|
| 356 |
# the key will be the identifier
|
| 357 |
projs = [] |
| 358 |
$doc.elements.each('/*/Project') do |node| |
| 359 |
proj = JiraProject.new(node)
|
| 360 |
projs.push(proj) |
| 361 |
end
|
| 362 |
|
| 363 |
migrated_projects = {}
|
| 364 |
projs.each do |p|
|
| 365 |
#puts "Name and descr.: #{p.red_name} and #{p.red_description}"
|
| 366 |
#puts "identifier: #{p.red_identifier}"
|
| 367 |
migrated_projects[p.jira_id] = p |
| 368 |
end
|
| 369 |
#puts migrated_projects
|
| 370 |
return projs
|
| 371 |
end
|
| 372 |
|
| 373 |
def self.parse_users() |
| 374 |
users = [] |
| 375 |
#users = self.get_list_from_tag('/*/OSUser')
|
| 376 |
# For users in Redmine we need:
|
| 377 |
# First Name, Last Name, E-mail, Password
|
| 378 |
# In Jira, the fullname and email are property (a little more hard to get)
|
| 379 |
|
| 380 |
$doc.elements.each('/entity-engine-xml/OSUser') do |node| |
| 381 |
user = JiraUser.new(node)
|
| 382 |
users.push(user) |
| 383 |
end
|
| 384 |
|
| 385 |
return users
|
| 386 |
end
|
| 387 |
|
| 388 |
ISSUE_TYPE_MARKER = "(choose a Redmine Tracker)" |
| 389 |
DEFAULT_ISSUE_TYPE_MAP = {
|
| 390 |
# Default map from Jira (key) to Redmine (value)
|
| 391 |
# the comments on right side are Jira definitions - http://confluence.atlassian.com/display/JIRA/What+is+an+Issue#
|
| 392 |
"Bug" => "Bug", # A problem which impairs or prevents the functions of the product. |
| 393 |
"Improvement" => "Feature", # An enhancement to an existing feature. |
| 394 |
"New Feature" => "Feature", # A new feature of the product. |
| 395 |
"Task" => "Task", # A task that needs to be done. |
| 396 |
"Custom Issue" => "Support", # A custom issue type, as defined by your organisation if required. |
| 397 |
} |
| 398 |
def self.get_jira_issue_types() |
| 399 |
# Issue Type
|
| 400 |
issue_types = self.get_list_from_tag('/*/IssueType') |
| 401 |
#migrated_issue_types = {"jira_type" => "redmine tracker"}
|
| 402 |
migrated_issue_types = {}
|
| 403 |
issue_types.each do |issue|
|
| 404 |
migrated_issue_types[issue["name"]] = DEFAULT_ISSUE_TYPE_MAP.fetch(issue["name"], ISSUE_TYPE_MARKER) |
| 405 |
$MIGRATED_ISSUE_TYPES_BY_ID[issue["id"]] = issue["name"] |
| 406 |
end
|
| 407 |
return migrated_issue_types
|
| 408 |
end
|
| 409 |
|
| 410 |
ISSUE_STATUS_MARKER = "(choose a Redmine Issue Status)" |
| 411 |
DEFAULT_ISSUE_STATUS_MAP = {
|
| 412 |
# Default map from Jira (key) to Redmine (value)
|
| 413 |
# the comments on right side are Jira definitions - http://confluence.atlassian.com/display/JIRA/What+is+an+Issue#
|
| 414 |
"Open" => "New", # This issue is in the initial 'Open' state, ready for the assignee to start work on it. |
| 415 |
"In Progress" => "In Progress", # This issue is being actively worked on at the moment by the assignee. |
| 416 |
"Resolved" => "Resolved", # A Resolution has been identified or implemented, and this issue is awaiting verification by the reporter. From here, issues are either 'Reopened' or are 'Closed'. |
| 417 |
"Reopened" => "Assigned", # This issue was once 'Resolved' or 'Closed', but is now being re-examined. (For example, an issue with a Resolution of 'Cannot Reproduce' is Reopened when more information becomes available and the issue becomes reproducible). From here, issues are either marked In Progress, Resolved or Closed. |
| 418 |
"Closed" => "Closed", # This issue is complete. ## Be careful to choose one which a "issue closed" attribute marked :-) |
| 419 |
} |
| 420 |
def self.get_jira_status() |
| 421 |
# Issue Status
|
| 422 |
issue_status = self.get_list_from_tag('/*/Status') |
| 423 |
migrated_issue_status = {}
|
| 424 |
issue_status.each do |issue|
|
| 425 |
migrated_issue_status[issue["name"]] = DEFAULT_ISSUE_STATUS_MAP.fetch(issue["name"], ISSUE_STATUS_MARKER) |
| 426 |
$MIGRATED_ISSUE_STATUS_BY_ID[issue["id"]] = issue["name"] |
| 427 |
end
|
| 428 |
return migrated_issue_status
|
| 429 |
end
|
| 430 |
|
| 431 |
ISSUE_PRIORITY_MARKER = "(choose a Redmine Enumeration Issue Priority)" |
| 432 |
DEFAULT_ISSUE_PRIORITY_MAP = {
|
| 433 |
# Default map from Jira (key) to Redmine (value)
|
| 434 |
# the comments on right side are Jira definitions - http://confluence.atlassian.com/display/JIRA/What+is+an+Issue#
|
| 435 |
"Blocker" => "Immediate", # Highest priority. Indicates that this issue takes precedence over all others. |
| 436 |
"Critical" => "Urgent", # Indicates that this issue is causing a problem and requires urgent attention. |
| 437 |
"Major" => "High", # Indicates that this issue has a significant impact. |
| 438 |
"Minor" => "Normal", # Indicates that this issue has a relatively minor impact. |
| 439 |
"Trivial" => "Low", # Lowest priority. |
| 440 |
} |
| 441 |
def self.get_jira_priorities() |
| 442 |
# Issue Priority
|
| 443 |
issue_priority = self.get_list_from_tag('/*/Priority') |
| 444 |
migrated_issue_priority = {}
|
| 445 |
issue_priority.each do |issue|
|
| 446 |
migrated_issue_priority[issue["name"]] = DEFAULT_ISSUE_PRIORITY_MAP.fetch(issue["name"], ISSUE_PRIORITY_MARKER) |
| 447 |
$MIGRATED_ISSUE_PRIORITIES_BY_ID[issue["id"]] = issue["name"] |
| 448 |
end
|
| 449 |
return migrated_issue_priority
|
| 450 |
end
|
| 451 |
|
| 452 |
def self.parse_comments() |
| 453 |
ret = [] |
| 454 |
$doc.elements.each('/*/Action[@type="comment"]') do |node| |
| 455 |
comment = JiraComment.new(node)
|
| 456 |
ret.push(comment) |
| 457 |
end
|
| 458 |
return ret
|
| 459 |
end
|
| 460 |
|
| 461 |
def self.parse_issues() |
| 462 |
ret = [] |
| 463 |
$doc.elements.each('/*/Issue') do |node| |
| 464 |
issue = JiraIssue.new(node)
|
| 465 |
ret.push(issue) |
| 466 |
end
|
| 467 |
return ret
|
| 468 |
end
|
| 469 |
|
| 470 |
def self.parse_attachments() |
| 471 |
attachs = [] |
| 472 |
$doc.elements.each('/*/FileAttachment') do |node| |
| 473 |
attach = JiraAttachment.new(node)
|
| 474 |
attachs.push(attach) |
| 475 |
end
|
| 476 |
|
| 477 |
return attachs
|
| 478 |
end
|
| 479 |
end
|
| 480 |
|
| 481 |
|
| 482 |
|
| 483 |
|
| 484 |
namespace :jira_migration do |
| 485 |
|
| 486 |
desc "Generates the configuration for the map things from Jira to Redmine"
|
| 487 |
task :generate_conf => :environment do |
| 488 |
conf_file = JiraMigration::CONF_FILE |
| 489 |
conf_exists = File.exists?(conf_file)
|
| 490 |
if conf_exists
|
| 491 |
puts "You already have a conf file"
|
| 492 |
print "You want overwrite it ? [y/N] "
|
| 493 |
overwrite = STDIN.gets.match(/^y$/i) |
| 494 |
end
|
| 495 |
|
| 496 |
if !conf_exists or overwrite |
| 497 |
# Let's give the user all options to fill out
|
| 498 |
options = JiraMigration.get_all_options()
|
| 499 |
|
| 500 |
File.open(conf_file, "w"){ |f| f.write(options.to_yaml) } |
| 501 |
|
| 502 |
puts "This migration script needs the migration table to continue "
|
| 503 |
puts "Please... fill the map table on the file: '#{conf_file}' and run again the script"
|
| 504 |
puts "To start the options again, just remove the file '#{conf_file} and run again the script"
|
| 505 |
exit(0)
|
| 506 |
end
|
| 507 |
end
|
| 508 |
|
| 509 |
desc "Gets the configuration from YAML"
|
| 510 |
task :pre_conf => :environment do |
| 511 |
conf_file = JiraMigration::CONF_FILE |
| 512 |
conf_exists = File.exists?(conf_file)
|
| 513 |
|
| 514 |
if !conf_exists
|
| 515 |
Rake::Task['jira_migration:generate_conf'].invoke |
| 516 |
end
|
| 517 |
$confs = YAML.load_file(conf_file) |
| 518 |
end
|
| 519 |
|
| 520 |
desc "Tests all parsers!"
|
| 521 |
task :test_all_migrations => [:environment, :pre_conf, |
| 522 |
:test_parse_projects,
|
| 523 |
:test_parse_users,
|
| 524 |
:test_parse_comments,
|
| 525 |
:test_parse_issues,
|
| 526 |
] do
|
| 527 |
puts "All parsers was run! :-)"
|
| 528 |
end
|
| 529 |
|
| 530 |
desc "Tests all parsers!"
|
| 531 |
task :do_all_migrations => [:environment, :pre_conf, |
| 532 |
:migrate_issue_types,
|
| 533 |
:migrate_issue_status,
|
| 534 |
:migrate_issue_priorities,
|
| 535 |
:migrate_projects,
|
| 536 |
:migrate_users,
|
| 537 |
:migrate_issues,
|
| 538 |
:migrate_comments,
|
| 539 |
:migrate_attachments,
|
| 540 |
] do
|
| 541 |
puts "All migrations done! :-)"
|
| 542 |
end
|
| 543 |
|
| 544 |
|
| 545 |
desc "Migrates Jira Issue Types to Redmine Trackes"
|
| 546 |
task :migrate_issue_types => [:environment, :pre_conf] do |
| 547 |
|
| 548 |
JiraMigration.get_jira_issue_types()
|
| 549 |
types = $confs["types"] |
| 550 |
types.each do |key, value|
|
| 551 |
t = Tracker.find_or_create_by_name(value)
|
| 552 |
t.save! |
| 553 |
t.reload |
| 554 |
$MIGRATED_ISSUE_TYPES[key] = t
|
| 555 |
end
|
| 556 |
puts "Migrated issue types"
|
| 557 |
end
|
| 558 |
|
| 559 |
desc "Migrates Jira Issue Status to Redmine Status"
|
| 560 |
task :migrate_issue_status => [:environment, :pre_conf] do |
| 561 |
JiraMigration.get_jira_status()
|
| 562 |
status = $confs["status"] |
| 563 |
status.each do |key, value|
|
| 564 |
s = IssueStatus.find_or_create_by_name(value)
|
| 565 |
s.save! |
| 566 |
s.reload |
| 567 |
$MIGRATED_ISSUE_STATUS[key] = s
|
| 568 |
end
|
| 569 |
puts "Migrated issue status"
|
| 570 |
end
|
| 571 |
|
| 572 |
desc "Migrates Jira Issue Priorities to Redmine Priorities"
|
| 573 |
task :migrate_issue_priorities => [:environment, :pre_conf] do |
| 574 |
JiraMigration.get_jira_priorities()
|
| 575 |
priorities = $confs["priorities"] |
| 576 |
|
| 577 |
priorities.each do |key, value|
|
| 578 |
p = IssuePriority.find_or_create_by_name(value)
|
| 579 |
p.save! |
| 580 |
p.reload |
| 581 |
$MIGRATED_ISSUE_PRIORITIES[key] = p
|
| 582 |
end
|
| 583 |
puts "Migrated issue priorities"
|
| 584 |
end
|
| 585 |
|
| 586 |
desc "Migrates Jira Projects to Redmine Projects"
|
| 587 |
task :migrate_projects => :environment do |
| 588 |
projects = JiraMigration.parse_projects()
|
| 589 |
projects.each do |p|
|
| 590 |
#pp(p)
|
| 591 |
p.migrate |
| 592 |
end
|
| 593 |
end
|
| 594 |
|
| 595 |
desc "Migrates Jira Users to Redmine Users"
|
| 596 |
task :migrate_users => :environment do |
| 597 |
users = JiraMigration.parse_users()
|
| 598 |
users.each do |u|
|
| 599 |
#pp(u)
|
| 600 |
u.migrate |
| 601 |
end
|
| 602 |
end
|
| 603 |
|
| 604 |
desc "Migrates Jira Issues to Redmine Issues"
|
| 605 |
task :migrate_issues => :environment do |
| 606 |
issues = JiraMigration.parse_issues()
|
| 607 |
issues.each do |i|
|
| 608 |
#pp(i)
|
| 609 |
i.migrate |
| 610 |
end
|
| 611 |
end
|
| 612 |
|
| 613 |
desc "Migrates Jira Issues Comments to Redmine Issues Journals (Notes)"
|
| 614 |
task :migrate_comments => :environment do |
| 615 |
comments = JiraMigration.parse_comments()
|
| 616 |
comments.each do |c|
|
| 617 |
#pp(c)
|
| 618 |
c.migrate |
| 619 |
end
|
| 620 |
end
|
| 621 |
|
| 622 |
desc "Migrates Jira Issues Attachments to Redmine Attachments"
|
| 623 |
task :migrate_attachments => :environment do |
| 624 |
attachs = JiraMigration.parse_attachments()
|
| 625 |
attachs.each do |a|
|
| 626 |
#pp(c)
|
| 627 |
a.migrate |
| 628 |
end
|
| 629 |
end
|
| 630 |
|
| 631 |
# Tests.....
|
| 632 |
desc "Just pretty print Jira Projects on screen"
|
| 633 |
task :test_parse_projects => :environment do |
| 634 |
projects = JiraMigration.parse_projects()
|
| 635 |
projects.each {|p| pp(p.run_all_redmine_fields) }
|
| 636 |
end
|
| 637 |
|
| 638 |
desc "Just pretty print Jira Users on screen"
|
| 639 |
task :test_parse_users => :environment do |
| 640 |
users = JiraMigration.parse_users()
|
| 641 |
users.each {|u| pp( u.run_all_redmine_fields) }
|
| 642 |
end
|
| 643 |
|
| 644 |
desc "Just pretty print Jira Comments on screen"
|
| 645 |
task :test_parse_comments => :environment do |
| 646 |
comments = JiraMigration.parse_comments()
|
| 647 |
comments.each {|c| pp( c.run_all_redmine_fields) }
|
| 648 |
end
|
| 649 |
|
| 650 |
desc "Just pretty print Jira Issues on screen"
|
| 651 |
task :test_parse_issues => :environment do |
| 652 |
issues = JiraMigration.parse_issues()
|
| 653 |
issues.each {|i| pp( i.run_all_redmine_fields) }
|
| 654 |
end
|
| 655 |
end
|