Class: Git::Daily::Release
Direct Known Subclasses
Hotfix
Constant Summary
collapse
- SUBCOMMAND =
{
"open" => :open,
"list" => :list,
"sync" => :sync,
"close" => :close
}
Instance Method Summary
collapse
Methods inherited from Command
branches, clean?, current_branch, develop, has_branch?, has_remote_branch?, logurl, master, merged_branches, pull_request_url, release_branches, remote, remote_branch, remotes
Constructor Details
Returns a new instance of Release.
16
17
18
19
20
|
# File 'lib/git-daily/command/release.rb', line 16
def initialize
@base_branch = Command.develop
@branch_prefix = "release"
@merge_to = [Command.master, Command.develop]
end
|
Instance Method Details
#close ⇒ Object
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
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
|
# File 'lib/git-daily/command/release.rb', line 106
def close
rel_branches = Command.release_branches(@branch_prefix)
if rel_branches.empty?
raise "#{@branch_prefix} branch not found. abort."
end
rel_branch = rel_branches.shift
remote = Command.remote
merge_branches.each do |branch_name|
branches = `git branch`.split("\n").select{|v| v[/#{branch_name}/]}
merge_branch = branches[0][/^\*/] ? branches[0][2 .. -1] : branches[0].strip
next unless merge_branch
if remote
puts "first, fetch remotes"
`git fetch --all`
puts "diff check"
diff_branch1 = "#{rel_branch}..#{remote}/#{rel_branch}"
diff_branch2 = "#{remote}/#{rel_branch}..#{rel_branch}"
diff1 = `git diff #{diff_branch1}`
diff2 = `git diff #{diff_branch2}`
unless diff1.empty? or diff1.empty?
$stderr.puts "There are some diff between local and $remote, run release sync first."
raise "abort"
end
end
$stderr.puts "checkout #{merge_branch} and merge #{rel_branch} to #{merge_branch}"
`git checkout #{merge_branch}`
if remote
r = `git daily pull`
puts r
unless $? == 0
$stderr.puts "pull failed"
raise "abort"
end
end
merged_branches = Command.merged_branches
unless merged_branches.find {|v| v == rel_branch}
r = `git merge --no-ff #{rel_branch}`
puts r
unless $? == 0
$stderr.puts "merge failed"
raise "abort"
end
end
puts "push #{merge_branch} to #{remote}"
`git checkout #{merge_branch}`
r = `git push #{remote} #{merge_branch}`
puts r
unless $? == 0
$stderr.puts "push failed"
raise "abort"
end
end
puts "delete branch: #{rel_branch}"
r = `git branch -d #{rel_branch}`
puts r
unless $? == 0
$stderr.puts "failed to delete local #{rel_branch}"
raise "abort"
end
if remote
r = `git push #{remote} :#{rel_branch}`
puts r
unless $? == 0
$stderr.puts "failed to delete #{remote}'s #{rel_branch}"
raise "abort"
end
end
base = @base_branch
`git checkout #{base}`
puts "#{@branch_prefix} closed"
end
|
#help ⇒ Object
22
23
24
|
# File 'lib/git-daily/command/release.rb', line 22
def help
"release\tOperation daily release"
end
|
#list ⇒ Object
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
|
# File 'lib/git-daily/command/release.rb', line 284
def list
release_branch = Command.release_branches(@branch_prefix)
if release_branch.empty?
raise "#{@branch_prefix} branch not found. abort."
end
current_branch = Command.current_branch
remote = Command.remote
master_branch = if remote
Command.remote_branch(remote, Command.master)
else
Command.master
end
puts "first, fetch remotes"
`git fetch --all`
revs = []
rev_ids = `git rev-list --no-merges #{master_branch}..#{current_branch}`.split(/\n/)
rev_ids.each do |rev_id|
rev = {}
rev[:id] = rev_id
rev[:add_files] = []
rev[:mod_files] = []
logs = `git show #{rev_id}`
file = nil
logs.each_line do |line|
case line
when /^Author: .+\<([^@]+)@([^>]+)>/
rev[:author] = $1
when /^diff --git a\/([^ ]+) /
file = $1
when /^new file mode/
rev[:add_files] << file
when /^index/
rev[:mod_files] << file
end
end
revs << rev
end
mod_files = []
add_files = []
revs.each do |rev|
mod_files += rev[:add_files]
mod_files += rev[:mod_files]
end
mod_files.sort!.uniq!
add_files.sort!.uniq!
if revs.size > 0
puts "Commit list:"
revs.each do |rev|
puts "\t#{rev[:id]} = #{rev[:author]}"
end
puts
end
if add_files.size > 0
puts "Added files:"
add_files.each do |file|
puts "\t#{file}"
end
puts
end
if mod_files.size > 0
puts "Modified files:"
mod_files.each do |file|
puts "\t#{file}"
end
puts
end
if Command.logurl and revs.size > 0
authors = {}
revs.each do |rev|
authors[rev[:author]] = [] unless authors[rev[:author]]
authors[rev[:author]] << rev[:id]
end
logurl = Command.logurl
puts "Author list:"
authors.keys.sort.each do |key|
puts "\t#{key}:"
authors[key].each do |id|
puts sprintf("\t#{logurl}", id)
end
puts
end
end
if Command.pull_request_url
puts 'Pull Requests: '
urlBase = Command.pull_request_url
merges = `git log --merges --pretty=format:'%<(30)%s | %an' #{master_branch}..#{current_branch}`.split(/\n/)
merges.each do |merge|
merge.match(/^Merge pull request #(?<id>[1-9][0-9]*) .+$/) do |match|
url = sprintf(urlBase, match[:id])
puts "\t#{url} | #{match[0]}"
end
end
end
end
|
#merge_branches ⇒ Object
102
103
104
|
# File 'lib/git-daily/command/release.rb', line 102
def merge_branches
@merge_to
end
|
#open ⇒ Object
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
|
# File 'lib/git-daily/command/release.rb', line 41
def open
cur_branch = Command.current_branch
base_branch = @base_branch
if cur_branch != base_branch
raise "currently not on #{base_branch} but on #{cur_branch}"
end
rel_branches = Command.release_branches(@branch_prefix)
unless rel_branches.empty?
raise "release process (on local) is not closed, so cannot open release\n release branches: #{rel_branches.join(',')}"
end
remote = Command.remote
if remote
puts "first, fetch remotes"
`git fetch --all`
rels = `git branch -a --no-color`.split(/\n/).select { |b| b[/remotes\/#{remote}\/#{@branch_prefix}/]}
unless rels.empty?
raise "release process (on local) is not closed, so cannot open release\n release branches: #{rels.join(',')}"
end
end
new_release_branch = "#{@branch_prefix}/#{DateTime.now.strftime("%Y%m%d-%H%M")}"
puts "Confirm: create branch #{new_release_branch} from #{cur_branch} ?"
print " [yN] : "
confirm = $stdin.gets
unless confirm.strip[/^[Yy]/]
raise "abort"
end
if remote
puts "merge #{cur_branch} branch from remote"
r = `git merge #{remote}/#{cur_branch}`
unless $? == 0
$stderr.puts "merge failed"
$stderr.puts r
raise "abort"
end
end
puts "create release branch: #{new_release_branch}"
r = `git branch #{new_release_branch}`
if remote
puts "push to remote: #{remote}"
r = `git push #{remote} #{new_release_branch}`
puts r
unless $? == 0
$stderr.puts "push failed"
r = `git branch -d #{new_release_branch}`
$stderr.puts r
$stderr.puts "rollback (delete branch)"
end
end
`git checkout #{new_release_branch}`
puts "release opened"
end
|
#run ⇒ Object
26
27
28
29
30
31
32
33
34
35
36
37
38
39
|
# File 'lib/git-daily/command/release.rb', line 26
def run
unless Command.clean?
raise "git status is not clean"
end
subcommand = ARGV.shift
if SUBCOMMAND.has_key?(subcommand)
return send(SUBCOMMAND[subcommand])
else
$stderr.puts "please specify release subcommand"
$stderr.puts usage
exit 1
end
end
|
#sync ⇒ Object
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
|
# File 'lib/git-daily/command/release.rb', line 189
def sync
remote = Command.remote
unless remote
raise "remote not found. abort."
end
cur = Command.current_branch
develop = Command.develop
puts "first, fetch remotes"
`git fetch --all`
puts "cleanup remote"
`git remote prune #{remote}`
rel = nil
rel_branches = Command.release_branches(@branch_prefix)
rel = rel_branches.shift if rel_branches.size == 1
r_closed = false
r_rel_branch = nil
r_rel_branches = `git branch -a`.split(/\n/).select { |a| a[/remotes\/#{remote}\/#{@branch_prefix}/] }
r_rel_branches.map! { |b| b.strip }
if r_rel_branches.size == 1
r_rel_branch = r_rel_branches.shift[/remotes\/#{remote}\/(.*)/, 1]
else
if r_rel_branches.empty?
r_closed = true
else
raise "there are a number of remote release branches"
end
end
if rel
if r_rel_branch != rel
r_closed = true
end
if r_closed
puts "release closed! so cleanup local release branch"
puts "checkout #{develop}"
`git checkout #{develop}`
r = `git daily pull`
puts r
puts "delete #{rel}"
r = `git branch -d #{rel}`
puts r
unless $? == 0
$stderr.puts "branch delete failed"
$stderr.puts " git branch delete failed, please manually"
end
if r_rel_branch != rel
$stderr.puts "Closed old release branch"
$stderr.puts "Please retry 'release sync'"
end
puts "sync to release close"
return
end
if cur != rel
puts "checkout #{rel}"
`git checkout #{rel}`
cur = Command.current_branch
end
puts "git pull"
r = `git daily pull`
puts r
unless $? == 0
raise "abort"
end
puts "git push"
r = `git daily push`
puts r
unless $? == 0
$stderr.puts "failed to push to remote"
raise "abort"
end
else
if r_closed
puts "sync completed (nothing to do)"
return
end
puts "checkout and traking #{r_rel_branch}"
r = `git checkout #{r_rel_branch}`
puts r
unless $? == 0
$stderr.puts "failed to checkout"
raise "abort"
end
puts "start to tracking release branch"
end
end
|
#usage ⇒ Object
394
395
396
397
398
399
400
401
|
# File 'lib/git-daily/command/release.rb', line 394
def usage
"Usage: git daily release open\\t: Open daily-release process\n git daily release list\\t: Show release list\n git daily release sync\\t: Sync current opened release process\n git daily release close\\t: Close to daily-release process\n"
end
|