ruby-changes:25608
From: drbrain <ko1@a...>
Date: Fri, 16 Nov 2012 07:02:06 +0900 (JST)
Subject: [ruby-changes:25608] drbrain:r37664 (trunk): * lib/rake*: Updated to rake 0.9.3
drbrain 2012-11-16 06:59:37 +0900 (Fri, 16 Nov 2012) New Revision: 37664 http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=37664 Log: * lib/rake*: Updated to rake 0.9.3 * test/rake*: ditto * bin/rake: ditto * NEWS: ditto Added files: trunk/lib/rake/backtrace.rb trunk/lib/rake/phony.rb trunk/lib/rake/private_reader.rb trunk/lib/rake/promise.rb trunk/lib/rake/thread_history_display.rb trunk/lib/rake/thread_pool.rb trunk/test/rake/test_private_reader.rb trunk/test/rake/test_rake_backtrace.rb trunk/test/rake/test_rake_reduce_compat.rb trunk/test/rake/test_rake_thread_pool.rb trunk/test/rake/test_thread_history_display.rb Modified files: trunk/ChangeLog trunk/NEWS trunk/bin/rake trunk/lib/rake/application.rb trunk/lib/rake/clean.rb trunk/lib/rake/cloneable.rb trunk/lib/rake/contrib/ftptools.rb trunk/lib/rake/contrib/sys.rb trunk/lib/rake/dsl_definition.rb trunk/lib/rake/ext/module.rb trunk/lib/rake/ext/string.rb trunk/lib/rake/ext/time.rb trunk/lib/rake/file_list.rb trunk/lib/rake/file_utils_ext.rb trunk/lib/rake/multi_task.rb trunk/lib/rake/rake_module.rb trunk/lib/rake/rdoctask.rb trunk/lib/rake/runtest.rb trunk/lib/rake/task.rb trunk/lib/rake/task_arguments.rb trunk/lib/rake/task_manager.rb trunk/lib/rake/testtask.rb trunk/lib/rake/version.rb trunk/lib/rake.rb trunk/test/rake/helper.rb trunk/test/rake/test_rake_application.rb trunk/test/rake/test_rake_application_options.rb trunk/test/rake/test_rake_directory_task.rb trunk/test/rake/test_rake_file_task.rb trunk/test/rake/test_rake_functional.rb trunk/test/rake/test_rake_multi_task.rb trunk/test/rake/test_rake_rake_test_loader.rb trunk/test/rake/test_rake_task.rb trunk/test/rake/test_rake_top_level_functions.rb Index: ChangeLog =================================================================== --- ChangeLog (revision 37663) +++ ChangeLog (revision 37664) @@ -1,3 +1,12 @@ +Fri Nov 16 06:58:52 2012 Eric Hodel <drbrain@s...> + + * lib/rake*: Updated to rake 0.9.3. See + http://rake.rubyforge.org/doc/release_notes/rake-0_9_3_rdoc.html for + a list of changes in 0.9.3. + * test/rake*: ditto + * bin/rake: ditto + * NEWS: ditto + Thu Nov 15 22:39:32 2012 Yusuke Endoh <mame@t...> * range.c (range_bsearch): fix some bugs: a documentation bug, a wrong Index: lib/rake/thread_history_display.rb =================================================================== --- lib/rake/thread_history_display.rb (revision 0) +++ lib/rake/thread_history_display.rb (revision 37664) @@ -0,0 +1,48 @@ +require 'rake/private_reader' + +module Rake + + class ThreadHistoryDisplay # :nodoc: all + include Rake::PrivateReader + + private_reader :stats, :items, :threads + + def initialize(stats) + @stats = stats + @items = { :_seq_ => 1 } + @threads = { :_seq_ => "A" } + end + + def show + puts "Job History:" + stats.each do |stat| + stat[:data] ||= {} + rename(stat, :thread, threads) + rename(stat[:data], :item_id, items) + rename(stat[:data], :new_thread, threads) + rename(stat[:data], :deleted_thread, threads) + printf("%8d %2s %-20s %s\n", + (stat[:time] * 1_000_000).round, + stat[:thread], + stat[:event], + stat[:data].map { |k,v| "#{k}:#{v}" }.join(" ")) + end + end + + private + + def rename(hash, key, renames) + if hash && hash[key] + original = hash[key] + value = renames[original] + unless value + value = renames[:_seq_] + renames[:_seq_] = renames[:_seq_].succ + renames[original] = value + end + hash[key] = value + end + end + end + +end Index: lib/rake/backtrace.rb =================================================================== --- lib/rake/backtrace.rb (revision 0) +++ lib/rake/backtrace.rb (revision 37664) @@ -0,0 +1,18 @@ +module Rake + module Backtrace + SUPPRESSED_PATHS = + RbConfig::CONFIG.values_at(*RbConfig::CONFIG. + keys.grep(/(prefix|libdir)/)) + [ + File.join(File.dirname(__FILE__), ".."), + ].map { |f| Regexp.quote(File.expand_path(f)) } + SUPPRESSED_PATHS.reject! { |s| s.nil? || s =~ /^ *$/ } + + SUPPRESS_PATTERN = %r!(\A#{SUPPRESSED_PATHS.join('|')}|bin/rake:\d+)!i + + def self.collapse(backtrace) + pattern = Rake.application.options.suppress_backtrace_pattern || + SUPPRESS_PATTERN + backtrace.reject { |elem| elem =~ pattern } + end + end +end Index: lib/rake/clean.rb =================================================================== --- lib/rake/clean.rb (revision 37663) +++ lib/rake/clean.rb (revision 37664) @@ -16,7 +16,7 @@ # :stopdoc: CLEAN = Rake::FileList["**/*~", "**/*.bak", "**/core"] CLEAN.clear_exclude.exclude { |fn| - fn.pathmap("%f") == 'core' && File.directory?(fn) + fn.pathmap("%f").downcase == 'core' && File.directory?(fn) } desc "Remove any temporary products." Index: lib/rake/dsl_definition.rb =================================================================== --- lib/rake/dsl_definition.rb (revision 37663) +++ lib/rake/dsl_definition.rb (revision 37664) @@ -52,8 +52,8 @@ # Declare a file creation task. # (Mainly used for the directory command). - def file_create(args, &block) - Rake::FileCreationTask.define_task(args, &block) + def file_create(*args, &block) + Rake::FileCreationTask.define_task(*args, &block) end # Declare a set of files tasks to create the given directories on @@ -62,12 +62,15 @@ # Example: # directory "testdata/doc" # - def directory(dir) + def directory(*args, &block) + result = file_create(*args, &block) + dir, _ = *Rake.application.resolve_args(args) Rake.each_dir_parent(dir) do |d| file_create d do |t| mkdir_p t.name if ! File.exist?(t.name) end end + result end # Declare a task that performs its prerequisites in @@ -78,8 +81,8 @@ # Example: # multitask :deploy => [:deploy_gem, :deploy_rdoc] # - def multitask(args, &block) - Rake::MultiTask.define_task(args, &block) + def multitask(*args, &block) + Rake::MultiTask.define_task(*args, &block) end # Create a new rake namespace and use it for evaluating the given @@ -167,10 +170,13 @@ private :#{name} }, __FILE__, line end - end + end unless defined? Rake::REDUCE_COMPAT extend FileUtilsExt end +# Extend the main object with the DSL commands. This allows top-level +# calls to task, etc. to work from a Rakefile without polluting the +# object inheritance tree. self.extend Rake::DSL -include Rake::DeprecatedObjectDSL +include Rake::DeprecatedObjectDSL unless defined? Rake::REDUCE_COMPAT Index: lib/rake/private_reader.rb =================================================================== --- lib/rake/private_reader.rb (revision 0) +++ lib/rake/private_reader.rb (revision 37664) @@ -0,0 +1,20 @@ +module Rake + + # Include PrivateReader to use +private_reader+. + module PrivateReader # :nodoc: all + + def self.included(base) + base.extend(ClassMethods) + end + + module ClassMethods + + # Declare a list of private accessors + def private_reader(*names) + attr_reader(*names) + private(*names) + end + end + + end +end Index: lib/rake/ext/time.rb =================================================================== --- lib/rake/ext/time.rb (revision 37663) +++ lib/rake/ext/time.rb (revision 37664) @@ -1,6 +1,8 @@ #-- # Extensions to time to allow comparisons with an early time class. +require 'rake/early_time' + class Time alias rake_original_time_compare :<=> def <=>(other) @@ -11,4 +13,3 @@ end end end - Index: lib/rake/ext/module.rb =================================================================== --- lib/rake/ext/module.rb (revision 37663) +++ lib/rake/ext/module.rb (revision 37664) @@ -36,4 +36,4 @@ rake_original_const_missing(const_name) end end -end +end unless defined? Rake::REDUCE_COMPAT Index: lib/rake/ext/string.rb =================================================================== --- lib/rake/ext/string.rb (revision 37663) +++ lib/rake/ext/string.rb (revision 37664) @@ -4,6 +4,7 @@ # Rake extension methods for String. # class String + rake_extension("ext") do # Replace the file extension with +newext+. If there is no extension on # the string, append the new extension to the end. If the new extension @@ -163,5 +164,5 @@ result end end -end # class String +end Index: lib/rake/testtask.rb =================================================================== --- lib/rake/testtask.rb (revision 37663) +++ lib/rake/testtask.rb (revision 37664) @@ -96,7 +96,11 @@ desc "Run tests" + (@name==:test ? "" : " for #{@name}") task @name do FileUtilsExt.verbose(@verbose) do - ruby "#{ruby_opts_string} #{run_code} #{file_list_string} #{option_list}" + ruby "#{ruby_opts_string} #{run_code} #{file_list_string} #{option_list}" do |ok, status| + if !ok && status.respond_to?(:signaled?) && status.signaled? + raise SignalException.new(status.termsig) + end + end end end self Index: lib/rake/application.rb =================================================================== --- lib/rake/application.rb (revision 37663) +++ lib/rake/application.rb (revision 37664) @@ -2,10 +2,14 @@ require 'optparse' require 'rake/task_manager' +require 'rake/thread_pool' +require 'rake/thread_history_display' require 'rake/win32' 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. @@ -54,7 +58,7 @@ # # * Initialize the command line options (+init+). # * Define the tasks (+load_rakefile+). - # * Run the top level tasks (+run_tasks+). + # * 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, @@ -85,7 +89,7 @@ # Run the top level tasks of a Rake application. def top_level - standard_exception_handling do + run_with_threads do if options.show_tasks display_tasks_and_comments elsif options.show_prereqs @@ -96,6 +100,21 @@ end end + # Run the given block with the thread startup and shutdown. + 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 + # Add a loader to handle imported files ending in the extension # +ext+. def add_loader(ext, loader) @@ -108,6 +127,11 @@ @options ||= OpenStruct.new end + # Return the thread pool used for multithreaded processing. + def thread_pool # :nodoc: + @thread_pool ||= ThreadPool.new(options.thread_pool_size||FIXNUM_MAX) + end + # private ---------------------------------------------------------------- def invoke_task(task_string) @@ -146,15 +170,15 @@ # Display the error message that caused the exception. def display_error_message(ex) - $stderr.puts "#{name} aborted!" - $stderr.puts ex.message - if options.trace - $stderr.puts ex.backtrace.join("\n") + trace "#{name} aborted!" + trace ex.message + if options.backtrace + trace ex.backtrace.join("\n") else - $stderr.puts rakefile_location(ex.backtrace) + trace Backtrace.collapse(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 + 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. @@ -180,7 +204,7 @@ def have_rakefile @rakefiles.each do |fn| if File.exist?(fn) - others = Dir.glob(fn, File::FNM_CASEFOLD) + others = Rake.glob(fn, File::FNM_CASEFOLD) return others.size == 1 ? others.first : fn elsif fn == '' return fn @@ -208,7 +232,7 @@ # Display the tasks and comments. def display_tasks_and_comments displayable_tasks = tasks.select { |t| - t.comment && t.name =~ options.show_task_pattern + (options.show_all_tasks || t.comment) && t.name =~ options.show_task_pattern } case options.show_tasks when :tasks @@ -222,7 +246,8 @@ when :describe displayable_tasks.each do |t| puts "#{name} #{t.name_with_args}" - t.full_comment.split("\n").each do |line| + comment = t.full_comment || "" + comment.split("\n").each do |line| puts " #{line}" end puts @@ -271,7 +296,9 @@ end def truncate(string, width) - if string.length <= width + if string.nil? + "" + elsif string.length <= width string else ( string[0, width-3] || "" ) + "..." @@ -286,141 +313,214 @@ end end + def trace(*str) + options.trace_output ||= $stderr + options.trace_output.puts(*str) + end + + def sort_options(options) + options.sort_by { |opt| + opt.select { |o| o =~ /^-/ }.map { |o| o.downcase }.sort.reverse + } + end + private :sort_options + # A list of all the standard options used in rake, suitable for # passing to OptionParser. 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 + 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 - rake_require value - rescue LoadError - raise ex + require value + rescue LoadError => ex + begin + rake_require value + rescue LoadError + raise ex + end 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 - } - ], - ['- (... truncated) -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/