forked from thoughtbot/appraisal
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Allow commands with spaces to be constructed as new Commands
If you were using the `appraisal` executable and passed an argument that contained spaces, those spaces would not be preserved when Appraisal went to execute the full command. For instance, this command... appraisal 4.2 rspec spec/some/file_spec.rb -e "some example group" *Should* be expanded as follows: BUNDLE_GEMFILE=$PWD/gemfiles/4.2.gemfile rspec spec/some/file_spec.rb -e "some example group" ...but before this commit would be incorrectly expanded as follows: BUNDLE_GEMFILE=$PWD/gemfiles/4.2.gemfile rspec spec/some/file_spec.rb -e some example group Close thoughtbot#86
- Loading branch information
Showing
4 changed files
with
64 additions
and
28 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,66 +1,85 @@ | ||
require "shellwords" | ||
|
||
module Appraisal | ||
# Executes commands with a clean environment | ||
class Command | ||
BUNDLER_ENV_VARS = %w(RUBYOPT BUNDLE_PATH BUNDLE_BIN_PATH BUNDLE_GEMFILE).freeze | ||
|
||
def self.from_args(gemfile) | ||
ARGV.shift | ||
command = ([$0] + ARGV).join(' ') | ||
new(command, gemfile) | ||
end | ||
attr_reader :command, :env, :gemfile, :original_env | ||
|
||
def initialize(command, gemfile = nil) | ||
def initialize(command, options = {}) | ||
@gemfile = options[:gemfile] | ||
@env = options.fetch(:env, {}) | ||
@command = command_starting_with_bundle(command) | ||
@original_env = {} | ||
@gemfile = gemfile | ||
if command =~ /^(bundle|BUNDLE_GEMFILE)/ | ||
@command = command | ||
else | ||
@command = "bundle exec #{command}" | ||
end | ||
end | ||
|
||
def run | ||
announce | ||
with_clean_env do | ||
unless Kernel.system(@command) | ||
unless Kernel.system(env, command_as_string) | ||
exit(1) | ||
end | ||
end | ||
end | ||
|
||
def exec | ||
announce | ||
with_clean_env { Kernel.exec(@command) } | ||
with_clean_env { Kernel.exec(env, command_as_string) } | ||
end | ||
|
||
private | ||
|
||
def with_clean_env | ||
unset_bundler_env_vars | ||
ENV['BUNDLE_GEMFILE'] = @gemfile | ||
ENV['BUNDLE_GEMFILE'] = gemfile | ||
ENV['APPRAISAL_INITIALIZED'] = '1' | ||
yield | ||
ensure | ||
restore_env | ||
end | ||
|
||
def announce | ||
if @gemfile | ||
puts ">> BUNDLE_GEMFILE=#{@gemfile} #{@command}" | ||
if gemfile | ||
puts ">> BUNDLE_GEMFILE=#{gemfile} #{command_as_string}" | ||
else | ||
puts ">> #{@command}" | ||
puts ">> #{command_as_string}" | ||
end | ||
end | ||
|
||
def unset_bundler_env_vars | ||
BUNDLER_ENV_VARS.each do |key| | ||
@original_env[key] = ENV[key] | ||
original_env[key] = ENV[key] | ||
ENV[key] = nil | ||
end | ||
end | ||
|
||
def restore_env | ||
@original_env.each { |key, value| ENV[key] = value } | ||
original_env.each { |key, value| ENV[key] = value } | ||
end | ||
|
||
def command_starts_with_bundle?(original_command) | ||
if original_command.is_a?(Array) | ||
original_command.first =~ /^bundle/ | ||
else | ||
original_command =~ /^bundle/ | ||
end | ||
end | ||
|
||
def command_starting_with_bundle(original_command) | ||
if command_starts_with_bundle?(original_command) | ||
original_command | ||
else | ||
%w(bundle exec) + original_command | ||
end | ||
end | ||
|
||
def command_as_string | ||
if command.is_a?(Array) | ||
Shellwords.join(command) | ||
else | ||
command | ||
end | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters