diff options
Diffstat (limited to 'lib/rake/application.rb')
-rw-r--r-- | lib/rake/application.rb | 175 |
1 files changed, 115 insertions, 60 deletions
diff --git a/lib/rake/application.rb b/lib/rake/application.rb index b76244b7a3..795b4685d4 100644 --- a/lib/rake/application.rb +++ b/lib/rake/application.rb @@ -12,10 +12,10 @@ module Rake CommandLineOptionError = Class.new(StandardError) - ###################################################################### + ## # Rake main application object. When invoking +rake+ from the # command line, a Rake::Application object is created and run. - # + class Application include TaskManager include TraceOutput @@ -84,7 +84,7 @@ module Rake standard_exception_handling do @name = app_name handle_options - collect_tasks + collect_command_line_tasks end end @@ -117,8 +117,8 @@ module Rake 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]}" + puts "Maximum active threads: #{stats[:max_active_threads]} + main" + puts "Total threads in play: #{stats[:total_threads_in_play]} + main" end ThreadHistoryDisplay.new(thread_pool.history).show if options.job_stats == :history @@ -138,30 +138,41 @@ module Rake # Return the thread pool used for multithreaded processing. def thread_pool # :nodoc: - @thread_pool ||= ThreadPool.new(options.thread_pool_size || FIXNUM_MAX) + @thread_pool ||= ThreadPool.new(options.thread_pool_size || Rake.suggested_thread_count-1) end - # private ---------------------------------------------------------------- + # internal ---------------------------------------------------------------- - def invoke_task(task_string) + # Invokes a task with arguments that are extracted from +task_string+ + def invoke_task(task_string) # :nodoc: name, args = parse_task_string(task_string) t = self[name] t.invoke(*args) end - def parse_task_string(string) - if string =~ /^([^\[]+)(\[(.*)\])$/ - name = $1 - args = $3.split(/\s*,\s*/) - else - name = string - args = [] - end - [name, args] + def parse_task_string(string) # :nodoc: + /^([^\[]+)(?:\[(.*)\])$/ =~ string.to_s + + name = $1 + remaining_args = $2 + + return string, [] unless name + return name, [] if remaining_args.empty? + + args = [] + + begin + /((?:[^\\,]|\\.)*?)\s*(?:,\s*(.*))?$/ =~ remaining_args + + remaining_args = $2 + args << $1.gsub(/\\(.)/, '\1') + end while remaining_args + + return name, args end # Provide standard exception handling for the given block. - def standard_exception_handling + def standard_exception_handling # :nodoc: yield rescue SystemExit # Exit silently with current status @@ -177,22 +188,47 @@ module Rake # Exit the program because of an unhandle exception. # (may be overridden by subclasses) - def exit_because_of_exception(ex) + def exit_because_of_exception(ex) # :nodoc: exit(false) end # Display the error message that caused the exception. - def display_error_message(ex) + def display_error_message(ex) # :nodoc: trace "#{name} aborted!" - trace ex.message + display_exception_details(ex) + trace "Tasks: #{ex.chain}" if has_chain?(ex) + trace "(See full trace by running task with --trace)" unless + options.backtrace + end + + def display_exception_details(ex) # :nodoc: + seen = Thread.current[:rake_display_exception_details_seen] ||= [] + return if seen.include? ex + seen << ex + + display_exception_message_details(ex) + display_exception_backtrace(ex) + display_exception_details(ex.cause) if has_cause?(ex) + end + + def has_cause?(ex) # :nodoc: + ex.respond_to?(:cause) && ex.cause + end + + def display_exception_message_details(ex) # :nodoc: + if ex.instance_of?(RuntimeError) + trace ex.message + else + trace "#{ex.class.name}: #{ex.message}" + end + end + + def display_exception_backtrace(ex) # :nodoc: 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 # Warn about deprecated usage. @@ -200,7 +236,7 @@ module Rake # Example: # Rake.application.deprecate("import", "Rake.import", caller.first) # - def deprecate(old_usage, new_usage, call_site) + def deprecate(old_usage, new_usage, call_site) # :nodoc: unless options.ignore_deprecate $stderr.puts "WARNING: '#{old_usage}' is deprecated. " + "Please use '#{new_usage}' instead.\n" + @@ -209,14 +245,14 @@ module Rake end # Does the exception have a task invocation chain? - def has_chain?(exception) + def has_chain?(exception) # :nodoc: exception.respond_to?(:chain) && exception.chain 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 + def have_rakefile # :nodoc: @rakefiles.each do |fn| if File.exist?(fn) others = FileList.glob(fn, File::FNM_CASEFOLD) @@ -229,23 +265,23 @@ module Rake end # True if we are outputting to TTY, false otherwise - def tty_output? + def tty_output? # :nodoc: @tty_output end # Override the detected TTY output state (mostly for testing) - def tty_output=(tty_output_state) + def tty_output=(tty_output_state) # :nodoc: @tty_output = tty_output_state end # We will truncate output if we are outputting to a TTY or if we've been # given an explicit column width to honor - def truncate_output? + def truncate_output? # :nodoc: tty_output? || @terminal_columns.nonzero? end # Display the tasks and comments. - def display_tasks_and_comments + def display_tasks_and_comments # :nodoc: displayable_tasks = tasks.select { |t| (options.show_all_tasks || t.comment) && t.name =~ options.show_task_pattern @@ -284,7 +320,7 @@ module Rake end end - def terminal_width + def terminal_width # :nodoc: if @terminal_columns.nonzero? result = @terminal_columns else @@ -296,28 +332,28 @@ module Rake end # Calculate the dynamic width of the - def dynamic_width + def dynamic_width # :nodoc: @dynamic_width ||= (dynamic_width_stty.nonzero? || dynamic_width_tput) end - def dynamic_width_stty + def dynamic_width_stty # :nodoc: %x{stty size 2>/dev/null}.split[1].to_i end - def dynamic_width_tput + def dynamic_width_tput # :nodoc: %x{tput cols 2>/dev/null}.to_i end - def unix? + def unix? # :nodoc: RbConfig::CONFIG['host_os'] =~ /(aix|darwin|linux|(net|free|open)bsd|cygwin|solaris|irix|hpux)/i end - def windows? + def windows? # :nodoc: Win32.windows? end - def truncate(string, width) + def truncate(string, width) # :nodoc: if string.nil? "" elsif string.length <= width @@ -328,19 +364,19 @@ module Rake end # Display the tasks and prerequisites - def display_prerequisites + def display_prerequisites # :nodoc: tasks.each do |t| puts "#{name} #{t.name}" t.prerequisites.each { |pre| puts " #{pre}" } end end - def trace(*strings) + def trace(*strings) # :nodoc: options.trace_output ||= $stderr trace_on(options.trace_output, *strings) end - def sort_options(options) + def sort_options(options) # :nodoc: options.sort_by { |opt| opt.select { |o| o =~ /^-/ }.map { |o| o.downcase }.sort.reverse } @@ -349,11 +385,11 @@ module Rake # A list of all the standard options used in rake, suitable for # passing to OptionParser. - def standard_rake_options + def standard_rake_options # :nodoc: sort_options( [ ['--all', '-A', - "Show all tasks, even uncommented ones", + "Show all tasks, even uncommented ones (in combination with -T or -D)", lambda { |value| options.show_all_tasks = value } @@ -365,6 +401,12 @@ module Rake select_trace_output(options, 'backtrace', value) } ], + ['--build-all', '-B', + "Build all prerequisites, including those which are up-to-date.", + lambda { |value| + options.build_all = true + } + ], ['--comments', "Show commented tasks only", lambda { |value| @@ -407,9 +449,17 @@ module Rake ], ['--jobs', '-j [NUMBER]', "Specifies the maximum number of tasks to execute in parallel. " + - "(default is 2)", + "(default is number of CPU cores + 4)", lambda { |value| - options.thread_pool_size = [(value || 2).to_i, 2].max + if value.nil? || value == '' + value = FIXNUM_MAX + elsif value =~ /^\d+$/ + value = value.to_i + else + value = Rake.suggested_thread_count + end + value = 1 if value < 1 + options.thread_pool_size = value - 1 } ], ['--job-stats [LEVEL]', @@ -443,8 +493,8 @@ module Rake "Do not log messages to standard output.", lambda { |value| Rake.verbose(false) } ], - ['--rakefile', '-f [FILE]', - "Use FILE as the rakefile.", + ['--rakefile', '-f [FILENAME]', + "Use FILENAME as the rakefile to search for.", lambda { |value| value ||= '' @rakefiles.clear @@ -545,14 +595,14 @@ module Rake ]) end - def select_tasks_to_show(options, show_tasks, value) + def select_tasks_to_show(options, show_tasks, value) # :nodoc: options.show_tasks = show_tasks options.show_task_pattern = Regexp.new(value || '') Rake::TaskManager.record_task_metadata = true end private :select_tasks_to_show - def select_trace_output(options, trace_option, value) + def select_trace_output(options, trace_option, value) # :nodoc: value = value.strip unless value.nil? case value when 'stdout' @@ -567,7 +617,7 @@ module Rake private :select_trace_output # Read and handle the command line options. - def handle_options + def handle_options # :nodoc: options.rakelib = ['rakelib'] options.trace_output = $stderr @@ -588,7 +638,7 @@ module Rake # Similar to the regular Ruby +require+ command, but will check # for *.rake files in addition to *.rb files. - def rake_require(file_name, paths=$LOAD_PATH, loaded=$") + def rake_require(file_name, paths=$LOAD_PATH, loaded=$") # :nodoc: fn = file_name + ".rake" return false if loaded.include?(fn) paths.each do |path| @@ -602,7 +652,7 @@ module Rake fail LoadError, "Can't find #{file_name}" end - def find_rakefile_location + def find_rakefile_location # :nodoc: here = Dir.pwd until (fn = have_rakefile) Dir.chdir("..") @@ -614,7 +664,7 @@ module Rake Dir.chdir(Rake.original_dir) end - def print_rakefile_directory(location) + def print_rakefile_directory(location) # :nodoc: $stderr.puts "(in #{Dir.pwd})" unless options.silent or original_dir == location end @@ -645,13 +695,13 @@ module Rake load_imports end - def glob(path, &block) + def glob(path, &block) # :nodoc: FileList.glob(path.gsub("\\", '/')).each(&block) end private :glob # The directory path containing the system wide rakefiles. - def system_dir + def system_dir # :nodoc: @system_dir ||= begin if ENV['RAKE_SYSTEM'] @@ -677,7 +727,7 @@ module Rake # 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. - def collect_tasks + def collect_command_line_tasks # :nodoc: @top_level_tasks = [] ARGV.each do |arg| if arg =~ /^(\w+)=(.*)$/m @@ -691,28 +741,33 @@ module Rake # Default task name ("default"). # (May be overridden by subclasses) - def default_task_name + def default_task_name # :nodoc: "default" end # Add a file to the list of files to be imported. - def add_import(fn) + def add_import(fn) # :nodoc: @pending_imports << fn end # Load the pending list of imported files. - def load_imports + def load_imports # :nodoc: while fn = @pending_imports.shift next if @imported.member?(fn) fn_task = lookup(fn) and fn_task.invoke ext = File.extname(fn) loader = @loaders[ext] || @default_loader loader.load(fn) + if fn_task = lookup(fn) and fn_task.needed? + fn_task.reenable + fn_task.invoke + loader.load(fn) + end @imported << fn end end - def rakefile_location(backtrace=caller) + def rakefile_location(backtrace=caller) # :nodoc: backtrace.map { |t| t[/([^:]+):/, 1] } re = /^#{@rakefile}$/ |