Maintenance of Ruby 2.0.0 ended on February 24, 2016. Read more
Rake main application object. When invoking rake from the
command line, a Rake::Application object is
created and run.
Initialize a Rake::Application object.
# File rake/application.rb, line 41
def initialize
super
@name = 'rake'
@rakefiles = DEFAULT_RAKEFILES.dup
@rakefile = nil
@pending_imports = []
@imported = []
@loaders = {}
@default_loader = Rake::DefaultLoader.new
@original_dir = Dir.pwd
@top_level_tasks = []
add_loader('rb', DefaultLoader.new)
add_loader('rf', DefaultLoader.new)
add_loader('rake', DefaultLoader.new)
@tty_output = STDOUT.tty?
@terminal_columns = ENV['RAKE_COLUMNS'].to_i
end
Add a file to the list of files to be imported.
# File rake/application.rb, line 659
def add_import(fn)
@pending_imports << fn
end
Add a loader to handle imported files ending in the extension
ext.
# File rake/application.rb, line 123
def add_loader(ext, loader)
ext = ".#{ext}" unless ext =~ /^\./
@loaders[ext] = loader
end
Collect the list of tasks on the command line. If no tasks are given, return a list containing only the default task. Environmental assignments are processed at this time as well.
# File rake/application.rb, line 646
def collect_tasks
@top_level_tasks = []
ARGV.each do |arg|
if arg =~ /^(\w+)=(.*)$/
ENV[$1] = $2
else
@top_level_tasks << arg unless arg =~ /^-/
end
end
@top_level_tasks.push("default") if @top_level_tasks.size == 0
end
Warn about deprecated use of top level constant names.
# File rake/application.rb, line 678
def const_warning(const_name)
@const_warning ||= false
if ! @const_warning
$stderr.puts %{WARNING: Deprecated reference to top-level constant '#{const_name}' } +
%{found at: #{rakefile_location}} # '
$stderr.puts %{ Use --classic-namespace on rake command}
$stderr.puts %{ or 'require "rake/classic_namespace"' in Rakefile}
end
@const_warning = true
end
Warn about deprecated usage.
Example:
Rake.application.deprecate("import", "Rake.import", caller.first)
# File rake/application.rb, line 192
def deprecate(old_usage, new_usage, call_site)
return if options.ignore_deprecate
$stderr.puts "WARNING: '#{old_usage}' is deprecated. " +
"Please use '#{new_usage}' instead.\n" +
" at #{call_site}"
end
Display the error message that caused the exception.
# File rake/application.rb, line 175
def display_error_message(ex)
trace "#{name} aborted!"
trace ex.message
if options.backtrace
trace ex.backtrace.join("\n")
else
trace Backtrace.collapse(ex.backtrace).join("\n")
end
trace "Tasks: #{ex.chain}" if has_chain?(ex)
trace "(See full trace by running task with --trace)" unless options.backtrace
end
Display the tasks and prerequisites
# File rake/application.rb, line 312
def display_prerequisites
tasks.each do |t|
puts "#{name} #{t.name}"
t.prerequisites.each { |pre| puts " #{pre}" }
end
end
Display the tasks and comments.
# File rake/application.rb, line 236
def display_tasks_and_comments
displayable_tasks = tasks.select { |t|
(options.show_all_tasks || t.comment) && t.name =~ options.show_task_pattern
}
case options.show_tasks
when :tasks
width = displayable_tasks.collect { |t| t.name_with_args.length }.max || 10
max_column = truncate_output? ? terminal_width - name.size - width - 7 : nil
displayable_tasks.each do |t|
printf "#{name} %-#{width}s # %s\n",
t.name_with_args, max_column ? truncate(t.comment, max_column) : t.comment
end
when :describe
displayable_tasks.each do |t|
puts "#{name} #{t.name_with_args}"
comment = t.full_comment || ""
comment.split("\n").each do |line|
puts " #{line}"
end
puts
end
when :lines
displayable_tasks.each do |t|
t.locations.each do |loc|
printf "#{name} %-30s %s\n",t.name_with_args, loc
end
end
else
fail "Unknown show task mode: '#{options.show_tasks}'"
end
end
Calculate the dynamic width of the
# File rake/application.rb, line 281
def dynamic_width
@dynamic_width ||= (dynamic_width_stty.nonzero? || dynamic_width_tput)
end
# File rake/application.rb, line 285
def dynamic_width_stty
%x{stty size 2>/dev/null}.split[1].to_i
end
# File rake/application.rb, line 289
def dynamic_width_tput
%x{tput cols 2>/dev/null}.to_i
end
# File rake/application.rb, line 569
def find_rakefile_location
here = Dir.pwd
while ! (fn = have_rakefile)
Dir.chdir("..")
if Dir.pwd == here || options.nosearch
return nil
end
here = Dir.pwd
end
[fn, here]
ensure
Dir.chdir(Rake.original_dir)
end
Read and handle the command line options.
# File rake/application.rb, line 524
def handle_options
options.rakelib = ['rakelib']
options.trace_output = $stderr
OptionParser.new do |opts|
opts.banner = "rake [-f rakefile] {options} targets..."
opts.separator ""
opts.separator "Options are ..."
opts.on_tail("-h", "--help", "-H", "Display this help message.") do
puts opts
exit
end
standard_rake_options.each { |args| opts.on(*args) }
opts.environment('RAKEOPT')
end.parse!
# If class namespaces are requested, set the global options
# according to the values in the options structure.
if options.classic_namespace
$show_tasks = options.show_tasks
$show_prereqs = options.show_prereqs
$trace = options.trace
$dryrun = options.dryrun
$silent = options.silent
end
end
True if one of the files in RAKEFILES is in the current directory. If a match is found, it is copied into @rakefile.
# File rake/application.rb, line 207
def have_rakefile
@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
end
return nil
end
Initialize the command line parameters and app name.
# File rake/application.rb, line 78
def init(app_name='rake')
standard_exception_handling do
@name = app_name
handle_options
collect_tasks
end
end
private —————————————————————-
# File rake/application.rb, line 140
def invoke_task(task_string)
name, args = parse_task_string(task_string)
t = self[name]
t.invoke(*args)
end
Load the pending list of imported files.
# File rake/application.rb, line 664
def load_imports
while fn = @pending_imports.shift
next if @imported.member?(fn)
if fn_task = lookup(fn)
fn_task.invoke
end
ext = File.extname(fn)
loader = @loaders[ext] || @default_loader
loader.load(fn)
@imported << fn
end
end
Find the rakefile and then load it and any pending imports.
# File rake/application.rb, line 87
def load_rakefile
standard_exception_handling do
raw_load_rakefile
end
end
Application options from the command line
# File rake/application.rb, line 129
def options
@options ||= OpenStruct.new
end
# File rake/application.rb, line 146
def parse_task_string(string)
if string =~ /^([^\[]+)(\[(.*)\])$/
name = $1
args = $3.split(/\s*,\s*/)
else
name = string
args = []
end
[name, args]
end
# File rake/application.rb, line 583
def print_rakefile_directory(location)
$stderr.puts "(in #{Dir.pwd})" unless
options.silent or original_dir == location
end
Similar to the regular Ruby require command, but will check
for *.rake files in addition to *.rb files.
# File rake/application.rb, line 555
def rake_require(file_name, paths=$LOAD_PATH, loaded=$")
fn = file_name + ".rake"
return false if loaded.include?(fn)
paths.each do |path|
full_path = File.join(path, fn)
if File.exist?(full_path)
Rake.load_rakefile(full_path)
loaded << fn
return true
end
end
fail LoadError, "Can't find #{file_name}"
end
# File rake/application.rb, line 689
def rakefile_location(backtrace=caller)
backtrace.map { |t| t[/([^:]+):/,1] }
re = /^#{@rakefile}$/
re = /#{re.source}/i if windows?
backtrace.find { |str| str =~ re } || ''
end
Run the Rake application. The run method performs the following three steps:
Initialize the command line options (init).
Define the tasks (load_rakefile).
Run the top level tasks (top_level).
If you wish to build a custom rake command, you should call
init on your application. Then define any tasks. Finally,
call top_level to run your top level tasks.
# File rake/application.rb, line 69
def run
standard_exception_handling do
init
load_rakefile
top_level
end
end
Run the given block with the thread startup and shutdown.
# File rake/application.rb, line 107
def run_with_threads
thread_pool.gather_history if options.job_stats == :history
yield
thread_pool.join
if options.job_stats
stats = thread_pool.statistics
puts "Maximum active threads: #{stats[:max_active_threads]}"
puts "Total threads in play: #{stats[:total_threads_in_play]}"
end
ThreadHistoryDisplay.new(thread_pool.history).show if options.job_stats == :history
end
Provide standard exception handling for the given block.
# File rake/application.rb, line 158
def standard_exception_handling
begin
yield
rescue SystemExit => ex
# Exit silently with current status
raise
rescue OptionParser::InvalidOption => ex
$stderr.puts ex.message
exit(false)
rescue Exception => ex
# Exit with error message
display_error_message(ex)
exit(false)
end
end
A list of all the standard options used in rake, suitable for passing to OptionParser.
# File rake/application.rb, line 333
def standard_rake_options
sort_options(
[
['--all', '-A', "Show all tasks, even uncommented ones",
lambda { |value|
options.show_all_tasks = value
}
],
['--backtrace=[OUT]', "Enable full backtrace. OUT can be stderr (default) or stdout.",
lambda { |value|
options.backtrace = true
select_trace_output(options, 'backtrace', value)
}
],
['--classic-namespace', '-C', "Put Task and FileTask in the top level namespace",
lambda { |value|
require 'rake/classic_namespace'
options.classic_namespace = true
}
],
['--comments', "Show commented tasks only",
lambda { |value|
options.show_all_tasks = !value
}
],
['--describe', '-D [PATTERN]', "Describe the tasks (matching optional PATTERN), then exit.",
lambda { |value|
select_tasks_to_show(options, :describe, value)
}
],
['--dry-run', '-n', "Do a dry run without executing actions.",
lambda { |value|
Rake.verbose(true)
Rake.nowrite(true)
options.dryrun = true
options.trace = true
}
],
['--execute', '-e CODE', "Execute some Ruby code and exit.",
lambda { |value|
eval(value)
exit
}
],
['--execute-print', '-p CODE', "Execute some Ruby code, print the result, then exit.",
lambda { |value|
puts eval(value)
exit
}
],
['--execute-continue', '-E CODE',
"Execute some Ruby code, then continue with normal task processing.",
lambda { |value| eval(value) }
],
['--jobs', '-j [NUMBER]',
"Specifies the maximum number of tasks to execute in parallel. (default:2)",
lambda { |value| options.thread_pool_size = [(value || 2).to_i,2].max }
],
['--job-stats [LEVEL]',
"Display job statistics. LEVEL=history displays a complete job list",
lambda { |value|
if value =~ /^history/i
options.job_stats = :history
else
options.job_stats = true
end
}
],
['--libdir', '-I LIBDIR', "Include LIBDIR in the search path for required modules.",
lambda { |value| $:.push(value) }
],
['--multitask', '-m', "Treat all tasks as multitasks.",
lambda { |value| options.always_multitask = true }
],
['--no-search', '--nosearch', '-N', "Do not search parent directories for the Rakefile.",
lambda { |value| options.nosearch = true }
],
['--prereqs', '-P', "Display the tasks and dependencies, then exit.",
lambda { |value| options.show_prereqs = true }
],
['--quiet', '-q', "Do not log messages to standard output.",
lambda { |value| Rake.verbose(false) }
],
['--rakefile', '-f [FILE]', "Use FILE as the rakefile.",
lambda { |value|
value ||= ''
@rakefiles.clear
@rakefiles << value
}
],
['--rakelibdir', '--rakelib', '-R RAKELIBDIR',
"Auto-import any .rake files in RAKELIBDIR. (default is 'rakelib')",
lambda { |value| options.rakelib = value.split(File::PATH_SEPARATOR) }
],
['--reduce-compat', "Remove DSL in Object; remove Module#const_missing which defines ::Task etc.",
# Load-time option.
# Handled in bin/rake where Rake::REDUCE_COMPAT is defined (or not).
lambda { |_| }
],
['--require', '-r MODULE', "Require MODULE before executing rakefile.",
lambda { |value|
begin
require value
rescue LoadError => ex
begin
rake_require value
rescue LoadError
raise ex
end
end
}
],
['--rules', "Trace the rules resolution.",
lambda { |value| options.trace_rules = true }
],
['--silent', '-s', "Like --quiet, but also suppresses the 'in directory' announcement.",
lambda { |value|
Rake.verbose(false)
options.silent = true
}
],
['--suppress-backtrace PATTERN', "Suppress backtrace lines matching regexp PATTERN. Ignored if --trace is on.",
lambda { |value|
options.suppress_backtrace_pattern = Regexp.new(value)
}
],
['--system', '-g',
"Using system wide (global) rakefiles (usually '~/.rake/*.rake').",
lambda { |value| options.load_system = true }
],
['--no-system', '--nosystem', '-G',
"Use standard project Rakefile search paths, ignore system wide rakefiles.",
lambda { |value| options.ignore_system = true }
],
['--tasks', '-T [PATTERN]', "Display the tasks (matching optional PATTERN) with descriptions, then exit.",
lambda { |value|
select_tasks_to_show(options, :tasks, value)
}
],
['--trace=[OUT]', '-t', "Turn on invoke/execute tracing, enable full backtrace. OUT can be stderr (default) or stdout.",
lambda { |value|
options.trace = true
options.backtrace = true
select_trace_output(options, 'trace', value)
Rake.verbose(true)
}
],
['--verbose', '-v', "Log message to standard output.",
lambda { |value| Rake.verbose(true) }
],
['--version', '-V', "Display the program version.",
lambda { |value|
puts "rake, version #{RAKEVERSION}"
exit
}
],
['--where', '-W [PATTERN]', "Describe the tasks (matching optional PATTERN), then exit.",
lambda { |value|
select_tasks_to_show(options, :lines, value)
options.show_all_tasks = true
}
],
['--no-deprecation-warnings', '-X', "Disable the deprecation warnings.",
lambda { |value|
options.ignore_deprecate = true
}
],
])
end
The directory path containing the system wide rakefiles.
# File rake/application.rb, line 620
def system_dir
@system_dir ||=
begin
if ENV['RAKE_SYSTEM']
ENV['RAKE_SYSTEM']
else
standard_system_dir
end
end
end
# File rake/application.rb, line 269
def terminal_width
if @terminal_columns.nonzero?
result = @terminal_columns
else
result = unix? ? dynamic_width : 80
end
(result < 10) ? 80 : result
rescue
80
end
Run the top level tasks of a Rake application.
# File rake/application.rb, line 94
def top_level
run_with_threads do
if options.show_tasks
display_tasks_and_comments
elsif options.show_prereqs
display_prerequisites
else
top_level_tasks.each { |task_name| invoke_task(task_name) }
end
end
end
# File rake/application.rb, line 319
def trace(*strings)
options.trace_output ||= $stderr
trace_on(options.trace_output, *strings)
end
# File rake/application.rb, line 301
def truncate(string, width)
if string.nil?
""
elsif string.length <= width
string
else
( string[0, width-3] || "" ) + "..."
end
end
We will truncate output if we are outputting to a TTY or if we've been given an explicit column width to honor
# File rake/application.rb, line 231
def truncate_output?
tty_output? || @terminal_columns.nonzero?
end
Override the detected TTY output state (mostly for testing)
# File rake/application.rb, line 225
def tty_output=( tty_output_state )
@tty_output = tty_output_state
end
True if we are outputting to TTY, false otherwise
# File rake/application.rb, line 220
def tty_output?
@tty_output
end