Skip to content

Commit 9ddc4ec

Browse files
authored
Merge pull request #605 from y-yagi/add_merge_action_to_file_collision
Add `merge` action to file colision menu
2 parents 73d41eb + 91229e4 commit 9ddc4ec

File tree

3 files changed

+60
-5
lines changed

3 files changed

+60
-5
lines changed

lib/thor/shell/basic.rb

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -247,11 +247,11 @@ def print_wrapped(message, options = {})
247247
#
248248
# ==== Parameters
249249
# destination<String>:: the destination file to solve conflicts
250-
# block<Proc>:: an optional block that returns the value to be used in diff
250+
# block<Proc>:: an optional block that returns the value to be used in diff and merge
251251
#
252252
def file_collision(destination)
253253
return true if @always_force
254-
options = block_given? ? "[Ynaqdh]" : "[Ynaqh]"
254+
options = block_given? ? "[Ynaqdhm]" : "[Ynaqh]"
255255

256256
loop do
257257
answer = ask(
@@ -275,6 +275,13 @@ def file_collision(destination)
275275
when is?(:diff)
276276
show_diff(destination, yield) if block_given?
277277
say "Retrying..."
278+
when is?(:merge)
279+
if block_given? && !merge_tool.empty?
280+
merge(destination, yield)
281+
return nil
282+
end
283+
284+
say "Please specify merge tool to `THOR_MERGE` env."
278285
else
279286
say file_collision_help
280287
end
@@ -352,6 +359,7 @@ def file_collision_help #:nodoc:
352359
q - quit, abort
353360
d - diff, show the differences between the old and the new
354361
h - help, show this help
362+
m - merge, run merge tool
355363
HELP
356364
end
357365

@@ -440,6 +448,23 @@ def ask_filtered(statement, color, options)
440448
end
441449
correct_answer
442450
end
451+
452+
def merge(destination, content) #:nodoc:
453+
require "tempfile"
454+
Tempfile.open([File.basename(destination), File.extname(destination)], File.dirname(destination)) do |temp|
455+
temp.write content
456+
temp.rewind
457+
system %(#{merge_tool} "#{temp.path}" "#{destination}")
458+
end
459+
end
460+
461+
def merge_tool #:nodoc:
462+
@merge_tool ||= ENV["THOR_MERGE"] || git_merge_tool
463+
end
464+
465+
def git_merge_tool #:nodoc:
466+
`git config merge.tool`.rstrip rescue ""
467+
end
443468
end
444469
end
445470
end

spec/actions/create_file_spec.rb

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ def silence!
104104
it "shows conflict status to the user" do
105105
file = File.join(destination_root, "doc/config.rb")
106106
expect(create_file("doc/config.rb")).not_to be_identical
107-
expect(Thor::LineEditor).to receive(:readline).with("Overwrite #{file}? (enter \"h\" for help) [Ynaqdh] ", anything).and_return("s")
107+
expect(Thor::LineEditor).to receive(:readline).with("Overwrite #{file}? (enter \"h\" for help) [Ynaqdhm] ", anything).and_return("s")
108108

109109
content = invoke!
110110
expect(content).to match(%r{conflict doc/config\.rb})
@@ -129,6 +129,14 @@ def silence!
129129
expect(@base.shell).to receive(:system).with(/diff -u/)
130130
invoke!
131131
end
132+
133+
it "executes the block given to run merge tool" do
134+
create_file("doc/config.rb")
135+
allow(@base.shell).to receive(:merge_tool).and_return("meld")
136+
expect(Thor::LineEditor).to receive(:readline).and_return("m")
137+
expect(@base.shell).to receive(:system).with(/meld/)
138+
invoke!
139+
end
132140
end
133141
end
134142

spec/shell/basic_spec.rb

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -356,8 +356,8 @@ def #456 Lanç...
356356
end
357357

358358
describe "when a block is given" do
359-
it "displays diff options to the user" do
360-
expect(Thor::LineEditor).to receive(:readline).with('Overwrite foo? (enter "h" for help) [Ynaqdh] ', :add_to_history => false).and_return("s")
359+
it "displays diff and merge options to the user" do
360+
expect(Thor::LineEditor).to receive(:readline).with('Overwrite foo? (enter "h" for help) [Ynaqdhm] ', :add_to_history => false).and_return("s")
361361
shell.file_collision("foo") {}
362362
end
363363

@@ -367,6 +367,28 @@ def #456 Lanç...
367367
expect(shell).to receive(:system).with(/diff -u/)
368368
capture(:stdout) { shell.file_collision("foo") {} }
369369
end
370+
371+
it "invokes the merge tool" do
372+
allow(shell).to receive(:merge_tool).and_return("meld")
373+
expect(Thor::LineEditor).to receive(:readline).and_return("m")
374+
expect(shell).to receive(:system).with(/meld/)
375+
capture(:stdout) { shell.file_collision("foo") {} }
376+
end
377+
378+
it "invokes the merge tool that specified at ENV['THOR_MERGE']" do
379+
allow(ENV).to receive(:[]).with("THOR_MERGE").and_return("meld")
380+
expect(Thor::LineEditor).to receive(:readline).and_return("m")
381+
expect(shell).to receive(:system).with(/meld/)
382+
capture(:stdout) { shell.file_collision("foo") {} }
383+
end
384+
385+
it "show warning if user chooses merge but merge tool is not specified" do
386+
allow(shell).to receive(:merge_tool).and_return("")
387+
expect(Thor::LineEditor).to receive(:readline).and_return("m")
388+
expect(Thor::LineEditor).to receive(:readline).and_return("n")
389+
help = capture(:stdout) { shell.file_collision("foo") {} }
390+
expect(help).to match(/Please specify merge tool to `THOR_MERGE` env/)
391+
end
370392
end
371393
end
372394
end

0 commit comments

Comments
 (0)