git-si 0.3.1 → 0.4.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.
- checksums.yaml +4 -4
- data/git-si.gemspec +2 -1
- data/lib/git/si.rb +68 -369
- data/lib/git/si/actions.rb +153 -0
- data/lib/git/si/errors.rb +20 -0
- data/lib/git/si/git-control.rb +112 -0
- data/lib/git/si/git-ignore.rb +23 -0
- data/lib/git/si/svn-control.rb +135 -0
- data/lib/git/si/util.rb +304 -0
- data/lib/git/si/version.rb +12 -1
- data/spec/actions_spec.rb +356 -0
- data/spec/git-control_spec.rb +254 -0
- data/spec/git-ignore_spec.rb +37 -0
- data/spec/svn-control_spec.rb +391 -0
- data/spec/util_spec.rb +458 -0
- data/spec/version_spec.rb +17 -0
- metadata +40 -8
data/spec/util_spec.rb
ADDED
@@ -0,0 +1,458 @@
|
|
1
|
+
require "git/si/git-ignore"
|
2
|
+
require "git/si/util"
|
3
|
+
|
4
|
+
describe Git::Si::Util do
|
5
|
+
let( :runner_spy ) { spy( 'runner_spy' ) }
|
6
|
+
let( :test_mixin_host ) {
|
7
|
+
Class.new do
|
8
|
+
include Git::Si::Util
|
9
|
+
|
10
|
+
def initialize( spy )
|
11
|
+
@spy = spy
|
12
|
+
end
|
13
|
+
|
14
|
+
def say(toss)
|
15
|
+
end
|
16
|
+
|
17
|
+
def debug(toss)
|
18
|
+
end
|
19
|
+
|
20
|
+
def in_svn_root
|
21
|
+
yield
|
22
|
+
end
|
23
|
+
|
24
|
+
def on_mirror_branch
|
25
|
+
yield
|
26
|
+
end
|
27
|
+
|
28
|
+
def error_message(toss)
|
29
|
+
end
|
30
|
+
|
31
|
+
def success_message(toss)
|
32
|
+
end
|
33
|
+
|
34
|
+
def notice_message(toss)
|
35
|
+
end
|
36
|
+
|
37
|
+
def did_last_command_succeed?
|
38
|
+
true
|
39
|
+
end
|
40
|
+
|
41
|
+
def run_command( command, options={} )
|
42
|
+
@spy.run_command( command, options )
|
43
|
+
raise "test error" if command =~ /raise/
|
44
|
+
"testing run_command"
|
45
|
+
end
|
46
|
+
end
|
47
|
+
}
|
48
|
+
|
49
|
+
let( :svn_info_output ) {
|
50
|
+
"Path: .
|
51
|
+
Working Copy Root Path: /path/place
|
52
|
+
URL: file:///Users/path/place
|
53
|
+
Relative URL: ^/test
|
54
|
+
Repository Root: file:///Users/path/place
|
55
|
+
Repository UUID: 0101010101
|
56
|
+
Revision: 1012
|
57
|
+
Node Kind: directory
|
58
|
+
Schedule: normal
|
59
|
+
Last Changed Author: me
|
60
|
+
Last Changed Rev: 1
|
61
|
+
" }
|
62
|
+
|
63
|
+
let( :svn_status_output ) { "Z foobar
|
64
|
+
X foobar
|
65
|
+
M foobar.git
|
66
|
+
M foobar.swp
|
67
|
+
M barfoo
|
68
|
+
A something
|
69
|
+
D something else
|
70
|
+
? whatever
|
71
|
+
" }
|
72
|
+
|
73
|
+
let( :svn_update_output ) { "
|
74
|
+
Restored 'bin/tests/importantthing'
|
75
|
+
A bin/tests/foobar
|
76
|
+
U bin/tests/api/goobar
|
77
|
+
G bin/tests/api/special
|
78
|
+
U bin/tests/api/anotherfile
|
79
|
+
A bin/tests/barfoo
|
80
|
+
? unknownfile.md
|
81
|
+
D byefile
|
82
|
+
C myimage.png
|
83
|
+
D badjs.js
|
84
|
+
C something/javascript.js
|
85
|
+
A something/newjs.js
|
86
|
+
C css/_base.scss
|
87
|
+
Updated to revision 113333.
|
88
|
+
" }
|
89
|
+
|
90
|
+
subject { test_mixin_host.new( runner_spy ) }
|
91
|
+
|
92
|
+
describe "#get_command_output" do
|
93
|
+
it "calls run_command" do
|
94
|
+
expect( runner_spy ).to receive( :run_command ).once
|
95
|
+
subject.get_command_output( 'test' )
|
96
|
+
end
|
97
|
+
|
98
|
+
it "passes :capture option to run_command" do
|
99
|
+
expect( runner_spy ).to receive( :run_command ).with( any_args, hash_including( capture: true ) )
|
100
|
+
subject.get_command_output( 'test' )
|
101
|
+
end
|
102
|
+
|
103
|
+
it "passes command to run_command" do
|
104
|
+
expect( runner_spy ).to receive( :run_command ).with( 'test', any_args )
|
105
|
+
subject.get_command_output( 'test' )
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
describe "#batch_add_files_to_git" do
|
110
|
+
it "calls run_command once for 10 filenames" do
|
111
|
+
expect( runner_spy ).to receive( :run_command ).exactly( 1 ).times
|
112
|
+
subject.batch_add_files_to_git( [ 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j' ] )
|
113
|
+
end
|
114
|
+
|
115
|
+
it "calls run_command twice for 11 filenames" do
|
116
|
+
expect( runner_spy ).to receive( :run_command ).exactly( 2 ).times
|
117
|
+
subject.batch_add_files_to_git( [ 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k' ] )
|
118
|
+
end
|
119
|
+
|
120
|
+
it "calls run_command 4 times for 3 filenames if a filename includes an error" do
|
121
|
+
expect( runner_spy ).to receive( :run_command ).exactly( 4 ).times
|
122
|
+
subject.batch_add_files_to_git( [ 'a', 'b', 'raise' ] )
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
describe "#add_files_to_git" do
|
127
|
+
it "calls run_command once for each filename" do
|
128
|
+
expect( runner_spy ).to receive( :run_command ).exactly( 3 ).times
|
129
|
+
subject.add_files_to_git( [ 'a', 'b', 'c' ] )
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
describe "#get_git_si_revision" do
|
134
|
+
it "calls git log command" do
|
135
|
+
expect( runner_spy ).to receive( :run_command ).with( /git log/, any_args )
|
136
|
+
subject.get_git_si_revision
|
137
|
+
end
|
138
|
+
|
139
|
+
it "returns the last svn revision logged in git" do
|
140
|
+
allow( subject ).to receive( :run_command ).and_return( "git-si 0.4.0 svn update to version 1011" )
|
141
|
+
expect( subject.get_git_si_revision ).to eq( '1011' )
|
142
|
+
end
|
143
|
+
end
|
144
|
+
|
145
|
+
describe "#get_svn_revision" do
|
146
|
+
it "calls svn info command" do
|
147
|
+
expect( runner_spy ).to receive( :run_command ).with( /svn info/, any_args )
|
148
|
+
subject.get_svn_revision
|
149
|
+
end
|
150
|
+
|
151
|
+
it "returns the current svn revision" do
|
152
|
+
allow( subject ).to receive( :run_command ).and_return( svn_info_output )
|
153
|
+
expect( subject.get_svn_revision ).to eq( '1012' )
|
154
|
+
end
|
155
|
+
end
|
156
|
+
|
157
|
+
describe "#get_svn_root" do
|
158
|
+
it "returns the svn root" do
|
159
|
+
allow( subject ).to receive( :run_command ).and_return( svn_info_output )
|
160
|
+
expect( subject.get_svn_root ).to eq( '/path/place' )
|
161
|
+
end
|
162
|
+
end
|
163
|
+
|
164
|
+
describe "#get_local_branch" do
|
165
|
+
it "returns the current branch name" do
|
166
|
+
data = "
|
167
|
+
MIRRORBRANCH
|
168
|
+
* master
|
169
|
+
"
|
170
|
+
allow( subject ).to receive( :run_command ).and_return( data )
|
171
|
+
expect( subject.get_local_branch ).to eq( 'master' )
|
172
|
+
end
|
173
|
+
end
|
174
|
+
|
175
|
+
describe "#do_revisions_differ" do
|
176
|
+
it "returns false if last logged svn revision is equal to current svn revision" do
|
177
|
+
allow( subject ).to receive( :run_command ).with( /svn info/, any_args ).and_return( svn_info_output )
|
178
|
+
allow( subject ).to receive( :run_command ).with( /git log/, any_args ).and_return( "svn update to version 1012" )
|
179
|
+
expect( subject.do_revisions_differ ).to be_falsey
|
180
|
+
end
|
181
|
+
|
182
|
+
it "raises an exception if last logged svn revision is less than current svn revision" do
|
183
|
+
allow( subject ).to receive( :run_command ).with( /svn info/, any_args ).and_return( svn_info_output )
|
184
|
+
allow( subject ).to receive( :run_command ).with( /git log/, any_args ).and_return( "svn update to version 1000" )
|
185
|
+
expect { subject.do_revisions_differ }.to raise_error
|
186
|
+
end
|
187
|
+
|
188
|
+
it "returns true if last logged svn revision is greater than current svn revision (if user says not to continue)" do
|
189
|
+
allow( subject ).to receive( :ask ).and_return( 'n' )
|
190
|
+
allow( subject ).to receive( :run_command ).with( /svn info/, any_args ).and_return( svn_info_output )
|
191
|
+
allow( subject ).to receive( :run_command ).with( /git log/, any_args ).and_return( "svn update to version 2000" )
|
192
|
+
expect( subject.do_revisions_differ ).to be_truthy
|
193
|
+
end
|
194
|
+
end
|
195
|
+
|
196
|
+
describe "#are_there_git_changes" do
|
197
|
+
it "returns true if there are git changes" do
|
198
|
+
data = "
|
199
|
+
M test1
|
200
|
+
"
|
201
|
+
allow( subject ).to receive( :run_command ).and_return( data )
|
202
|
+
expect( subject.are_there_git_changes? ).to be_truthy
|
203
|
+
end
|
204
|
+
|
205
|
+
it "returns false if there are no git changes" do
|
206
|
+
data = "
|
207
|
+
?? test1
|
208
|
+
"
|
209
|
+
allow( subject ).to receive( :run_command ).and_return( data )
|
210
|
+
expect( subject.are_there_git_changes? ).to be_falsey
|
211
|
+
end
|
212
|
+
end
|
213
|
+
|
214
|
+
describe "#create_git_repository" do
|
215
|
+
|
216
|
+
it "returns false if the repository already exists" do
|
217
|
+
allow( subject ).to receive( :did_last_command_succeed? ).and_return( true )
|
218
|
+
allow( File ).to receive( :exist? ).and_return( true )
|
219
|
+
expect( subject.create_git_repository ).to be_falsey
|
220
|
+
end
|
221
|
+
|
222
|
+
context "when the repository does not exist" do
|
223
|
+
|
224
|
+
before do
|
225
|
+
allow( File ).to receive( :exist? ).and_return( false )
|
226
|
+
end
|
227
|
+
|
228
|
+
it "returns true" do
|
229
|
+
expect( subject.create_git_repository ).to be_truthy
|
230
|
+
end
|
231
|
+
|
232
|
+
it "calls git init" do
|
233
|
+
expect( runner_spy ).to receive( :run_command ).with( /git init/, any_args )
|
234
|
+
subject.create_git_repository
|
235
|
+
end
|
236
|
+
|
237
|
+
it "calls add_all_svn_files" do
|
238
|
+
expect( subject ).to receive( :add_all_svn_files ).once
|
239
|
+
subject.create_git_repository
|
240
|
+
end
|
241
|
+
|
242
|
+
end
|
243
|
+
end
|
244
|
+
|
245
|
+
describe "#create_gitignore" do
|
246
|
+
before do
|
247
|
+
allow( subject ).to receive( :create_file )
|
248
|
+
allow( subject ).to receive( :append_to_file )
|
249
|
+
end
|
250
|
+
|
251
|
+
context "when the gitignore file does not exist" do
|
252
|
+
before do
|
253
|
+
allow( File ).to receive( :exist? ).and_return( false )
|
254
|
+
end
|
255
|
+
|
256
|
+
it "creates the file" do
|
257
|
+
expect( subject ).to receive( :create_file ).with( '.gitignore', /\*\.log/ )
|
258
|
+
subject.create_gitignore
|
259
|
+
end
|
260
|
+
|
261
|
+
it "returns true" do
|
262
|
+
expect( subject.create_gitignore ).to be_truthy
|
263
|
+
end
|
264
|
+
|
265
|
+
it "adds external repos to the file" do
|
266
|
+
data = "Z foobar
|
267
|
+
X foobar
|
268
|
+
M something else
|
269
|
+
? whatever
|
270
|
+
"
|
271
|
+
allow( subject ).to receive( :run_command ).and_return( data )
|
272
|
+
expect( subject ).to receive( :create_file ).with( '.gitignore', /foobar/ )
|
273
|
+
subject.create_gitignore
|
274
|
+
end
|
275
|
+
|
276
|
+
it "adds the file to git" do
|
277
|
+
expect( runner_spy ).to receive( :run_command ).with( /git add \.gitignore/, any_args ).once
|
278
|
+
subject.create_gitignore
|
279
|
+
end
|
280
|
+
end
|
281
|
+
|
282
|
+
context "when the gitignore file already exists" do
|
283
|
+
before do
|
284
|
+
allow( File ).to receive( :exist? ).and_return( true )
|
285
|
+
end
|
286
|
+
|
287
|
+
context "and there are lines missing" do
|
288
|
+
before do
|
289
|
+
data = ['.*', '*.config']
|
290
|
+
allow( File ).to receive( :readlines ).and_return( data )
|
291
|
+
allow( subject ).to receive( :yes? ).and_return( 'y' )
|
292
|
+
end
|
293
|
+
|
294
|
+
it "adds those lines to the file" do
|
295
|
+
expect( subject ).to receive( :append_to_file ).with( '.gitignore', /\*\.log/ )
|
296
|
+
subject.create_gitignore
|
297
|
+
end
|
298
|
+
|
299
|
+
it "returns true" do
|
300
|
+
expect( subject.create_gitignore ).to be_truthy
|
301
|
+
end
|
302
|
+
|
303
|
+
it "adds the file to git" do
|
304
|
+
expect( runner_spy ).to receive( :run_command ).with( /git add \.gitignore/, any_args ).once
|
305
|
+
subject.create_gitignore
|
306
|
+
end
|
307
|
+
end
|
308
|
+
|
309
|
+
context "and all lines are present in the file" do
|
310
|
+
before do
|
311
|
+
data = Git::Si::GitIgnore.ignore_patterns
|
312
|
+
allow( File ).to receive( :readlines ).and_return( data )
|
313
|
+
allow( subject ).to receive( :yes? ).and_return( 'y' )
|
314
|
+
end
|
315
|
+
|
316
|
+
it "returns false" do
|
317
|
+
expect( subject.create_gitignore ).to be_falsey
|
318
|
+
end
|
319
|
+
end
|
320
|
+
end
|
321
|
+
end
|
322
|
+
|
323
|
+
describe "#add_all_svn_files" do
|
324
|
+
it "adds all the svn files to git" do
|
325
|
+
data = "file1
|
326
|
+
file2
|
327
|
+
dir1/
|
328
|
+
dir1/file3
|
329
|
+
"
|
330
|
+
allow( subject ).to receive( :run_command ).and_return( data )
|
331
|
+
allow( subject ).to receive( :batch_add_files_to_git )
|
332
|
+
expect( subject ).to receive( :batch_add_files_to_git ).with( [ 'file1', 'file2', 'dir1/file3' ] )
|
333
|
+
subject.add_all_svn_files
|
334
|
+
end
|
335
|
+
end
|
336
|
+
|
337
|
+
describe "#create_mirror_branch" do
|
338
|
+
it "does not create the mirror branch if it already exists" do
|
339
|
+
expect( runner_spy ).not_to receive( :run_command ).with( /git branch \w+/, any_args )
|
340
|
+
subject.create_mirror_branch
|
341
|
+
end
|
342
|
+
|
343
|
+
it "creates the mirror branch if it does not exist" do
|
344
|
+
allow( subject ).to receive( :did_last_command_succeed? ).and_return( false )
|
345
|
+
expect( runner_spy ).to receive( :run_command ).with( /git branch \w+/, any_args )
|
346
|
+
subject.create_mirror_branch
|
347
|
+
end
|
348
|
+
end
|
349
|
+
|
350
|
+
describe "#stash_local_changes" do
|
351
|
+
it "does not call stash_command if there are no changes" do
|
352
|
+
allow( subject ).to receive( :are_there_git_changes? ).and_return( false )
|
353
|
+
expect( runner_spy ).not_to receive( :run_command ).with( /git stash/, any_args )
|
354
|
+
subject.stash_local_changes
|
355
|
+
end
|
356
|
+
|
357
|
+
it "calls the stash_command if there are changes" do
|
358
|
+
allow( subject ).to receive( :are_there_git_changes? ).and_return( true )
|
359
|
+
expect( runner_spy ).to receive( :run_command ).with( /git stash/, any_args )
|
360
|
+
subject.stash_local_changes
|
361
|
+
end
|
362
|
+
|
363
|
+
it "returns true if there are changes" do
|
364
|
+
allow( subject ).to receive( :are_there_git_changes? ).and_return( true )
|
365
|
+
expect( subject.stash_local_changes ).to eq( true )
|
366
|
+
end
|
367
|
+
|
368
|
+
it "returns false if there are no changes" do
|
369
|
+
allow( subject ).to receive( :are_there_git_changes? ).and_return( false )
|
370
|
+
expect( subject.stash_local_changes ).to eq( false )
|
371
|
+
end
|
372
|
+
end
|
373
|
+
|
374
|
+
describe "#unstash_local_changes" do
|
375
|
+
it "does not call unstash_command if there are no changes" do
|
376
|
+
expect( runner_spy ).not_to receive( :run_command ).with( /git stash/, any_args )
|
377
|
+
subject.unstash_local_changes( false )
|
378
|
+
end
|
379
|
+
|
380
|
+
it "calls the unstash_command if there are changes" do
|
381
|
+
expect( runner_spy ).to receive( :run_command ).with( /git stash/, any_args )
|
382
|
+
subject.unstash_local_changes( true )
|
383
|
+
end
|
384
|
+
end
|
385
|
+
|
386
|
+
describe "#revert_files_to_svn_update" do
|
387
|
+
before do
|
388
|
+
allow( subject ).to receive( :run_command )
|
389
|
+
end
|
390
|
+
|
391
|
+
it "runs the revert command for all files" do
|
392
|
+
expect( subject ).to receive( :run_command ).with( /svn revert -R \./ )
|
393
|
+
subject.revert_files_to_svn_update( svn_update_output )
|
394
|
+
end
|
395
|
+
|
396
|
+
it "runs the revert command for every conflicted file in the input string" do
|
397
|
+
expect( subject ).to receive( :run_command ).with( /svn revert/ ).exactly( 4 ).times
|
398
|
+
subject.revert_files_to_svn_update( svn_update_output )
|
399
|
+
end
|
400
|
+
end
|
401
|
+
|
402
|
+
describe "#delete_files_after_svn_update" do
|
403
|
+
before do
|
404
|
+
allow( subject ).to receive( :run_command )
|
405
|
+
end
|
406
|
+
|
407
|
+
it "runs the delete command for every deleted file in the input string" do
|
408
|
+
expect( subject ).to receive( :run_command ).with( /git rm/ ).exactly( 2 ).times
|
409
|
+
subject.delete_files_after_svn_update( svn_update_output )
|
410
|
+
end
|
411
|
+
end
|
412
|
+
|
413
|
+
describe "#add_files_after_svn_update" do
|
414
|
+
before do
|
415
|
+
allow( subject ).to receive( :run_command )
|
416
|
+
end
|
417
|
+
|
418
|
+
it "runs the add command for every updated file in the input string" do
|
419
|
+
expect( subject ).to receive( :batch_add_files_to_git ).with( [ 'bin/tests/importantthing', 'bin/tests/foobar', 'bin/tests/api/goobar', 'bin/tests/api/special', 'bin/tests/api/anotherfile', 'bin/tests/barfoo', 'something/newjs.js' ] )
|
420
|
+
subject.add_files_after_svn_update( svn_update_output )
|
421
|
+
end
|
422
|
+
end
|
423
|
+
|
424
|
+
describe "#delete_committed_branch" do
|
425
|
+
before do
|
426
|
+
allow( subject ).to receive( :do_rebase_action )
|
427
|
+
end
|
428
|
+
|
429
|
+
it "checks out the master branch" do
|
430
|
+
expect( runner_spy ).to receive( :run_command ).with( /git checkout master/, any_args )
|
431
|
+
subject.delete_committed_branch( 'foobar' )
|
432
|
+
end
|
433
|
+
|
434
|
+
it "rebases onto the mirror branch" do
|
435
|
+
expect( subject ).to receive( :do_rebase_action ).once
|
436
|
+
subject.delete_committed_branch( 'foobar' )
|
437
|
+
end
|
438
|
+
|
439
|
+
it "deletes the passed branch" do
|
440
|
+
expect( runner_spy ).to receive( :run_command ).with( /git branch -D.+foobar/, any_args )
|
441
|
+
subject.delete_committed_branch( 'foobar' )
|
442
|
+
end
|
443
|
+
end
|
444
|
+
|
445
|
+
describe "#is_file_in_git?" do
|
446
|
+
it "returns true if the file is listed by git" do
|
447
|
+
allow( subject ).to receive( :run_command ).with( /git ls-files.+foobar/, any_args ).and_return( 'foobar' )
|
448
|
+
expect( subject.is_file_in_git?( 'foobar' ) ).to be_truthy
|
449
|
+
end
|
450
|
+
|
451
|
+
it "returns false if the file is not listed by git" do
|
452
|
+
allow( subject ).to receive( :run_command ).with( /git ls-files.+foobar/, any_args ).and_return( '' )
|
453
|
+
expect( subject.is_file_in_git?( 'foobar' ) ).to be_falsey
|
454
|
+
end
|
455
|
+
end
|
456
|
+
|
457
|
+
end
|
458
|
+
|