From efea18327b22f24a91d45675bb5d457eec81ee96 Mon Sep 17 00:00:00 2001 From: Jeremy Cook Date: Sat, 12 Apr 2014 15:39:51 -0400 Subject: [PATCH] Added options for exec command and a new exec_all command. --- lib/homesick.rb | 46 +++++++++++++++++-- spec/homesick_spec.rb | 100 +++++++++++++++++++++++++++++++++++++----- 2 files changed, 130 insertions(+), 16 deletions(-) diff --git a/lib/homesick.rb b/lib/homesick.rb index 288ee22..e2abdb1 100644 --- a/lib/homesick.rb +++ b/lib/homesick.rb @@ -279,6 +279,16 @@ class Homesick < Thor desc 'exec CASTLE COMMAND', 'Execute a single shell command inside the root of a castle' + method_option :pretend, + type: :boolean, + default: false, + required: false, + desc: 'Perform a dry run of the command' + method_option :quiet, + type: :boolean, + default: false, + required: false, + desc: 'Run a command without any output from Homesick' def exec(castle, *args) check_castle_existance castle, 'exec' unless args.count > 0 @@ -289,10 +299,38 @@ class Homesick < Thor end full_command = args.join(' ') say_status "exec '#{full_command}'", - "Executing command '#{full_command}' in castle '#{castle}'", - :green + "#{options[:pretend] ? 'Would execute' : 'Executing command'} '#{full_command}' in castle '#{castle}'", + :green unless options[:quiet] inside repos_dir.join(castle) do - system(full_command) + system(full_command) unless options[:pretend] + end + end + + desc 'exec_all COMMAND', + 'Execute a single shell command inside the root of every cloned castle' + method_option :pretend, + type: :boolean, + default: false, + required: false, + desc: 'Perform a dry run of the command' + method_option :quiet, + type: :boolean, + default: false, + required: false, + desc: 'Run a command without any output from Homesick' + def exec_all(*args) + unless args.count > 0 + say_status :error, + 'You must pass a shell command to execute', + :red + exit(1) + end + full_command = args.join(' ') + inside_each_castle do |castle| + say_status "exec '#{full_command}'", + "#{options[:pretend] ? 'Would execute' : 'Executing command'} '#{full_command}' in castle '#{castle}'", + :green unless options[:quiet] + system(full_command) unless options[:pretend] end end @@ -386,7 +424,7 @@ class Homesick < Thor subdir_filepath = subdir_file(castle) File.open(subdir_filepath, 'a+') do |subdir| subdir.puts path unless subdir.readlines.reduce(false) do |memo, line| - line.eql?("#{path.to_s}\n") || memo + line.eql?("#{path}\n") || memo end end diff --git a/spec/homesick_spec.rb b/spec/homesick_spec.rb index 9804746..26657d6 100644 --- a/spec/homesick_spec.rb +++ b/spec/homesick_spec.rb @@ -660,7 +660,7 @@ describe 'homesick' do it 'returns an error message when the given castle does not exist' do # Set a default just in case none is set allow(ENV).to receive(:[]).with('EDITOR').and_return('vim') - expect(homesick).to receive('say_status').once + allow(homesick).to receive('say_status').once .with(:error, /Could not open castle_repo, expected .* exist and contain dotfiles/, :red) @@ -676,36 +676,112 @@ describe 'homesick' do end describe 'exec' do - it 'executes a single command with no arguments inside a given castle' do + before do given_castle 'castle_repo' - expect(homesick).to receive('inside').once.with(kind_of(Pathname)).and_yield - expect(homesick).to receive('say_status').once + end + it 'executes a single command with no arguments inside a given castle' do + allow(homesick).to receive('inside').once.with(kind_of(Pathname)).and_yield + allow(homesick).to receive('say_status').once .with(be_a(String), be_a(String), :green) - expect(homesick).to receive('system').once.with('ls') + allow(homesick).to receive('system').once.with('ls') Capture.stdout { homesick.exec 'castle_repo', 'ls' } end it 'executes a single command with arguments inside a given castle' do - given_castle 'castle_repo' - expect(homesick).to receive('inside').once.with(kind_of(Pathname)).and_yield - expect(homesick).to receive('say_status').once + allow(homesick).to receive('inside').once.with(kind_of(Pathname)).and_yield + allow(homesick).to receive('say_status').once .with(be_a(String), be_a(String), :green) - expect(homesick).to receive('system').once.with('ls -la') + allow(homesick).to receive('system').once.with('ls -la') Capture.stdout { homesick.exec 'castle_repo', 'ls', '-la' } end it 'raises an error when the method is called without a command' do - given_castle 'castle_repo' - expect(homesick).to receive('say_status').once + allow(homesick).to receive('say_status').once .with(:error, be_a(String), :red) - expect(homesick).to receive('exit').once.with(1) + allow(homesick).to receive('exit').once.with(1) Capture.stdout { homesick.exec 'castle_repo' } end + + context 'pretend' do + it 'does not execute a command when the pretend option is passed' do + allow(homesick).to receive('say_status').once + .with(be_a(String), + match(/.*Would execute.*/), + :green) + expect(homesick).to receive('system').never + Capture.stdout { homesick.invoke 'exec', %w(castle_repo ls -la), pretend: true } + end + end + + context 'quiet' do + it 'does not print status information when quiet is passed' do + expect(homesick).to receive('say_status').never + allow(homesick).to receive('system').once + .with('ls -la') + Capture.stdout { homesick.invoke 'exec', %w(castle_repo ls -la), quiet: true } + end + end + end + + describe 'exec_all' do + before do + given_castle 'castle_repo' + given_castle 'another_castle_repo' + end + + it 'executes a command without arguments inside the root of each cloned castle' do + allow(homesick).to receive('inside_each_castle').exactly(:twice).and_yield('castle_repo').and_yield('another_castle_repo') + allow(homesick).to receive('say_status').at_least(:once) + .with(be_a(String), + be_a(String), + :green) + allow(homesick).to receive('system').at_least(:once).with('ls') + Capture.stdout { homesick.exec_all 'ls' } + end + + it 'executes a command with arguments inside the root of each cloned castle' do + allow(homesick).to receive('inside_each_castle').exactly(:twice).and_yield('castle_repo').and_yield('another_castle_repo') + allow(homesick).to receive('say_status').at_least(:once) + .with(be_a(String), + be_a(String), + :green) + allow(homesick).to receive('system').at_least(:once).with('ls -la') + Capture.stdout { homesick.exec_all 'ls', '-la' } + end + + it 'raises an error when the method is called without a command' do + allow(homesick).to receive('say_status').once + .with(:error, + be_a(String), + :red) + allow(homesick).to receive('exit').once.with(1) + Capture.stdout { homesick.exec_all } + end + + context 'pretend' do + it 'does not execute a command when the pretend option is passed' do + allow(homesick).to receive('say_status').at_least(:once) + .with(be_a(String), + match(/.*Would execute.*/), + :green) + expect(homesick).to receive('system').never + Capture.stdout { homesick.invoke 'exec_all', %w(ls -la), pretend: true } + end + end + + context 'quiet' do + it 'does not print status information when quiet is passed' do + expect(homesick).to receive('say_status').never + allow(homesick).to receive('system').at_least(:once) + .with('ls -la') + Capture.stdout { homesick.invoke 'exec_all', %w(ls -la), quiet: true } + end + end end end