Extended maintenance of Ruby 1.9.3 ended on February 23, 2015. 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 34
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 556
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 101
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 543
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 575
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 165
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 148
def display_error_message(ex)
$stderr.puts "#{name} aborted!"
$stderr.puts ex.message
if options.trace
$stderr.puts ex.backtrace.join("\n")
else
$stderr.puts rakefile_location(ex.backtrace)
end
$stderr.puts "Tasks: #{ex.chain}" if has_chain?(ex)
$stderr.puts "(See full trace by running task with --trace)" unless options.trace
end
Display the tasks and prerequisites
# File rake/application.rb, line 282
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 209
def display_tasks_and_comments
displayable_tasks = tasks.select { |t|
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}"
t.full_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 253
def dynamic_width
@dynamic_width ||= (dynamic_width_stty.nonzero? || dynamic_width_tput)
end
# File rake/application.rb, line 257
def dynamic_width_stty
%x{stty size 2>/dev/null}.split[1].to_i
end
# File rake/application.rb, line 261
def dynamic_width_tput
%x{tput cols 2>/dev/null}.to_i
end
# File rake/application.rb, line 466
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 422
def handle_options
options.rakelib = ['rakelib']
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 180
def have_rakefile
@rakefiles.each do |fn|
if File.exist?(fn)
others = Dir.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 71
def init(app_name='rake')
standard_exception_handling do
@name = app_name
handle_options
collect_tasks
end
end
private —————————————————————-
# File rake/application.rb, line 113
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 561
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 80
def load_rakefile
standard_exception_handling do
raw_load_rakefile
end
end
Application options from the command line
# File rake/application.rb, line 107
def options
@options ||= OpenStruct.new
end
# File rake/application.rb, line 119
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 480
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 452
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 586
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 (run_tasks).
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 62
def run
standard_exception_handling do
init
load_rakefile
top_level
end
end
Provide standard exception handling for the given block.
# File rake/application.rb, line 131
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 291
def standard_rake_options
[
['--classic-namespace', '-C', "Put Task and FileTask in the top level namespace",
lambda { |value|
require 'rake/classic_namespace'
options.classic_namespace = true
}
],
['--describe', '-D [PATTERN]', "Describe the tasks (matching optional PATTERN), then exit.",
lambda { |value|
options.show_tasks = :describe
options.show_task_pattern = Regexp.new(value || '')
TaskManager.record_task_metadata = true
}
],
['--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) }
],
['--libdir', '-I LIBDIR', "Include LIBDIR in the search path for required modules.",
lambda { |value| $:.push(value) }
],
['--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')",
# HACK Use File::PATH_SEPARATOR
lambda { |value| options.rakelib = value.split(':') }
],
['--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
}
],
['--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|
options.show_tasks = :tasks
options.show_task_pattern = Regexp.new(value || '')
Rake::TaskManager.record_task_metadata = true
}
],
['--trace', '-t', "Turn on invoke/execute tracing, enable full backtrace.",
lambda { |value|
options.trace = true
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|
options.show_tasks = :lines
options.show_task_pattern = Regexp.new(value || '')
Rake::TaskManager.record_task_metadata = 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 517
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 241
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 87
def top_level
standard_exception_handling 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 273
def truncate(string, width)
if 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 204
def truncate_output?
tty_output? || @terminal_columns.nonzero?
end
Override the detected TTY output state (mostly for testing)
# File rake/application.rb, line 198
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 193
def tty_output?
@tty_output
end