Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Limit calls to Dir.chdir in Rake::Application #365

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
76 changes: 37 additions & 39 deletions lib/rake/application.rb
Original file line number Diff line number Diff line change
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 @@ -676,45 +669,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 @@ -723,6 +708,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 @@ -778,6 +768,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
Original file line number Diff line number Diff line change
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