1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133 | #!/usr/bin/env ruby
require 'date'
require 'optparse'
require 'methadone'
require 'git2bit'
class App
include Methadone::Main
include Methadone::CLILogging
main do
help_now!("'guser' is required") unless options[:guser]
help_now!("'gpass' is required") unless options[:gpass]
help_now!("'grepo' is required") unless options[:grepo]
help_now!("'buser' is required") unless options[:buser]
help_now!("'bpass' is required") unless options[:bpass]
help_now!("'brepo' is required") unless options[:brepo]
debug "Configuration Used: " + options.inspect
# Connect to Bitbucket and Github
bitbucket = Git2bit::BitbucketProxy.new({:user => options[:buser], :pass => options[:bpass],:repo => options[:brepo]})
github = Git2bit::GithubProxy.new({:user => options[:guser], :pass => options[:gpass], :org => options[:gorg], :repo => options[:grepo]})
if options[:issue]
info "Will only process Github issue ##{options[:issue]}"
else
if options[:closed]
info "Starting to process through ALL Github issues"
else
info "Starting to process through only the OPENED Github issues"
end
end
# Start processing each issue in Github
issues = Hash.new
github.each_issue(options[:closed]) { |issue|
issues.store(issue.number, issue)
}
issues.keys.sort.each { |key|
issue = issues[key]
# Go to the next iteration if the issue number does not match option provided
next if options[:issue] and options[:issue].to_i != issue.number
info "Processing Github issue ##{issue.number}"
if issue.milestone and !bitbucket.milestones.find_index(issue.milestone.title)
# If there is a milestone and it does not already exist, then create it
bitbucket.create_milestone(issue.milestone.title)
end
# Analyze the Github labels in an attempt to find the BitBucket data we need
tags = bitbucket.analyze_labels issue.labels.map{|x| x.name}
if tags[:status].nil? or issue.state == 'closed'
# If a status was not defined in the github labels, then set to open/resolved
# If the Github state is closed, we want to ignore the labels and set the ticket to resolved
tags[:status] = issue.state == 'open' ? 'open' : 'resolved'
end
issue_date = DateTime.parse(issue.created_at)
issue_body = "_Github issue **##{issue.number}** created by **#{issue.user.login}** on #{issue_date.strftime('%F %T')}_\n\n#{issue[:body]}"
# Create the Bitbucket issue
new_issue = bitbucket.create_issue({
:title => issue.title,
:content => issue_body,
:responsible => issue.assignee,
:milestone => issue.milestone ? issue.milestone.title : nil,
:component => tags[:component],
:priority => tags[:priority],
:status => tags[:status],
:kind => tags[:kind]
})
# Add the Github labels as a comment so the data is not lost
bitbucket.create_comment new_issue, "**Github labels**: " + tags[:labels].join(', ')
# Process Comments if the Github issue has any
if issue.comments > 1
# Get the Github comments
comments = github.get_comments issue.number
comments.each do |comment|
comment_date = DateTime.parse(comment.created_at)
# Add the comment into the newly created bitbucket issue
bitbucket.create_comment new_issue, "_Github comment by **#{comment.user.login}** on #{comment_date.strftime('%F %T')}_\n\n#{comment[:body]}"
end
end
}
info "Processing Complete."
end
# Declare command-line interface here
version Git2bit::VERSION
description 'git2bit migrates issues with their comments and milestones from a github repo to a bitbucket repo'
on("--[no-]closed","[Do not] migrate closed issues")
on("--issue ISSUE_NUMBER","Process only a single Github issue number")
on("--guser USER","Github username")
on("--gpass PASSWORD","Github password")
on("--grepo REPO","Github repo name")
on("--gorg ORG", "Github Organization name for repos owned by Organizations")
on("--buser USER","BitBucket username")
on("--bpass PASSWORD","BitBucket password")
on("--brepo REPO","BitBucket repo name")
use_log_level_option
defaults_from_config_file '.git2bit.rc'
go!
end
__END__
# Sample .git2bit.rc file
closed: true
guser: joeworkman
gpass: p@ssw0rd
grepo: myrepo
buser: joeworkman
bpass: p@ssw0rd
brepo: newrepo
|