diff --git a/lib/homesick.rb b/lib/homesick.rb index 7b722ed..288ee22 100644 --- a/lib/homesick.rb +++ b/lib/homesick.rb @@ -277,6 +277,25 @@ class Homesick < Thor end end + desc 'exec CASTLE COMMAND', + 'Execute a single shell command inside the root of a castle' + def exec(castle, *args) + check_castle_existance castle, 'exec' + unless args.count > 0 + say_status :error, + 'You must pass a shell command to execute', + :red + exit(1) + end + full_command = args.join(' ') + say_status "exec '#{full_command}'", + "Executing command '#{full_command}' in castle '#{castle}'", + :green + inside repos_dir.join(castle) do + system(full_command) + end + end + desc 'version', 'Display the current version of homesick' def version say Homesick::Version::STRING diff --git a/spec/homesick_spec.rb b/spec/homesick_spec.rb index 962f234..9804746 100644 --- a/spec/homesick_spec.rb +++ b/spec/homesick_spec.rb @@ -436,7 +436,7 @@ describe 'homesick' do it 'prints an error message when trying to pull a non-existant castle' do expect(homesick).to receive('say_status').once .with(:error, - %r{Could not pull castle_repo, expected .* exist and contain dotfiles}, + /Could not pull castle_repo, expected .* exist and contain dotfiles/, :red) expect { homesick.pull 'castle_repo' }.to raise_error(SystemExit) end @@ -468,7 +468,7 @@ describe 'homesick' do it 'prints an error message when trying to push a non-existant castle' do expect(homesick).to receive('say_status').once .with(:error, - %r{Could not push castle_repo, expected .* exist and contain dotfiles}, + /Could not push castle_repo, expected .* exist and contain dotfiles/, :red) expect { homesick.push 'castle_repo' }.to raise_error(SystemExit) end @@ -629,7 +629,7 @@ describe 'homesick' do it 'returns an error message when the given castle does not exist' do expect(homesick).to receive('say_status').once .with(:error, - %r{Could not cd castle_repo, expected .* exist and contain dotfiles}, + /Could not cd castle_repo, expected .* exist and contain dotfiles/, :red) expect { homesick.cd 'castle_repo' }.to raise_error(SystemExit) end @@ -662,7 +662,7 @@ describe 'homesick' do allow(ENV).to receive(:[]).with('EDITOR').and_return('vim') expect(homesick).to receive('say_status').once .with(:error, - %r{Could not open castle_repo, expected .* exist and contain dotfiles}, + /Could not open castle_repo, expected .* exist and contain dotfiles/, :red) expect { homesick.open 'castle_repo' }.to raise_error(SystemExit) end @@ -674,4 +674,38 @@ describe 'homesick' do expect(text.chomp).to match(/\d+\.\d+\.\d+/) end end + + describe 'exec' do + it 'executes a single command with no 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 + .with(be_a(String), + be_a(String), + :green) + expect(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 + .with(be_a(String), + be_a(String), + :green) + expect(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 + .with(:error, + be_a(String), + :red) + expect(homesick).to receive('exit').once.with(1) + Capture.stdout { homesick.exec 'castle_repo' } + end + end end