git-pr-release 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 98451853b6d661fc267e971bc26da386c77db073
4
- data.tar.gz: 2437ff8212312fae03bbdfc28f2bae9e1b2806a7
3
+ metadata.gz: 79571d68044b4b6400cd27b0ea810cc26cc4d009
4
+ data.tar.gz: 4a5413b28460e4083c3aa9492d78a429285ba0a5
5
5
  SHA512:
6
- metadata.gz: e03be692ee0bbb5a4ac1dd4cffd68fb625a39601cda7171d2c93770f4162b162e6cd5ae287877f4030ca2c4d65dafd442e8bd42803f0389c9f58178f5171aec5
7
- data.tar.gz: d8831448a215b076fdd69782ccfdcbc5c22eeb979623f7cb0818754dbdc311fb07bb681eae75f0608af00dfdb89e592e8c0529746ecf3180dc5828966f8dcf3f
6
+ metadata.gz: 563d365becde236f2bff0b111925b8dff67021f2e6a7cf931dc857671bf198934b671c3823c7996d1d1b4df9cb947cdc762c4d2d63f6fceb2dc5c1edd76a4860
7
+ data.tar.gz: 510e8000fcd8a6de989f8366284b7eefbbf7ae44717bb195df3c6d328bef791600b80661586f3ca988ac8429fdadc45fef9e140c6e2f826e71103ed31411f52d
@@ -3,6 +3,7 @@ PATH
3
3
  specs:
4
4
  git-pr-release (0.0.1)
5
5
  colorize (~> 0.6)
6
+ diff-lcs (~> 1.2)
6
7
  highline (~> 1.6)
7
8
  octokit (~> 2.7)
8
9
 
@@ -11,13 +12,14 @@ GEM
11
12
  specs:
12
13
  addressable (2.3.5)
13
14
  colorize (0.6.0)
15
+ diff-lcs (1.2.5)
14
16
  faraday (0.9.0)
15
17
  multipart-post (>= 1.2, < 3)
16
18
  highline (1.6.20)
17
19
  multipart-post (2.0.0)
18
20
  octokit (2.7.0)
19
21
  sawyer (~> 0.5.2)
20
- sawyer (0.5.2)
22
+ sawyer (0.5.3)
21
23
  addressable (~> 2.3.5)
22
24
  faraday (~> 0.8, < 0.10)
23
25
 
@@ -0,0 +1 @@
1
+ require 'bundler/gem_tasks'
@@ -1,10 +1,24 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
- require 'rubygems'
4
3
  require 'uri'
4
+ require 'erb'
5
5
  require 'open3'
6
+ require 'tmpdir'
6
7
  require 'octokit'
7
8
  require 'colorize'
9
+ require 'diff/lcs'
10
+
11
+ class PullRequest
12
+ attr_reader :pr
13
+
14
+ def initialize(pr)
15
+ @pr = pr
16
+ end
17
+
18
+ def to_checklist_item
19
+ "- [ ] ##{pr.number} #{pr.title}" + (pr.assignee ? " @#{pr.assignee.login}" : '')
20
+ end
21
+ end
8
22
 
9
23
  def say(message, level)
10
24
  color = case level
@@ -46,10 +60,64 @@ def git_config(key)
46
60
  end
47
61
  end
48
62
 
49
- def generate_description(pull_requests)
50
- pull_requests.map do |pr|
51
- "- [ ] ##{pr.number} #{pr.title}" + (pr.assignee ? " @#{pr.assignee.login}" : '')
52
- end.join("\n")
63
+ # First line will be the title of the PR
64
+ DEFAULT_PR_TEMPLATE = <<ERB
65
+ Release <%= Time.now %>
66
+ <% pull_requests.each do |pr| -%>
67
+ <%= pr.to_checklist_item %>
68
+ <% end -%>
69
+ ERB
70
+
71
+ def build_pr_title_and_body(prs)
72
+ pull_requests = prs.map { |pr| PullRequest.new(pr) }
73
+
74
+ template = DEFAULT_PR_TEMPLATE
75
+
76
+ if path = git_config('pr-release.template.path')
77
+ template_path = File.join(git('rev-parse', '--show-toplevel').first.chomp, path)
78
+ template = File.read(template_path)
79
+ end
80
+
81
+ erb = ERB.new template, nil, '-'
82
+ content = erb.result binding
83
+ content.split(/\n/, 2)
84
+ end
85
+
86
+ def merge_pr_body(old_body, new_body)
87
+ # Try to take over checklist statuses
88
+ pr_body_lines = []
89
+
90
+ Diff::LCS.traverse_balanced(old_body.split(/\r?\n/), new_body.split(/\r?\n/)) do |event|
91
+ say "diff: #{event.inspect}", :trace
92
+ action, old, new = *event
93
+ old_nr, old_line = *old
94
+ new_nr, new_line = *new
95
+
96
+ case action
97
+ when '=', '+'
98
+ say "Use line as is: #{new_line}", :trace
99
+ pr_body_lines << new_line
100
+ when '-'
101
+ say "Use old line: #{old_line}", :trace
102
+ pr_body_lines << old_line
103
+ when '!'
104
+ if [ old_line, new_line ].all? { |line| /^- \[[ x]\]/ === line }
105
+ say "Found checklist diff; use old one: #{old_line}", :trace
106
+ pr_body_lines << old_line
107
+ else
108
+ # not a checklist diff, use both line
109
+ say "Use line as is: #{old_line}", :trace
110
+ pr_body_lines << old_line
111
+
112
+ say "Use line as is: #{new_line}", :trace
113
+ pr_body_lines << new_line
114
+ end
115
+ else
116
+ say "Unknown diff event: #{event}", :warn
117
+ end
118
+ end
119
+
120
+ pr_body_lines.join("\n")
53
121
  end
54
122
 
55
123
  def obtain_token!
@@ -91,7 +159,8 @@ if remote_url.host != 'github.com'
91
159
  end
92
160
  end
93
161
 
94
- ## Project specific configuration
162
+ ### Set up configuration
163
+
95
164
  production_branch = git_config('pr-release.branch.production') || 'master'
96
165
  staging_branch = git_config('pr-release.branch.staging') || 'staging'
97
166
 
@@ -103,6 +172,8 @@ client = Octokit::Client.new :access_token => obtain_token!
103
172
 
104
173
  git :remote, 'update', 'origin'
105
174
 
175
+ ### Fetch merged PRs
176
+
106
177
  merged_feature_head_sha1s = git(
107
178
  :log, '--merges', '--pretty=format:%P', "origin/#{production_branch}..origin/#{staging_branch}"
108
179
  ).map do |line|
@@ -140,22 +211,34 @@ pull_requests = merged_pull_request_numbers.map do |nr|
140
211
  pr
141
212
  end
142
213
 
214
+ ### Create a release PR
215
+
143
216
  say 'Searching for existing release pull requests...', :info
144
- release_pr = client.pull_requests(repository).find do |pr|
217
+ existing_release_pr = client.pull_requests(repository).find do |pr|
145
218
  pr.head.ref == staging_branch && pr.base.ref == production_branch
146
219
  end
147
220
 
148
221
  created = false
149
222
 
150
- if release_pr
151
- say "Updating release pull request ##{release_pr.number}...", :info
152
- client.update_pull_request(
153
- repository, release_pr.number, :body => generate_description(pull_requests)
223
+ pr_title, pr_body = build_pr_title_and_body pull_requests
224
+
225
+ say 'Pull request body:', :debug
226
+ say pr_body, :debug
227
+
228
+ release_pr = nil
229
+
230
+ if existing_release_pr
231
+ say "Updating release pull request ##{existing_release_pr.number}...", :info
232
+
233
+ merged_pr_body = merge_pr_body existing_release_pr.body, pr_body
234
+
235
+ release_pr = client.update_pull_request(
236
+ repository, existing_release_pr.number, :title => pr_title, :body => merged_pr_body
154
237
  )
155
238
  else
156
239
  say 'Creating release pull request...', :info
157
240
  release_pr = client.create_pull_request(
158
- repository, production_branch, staging_branch, "release #{Time.now}", generate_description(pull_requests)
241
+ repository, production_branch, staging_branch, pr_title, pr_body
159
242
  )
160
243
  created = true
161
244
  end
@@ -4,7 +4,7 @@ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
4
 
5
5
  Gem::Specification.new do |spec|
6
6
  spec.name = "git-pr-release"
7
- spec.version = '0.0.1'
7
+ spec.version = '0.0.2'
8
8
  spec.authors = ["motemen"]
9
9
  spec.email = ["motemen@gmail.com"]
10
10
  spec.summary = 'Creates a release pull request'
@@ -19,6 +19,7 @@ Gem::Specification.new do |spec|
19
19
  spec.add_dependency 'octokit', '~> 2.7'
20
20
  spec.add_dependency 'highline', '~> 1.6'
21
21
  spec.add_dependency 'colorize', '~> 0.6'
22
+ spec.add_dependency 'diff-lcs', '~> 1.2'
22
23
 
23
24
  spec.license = 'MIT'
24
25
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: git-pr-release
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - motemen
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-01-21 00:00:00.000000000 Z
11
+ date: 2014-01-29 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: octokit
@@ -52,6 +52,20 @@ dependencies:
52
52
  - - ~>
53
53
  - !ruby/object:Gem::Version
54
54
  version: '0.6'
55
+ - !ruby/object:Gem::Dependency
56
+ name: diff-lcs
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ~>
60
+ - !ruby/object:Gem::Version
61
+ version: '1.2'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ~>
67
+ - !ruby/object:Gem::Version
68
+ version: '1.2'
55
69
  description: git-pr-release creates a pull request which summarizes feature branches
56
70
  that are to be released into production
57
71
  email:
@@ -65,6 +79,7 @@ files:
65
79
  - Gemfile
66
80
  - Gemfile.lock
67
81
  - README.md
82
+ - Rakefile
68
83
  - bin/git-pr-release
69
84
  - git-pr-release.gemspec
70
85
  homepage: https://github.com/motemen/git-pr-release