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,208 @@
1
+ require 'git-process/git_process'
2
+ require 'GitRepoHelper'
3
+ require 'fileutils'
4
+
5
+ describe GitProc::Process do
6
+ include GitRepoHelper
7
+
8
+
9
+ def log_level
10
+ Logger::ERROR
11
+ end
12
+
13
+
14
+ before(:each) do
15
+ create_files(%w(.gitignore))
16
+ gitlib.commit('initial')
17
+ end
18
+
19
+
20
+ after(:each) do
21
+ rm_rf(gitlib.workdir)
22
+ end
23
+
24
+
25
+ describe 'run lifecycle' do
26
+
27
+ it 'should call the standard hooks' do
28
+ proc = GitProc::Process.new(gitlib)
29
+ proc.should_receive(:verify_preconditions)
30
+ proc.should_receive(:runner)
31
+ proc.should_receive(:cleanup)
32
+ proc.should_not_receive(:exit)
33
+
34
+ proc.run
35
+ end
36
+
37
+
38
+ it "should call 'cleanup' even if there's an error" do
39
+ proc = GitProc::Process.new(gitlib)
40
+ proc.should_receive(:verify_preconditions)
41
+ proc.should_receive(:runner).and_raise(GitProc::GitProcessError.new("Error!"))
42
+ proc.should_receive(:cleanup)
43
+ proc.should_receive(:exit)
44
+ proc.should_receive(:puts).with("Error!")
45
+
46
+ proc.run
47
+ end
48
+
49
+ end
50
+
51
+
52
+ describe "validate local integration branch" do
53
+
54
+ it "should use remove the int-branch if not on it and not blocked" do
55
+ clone_repo('master') do |gl|
56
+ gl.checkout('fb', :new_branch => 'master')
57
+
58
+ gp = GitProc::Process.new(gl)
59
+ gp.stub(:ask_about_removing_master).and_return(true)
60
+
61
+ gp.verify_preconditions
62
+
63
+ gl.branches.include?('master').should be_false
64
+ end
65
+ end
66
+
67
+
68
+ it "should ask use remove the int-branch if not on it and not blocked" do
69
+ clone_repo('master') do |gl|
70
+ gl.checkout('fb', :new_branch => 'master')
71
+
72
+ gp = GitProc::Process.new(gl)
73
+ gp.should_receive(:ask_about_removing_master).and_return(true)
74
+
75
+ gp.verify_preconditions
76
+
77
+ gl.branches.include?('master').should be_false
78
+ end
79
+ end
80
+
81
+
82
+ it "should ask use remove the int-branch if not on it and not blocked and not remove if answered no" do
83
+ clone_repo('master') do |gl|
84
+ gl.checkout('fb', :new_branch => 'master')
85
+
86
+ gp = GitProc::Process.new(gl)
87
+ gp.should_receive(:ask_about_removing_master).and_return(false)
88
+
89
+ gp.verify_preconditions
90
+
91
+ gl.branches.include?('master').should be_true
92
+ end
93
+ end
94
+
95
+
96
+ it "should not remove the int-branch if on it" do
97
+ clone_repo('master') do |gl|
98
+ gp = GitProc::Process.new(gl)
99
+ gp.verify_preconditions
100
+
101
+ gl.branches.include?('master').should be_true
102
+ end
103
+ end
104
+
105
+
106
+ it "should not remove the int-branch if blocked" do
107
+ clone_repo('master') do |gl|
108
+ gl.config['gitProcess.keepLocalIntegrationBranch'] = 'true'
109
+ gl.checkout('fb', :new_branch => 'master')
110
+
111
+ gp = GitProc::Process.new(gl)
112
+ gp.verify_preconditions
113
+
114
+ gl.branches.include?('master').should be_true
115
+ end
116
+ end
117
+
118
+
119
+ describe "local vs remote branch status" do
120
+
121
+ before(:each) do
122
+ change_file_and_commit('a.txt', 'a content', gitlib)
123
+ change_file_and_commit('b.txt', 'b content', gitlib)
124
+ end
125
+
126
+
127
+ it "should not remove if both have changes" do
128
+ clone_repo('master') do |gl|
129
+ change_file_and_commit('c.txt', 'c on origin/master', gitlib)
130
+ change_file_and_commit('d.txt', 'd on master', gl)
131
+
132
+ gl.checkout('fb', :new_branch => 'master')
133
+
134
+ gl.fetch
135
+
136
+ gp = GitProc::Process.new(gl)
137
+ gp.verify_preconditions
138
+
139
+ gl.branches.include?('master').should be_true
140
+ end
141
+ end
142
+
143
+
144
+ it "should remove if server changed but not local" do
145
+ clone_repo('master') do |gl|
146
+ gp = GitProc::Process.new(gl)
147
+ gp.stub(:ask_about_removing_master).and_return(true)
148
+
149
+ change_file_and_commit('c.txt', 'c on origin/master', gitlib)
150
+
151
+ gl.checkout('fb', :new_branch => 'master')
152
+
153
+ gl.fetch
154
+
155
+ gp.verify_preconditions
156
+
157
+ gl.branches.include?('master').should be_false
158
+ end
159
+ end
160
+
161
+
162
+ it "should not remove if server did not change but local did" do
163
+ clone_repo('master') do |gl|
164
+ change_file_and_commit('c.txt', 'c on master', gl)
165
+
166
+ gl.checkout('fb', :new_branch => 'master')
167
+
168
+ gl.fetch
169
+
170
+ gp = GitProc::Process.new(gl)
171
+ gp.verify_preconditions
172
+
173
+ gl.branches.include?('master').should be_true
174
+ end
175
+ end
176
+
177
+
178
+ it "should remove if server and local are the same" do
179
+ change_file_and_commit('c.txt', 'c on origin/master', gitlib)
180
+
181
+ clone_repo('master') do |gl|
182
+ gl.checkout('fb', :new_branch => 'master')
183
+ gp = GitProc::Process.new(gl)
184
+ gp.stub(:ask_about_removing_master).and_return(true)
185
+
186
+ gl.fetch
187
+ gp.verify_preconditions
188
+
189
+ gl.branches.include?('master').should be_false
190
+ end
191
+ end
192
+
193
+ end
194
+
195
+
196
+ it "should not remove the int-branch if not a clone" do
197
+ gitlib.config['gitProcess.keepLocalIntegrationBranch'] = 'false'
198
+ gitlib.checkout('fb', :new_branch => 'master')
199
+
200
+ gitprocess = GitProc::Process.new(gitlib)
201
+ gitprocess.verify_preconditions
202
+
203
+ gitlib.branches.include?('master').should be_true
204
+ end
205
+
206
+ end
207
+
208
+ end
@@ -0,0 +1,227 @@
1
+ require 'git-process/git_remote'
2
+ require 'GitRepoHelper'
3
+ include GitProc
4
+
5
+ describe GitRemote do
6
+
7
+ def log_level
8
+ Logger::ERROR
9
+ end
10
+
11
+
12
+ describe '#name' do
13
+ include GitRepoHelper
14
+
15
+ it 'should work with origin' do
16
+ change_file_and_commit('a', '')
17
+
18
+ clone_repo('master', 'origin') do |gl|
19
+ gl.remote.name.should == 'origin'
20
+ gl.branches.include?('origin/master').should be_true
21
+ end
22
+ end
23
+
24
+
25
+ it 'should work with a different remote name' do
26
+ change_file_and_commit('a', '')
27
+
28
+ clone_repo('master', 'a_remote') do |gl|
29
+ gl.remote.name.should == 'a_remote'
30
+ gl.branches.include?('a_remote/master').should be_true
31
+ end
32
+ end
33
+
34
+
35
+ it 'should work with an overridden remote name' do
36
+ change_file_and_commit('a', '')
37
+
38
+ clone_repo('master', 'a_remote') do |gl|
39
+ gl.config['gitProcess.remoteName'] = 'something_else'
40
+
41
+ gl.remote.name.should == 'something_else'
42
+ end
43
+ end
44
+
45
+ end
46
+
47
+
48
+ describe "#expanded_url" do
49
+ include GitRepoHelper
50
+
51
+ it "should work for an ssh address" do
52
+ remote.add('torigin', 'tuser@github.myco.com:jdigger/git-process.git')
53
+
54
+ remote.expanded_url('torigin').should == 'ssh://tuser@github.myco.com/jdigger/git-process.git'
55
+ end
56
+
57
+
58
+ it 'should work for an http address' do
59
+ remote.add('torigin', 'http://github.myco.com:8080/jdigger/git-process.git')
60
+
61
+ remote.expanded_url('torigin').should == 'http://github.myco.com:8080/jdigger/git-process.git'
62
+ end
63
+
64
+
65
+ it "should work for an https address" do
66
+ remote.add('torigin', 'https://github.myco.com/jdigger/git-process.git')
67
+
68
+ remote.expanded_url('torigin').should == 'https://github.myco.com/jdigger/git-process.git'
69
+ end
70
+
71
+
72
+ it "should work for an ssh-configured url address" do
73
+ remote.add('origin', 'mygithub:jdigger/git-process.git')
74
+
75
+ content = "\nHost mygithub\n"+
76
+ " User tuser\n"+
77
+ " HostName github.myco.com\n"
78
+
79
+ in_tempfile('ssh_config', content) do |file|
80
+ remote.expanded_url('origin', nil, :ssh_config_file => file.path).should == 'ssh://tuser@github.myco.com/jdigger/git-process.git'
81
+ end
82
+ end
83
+
84
+ end
85
+
86
+
87
+ describe "#repo_name" do
88
+ include GitRepoHelper
89
+
90
+ it "should work for an ssh address" do
91
+ remote.add('torigin', 'tuser@github.myco.com:jdigger/git-process.git')
92
+
93
+ remote.repo_name.should == 'jdigger/git-process'
94
+ end
95
+
96
+
97
+ it 'should work for an http address' do
98
+ remote.add('torigin', 'http://github.myco.com:8080/jdigger/git-process.git')
99
+
100
+ remote.repo_name.should == 'jdigger/git-process'
101
+ end
102
+
103
+
104
+ it "should work for an https address" do
105
+ remote.add('torigin', 'https://github.myco.com/jdigger/git-process.git')
106
+
107
+ remote.repo_name.should == 'jdigger/git-process'
108
+ end
109
+
110
+
111
+ it "should work for an ssh-configured url address" do
112
+ remote.add('origin', 'mygithub:jdigger/git-process.git')
113
+
114
+ content = "\nHost mygithub\n"+
115
+ " User tuser\n"+
116
+ " HostName github.myco.com\n"
117
+
118
+ in_tempfile('ssh_config', content) do |file|
119
+ remote.repo_name.should == 'jdigger/git-process'
120
+ end
121
+ end
122
+
123
+ end
124
+
125
+
126
+ describe "#hostname_and_user_from_ssh_config" do
127
+ include GitRepoHelper
128
+
129
+ it "should find in a single entry" do
130
+ content = "\nHost mygithub\n"+
131
+ " User git\n"+
132
+ " HostName github.myco.com\n"
133
+
134
+ in_tempfile('ssh_config', content) do |file|
135
+ GitRemote.hostname_and_user_from_ssh_config('mygithub', file.path).should == %w(github.myco.com git)
136
+ end
137
+ end
138
+
139
+
140
+ it "should find in multiple entries" do
141
+ content = "\nHost mygithub1\n"+
142
+ " User gittyw\n"+
143
+ " HostName github.mycoy.com\n"+
144
+ "Host mygithub2\n"+
145
+ " User gitty\n"+
146
+ " HostName github.myco.com\n"+
147
+ "Host mygithub3\n"+
148
+ " User gittyz\n"+
149
+ " HostName github.mycoz.com\n"
150
+
151
+ in_tempfile('ssh_config', content) do |file|
152
+ GitRemote.hostname_and_user_from_ssh_config('mygithub2', file.path).should == %w(github.myco.com gitty)
153
+ end
154
+ end
155
+
156
+
157
+ it "should return nil when no file" do
158
+ GitRemote.hostname_and_user_from_ssh_config('mygithub', '/bogus_file').should == nil
159
+ end
160
+
161
+
162
+ it "should return nil when given an unknown host" do
163
+ content = "\nHost mygithub1\n"+
164
+ " User gittyw\n"+
165
+ " HostName github.mycoy.com\n"+
166
+ "Host mygithub2\n"+
167
+ " User gitty\n"+
168
+ " HostName github.myco.com\n"+
169
+ "Host mygithub3\n"+
170
+ " User gittyz\n"+
171
+ " HostName github.mycoz.com\n"
172
+
173
+ in_tempfile('ssh_config', content) do |file|
174
+ GitRemote.hostname_and_user_from_ssh_config('UNKNOWNZ', file.path).should == nil
175
+ end
176
+ end
177
+
178
+
179
+ it "should return nil when no hostname for an existing host" do
180
+ content = "\nHost mygithub1\n"+
181
+ " User gittyw\n"+
182
+ " HostName github.mycoy.com\n"+
183
+ "Host mygithub2\n"+
184
+ " User gitty\n"+
185
+ "Host mygithub3\n"+
186
+ " User gittyz\n"+
187
+ " HostName github.mycoz.com\n"
188
+
189
+ in_tempfile('ssh_config', content) do |file|
190
+ GitRemote.hostname_and_user_from_ssh_config('mygithub2', file.path).should == nil
191
+ end
192
+ end
193
+
194
+
195
+ it "should return hostname but no username when no user for an existing host" do
196
+ content = "\nHost mygithub1\n"+
197
+ " User gittyw\n"+
198
+ " HostName github.mycoy.com\n"+
199
+ "Host mygithub2\n"+
200
+ " HostName github.myco.com\n"+
201
+ "Host mygithub3\n"+
202
+ " User gittyz\n"+
203
+ " HostName github.mycoz.com\n"
204
+
205
+ in_tempfile('ssh_config', content) do |file|
206
+ GitRemote.hostname_and_user_from_ssh_config('mygithub2', file.path).should == ['github.myco.com', nil]
207
+ end
208
+ end
209
+
210
+ end
211
+
212
+ end
213
+
214
+
215
+ def in_tempfile(filename, content, &block)
216
+ file = Tempfile.new(filename)
217
+ file.puts content
218
+ file.flush
219
+
220
+ begin
221
+ block.call(file)
222
+ ensure
223
+ file.close
224
+ file.unlink
225
+ end
226
+ end
227
+
@@ -0,0 +1,122 @@
1
+ require 'git-process/git_status'
2
+ require 'GitRepoHelper'
3
+ require 'fileutils'
4
+
5
+ describe GitProc::GitStatus do
6
+ include GitRepoHelper
7
+
8
+
9
+ def log_level
10
+ Logger::ERROR
11
+ end
12
+
13
+
14
+ before(:each) do
15
+ create_files(%w(.gitignore))
16
+ gitlib.commit('initial')
17
+ end
18
+
19
+
20
+ after(:each) do
21
+ rm_rf(gitlib.workdir)
22
+ end
23
+
24
+
25
+ it 'should handle added files' do
26
+ create_files(['a', 'b file.txt', 'c'])
27
+
28
+ gitlib.status.added.should == ['a', 'b file.txt', 'c']
29
+ end
30
+
31
+
32
+ it 'should handle a modification on both sides' do
33
+ change_file_and_commit('a', '')
34
+
35
+ gitlib.checkout('fb', :new_branch => 'master')
36
+ change_file_and_commit('a', 'hello')
37
+
38
+ gitlib.checkout('master')
39
+ change_file_and_commit('a', 'goodbye')
40
+
41
+ gitlib.merge('fb') rescue ''
42
+
43
+ status = gitlib.status
44
+ status.unmerged.should == %w(a)
45
+ status.modified.should == %w(a)
46
+ end
47
+
48
+
49
+ it "should handle an addition on both sides" do
50
+ gitlib.checkout('fb', :new_branch => 'master')
51
+ change_file_and_commit('a', 'hello')
52
+
53
+ gitlib.checkout('master')
54
+ change_file_and_commit('a', 'goodbye')
55
+
56
+ gitlib.merge('fb') rescue ''
57
+
58
+ status = gitlib.status
59
+ status.unmerged.should == %w(a)
60
+ status.added.should == %w(a)
61
+ end
62
+
63
+
64
+ it "should handle a merge deletion on fb" do
65
+ change_file_and_commit('a', '')
66
+
67
+ gitlib.checkout('fb', :new_branch => 'master')
68
+ gitlib.remove('a', :force => true)
69
+ gitlib.commit('removed a')
70
+
71
+ gitlib.checkout('master')
72
+ change_file_and_commit('a', 'goodbye')
73
+
74
+ gitlib.merge('fb') rescue ''
75
+
76
+ status = gitlib.status
77
+ status.unmerged.should == %w(a)
78
+ status.deleted.should == %w(a)
79
+ end
80
+
81
+
82
+ it "should handle a merge deletion on master" do
83
+ change_file_and_commit('a', '')
84
+
85
+ gitlib.checkout('fb', :new_branch => 'master')
86
+ change_file_and_commit('a', 'hello')
87
+
88
+ gitlib.checkout('master')
89
+ gitlib.remove('a', :force => true)
90
+ gitlib.commit('removed a')
91
+
92
+ gitlib.merge('fb') rescue ''
93
+
94
+ status = gitlib.status
95
+ status.unmerged.should == %w(a)
96
+ status.deleted.should == %w(a)
97
+ end
98
+
99
+
100
+ it "should handle a move/rename" do
101
+ FileUtils.cp __FILE__, File.join(gitlib.workdir, 'a file.txt')
102
+ gitlib.add('a file.txt')
103
+ gitlib.commit('a with content')
104
+
105
+ FileUtils.cp __FILE__, File.join(gitlib.workdir, 'b file.txt')
106
+ gitlib.remove 'a file.txt'
107
+ gitlib.add 'b file.txt'
108
+
109
+ status = gitlib.status
110
+ status.deleted.should == ['a file.txt']
111
+ status.added.should == ['b file.txt']
112
+ end
113
+
114
+
115
+ it "should return an empty result" do
116
+ gitlib.status.added.should == []
117
+ gitlib.status.deleted.should == []
118
+ gitlib.status.modified.should == []
119
+ gitlib.status.unmerged.should == []
120
+ end
121
+
122
+ end