Skip to content

Commit

Permalink
Limit calls to Dir.chdir in Rake::Application
Browse files Browse the repository at this point in the history
This reduces "conflicting chdir during another chdir block" warnings
when calling `Rake::Application#run` inside a `Dir.chdir` block.
  • Loading branch information
jonathanhefner committed Dec 26, 2020
1 parent c2eeae2 commit 856409f
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 39 deletions.
76 changes: 37 additions & 39 deletions lib/rake/application.rb
Expand Up @@ -269,18 +269,11 @@ def has_chain?(exception) # :nodoc:
end
private :has_chain?

# True if one of the files in RAKEFILES is in the current directory.
# If a match is found, it is copied into @rakefile.
def have_rakefile # :nodoc:
@rakefiles.each do |fn|
if File.exist?(fn)
others = FileList.glob(fn, File::FNM_CASEFOLD)
return others.size == 1 ? others.first : fn
elsif fn == ""
return fn
end
# Returns first filename from @rakefiles that exists in the specified dir.
def have_rakefile(dir = Dir.pwd) # :nodoc:
Dir.chdir(dir) do
Dir.glob(@rakefiles.map { |name| escape_for_glob(name) }).first || @rakefiles.find(&:empty?)
end
return nil
end

# True if we are outputting to TTY, false otherwise
Expand Down Expand Up @@ -669,45 +662,37 @@ def rake_require(file_name, paths=$LOAD_PATH, loaded=$") # :nodoc:
end

def find_rakefile_location # :nodoc:
here = Dir.pwd
until (fn = have_rakefile)
Dir.chdir("..")
return nil if Dir.pwd == here || options.nosearch
here = Dir.pwd
previous_dir, current_dir = nil, original_dir
until (rakefile = have_rakefile(current_dir)) || current_dir == previous_dir
break if options.nosearch
previous_dir, current_dir = current_dir, File.expand_path("..", current_dir)
end
[fn, here]
ensure
Dir.chdir(Rake.original_dir)
[rakefile, current_dir] if rakefile
end

def print_rakefile_directory(location) # :nodoc:
$stderr.puts "(in #{Dir.pwd})" unless
options.silent or original_dir == location
def print_rakefile_directory # :nodoc:
$stderr.puts "(in #{@rakefile_dir})" unless
options.silent || original_dir == @rakefile_dir
end

def raw_load_rakefile # :nodoc:
rakefile, location = find_rakefile_location
@rakefile, @rakefile_dir = find_rakefile_location

if (!options.ignore_system) &&
(options.load_system || rakefile.nil?) &&
(options.load_system || @rakefile.nil?) &&
system_dir && File.directory?(system_dir)
print_rakefile_directory(location)
glob("#{system_dir}/*.rake") do |name|
add_import name
end
print_rakefile_directory
add_globbed_imports(system_dir, "*.rake")
else
fail "No Rakefile found (looking for: #{@rakefiles.join(', ')})" if
rakefile.nil?
@rakefile = rakefile
Dir.chdir(location)
print_rakefile_directory(location)
Rake.load_rakefile(File.expand_path(@rakefile)) if
@rakefile && @rakefile != ""
options.rakelib.each do |rlib|
glob("#{rlib}/*.rake") do |name|
add_import name
end
fail "No Rakefile found (looking for: #{@rakefiles.join(", ")})" if @rakefile.nil?
Dir.chdir(@rakefile_dir) unless @rakefile_dir == Dir.pwd
print_rakefile_directory
Rake.load_rakefile(File.expand_path(@rakefile, @rakefile_dir)) unless @rakefile.empty?
options.rakelib.each do |rakelib|
add_globbed_imports(File.expand_path(rakelib, @rakefile_dir), "*.rake")
end
end

load_imports
end

Expand All @@ -716,6 +701,11 @@ def glob(path, &block) # :nodoc:
end
private :glob

def escape_for_glob(pattern)
pattern.tr("\\", "/").gsub(/[*?\[\]{}]/, "\\\\" + '\0')
end
private :escape_for_glob

# The directory path containing the system wide rakefiles.
def system_dir # :nodoc:
@system_dir ||=
Expand Down Expand Up @@ -771,6 +761,14 @@ def add_import(fn) # :nodoc:
@pending_imports << fn
end

# Globs "#{directory}/#{pattern}", and adds the results to the list
# of files to be imported.
def add_globbed_imports(directory, pattern) # :nodoc:
Dir.glob("#{escape_for_glob(directory).chomp("/")}/#{pattern}") do |path|
add_import path
end
end

# Load the pending list of imported files.
def load_imports # :nodoc:
while fn = @pending_imports.shift
Expand Down
14 changes: 14 additions & 0 deletions test/test_rake_application.rb
Expand Up @@ -240,6 +240,7 @@ def test_load_rakefile_doesnt_print_rakefile_directory_from_same_dir
def test_load_rakefile_from_subdir
rakefile_unittest
Dir.chdir "subdir"
@app = Rake::Application.new

@app.instance_eval do
handle_options []
Expand Down Expand Up @@ -439,6 +440,19 @@ def test_good_run
assert_equal "DEFAULT\n", out
end

def test_runs_in_rakefile_directory_from_subdir
rakefile_unittest
Dir.chdir "subdir"
@app = Rake::Application.new

pwd = nil
@app.define_task(Rake::Task, "default") { pwd = Dir.pwd }

@app.run %w[--silent]

assert_equal @tempdir, pwd
end

def test_display_task_run
ran = false
@app.last_description = "COMMENT"
Expand Down

0 comments on commit 856409f

Please sign in to comment.