class Rake::RakeApp
Rake
main application object. When invoking rake
from the command line, a Rake::Application
object is created and run.
Constants
- DEFAULT_RAKEFILES
Attributes
The name of the application (typically ‘rake’)
The original directory where rake was invoked.
Name of the actual rakefile used.
List of the top level task names (task names from the command line).
Public Class Methods
Source
# File lib/rake/application.rb 31 def initialize 32 super 33 @name = 'rake' 34 @rakefiles = DEFAULT_RAKEFILES.dup 35 @rakefile = nil 36 @pending_imports = [] 37 @imported = [] 38 @loaders = {} 39 @default_loader = Rake::DefaultLoader.new 40 @original_dir = Dir.pwd 41 @top_level_tasks = [] 42 add_loader('rb', DefaultLoader.new) 43 add_loader('rf', DefaultLoader.new) 44 add_loader('rake', DefaultLoader.new) 45 @tty_output = STDOUT.tty? 46 end
Initialize a Rake::Application
object.
Rake::TaskManager::new
Public Instance Methods
Source
# File lib/rake/application.rb 566 def add_import(fn) 567 @pending_imports << fn 568 end
Add a file to the list of files to be imported.
Source
# File lib/rake/application.rb 97 def add_loader(ext, loader) 98 ext = ".#{ext}" unless ext =~ /^\./ 99 @loaders[ext] = loader 100 end
Add a loader to handle imported files ending in the extension ext
.
Source
# File lib/rake/application.rb 553 def collect_tasks 554 @top_level_tasks = [] 555 ARGV.each do |arg| 556 if arg =~ /^(\w+)=(.*)$/ 557 ENV[$1] = $2 558 else 559 @top_level_tasks << arg unless arg =~ /^-/ 560 end 561 end 562 @top_level_tasks.push("default") if @top_level_tasks.size == 0 563 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.
Source
# File lib/rake/application.rb 585 def const_warning(const_name) 586 @const_warning ||= false 587 if ! @const_warning 588 $stderr.puts %{WARNING: Deprecated reference to top-level constant '#{const_name}' } + 589 %{found at: #{rakefile_location}} # ' 590 $stderr.puts %{ Use --classic-namespace on rake command} 591 $stderr.puts %{ or 'require "rake/classic_namespace"' in Rakefile} 592 end 593 @const_warning = true 594 end
Warn about deprecated use of top level constant names.
Source
# File lib/rake/application.rb 161 def deprecate(old_usage, new_usage, call_site) 162 return if options.ignore_deprecate 163 $stderr.puts "WARNING: '#{old_usage}' is deprecated. " + 164 "Please use '#{new_usage}' instead.\n" + 165 " at #{call_site}" 166 end
Warn about deprecated usage.
Example:
Rake.application.deprecate("import", "Rake.import", caller.first)
Source
# File lib/rake/application.rb 144 def display_error_message(ex) 145 $stderr.puts "#{name} aborted!" 146 $stderr.puts ex.message 147 if options.trace 148 $stderr.puts ex.backtrace.join("\n") 149 else 150 $stderr.puts rakefile_location(ex.backtrace) 151 end 152 $stderr.puts "Tasks: #{ex.chain}" if has_chain?(ex) 153 $stderr.puts "(See full trace by running task with --trace)" unless options.trace 154 end
Display the error message that caused the exception.
Source
# File lib/rake/application.rb 277 def display_prerequisites 278 tasks.each do |t| 279 puts "#{name} #{t.name}" 280 t.prerequisites.each { |pre| puts " #{pre}" } 281 end 282 end
Display the tasks and prerequisites
Source
# File lib/rake/application.rb 205 def display_tasks_and_comments 206 displayable_tasks = tasks.select { |t| 207 t.comment && t.name =~ options.show_task_pattern 208 } 209 case options.show_tasks 210 when :tasks 211 width = displayable_tasks.collect { |t| t.name_with_args.length }.max || 10 212 max_column = truncate_output? ? terminal_width - name.size - width - 7 : nil 213 displayable_tasks.each do |t| 214 printf "#{name} %-#{width}s # %s\n", 215 t.name_with_args, max_column ? truncate(t.comment, max_column) : t.comment 216 end 217 when :describe 218 displayable_tasks.each do |t| 219 puts "#{name} #{t.name_with_args}" 220 t.full_comment.split("\n").each do |line| 221 puts " #{line}" 222 end 223 puts 224 end 225 when :lines 226 displayable_tasks.each do |t| 227 t.locations.each do |loc| 228 printf "#{name} %-30s %s\n",t.name_with_args, loc 229 end 230 end 231 else 232 fail "Unknown show task mode: '#{options.show_tasks}'" 233 end 234 end
Display the tasks and comments.
Source
# File lib/rake/application.rb 248 def dynamic_width 249 @dynamic_width ||= (dynamic_width_stty.nonzero? || dynamic_width_tput) 250 end
Calculate the dynamic width of the
Source
# File lib/rake/application.rb 252 def dynamic_width_stty 253 %x{stty size 2>/dev/null}.split[1].to_i 254 end
Source
# File lib/rake/application.rb 256 def dynamic_width_tput 257 %x{tput cols 2>/dev/null}.to_i 258 end
Source
# File lib/rake/application.rb 476 def find_rakefile_location 477 here = Dir.pwd 478 while ! (fn = have_rakefile) 479 Dir.chdir("..") 480 if Dir.pwd == here || options.nosearch 481 return nil 482 end 483 here = Dir.pwd 484 end 485 [fn, here] 486 ensure 487 Dir.chdir(Rake.original_dir) 488 end
Source
# File lib/rake/application.rb 432 def handle_options 433 options.rakelib = ['rakelib'] 434 435 OptionParser.new do |opts| 436 opts.banner = "drake [-f rakefile] {options} targets..." 437 opts.separator "" 438 opts.separator "Options are ..." 439 440 opts.on_tail("-h", "--help", "-H", "Display this help message.") do 441 puts opts 442 exit 443 end 444 445 standard_rake_options.each { |args| opts.on(*args) } 446 opts.environment('RAKEOPT') 447 end.parse! 448 449 # If class namespaces are requested, set the global options 450 # according to the values in the options structure. 451 if options.classic_namespace 452 $show_tasks = options.show_tasks 453 $show_prereqs = options.show_prereqs 454 $trace = options.trace 455 $dryrun = options.dryrun 456 $silent = options.silent 457 end 458 end
Read and handle the command line options.
Source
# File lib/rake/application.rb 176 def have_rakefile 177 @rakefiles.each do |fn| 178 if File.exist?(fn) 179 others = Dir.glob(fn, File::FNM_CASEFOLD) 180 return others.size == 1 ? others.first : fn 181 elsif fn == '' 182 return fn 183 end 184 end 185 return nil 186 end
True if one of the files in RAKEFILES is in the current directory. If a match is found, it is copied into @rakefile.
Source
# File lib/rake/application.rb 67 def init(app_name='rake') 68 standard_exception_handling do 69 @name = app_name 70 handle_options 71 collect_tasks 72 end 73 end
Initialize the command line parameters and app name.
Source
# File lib/rake/application.rb 109 def invoke_task(task_string) 110 name, args = parse_task_string(task_string) 111 t = self[name] 112 t.invoke(*args) 113 end
private —————————————————————-
Source
# File lib/rake/application.rb 571 def load_imports 572 while fn = @pending_imports.shift 573 next if @imported.member?(fn) 574 if fn_task = lookup(fn) 575 fn_task.invoke 576 end 577 ext = File.extname(fn) 578 loader = @loaders[ext] || @default_loader 579 loader.load(fn) 580 @imported << fn 581 end 582 end
Load the pending list of imported files.
Source
# File lib/rake/application.rb 76 def load_rakefile 77 standard_exception_handling do 78 raw_load_rakefile 79 end 80 end
Find the rakefile and then load it and any pending imports.
Source
# File lib/rake/application.rb 103 def options 104 @options ||= Options.new 105 end
Application
options from the command line
Source
# File lib/rake/application.rb 115 def parse_task_string(string) 116 if string =~ /^([^\[]+)(\[(.*)\])$/ 117 name = $1 118 args = $3.split(/\s*,\s*/) 119 else 120 name = string 121 args = [] 122 end 123 [name, args] 124 end
Source
# File lib/rake/application.rb 490 def print_rakefile_directory(location) 491 $stderr.puts "(in #{Dir.pwd})" unless 492 options.silent or original_dir == location 493 end
Source
# File lib/rake/application.rb 462 def rake_require(file_name, paths=$LOAD_PATH, loaded=$") 463 fn = file_name + ".rake" 464 return false if loaded.include?(fn) 465 paths.each do |path| 466 full_path = File.join(path, fn) 467 if File.exist?(full_path) 468 Rake.load_rakefile(full_path) 469 loaded << fn 470 return true 471 end 472 end 473 fail LoadError, "Can't find #{file_name}" 474 end
Similar to the regular Ruby require
command, but will check for *.rake files in addition to *.rb files.
Source
# File lib/rake/application.rb 596 def rakefile_location backtrace = caller 597 backtrace.map { |t| t[/([^:]+):/,1] } 598 599 re = /^#{@rakefile}$/ 600 re = /#{re.source}/i if windows? 601 602 backtrace.find { |str| str =~ re } || '' 603 end
Source
# File lib/rake/application.rb 58 def run 59 standard_exception_handling do 60 init 61 load_rakefile 62 top_level 63 end 64 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.
Source
# File lib/rake/application.rb 127 def standard_exception_handling 128 begin 129 yield 130 rescue SystemExit => ex 131 # Exit silently with current status 132 raise 133 rescue OptionParser::InvalidOption => ex 134 $stderr.puts ex.message 135 exit(false) 136 rescue Exception => ex 137 # Exit with error message 138 display_error_message(ex) 139 exit(false) 140 end 141 end
Provide standard exception handling for the given block.
Source
# File lib/rake/application.rb 286 def standard_rake_options 287 [ 288 ['--classic-namespace', '-C', "Put Task and FileTask in the top level namespace", 289 lambda { |value| 290 require 'rake/classic_namespace' 291 options.classic_namespace = true 292 } 293 ], 294 ['--describe', '-D [PATTERN]', "Describe the tasks (matching optional PATTERN), then exit.", 295 lambda { |value| 296 options.show_tasks = :describe 297 options.show_task_pattern = Regexp.new(value || '') 298 TaskManager.record_task_metadata = true 299 } 300 ], 301 ['--dry-run', '-n', "Do a dry run without executing actions.", 302 lambda { |value| 303 Rake.verbose(true) 304 Rake.nowrite(true) 305 options.dryrun = true 306 options.trace = true 307 } 308 ], 309 ['--execute', '-e CODE', "Execute some Ruby code and exit.", 310 lambda { |value| 311 eval(value) 312 exit 313 } 314 ], 315 ['--execute-print', '-p CODE', "Execute some Ruby code, print the result, then exit.", 316 lambda { |value| 317 puts eval(value) 318 exit 319 } 320 ], 321 ['--execute-continue', '-E CODE', 322 "Execute some Ruby code, then continue with normal task processing.", 323 lambda { |value| eval(value) } 324 ], 325 ['--threads', '-j [N]', Integer, "Run up to N tasks simultaneously; without N (or N=0), no limit.", 326 lambda { |value| 327 # nil.to_i == 0, which means unlimited threads 328 options.threads = value.to_i 329 } 330 ], 331 ['--libdir', '-I LIBDIR', "Include LIBDIR in the search path for required modules.", 332 lambda { |value| $:.push(value) } 333 ], 334 ['--no-search', '--nosearch', '-N', "Do not search parent directories for the Rakefile.", 335 lambda { |value| options.nosearch = true } 336 ], 337 ['--prereqs', '-P', "Display the tasks and dependencies, then exit.", 338 lambda { |value| options.show_prereqs = true } 339 ], 340 ['--quiet', '-q', "Do not log messages to standard output.", 341 lambda { |value| Rake.verbose(false) } 342 ], 343 ['--rakefile', '-f [FILE]', "Use FILE as the rakefile.", 344 lambda { |value| 345 value ||= '' 346 @rakefiles.clear 347 @rakefiles << value 348 } 349 ], 350 ['--rakelibdir', '--rakelib', '-R RAKELIBDIR', 351 "Auto-import any .rake files in RAKELIBDIR. (default is 'rakelib')", 352 lambda { |value| options.rakelib = value.split(':') } 353 ], 354 ['--randomize[=SEED]', Integer, "Randomize the order of sibling prerequisites.", 355 lambda { |value| 356 MultiTask.class_eval { remove_method(:invoke_prerequisites) } 357 options.randomize = value || (srand ; srand % 10_000) 358 srand options.randomize 359 at_exit do 360 $stderr.puts "Run options: --randomize=#{options.randomize}" 361 end 362 } 363 ], 364 ['--require', '-r MODULE', "Require MODULE before executing rakefile.", 365 lambda { |value| 366 begin 367 require value 368 rescue LoadError => ex 369 begin 370 rake_require value 371 rescue LoadError 372 raise ex 373 end 374 end 375 } 376 ], 377 ['--rules', "Trace the rules resolution.", 378 lambda { |value| options.trace_rules = true } 379 ], 380 ['--silent', '-s', "Like --quiet, but also suppresses the 'in directory' announcement.", 381 lambda { |value| 382 Rake.verbose(false) 383 options.silent = true 384 } 385 ], 386 ['--system', '-g', 387 "Using system wide (global) rakefiles (usually '~/.rake/*.rake').", 388 lambda { |value| options.load_system = true } 389 ], 390 ['--no-system', '--nosystem', '-G', 391 "Use standard project Rakefile search paths, ignore system wide rakefiles.", 392 lambda { |value| options.ignore_system = true } 393 ], 394 ['--tasks', '-T [PATTERN]', "Display the tasks (matching optional PATTERN) with descriptions, then exit.", 395 lambda { |value| 396 options.show_tasks = :tasks 397 options.show_task_pattern = Regexp.new(value || '') 398 Rake::TaskManager.record_task_metadata = true 399 } 400 ], 401 ['--trace', '-t', "Turn on invoke/execute tracing, enable full backtrace.", 402 lambda { |value| 403 options.trace = true 404 Rake.verbose(true) 405 } 406 ], 407 ['--verbose', '-v', "Log message to standard output.", 408 lambda { |value| Rake.verbose(true) } 409 ], 410 ['--version', '-V', "Display the program version.", 411 lambda { |value| 412 puts "drake, version #{RAKEVERSION}" 413 exit 414 } 415 ], 416 ['--where', '-W [PATTERN]', "Describe the tasks (matching optional PATTERN), then exit.", 417 lambda { |value| 418 options.show_tasks = :lines 419 options.show_task_pattern = Regexp.new(value || '') 420 Rake::TaskManager.record_task_metadata = true 421 } 422 ], 423 ['--no-deprecation-warnings', '-X', "Disable the deprecation warnings.", 424 lambda { |value| 425 options.ignore_deprecate = true 426 } 427 ], 428 ] 429 end
A list of all the standard options used in rake, suitable for passing to OptionParser.
Source
# File lib/rake/application.rb 527 def system_dir 528 @system_dir ||= 529 begin 530 if ENV['RAKE_SYSTEM'] 531 ENV['RAKE_SYSTEM'] 532 else 533 standard_system_dir 534 end 535 end 536 end
The directory path containing the system wide rakefiles.
Source
# File lib/rake/application.rb 236 def terminal_width 237 if ENV['RAKE_COLUMNS'] 238 result = ENV['RAKE_COLUMNS'].to_i 239 else 240 result = unix? ? dynamic_width : 80 241 end 242 (result < 10) ? 80 : result 243 rescue 244 80 245 end
Source
# File lib/rake/application.rb 83 def top_level 84 standard_exception_handling do 85 if options.show_tasks 86 display_tasks_and_comments 87 elsif options.show_prereqs 88 display_prerequisites 89 else 90 top_level_tasks.each { |task_name| invoke_task(task_name) } 91 end 92 end 93 end
Run the top level tasks of a Rake
application.
Source
# File lib/rake/application.rb 268 def truncate(string, width) 269 if string.length <= width 270 string 271 else 272 ( string[0, width-3] || "" ) + "..." 273 end 274 end
Source
# File lib/rake/application.rb 200 def truncate_output? 201 tty_output? || ENV['RAKE_COLUMNS'] 202 end
We will truncate output if we are outputting to a TTY or if we’ve been given an explicit column width to honor
Source
# File lib/rake/application.rb 194 def tty_output=( tty_output_state ) 195 @tty_output = tty_output_state 196 end
Override the detected TTY output state (mostly for testing)
Source
# File lib/rake/application.rb 189 def tty_output? 190 @tty_output 191 end
True if we are outputting to TTY, false otherwise
Source
# File lib/rake/application.rb 260 def unix? 261 RbConfig::CONFIG['host_os'] =~ /(aix|darwin|linux|(net|free|open)bsd|cygwin|solaris|irix|hpux)/i 262 end
Private Instance Methods
Source
# File lib/rake/application.rb 521 def glob(path, &block) 522 Dir[path.gsub("\\", '/')].each(&block) 523 end
Source
# File lib/rake/application.rb 169 def has_chain?(exception) 170 exception.respond_to?(:chain) && exception.chain 171 end
Does the exception have a task invocation chain?