git-process-lib 2.0.0

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.
Files changed (69) hide show
  1. data/CHANGELOG.md +123 -0
  2. data/Gemfile +21 -0
  3. data/Gemfile.lock +57 -0
  4. data/LICENSE +193 -0
  5. data/README.md +342 -0
  6. data/Rakefile +32 -0
  7. data/bin/git-new-fb +39 -0
  8. data/bin/git-pull-request +63 -0
  9. data/bin/git-sync +38 -0
  10. data/bin/git-to-master +44 -0
  11. data/docs/git-new-fb.1.adoc +83 -0
  12. data/docs/git-process.1.adoc +227 -0
  13. data/docs/git-pull-request.1.adoc +166 -0
  14. data/docs/git-sync.1.adoc +120 -0
  15. data/docs/git-to-master.1.adoc +172 -0
  16. data/git-new-fb.gemspec +20 -0
  17. data/git-process-lib.gemspec +25 -0
  18. data/git-process.gemspec +22 -0
  19. data/git-pull-request.gemspec +20 -0
  20. data/git-sync.gemspec +20 -0
  21. data/git-to-master.gemspec +20 -0
  22. data/lib/git-process/abstract_error_builder.rb +53 -0
  23. data/lib/git-process/changed_file_helper.rb +115 -0
  24. data/lib/git-process/git_abstract_merge_error_builder.rb +130 -0
  25. data/lib/git-process/git_branch.rb +105 -0
  26. data/lib/git-process/git_branches.rb +81 -0
  27. data/lib/git-process/git_config.rb +135 -0
  28. data/lib/git-process/git_lib.rb +646 -0
  29. data/lib/git-process/git_logger.rb +84 -0
  30. data/lib/git-process/git_merge_error.rb +28 -0
  31. data/lib/git-process/git_process.rb +159 -0
  32. data/lib/git-process/git_process_error.rb +18 -0
  33. data/lib/git-process/git_process_options.rb +101 -0
  34. data/lib/git-process/git_rebase_error.rb +30 -0
  35. data/lib/git-process/git_remote.rb +222 -0
  36. data/lib/git-process/git_status.rb +108 -0
  37. data/lib/git-process/github_configuration.rb +298 -0
  38. data/lib/git-process/github_pull_request.rb +165 -0
  39. data/lib/git-process/new_fb.rb +49 -0
  40. data/lib/git-process/parked_changes_error.rb +41 -0
  41. data/lib/git-process/pull_request.rb +136 -0
  42. data/lib/git-process/pull_request_error.rb +25 -0
  43. data/lib/git-process/rebase_to_master.rb +148 -0
  44. data/lib/git-process/sync_process.rb +55 -0
  45. data/lib/git-process/syncer.rb +157 -0
  46. data/lib/git-process/uncommitted_changes_error.rb +23 -0
  47. data/lib/git-process/version.rb +22 -0
  48. data/local-build.rb +24 -0
  49. data/spec/FileHelpers.rb +19 -0
  50. data/spec/GitRepoHelper.rb +123 -0
  51. data/spec/changed_file_helper_spec.rb +127 -0
  52. data/spec/git_abstract_merge_error_builder_spec.rb +64 -0
  53. data/spec/git_branch_spec.rb +123 -0
  54. data/spec/git_config_spec.rb +45 -0
  55. data/spec/git_lib_spec.rb +176 -0
  56. data/spec/git_logger_spec.rb +66 -0
  57. data/spec/git_process_spec.rb +208 -0
  58. data/spec/git_remote_spec.rb +227 -0
  59. data/spec/git_status_spec.rb +122 -0
  60. data/spec/github_configuration_spec.rb +152 -0
  61. data/spec/github_pull_request_spec.rb +117 -0
  62. data/spec/github_test_helper.rb +49 -0
  63. data/spec/new_fb_spec.rb +126 -0
  64. data/spec/pull_request_helper.rb +94 -0
  65. data/spec/pull_request_spec.rb +137 -0
  66. data/spec/rebase_to_master_spec.rb +362 -0
  67. data/spec/spec_helper.rb +21 -0
  68. data/spec/sync_spec.rb +1474 -0
  69. metadata +249 -0
@@ -0,0 +1,137 @@
1
+ require 'git-process/pull_request'
2
+ #require 'git-process/github_configuration'
3
+ require 'github_test_helper'
4
+ require 'pull_request_helper'
5
+ require 'GitRepoHelper'
6
+ require 'hashie'
7
+
8
+
9
+ describe GitProc::PullRequest do
10
+ include GitRepoHelper
11
+ include GitHubTestHelper
12
+
13
+ before(:each) do
14
+ create_files(%w(.gitignore))
15
+ gitlib.commit('initial')
16
+ end
17
+
18
+
19
+ after(:each) do
20
+ rm_rf(gitlib.workdir)
21
+ end
22
+
23
+
24
+ def log_level
25
+ Logger::ERROR
26
+ end
27
+
28
+
29
+ describe 'with no parameters' do
30
+ def create_process(dir, opts)
31
+ GitProc::PullRequest.new(dir, opts)
32
+ end
33
+
34
+
35
+ it 'should push the branch and create a default pull request' do
36
+ pr_client = double('pr_client')
37
+
38
+ gitlib.config['gitProcess.integrationBranch'] = 'develop'
39
+ gitlib.remote.add('origin', 'git@github.com:jdigger/git-process.git')
40
+
41
+ GitProc::PullRequest.stub(:create_pull_request_client).and_return(pr_client)
42
+ #PullRequest.stub(:create_pull_request_client).with(anything, 'origin', 'jdigger/git-process').and_return(pr_client)
43
+ gitlib.should_receive(:push)
44
+ pr_client.should_receive(:create).with('develop', 'master', 'master', '').and_return(Hashie::Mash.new({:html_url => 'http://test'}))
45
+
46
+ gitprocess.runner
47
+ end
48
+
49
+
50
+ it "should fail if the base and head branch are the same" do
51
+ gitlib.remote.add('origin', 'git@github.com:jdigger/git-process.git')
52
+
53
+ expect {
54
+ gitprocess.runner
55
+ }.to raise_error GitProc::PullRequestError
56
+ end
57
+
58
+ end
59
+
60
+
61
+ describe 'checkout pull request' do
62
+ include PullRequestHelper
63
+
64
+ before(:each) do
65
+ gitlib.config['gitProcess.github.authToken'] = 'sdfsfsdf'
66
+ gitlib.config['github.user'] = 'jdigger'
67
+ end
68
+
69
+
70
+ describe "with PR #" do
71
+
72
+ def pull_request
73
+ @pr ||= create_pull_request({})
74
+ end
75
+
76
+
77
+ def create_process(dir, opts)
78
+ GitProc::PullRequest.new(dir, opts.merge({:prNumber => pull_request[:number]}))
79
+ end
80
+
81
+
82
+ it "should checkout the branch for the pull request" do
83
+ add_remote(:head)
84
+ stub_fetch(:head)
85
+
86
+ stub_get_pull_request(pull_request)
87
+
88
+ expect_checkout_pr_head()
89
+ expect_upstream_set()
90
+
91
+ gitlib.stub(:branch).with(nil, :no_color => true, :all => true).and_return("")
92
+ gitlib.stub(:branch).with(nil, :no_color => true, :remote => true).and_return("")
93
+ gitlib.should_receive(:rebase).with('test_repo/master', {})
94
+
95
+ gitprocess.runner
96
+ end
97
+
98
+ end
99
+
100
+
101
+ describe "with repo name and PR #" do
102
+
103
+ def pull_request
104
+ @pr ||= create_pull_request(:base_remote => 'sourcerepo', :base_repo => 'source_repo')
105
+ end
106
+
107
+
108
+ def create_process(dir, opts)
109
+ GitProc::PullRequest.new(dir, opts.merge({:prNumber => pull_request[:number],
110
+ :server => pull_request[:head][:remote]}))
111
+ end
112
+
113
+
114
+ it "should checkout the branch for the pull request" do
115
+ add_remote(:head)
116
+ add_remote(:base)
117
+ stub_fetch(:head)
118
+ stub_fetch(:base)
119
+ gitlib.config['gitProcess.remoteName'] = pull_request[:head][:repo][:name]
120
+
121
+ stub_get_pull_request(pull_request)
122
+
123
+ expect_checkout_pr_head()
124
+ expect_upstream_set()
125
+
126
+ gitlib.stub(:branch).with(nil, :no_color => true, :all => true).and_return('')
127
+ gitlib.stub(:branch).with(nil, :no_color => true, :remote => true).and_return('')
128
+ gitlib.should_receive(:rebase).with('test_repo/master', {})
129
+
130
+ gitprocess.runner
131
+ end
132
+
133
+ end
134
+
135
+ end
136
+
137
+ end
@@ -0,0 +1,362 @@
1
+ require 'git-process/rebase_to_master'
2
+ require 'GitRepoHelper'
3
+ require 'github_test_helper'
4
+ require 'pull_request_helper'
5
+ require 'webmock/rspec'
6
+ require 'json'
7
+ include GitProc
8
+
9
+ describe RebaseToMaster do
10
+ include GitRepoHelper
11
+ include GitHubTestHelper
12
+
13
+
14
+ def log_level
15
+ Logger::ERROR
16
+ end
17
+
18
+
19
+ before(:each) do
20
+ create_files(%w(.gitignore))
21
+ gitlib.commit('initial')
22
+ end
23
+
24
+
25
+ after(:each) do
26
+ rm_rf(gitlib.workdir)
27
+ end
28
+
29
+
30
+ def create_process(base, opts = {})
31
+ RebaseToMaster.new(base, opts)
32
+ end
33
+
34
+
35
+ describe 'rebase to master' do
36
+
37
+ it 'should work easily for a simple rebase' do
38
+ gitlib.checkout('fb', :new_branch => 'master')
39
+ change_file_and_commit('a', '')
40
+
41
+ commit_count.should == 2
42
+
43
+ gitlib.checkout('master')
44
+ change_file_and_commit('b', '')
45
+
46
+ gitlib.checkout('fb')
47
+
48
+ gitprocess.run
49
+
50
+ commit_count.should == 3
51
+ end
52
+
53
+
54
+ describe 'when used on _parking_' do
55
+ it 'should fail #rebase_to_master' do
56
+ gitlib.checkout('_parking_', :new_branch => 'master')
57
+ change_file_and_commit('a', '')
58
+
59
+ expect { gitprocess.verify_preconditions }.to raise_error ParkedChangesError
60
+ end
61
+ end
62
+
63
+
64
+ describe 'closing the pull request' do
65
+ include PullRequestHelper
66
+
67
+
68
+ def pull_request
69
+ @pr ||= create_pull_request(:pr_number => '987', :head_branch => 'fb', :base_branch => 'master')
70
+ end
71
+
72
+
73
+ it 'should not try when there is no auth token' do
74
+ gitlib.branch('fb', :base_branch => 'master')
75
+ clone_repo('fb') do |gl|
76
+ gl.config['gitProcess.github.authToken'] = ''
77
+ gl.config['remote.origin.url'] = 'git@github.com:test_repo.git'
78
+ gl.config['github.user'] = 'test_user'
79
+
80
+ rtm = RebaseToMaster.new(gl, :log_level => log_level)
81
+ rtm.gitlib.stub(:fetch)
82
+ rtm.gitlib.stub(:push)
83
+ rtm.runner
84
+ end
85
+ end
86
+
87
+ end
88
+
89
+ end
90
+
91
+
92
+ describe 'custom integration branch' do
93
+
94
+ it "should use the 'gitProcess.integrationBranch' configuration" do
95
+ gitlib.checkout('int-br', :new_branch => 'master')
96
+ change_file_and_commit('a', '')
97
+
98
+ gitlib.checkout('fb', :new_branch => 'master')
99
+ change_file_and_commit('b', '')
100
+
101
+ gitlib.branches['master'].delete!
102
+
103
+ clone_repo('int-br') do |gl|
104
+ gl.config['gitProcess.integrationBranch'] = 'int-br'
105
+
106
+ gl.checkout('ab', :new_branch => 'origin/int-br')
107
+
108
+ my_branches = gl.branches
109
+ my_branches.include?('origin/master').should be_false
110
+ my_branches['ab'].sha.should == my_branches['origin/int-br'].sha
111
+
112
+ gl.stub(:repo_name).and_return('test_repo')
113
+
114
+ change_file_and_commit('c', '', gl)
115
+
116
+ my_branches = gl.branches
117
+ my_branches['ab'].sha.should_not == my_branches['origin/int-br'].sha
118
+
119
+ RebaseToMaster.new(gl, :log_level => log_level).runner
120
+
121
+ my_branches = gl.branches
122
+ my_branches['HEAD'].sha.should == my_branches['origin/int-br'].sha
123
+ end
124
+ end
125
+
126
+ end
127
+
128
+
129
+ describe 'remove current feature branch' do
130
+
131
+ describe 'when handling the parking branch' do
132
+
133
+ it 'should create it based on origin/master' do
134
+ gitlib.branch('fb', :base_branch => 'master')
135
+ clone_repo('fb') do |gl|
136
+ create_process(gl).remove_feature_branch
137
+ gl.branches.current.name.should == '_parking_'
138
+ end
139
+ end
140
+
141
+
142
+ it 'should move it to the new origin/master if it already exists and is clean' do
143
+ clone_repo do |gl|
144
+ gl.branch('_parking_', :base_branch => 'origin/master')
145
+ change_file_and_commit('a', '', gl)
146
+
147
+ gl.checkout('fb', :new_branch => 'origin/master')
148
+
149
+ create_process(gl).remove_feature_branch
150
+
151
+ gl.branches.current.name.should == '_parking_'
152
+ end
153
+ end
154
+
155
+
156
+ it 'should move it to the new origin/master if it already exists and changes are part of the current branch' do
157
+ gitlib.checkout('afb', :new_branch => 'master')
158
+ clone_repo do |gl|
159
+ gl.checkout('_parking_', :new_branch => 'origin/master') do
160
+ change_file_and_commit('a', '', gl)
161
+ end
162
+
163
+ gl.checkout('fb', :new_branch => '_parking_')
164
+ gl.push('origin', 'fb', 'master')
165
+
166
+ create_process(gl).remove_feature_branch
167
+ gl.branches.current.name.should == '_parking_'
168
+ end
169
+ end
170
+
171
+
172
+ it 'should move it out of the way if it has unaccounted changes on it' do
173
+ clone_repo do |gl|
174
+ gl.checkout('_parking_', :new_branch => 'origin/master')
175
+ change_file_and_commit('a', '', gl)
176
+ gl.checkout('fb', :new_branch => 'origin/master')
177
+
178
+ gl.branches.include?('_parking_OLD_').should be_false
179
+
180
+ create_process(gl).remove_feature_branch
181
+
182
+ gl.branches.include?('_parking_OLD_').should be_true
183
+ gl.branches.current.name.should == '_parking_'
184
+ end
185
+ end
186
+
187
+ end
188
+
189
+
190
+ it 'should delete the old local branch when it has been merged into origin/master' do
191
+ clone_repo do |gl|
192
+ change_file_and_commit('a', '', gl)
193
+
194
+ gl.checkout('fb', :new_branch => 'origin/master')
195
+ gl.branches.include?('fb').should be_true
196
+
197
+ create_process(gl).remove_feature_branch
198
+
199
+ gl.branches.include?('fb').should be_false
200
+ gl.branches.current.name.should == '_parking_'
201
+ end
202
+ end
203
+
204
+
205
+ it 'should raise an error when the local branch has not been merged into origin/master' do
206
+ clone_repo do |gl|
207
+ gl.checkout('fb', :new_branch => 'origin/master')
208
+ change_file_and_commit('a', '', gl)
209
+
210
+ gl.branches.include?('fb').should be_true
211
+
212
+ expect { create_process(gl).remove_feature_branch }.to raise_error GitProcessError
213
+ end
214
+ end
215
+
216
+
217
+ it 'should delete the old remote branch' do
218
+ change_file_and_commit('a', '')
219
+
220
+ gitlib.branch('fb', :base_branch => 'master')
221
+
222
+ clone_repo('fb') do |gl|
223
+ gl.branches.include?('origin/fb').should be_true
224
+ create_process(gl).remove_feature_branch
225
+ gl.branches.include?('origin/fb').should be_false
226
+ gitlib.branches.include?('fb').should be_false
227
+ gl.branches.current.name.should == '_parking_'
228
+ end
229
+ end
230
+
231
+ end
232
+
233
+
234
+ describe ':keep option' do
235
+
236
+ it 'should not try to close a pull request or remove remote branch' do
237
+ gitlib.branch('fb', :base_branch => 'master')
238
+
239
+ clone_repo('fb') do |gl|
240
+ rtm = GitProc::RebaseToMaster.new(gl, :log_level => log_level, :keep => true)
241
+ gl.should_receive(:fetch).at_least(1)
242
+ gl.should_receive(:push).with('origin', gl.branches.current.name, 'master')
243
+ gl.should_not_receive(:push).with('origin', nil, nil, :delete => 'fb')
244
+ rtm.runner
245
+ end
246
+ end
247
+
248
+ end
249
+
250
+
251
+ describe 'to-master pull request' do
252
+ include PullRequestHelper
253
+
254
+
255
+ def pull_request_number
256
+ pull_request[:number]
257
+ end
258
+
259
+
260
+ def head_repo_name
261
+ pull_request[:head][:repo][:name]
262
+ end
263
+
264
+
265
+ def base_repo_name
266
+ pull_request[:base][:repo][:name]
267
+ end
268
+
269
+
270
+ def base_branch_name
271
+ pull_request[:base][:ref]
272
+ end
273
+
274
+
275
+ def head_branch_name
276
+ pull_request[:head][:ref]
277
+ end
278
+
279
+
280
+ before(:each) do
281
+ gitlib.branch(head_branch_name, :base_branch => 'master')
282
+ end
283
+
284
+
285
+ def configure(gl)
286
+ gl.config['gitProcess.github.authToken'] = 'sdfsfsdf'
287
+ gl.config["remote.#{head_repo_name}.url"] = "git@github.com:#{head_repo_name}.git"
288
+ gl.config['github.user'] = 'jdigger'
289
+ gl.config['gitProcess.remoteName'] = head_repo_name
290
+
291
+ stub_fetch(:head, gl)
292
+ stub_fetch(:base, gl)
293
+
294
+ stub_get("https://api.github.com/repos/#{head_repo_name}/pulls/#{pull_request_number}", :body => pull_request)
295
+ stub_patch("https://api.github.com/repos/#{head_repo_name}/pulls/#{pull_request_number}")
296
+ end
297
+
298
+
299
+ describe 'with PR #' do
300
+
301
+ def pull_request
302
+ @pr ||= create_pull_request({})
303
+ end
304
+
305
+
306
+ def create_process(dir, opts)
307
+ RebaseToMaster.new(dir, opts.merge({:prNumber => pull_request_number}))
308
+ end
309
+
310
+
311
+ it 'should checkout the branch for the pull request' do
312
+ clone_repo('master', head_repo_name) do |gl|
313
+ gl.branch("#{base_repo_name}/#{base_branch_name}", :base_branch => "#{head_repo_name}/master")
314
+
315
+ configure(gl)
316
+
317
+ rtm = GitProc::RebaseToMaster.new(gl, :log_level => log_level, :prNumber => pull_request_number)
318
+
319
+ gl.should_receive(:push).with(head_repo_name, head_branch_name, 'master')
320
+ gl.should_receive(:push).with(head_repo_name, nil, nil, :delete => head_branch_name)
321
+
322
+ rtm.runner
323
+ end
324
+ end
325
+
326
+ end
327
+
328
+
329
+ describe 'with repo name and PR #' do
330
+
331
+ def pull_request
332
+ @pr ||= create_pull_request(:base_remote => 'sourcerepo', :base_repo => 'source_repo')
333
+ end
334
+
335
+
336
+ def create_process(dir, opts = {})
337
+ RebaseToMaster.new(dir, opts.merge({:prNumber => var,
338
+ :server => pull_request[:head][:remote]}))
339
+ end
340
+
341
+
342
+ it 'should checkout the branch for the pull request' do
343
+ clone_repo('master', head_repo_name) do |gl|
344
+ add_remote(:base, gl)
345
+ gl.branch("#{base_repo_name}/#{base_branch_name}", :base_branch => "#{head_repo_name}/master")
346
+
347
+ configure(gl)
348
+
349
+ rtm = GitProc::RebaseToMaster.new(gl, :log_level => log_level, :prNumber => pull_request_number)
350
+
351
+ gl.should_receive(:push).with(head_repo_name, head_branch_name, 'master')
352
+ gl.should_receive(:push).with(head_repo_name, nil, nil, :delete => head_branch_name)
353
+
354
+ rtm.runner
355
+ end
356
+ end
357
+
358
+ end
359
+
360
+ end
361
+
362
+ end