git-pr-release 0.0.1 → 0.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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