git-process-lib 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
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