Project

General

Profile

RE: Import from Lighthouse ยป lighthouse_import.rake

lighthouse -> redmine migration script - Ben Mishkin, 2009-02-17 17:29

 
1
# updated feb-09
2
# bmishkin@sagebit.com
3
#
4
# to install up-to-date lighthouse api gem:
5
# gem install Caged-lighthouse-api --source=http://gems.github.com
6
#
7
# to import a project, create identically named redmine project
8
# to enable issue state -> ticket status, you need to create identically-named statuses in redmine before starting
9

    
10
require 'lighthouse-api'
11
namespace :import do
12
  task :lighthouse => :environment do
13

    
14
    Lighthouse.account = ENV["LH_ACCOUNT"]
15
    Lighthouse.token = ENV["LH_TOKEN"]
16

    
17
    users = User.find(:all)
18
    find_user = lambda do |lh_user| 
19
      names = lh_user.name.split(/\s/)
20
      names[1] = "Unknown" if !names[1] || names[1].strip.blank?
21
      result = User.find(:all).detect {|u| 
22
        "#{u.firstname} #{u.lastname}" == names.join(' ')
23
      }
24
      unless result
25
        result = User.find_by_admin(1) unless ENV['CREATE_USERS']
26
      end
27
      unless result
28
        begin
29
          login = names.first.downcase.gsub(/[^\w]/, '') + 
30
            (rand * 1000 + 100).to_s.first(3)
31

    
32
          result = User.new(
33
            :firstname => names.shift,
34
            :lastname => names.join(' '),
35
            :mail => "#{login}@fixme.com"
36
          )
37
          result.login = login
38
          result.password = result.password_confirmation = login
39
          result.save!
40
          puts "Created a user: " +
41
            "#{result.firstname} #{result.lastname} (#{result.login})"
42
        rescue => e
43
          raise "Failed creating user from: #{lh_user.inspect} -- #{e.inspect}"
44
        end
45
      end
46
      result
47
    end
48
    
49
    cat_for_tag = lambda do |project, tag|
50
      project.issue_categories.find_by_name(tag) || 
51
        project.issue_categories.create(:name => tag)
52
    end
53

    
54
    # TODO: attempt to match priorities somehow?
55
    priority = Enumeration.find_by_opt_and_name('IPRI', 'Normal')
56

    
57
    puts "Identifying matching projects..."
58
    projects = Lighthouse::Project.find(:all).collect do |lh_project| 
59
      rm_project = Project.find_by_name(lh_project.name)
60
      puts "#{lh_project.name} => #{rm_project || '???'}"
61
      
62
      # NOTE: disabled because creating projects involves a number of decisions
63
      # about trackers, issue statuses, workflows, users, modules, etc that we
64
      # don't want to get into.
65
      #
66
      #if rm_project
67
      #  puts "#{lh_project.name} => #{rm_project}"
68
      #else
69
      #  rm_project = Project.create!(
70
      #    :name => lh_project.name,
71
      #    :identifier => lh_project.name.downcase.gsub(/[^\w]/, '-').first(20),
72
      #    :created_on => lh_project.created_at,
73
      #    :updated_on => lh_project.updated_at,
74
      #    :is_public => lh_project.public
75
      #  )
76
      #  puts "#{lh_project.name} => #{rm_project} [CREATED]"
77
      #end
78

    
79
      {lh_project => rm_project}
80
    end
81

    
82
    project_pairs = projects.inject({}) {|acc, hash| acc.update(hash)}
83

    
84
    project_pairs.each_pair do |lh_project, rm_project|
85
      next unless rm_project
86

    
87
      if rm_project.trackers.empty?
88
        raise "No trackers found for #{project.name!}. Cannot create an issue."
89
      end
90

    
91
      lh_project.milestones.each do |milestone|
92
        next if rm_project.versions.find_by_name(milestone.title)
93
        v = rm_project.versions.create!(
94
          :name => milestone.title,
95
          :description => milestone.goals,
96
          :effective_date => milestone.due_on ? milestone.due_on.to_date : nil,
97
          :created_on => milestone.created_at,
98
          :updated_on => milestone.updated_at
99
        )
100
        puts "Created new target version for #{rm_project.name}: #{v.name}"
101
      end
102

    
103
      pg = 0
104
      while (tix = lh_project.tickets(:page => (pg += 1), :q => 'sort:number status:any')).length > 0
105
        puts "Chewing tickets on page #{pg}"
106
        tix.each do |ticket_lite|
107
          ticket = Lighthouse::Ticket.find(
108
            ticket_lite.to_param, 
109
            :params => ticket_lite.instance_variable_get(:@prefix_options)
110
          )
111
          next if Issue.find_by_subject(ticket.title)
112
          first_version = ticket.versions.shift
113

    
114
          ticket_creator = Lighthouse::User.find(ticket.user_id) unless ticket.user_id.blank?
115
          ticket_assignee = Lighthouse::User.find(ticket.assigned_user_id) unless ticket.assigned_user_id.blank?
116
          issue = Issue.new
117
          issue.project = rm_project
118
          issue.tracker = rm_project.trackers.first
119
          issue.author = find_user.call(ticket_creator) unless ticket_creator.blank?
120
          issue.assigned_to = find_user.call(ticket_assignee) unless ticket_assignee.blank?
121
          issue.priority = priority
122
          issue.status = IssueStatus.find(
123
            :first,
124
            :conditions => ["UCASE(name) = ?", ticket.state.upcase]
125
          ) || IssueStatus.default
126
          issue.fixed_version = rm_project.versions.find_by_name(
127
            lh_project.milestones.detect {|ms| ms.id == ticket.milestone_id}.title
128
          ) unless ticket.milestone_id.blank?
129
          issue.attributes = {
130
            :subject => ticket.title, 
131
            :description => first_version.body || "[No description]",
132
            :done_ratio => 0,
133
            :created_on => ticket.created_at,
134
            :updated_on => ticket.updated_at
135
          }
136

    
137
          if ticket.tags && ticket.tags.any?
138
            issue.category = cat_for_tag.call(rm_project, ticket.tags.first) 
139
          end
140

    
141
          if issue.save
142
            puts "Added ticket [##{ticket.number}] to #{rm_project.name}: '#{issue.subject}' : #{ticket.state.upcase}"
143
          else
144
            puts "Failed to add issue: #{issue.inspect} - " +
145
              issue.errors.full_messages.join(', ')
146
          end
147

    
148
          ticket.versions.each do |version|
149
            next if version.body.blank?
150

    
151
            version_author = Lighthouse::User.find(version.user_id)
152
            issue.instance_variable_set(:@current_journal, nil)
153
            issue.init_journal(find_user.call(version_author), version.body)
154
            cj = issue.instance_variable_get(:@current_journal)
155
            cj.created_on = version.created_at
156
            issue.save!
157
          end
158
        end
159
      end
160
    end
161

    
162
  end
163
end
    (1-1/1)