diff options
author | hsbt <hsbt@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2014-07-15 03:07:37 +0000 |
---|---|---|
committer | hsbt <hsbt@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2014-07-15 03:07:37 +0000 |
commit | 6361928083d01906ab9d8782b6533b4ed7c834a0 (patch) | |
tree | 172488be8a74c9313d35b9cd7d53999cd55f561d /lib/rake | |
parent | 031e1570b934d6b3a1e17ae8eb78a44dac8186d3 (diff) | |
download | ruby-6361928083d01906ab9d8782b6533b4ed7c834a0.tar.gz |
* lib/rake.rb, lib/rake/*.rb: Upgrade to rake-10.3.2
[fix GH-668]
* test/rake/*.rb: ditto.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@46818 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'lib/rake')
44 files changed, 598 insertions, 267 deletions
diff --git a/lib/rake/alt_system.rb b/lib/rake/alt_system.rb index a42597bf09..aa7b7791b6 100644 --- a/lib/rake/alt_system.rb +++ b/lib/rake/alt_system.rb @@ -24,11 +24,13 @@ require 'rbconfig' -# +## # Alternate implementations of system() and backticks `` on Windows # for ruby-1.8 and earlier. -# -module Rake::AltSystem +#-- +# TODO: Remove in Rake 11 + +module Rake::AltSystem # :nodoc: all WINDOWS = RbConfig::CONFIG["host_os"] =~ %r!(msdos|mswin|djgpp|mingw|[Ww]indows)! 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}$/ diff --git a/lib/rake/backtrace.rb b/lib/rake/backtrace.rb index 9b2ba6157f..439255d78b 100644 --- a/lib/rake/backtrace.rb +++ b/lib/rake/backtrace.rb @@ -1,5 +1,5 @@ module Rake - module Backtrace + module Backtrace # :nodoc: all SYS_KEYS = RbConfig::CONFIG.keys.grep(/(prefix|libdir)/) SYS_PATHS = RbConfig::CONFIG.values_at(*SYS_KEYS).uniq + [ File.join(File.dirname(__FILE__), "..") ] @@ -9,6 +9,9 @@ module Rake map { |f| File.expand_path(f) }. reject { |s| s.nil? || s =~ /^ *$/ } SUPPRESSED_PATHS_RE = SUPPRESSED_PATHS.map { |f| Regexp.quote(f) }.join("|") + SUPPRESSED_PATHS_RE << "|^org\\/jruby\\/\\w+\\.java" if + Object.const_defined?(:RUBY_ENGINE) and RUBY_ENGINE == 'jruby' + SUPPRESS_PATTERN = %r!(\A(#{SUPPRESSED_PATHS_RE})|bin/rake:\d+)!i def self.collapse(backtrace) diff --git a/lib/rake/clean.rb b/lib/rake/clean.rb index 8001ce569a..a49cd44167 100644 --- a/lib/rake/clean.rb +++ b/lib/rake/clean.rb @@ -31,9 +31,30 @@ module Rake begin rm_r file_name, opts rescue StandardError => ex - puts "Failed to remove #{file_name}: #{ex}" + puts "Failed to remove #{file_name}: #{ex}" unless file_already_gone?(file_name) end end + + def file_already_gone?(file_name) + return false if File.exist?(file_name) + + path = file_name + prev = nil + + while path = File.dirname(path) + return false if cant_be_deleted?(path) + break if [prev, "."].include?(path) + prev = path + end + true + end + private_class_method :file_already_gone? + + def cant_be_deleted?(path_name) + File.exist?(path_name) && + (!File.readable?(path_name) || !File.executable?(path_name)) + end + private_class_method :cant_be_deleted? end end diff --git a/lib/rake/cloneable.rb b/lib/rake/cloneable.rb index ac67471232..cd19cd3733 100644 --- a/lib/rake/cloneable.rb +++ b/lib/rake/cloneable.rb @@ -1,8 +1,8 @@ module Rake - # ########################################################################## + ## # Mixin for creating easily cloned objects. - # - module Cloneable + + module Cloneable # :nodoc: # The hook that invoked by 'clone' and 'dup' methods. def initialize_copy(source) super diff --git a/lib/rake/contrib/ftptools.rb b/lib/rake/contrib/ftptools.rb index 0dd50fdc8d..b178523bc6 100644 --- a/lib/rake/contrib/ftptools.rb +++ b/lib/rake/contrib/ftptools.rb @@ -9,9 +9,7 @@ require 'rake/file_list' module Rake # :nodoc: - #################################################################### - # <b>Note:</b> <em> Not released for general use.</em> - class FtpFile + class FtpFile # :nodoc: all attr_reader :name, :size, :owner, :group, :time def self.date @@ -68,9 +66,9 @@ module Rake # :nodoc: end end - #################################################################### + ## # Manage the uploading of files to an FTP account. - class FtpUploader + class FtpUploader # :nodoc: # Log uploads to standard output when true. attr_accessor :verbose diff --git a/lib/rake/contrib/publisher.rb b/lib/rake/contrib/publisher.rb index 8b11edb59c..f4ee1abf86 100644 --- a/lib/rake/contrib/publisher.rb +++ b/lib/rake/contrib/publisher.rb @@ -14,8 +14,10 @@ HostInfo = Struct.new(:name, :webdir, :pkgdir) # :startdoc: +# TODO: Move to contrib/sshpublisher +#-- # Manage several publishers as a single entity. -class CompositePublisher +class CompositePublisher # :nodoc: def initialize @publishers = [] end @@ -31,9 +33,11 @@ class CompositePublisher end end +# TODO: Remove in Rake 11, duplicated +#-- # Publish an entire directory to an existing remote directory using # SSH. -class SshDirPublisher +class SshDirPublisher # :nodoc: all def initialize(host, remote_dir, local_dir) @host = host @remote_dir = remote_dir @@ -45,8 +49,10 @@ class SshDirPublisher end end +# TODO: Remove in Rake 11, duplicated +#-- # Publish an entire directory to a fresh remote directory using SSH. -class SshFreshDirPublisher < SshDirPublisher +class SshFreshDirPublisher < SshDirPublisher # :nodoc: all def upload run %{ssh #{@host} rm -rf #{@remote_dir}} rescue nil run %{ssh #{@host} mkdir #{@remote_dir}} @@ -54,8 +60,10 @@ class SshFreshDirPublisher < SshDirPublisher end end +# TODO: Remove in Rake 11, duplicated +#-- # Publish a list of files to an existing remote directory. -class SshFilePublisher +class SshFilePublisher # :nodoc: all # Create a publisher using the give host information. def initialize(host, remote_dir, local_dir, *files) @host = host diff --git a/lib/rake/contrib/rubyforgepublisher.rb b/lib/rake/contrib/rubyforgepublisher.rb index a4b96936c8..00889ad7b9 100644 --- a/lib/rake/contrib/rubyforgepublisher.rb +++ b/lib/rake/contrib/rubyforgepublisher.rb @@ -1,8 +1,10 @@ +# TODO: Remove in Rake 11 + require 'rake/contrib/sshpublisher' module Rake - class RubyForgePublisher < SshDirPublisher + class RubyForgePublisher < SshDirPublisher # :nodoc: all attr_reader :project, :proj_id, :user def initialize(projname, user) diff --git a/lib/rake/contrib/sshpublisher.rb b/lib/rake/contrib/sshpublisher.rb index bd6adc127e..64f577017c 100644 --- a/lib/rake/contrib/sshpublisher.rb +++ b/lib/rake/contrib/sshpublisher.rb @@ -8,22 +8,30 @@ module Rake class SshDirPublisher include Rake::DSL + # Creates an SSH publisher which will scp all files in +local_dir+ to + # +remote_dir+ on +host+ + def initialize(host, remote_dir, local_dir) @host = host @remote_dir = remote_dir @local_dir = local_dir end + # Uploads the files + def upload - sh %{scp -rq #{@local_dir}/* #{@host}:#{@remote_dir}} + sh "scp", "-rq", "#{@local_dir}/*", "#{@host}:#{@remote_dir}" end end # Publish an entire directory to a fresh remote directory using SSH. class SshFreshDirPublisher < SshDirPublisher + + # Uploads the files after removing the existing remote directory. + def upload - sh %{ssh #{@host} rm -rf #{@remote_dir}} rescue nil - sh %{ssh #{@host} mkdir #{@remote_dir}} + sh "ssh", @host, "rm", "-rf", @remote_dir rescue nil + sh "ssh", @host, "mkdir", @remote_dir super end end @@ -32,7 +40,9 @@ module Rake class SshFilePublisher include Rake::DSL - # Create a publisher using the give host information. + # Creates an SSH publisher which will scp all +files+ in +local_dir+ to + # +remote_dir+ on +host+. + def initialize(host, remote_dir, local_dir, *files) @host = host @remote_dir = remote_dir @@ -40,10 +50,11 @@ module Rake @files = files end - # Upload the local directory to the remote directory. + # Uploads the files + def upload @files.each do |fn| - sh %{scp -q #{@local_dir}/#{fn} #{@host}:#{@remote_dir}} + sh "scp", "-q", "#{@local_dir}/#{fn}", "#{@host}:#{@remote_dir}" end end end diff --git a/lib/rake/contrib/sys.rb b/lib/rake/contrib/sys.rb index a3a9f69e25..8d4c735434 100644 --- a/lib/rake/contrib/sys.rb +++ b/lib/rake/contrib/sys.rb @@ -1,2 +1,4 @@ +# TODO: Remove in Rake 11 + fail "ERROR: 'rake/contrib/sys' is obsolete and no longer supported. " + "Use 'FileUtils' instead." diff --git a/lib/rake/cpu_counter.rb b/lib/rake/cpu_counter.rb new file mode 100644 index 0000000000..c05b69b7a7 --- /dev/null +++ b/lib/rake/cpu_counter.rb @@ -0,0 +1,109 @@ +require 'rbconfig' + +# TODO: replace with IO.popen using array-style arguments in Rake 11 +require 'open3' + +module Rake + + # Based on a script at: + # http://stackoverflow.com/questions/891537/ruby-detect-number-of-cpus-installed + class CpuCounter # :nodoc: all + def self.count + new.count_with_default + end + + def count_with_default(default=4) + count || default + rescue StandardError + default + end + + def count + if defined?(Java::Java) + count_via_java_runtime + else + case RbConfig::CONFIG['host_os'] + when /darwin9/ + count_via_hwprefs_cpu_count + when /darwin/ + count_via_hwprefs_thread_count || count_via_sysctl + when /linux/ + count_via_cpuinfo + when /bsd/ + count_via_sysctl + when /mswin|mingw/ + count_via_win32 + else + # Try everything + count_via_win32 || + count_via_sysctl || + count_via_hwprefs_thread_count || + count_via_hwprefs_cpu_count + end + end + end + + def count_via_java_runtime + Java::Java.lang.Runtime.getRuntime.availableProcessors + rescue StandardError + nil + end + + def count_via_win32 + require 'win32ole' + wmi = WIN32OLE.connect("winmgmts://") + cpu = wmi.ExecQuery("select NumberOfCores from Win32_Processor") # TODO count hyper-threaded in this + cpu.to_enum.first.NumberOfCores + rescue StandardError, LoadError + nil + end + + def count_via_cpuinfo + open('/proc/cpuinfo') { |f| f.readlines }.grep(/processor/).size + rescue StandardError + nil + end + + def count_via_hwprefs_thread_count + run 'hwprefs', 'thread_count' + end + + def count_via_hwprefs_cpu_count + run 'hwprefs', 'cpu_count' + end + + def count_via_sysctl + run 'sysctl', '-n', 'hw.ncpu' + end + + def run(command, *args) + cmd = resolve_command(command) + if cmd + Open3.popen3 cmd, *args do |inn, out, err,| + inn.close + err.read + out.read.to_i + end + else + nil + end + end + + def resolve_command(command) + look_for_command("/usr/sbin", command) || + look_for_command("/sbin", command) || + in_path_command(command) + end + + def look_for_command(dir, command) + path = File.join(dir, command) + File.exist?(path) ? path : nil + end + + def in_path_command(command) + Open3.popen3 'which', command do |_, out,| + out.eof? ? nil : command + end + end + end +end diff --git a/lib/rake/default_loader.rb b/lib/rake/default_loader.rb index 5dd3c05617..6154408f44 100644 --- a/lib/rake/default_loader.rb +++ b/lib/rake/default_loader.rb @@ -2,6 +2,10 @@ module Rake # Default Rakefile loader used by +import+. class DefaultLoader + + ## + # Loads a rakefile into the current application from +fn+ + def load(fn) Rake.load_rakefile(File.expand_path(fn)) end diff --git a/lib/rake/dsl_definition.rb b/lib/rake/dsl_definition.rb index b24a821386..28e9631c3c 100644 --- a/lib/rake/dsl_definition.rb +++ b/lib/rake/dsl_definition.rb @@ -6,6 +6,9 @@ module Rake ## # DSL is a module that provides #task, #desc, #namespace, etc. Use this # when you'd like to use rake outside the top level scope. + # + # For a Rakefile you run from the comamnd line this module is automatically + # included. module DSL @@ -21,14 +24,45 @@ module Rake private - # Declare a basic task. + # :call-seq: + # task task_name + # task task_name: dependencies + # task task_name, arguments => dependencies + # task task_name, argument[, argument ...], :needs: dependencies # - # Example: - # task :clobber => [:clean] do + # Declare a basic task. The +task_name+ is always the first argument. If + # the task name contains a ":" it is defined in that namespace. + # + # The +dependencies+ may be a single task name or an Array of task names. + # The +argument+ (a single name) or +arguments+ (an Array of names) define + # the arguments provided to the task. + # + # The task, argument and dependency names may be either symbols or + # strings. + # + # A task with a single dependency: + # + # task clobber: %w[clean] do # rm_rf "html" # end # - def task(*args, &block) + # A task with an argument and a dependency: + # + # task :package, [:version] => :test do |t, args| + # # ... + # end + # + # To invoke this task from the command line: + # + # $ rake package[1.2.3] + # + # Alternate definition: + # + # task :package, :version, needs: :test do |t, args| + # # ... + # end + # + def task(*args, &block) # :doc: Rake::Task.define_task(*args, &block) end @@ -45,7 +79,7 @@ module Rake # end # end # - def file(*args, &block) + def file(*args, &block) # :doc: Rake::FileTask.define_task(*args, &block) end @@ -61,7 +95,7 @@ module Rake # Example: # directory "testdata/doc" # - def directory(*args, &block) + def directory(*args, &block) # :doc: result = file_create(*args, &block) dir, _ = *Rake.application.resolve_args(args) Rake.each_dir_parent(dir) do |d| @@ -78,9 +112,9 @@ module Rake # about it) # # Example: - # multitask :deploy => [:deploy_gem, :deploy_rdoc] + # multitask deploy: %w[deploy_gem deploy_rdoc] # - def multitask(*args, &block) + def multitask(*args, &block) # :doc: Rake::MultiTask.define_task(*args, &block) end @@ -88,14 +122,22 @@ module Rake # block. Returns a NameSpace object that can be used to lookup # tasks defined in the namespace. # - # E.g. + # Example: # # ns = namespace "nested" do + # # the "nested:run" task # task :run # end # task_run = ns[:run] # find :run in the given namespace. # - def namespace(name=nil, &block) + # Tasks can also be defined in a namespace by using a ":" in the task + # name: + # + # task "nested:test" do + # # ... + # end + # + def namespace(name=nil, &block) # :doc: name = name.to_s if name.kind_of?(Symbol) name = name.to_str if name.respond_to?(:to_str) unless name.kind_of?(String) || name.nil? @@ -108,23 +150,22 @@ module Rake # # Example: # rule '.o' => '.c' do |t| - # sh %{cc -o #{t.name} #{t.source}} + # sh 'cc', '-o', t.name, t.source # end # - def rule(*args, &block) + def rule(*args, &block) # :doc: Rake::Task.create_rule(*args, &block) end - # Describe the next rake task. - # Duplicate descriptions are discarded. + # Describes the next rake task. Duplicate descriptions are discarded. # # Example: # desc "Run the Unit Tests" - # task :test => [:build] - # runtests + # task test: [:build] + # # ... run tests # end # - def desc(description) + def desc(description) # :doc: Rake.application.last_description = description end @@ -142,7 +183,7 @@ module Rake # Example: # import ".depend", "my_rules" # - def import(*fns) + def import(*fns) # :doc: fns.each do |fn| Rake.application.add_import(fn) end diff --git a/lib/rake/early_time.rb b/lib/rake/early_time.rb index 8c0e7d3339..abcb1872b5 100644 --- a/lib/rake/early_time.rb +++ b/lib/rake/early_time.rb @@ -5,11 +5,14 @@ module Rake include Comparable include Singleton + ## + # The EarlyTime always comes before +other+! + def <=>(other) -1 end - def to_s + def to_s # :nodoc: "<EARLY TIME>" end end diff --git a/lib/rake/ext/core.rb b/lib/rake/ext/core.rb index c924c7eaba..7575df15a9 100644 --- a/lib/rake/ext/core.rb +++ b/lib/rake/ext/core.rb @@ -1,8 +1,5 @@ -###################################################################### -# Core extension library -# class Module - # Check for an existing method in the current class before extending. IF + # Check for an existing method in the current class before extending. If # the method already exists, then a warning is printed and the extension is # not added. Otherwise the block is yielded and any definitions in the # block will take effect. @@ -17,7 +14,7 @@ class Module # end # end # - def rake_extension(method) + def rake_extension(method) # :nodoc: if method_defined?(method) $stderr.puts "WARNING: Possible conflict with Rake extension: " + "#{self}##{method} already exists" diff --git a/lib/rake/ext/module.rb b/lib/rake/ext/module.rb index 8b13789179..3ee155ff6c 100644 --- a/lib/rake/ext/module.rb +++ b/lib/rake/ext/module.rb @@ -1 +1,2 @@ +# TODO: remove in Rake 11 diff --git a/lib/rake/ext/string.rb b/lib/rake/ext/string.rb index 07ef167f82..34ee328f72 100644 --- a/lib/rake/ext/string.rb +++ b/lib/rake/ext/string.rb @@ -1,8 +1,5 @@ require 'rake/ext/core' -###################################################################### -# Rake extension methods for String. -# class String rake_extension("ext") do @@ -11,6 +8,8 @@ class String # is not given, or is the empty string, remove any existing extension. # # +ext+ is a user added method for the String class. + # + # This String extension comes from Rake def ext(newext='') return self.dup if ['.', '..'].include? self newext = (newext =~ /^\./) ? newext : ("." + newext) if newext != '' @@ -20,6 +19,8 @@ class String rake_extension("pathmap") do # Explode a path into individual components. Used by +pathmap+. + # + # This String extension comes from Rake def pathmap_explode head, tail = File.split(self) return [self] if head == self @@ -32,6 +33,8 @@ class String # Extract a partial path from the path. Include +n+ directories from the # front end (left hand side) if +n+ is positive. Include |+n+| # directories from the back end (right hand side) if +n+ is negative. + # + # This String extension comes from Rake def pathmap_partial(n) dirs = File.dirname(self).pathmap_explode partial_dirs = @@ -48,6 +51,8 @@ class String # Preform the pathmap replacement operations on the given path. The # patterns take the form 'pat1,rep1;pat2,rep2...'. + # + # This String extension comes from Rake def pathmap_replace(patterns, &block) result = self patterns.split(';').each do |pair| @@ -69,35 +74,36 @@ class String # controls the details of the mapping. The following special patterns are # recognized: # - # * <b>%p</b> -- The complete path. - # * <b>%f</b> -- The base file name of the path, with its file extension, - # but without any directories. - # * <b>%n</b> -- The file name of the path without its file extension. - # * <b>%d</b> -- The directory list of the path. - # * <b>%x</b> -- The file extension of the path. An empty string if there - # is no extension. - # * <b>%X</b> -- Everything *but* the file extension. - # * <b>%s</b> -- The alternate file separator if defined, otherwise use - # the standard file separator. - # * <b>%%</b> -- A percent sign. - # - # The %d specifier can also have a numeric prefix (e.g. '%2d'). If the - # number is positive, only return (up to) +n+ directories in the path, - # starting from the left hand side. If +n+ is negative, return (up to) - # |+n+| directories from the right hand side of the path. + # <tt>%p</tt> :: The complete path. + # <tt>%f</tt> :: The base file name of the path, with its file extension, + # but without any directories. + # <tt>%n</tt> :: The file name of the path without its file extension. + # <tt>%d</tt> :: The directory list of the path. + # <tt>%x</tt> :: The file extension of the path. An empty string if there + # is no extension. + # <tt>%X</tt> :: Everything *but* the file extension. + # <tt>%s</tt> :: The alternate file separator if defined, otherwise use # + # the standard file separator. + # <tt>%%</tt> :: A percent sign. + # + # The <tt>%d</tt> specifier can also have a numeric prefix (e.g. '%2d'). + # If the number is positive, only return (up to) +n+ directories in the + # path, starting from the left hand side. If +n+ is negative, return (up + # to) +n+ directories from the right hand side of the path. # # Examples: # # 'a/b/c/d/file.txt'.pathmap("%2d") => 'a/b' # 'a/b/c/d/file.txt'.pathmap("%-2d") => 'c/d' # - # Also the %d, %p, %f, %n, %x, and %X operators can take a - # pattern/replacement argument to perform simple string substitutions on a - # particular part of the path. The pattern and replacement are separated - # by a comma and are enclosed by curly braces. The replacement spec comes - # after the % character but before the operator letter. (e.g. - # "%{old,new}d"). Multiple replacement specs should be separated by - # semi-colons (e.g. "%{old,new;src,bin}d"). + # Also the <tt>%d</tt>, <tt>%p</tt>, <tt>%f</tt>, <tt>%n</tt>, + # <tt>%x</tt>, and <tt>%X</tt> operators can take a pattern/replacement + # argument to perform simple string substitutions on a particular part of + # the path. The pattern and replacement are separated by a comma and are + # enclosed by curly braces. The replacement spec comes after the % + # character but before the operator letter. (e.g. "%{old,new}d"). + # Multiple replacement specs should be separated by semi-colons (e.g. + # "%{old,new;src,bin}d"). # # Regular expressions may be used for the pattern, and back refs may be # used in the replacement text. Curly braces, commas and semi-colons are @@ -106,11 +112,11 @@ class String # # For example: # - # "src/org/onestepback/proj/A.java".pathmap("%{^src,bin}X.class") + # "src/org/onestepback/proj/A.java".pathmap("%{^src,class}X.class") # # returns: # - # "bin/org/onestepback/proj/A.class" + # "class/org/onestepback/proj/A.class" # # If the replacement text is '*', then a block may be provided to perform # some arbitrary calculation for the replacement. @@ -125,6 +131,7 @@ class String # # "/path/to/file.txt" # + # This String extension comes from Rake def pathmap(spec=nil, &block) return self if spec.nil? result = '' diff --git a/lib/rake/ext/time.rb b/lib/rake/ext/time.rb index ea8b037e39..c058649b7e 100644 --- a/lib/rake/ext/time.rb +++ b/lib/rake/ext/time.rb @@ -3,7 +3,7 @@ require 'rake/early_time' -class Time +class Time # :nodoc: all alias rake_original_time_compare :<=> def <=>(other) if Rake::EarlyTime === other diff --git a/lib/rake/file_list.rb b/lib/rake/file_list.rb index f32b8c62a4..b01dbbb341 100644 --- a/lib/rake/file_list.rb +++ b/lib/rake/file_list.rb @@ -2,10 +2,10 @@ require 'rake/cloneable' require 'rake/file_utils_ext' require 'rake/pathmap' -###################################################################### + module Rake - # ######################################################################### + ## # A FileList is essentially an array with a few helper methods defined to # make file manipulation a bit easier. # @@ -156,7 +156,6 @@ module Rake self end - # Clear all the exclude patterns so that we exclude nothing. def clear_exclude @exclude_patterns = [] @@ -164,7 +163,7 @@ module Rake self end - # Define equality. + # A FileList is equal through array equality. def ==(array) to_ary == array end @@ -208,7 +207,7 @@ module Rake self end - def resolve_add(fn) + def resolve_add(fn) # :nodoc: case fn when %r{[*?\[\{]} add_matching(fn) @@ -218,7 +217,7 @@ module Rake end private :resolve_add - def resolve_exclude + def resolve_exclude # :nodoc: reject! { |fn| excluded_from_list?(fn) } self end @@ -276,7 +275,6 @@ module Rake collect { |fn| fn.ext(newext) } end - # Grep each of the files in the filelist using the given pattern. If a # block is given, call the block on each matching line, passing the file # name, line number, and the matching line of text. If no block is given, @@ -377,7 +375,7 @@ module Rake proc { |fn| fn =~ /(^|[\/\\])core$/ && ! File.directory?(fn) } ] - def import(array) + def import(array) # :nodoc: @items = array self end diff --git a/lib/rake/file_task.rb b/lib/rake/file_task.rb index 3e717c24b7..03e26d967b 100644 --- a/lib/rake/file_task.rb +++ b/lib/rake/file_task.rb @@ -2,7 +2,7 @@ require 'rake/task.rb' require 'rake/early_time' module Rake - # ######################################################################### + # A FileTask is a task that includes time based dependencies. If any of a # FileTask's prerequisites have a timestamp that is later than the file # represented by this task, then the file must be rebuilt (using the @@ -13,7 +13,7 @@ module Rake # Is this file task needed? Yes if it doesn't exist, or if its time stamp # is out of date. def needed? - ! File.exist?(name) || out_of_date?(timestamp) + ! File.exist?(name) || out_of_date?(timestamp) || @application.options.build_all end # Time stamp for file task. diff --git a/lib/rake/file_utils.rb b/lib/rake/file_utils.rb index 0f7f459d87..27f4e2e1d1 100644 --- a/lib/rake/file_utils.rb +++ b/lib/rake/file_utils.rb @@ -14,12 +14,24 @@ module FileUtils OPT_TABLE['sh'] = %w(noop verbose) OPT_TABLE['ruby'] = %w(noop verbose) - # Run the system command +cmd+. If multiple arguments are given the command - # is not run with the shell (same semantics as Kernel::exec and + # Run the system command +cmd+. If multiple arguments are given the command + # is run directly (without the shell, same semantics as Kernel::exec and # Kernel::system). # - # Example: - # sh %{ls -ltr} + # It is recommended you use the multiple argument form over interpolating + # user input for both usability and security reasons. With the multiple + # argument form you can easily process files with spaces or other shell + # reserved characters in them. With the multiple argument form your rake + # tasks are not vulnerable to users providing an argument like + # <code>; rm # -rf /</code>. + # + # If a block is given, upon command completion the block is called with an + # OK flag (true on a zero exit status) and a Process::Status object. + # Without a block a RuntimeError is raised when the command exits non-zero. + # + # Examples: + # + # sh 'ls -ltr' # # sh 'ls', 'file with spaces' # diff --git a/lib/rake/gempackagetask.rb b/lib/rake/gempackagetask.rb index 4ace0a6f0e..16e7ce042b 100644 --- a/lib/rake/gempackagetask.rb +++ b/lib/rake/gempackagetask.rb @@ -1,2 +1,4 @@ +# TODO: Remove in Rake 11 + fail "ERROR: 'rake/gempackagetask' is obsolete and no longer supported. " + - "Use 'rubygems/packagetask' instead." + "Use 'rubygems/package_task' instead." diff --git a/lib/rake/invocation_chain.rb b/lib/rake/invocation_chain.rb index dae9a35915..690435169a 100644 --- a/lib/rake/invocation_chain.rb +++ b/lib/rake/invocation_chain.rb @@ -1,6 +1,5 @@ module Rake - #################################################################### # InvocationChain tracks the chain of task invocations to detect # circular dependencies. class InvocationChain < LinkedList diff --git a/lib/rake/lib/.document b/lib/rake/lib/.document deleted file mode 100644 index 098e64716e..0000000000 --- a/lib/rake/lib/.document +++ /dev/null @@ -1 +0,0 @@ -# Ignore project.rake diff --git a/lib/rake/lib/project.rake b/lib/rake/lib/project.rake deleted file mode 100644 index a5497328a7..0000000000 --- a/lib/rake/lib/project.rake +++ /dev/null @@ -1,21 +0,0 @@ -task "create:project" => ["lib", "test", "Rakefile"] - -directory "lib" -directory "test" - -file "Rakefile" do - File.open("Rakefile", "w") do |out| - out.puts %{# -*- ruby -*- - -require 'rake/clean' -require 'rake/testtask' - -task :default => :test - -Rake::TestTask.new do |t| - t.verbose = false - t.test_files = FileList['test/test_*.rb'] -end -} - end -end diff --git a/lib/rake/linked_list.rb b/lib/rake/linked_list.rb index 7369e83ac3..b5ab797808 100644 --- a/lib/rake/linked_list.rb +++ b/lib/rake/linked_list.rb @@ -13,7 +13,7 @@ module Rake end # Polymorphically add a new element to the head of a list. The - # type of head node will be the same list type has the tail. + # type of head node will be the same list type as the tail. def conj(item) self.class.cons(item, self) end diff --git a/lib/rake/name_space.rb b/lib/rake/name_space.rb index e1cc0940b8..58f911e434 100644 --- a/lib/rake/name_space.rb +++ b/lib/rake/name_space.rb @@ -1,25 +1,38 @@ -module Rake - - # The NameSpace class will lookup task names in the the scope - # defined by a +namespace+ command. - # - class NameSpace - - # Create a namespace lookup object using the given task manager - # and the list of scopes. - def initialize(task_manager, scope_list) - @task_manager = task_manager - @scope = scope_list.dup - end - - # Lookup a task named +name+ in the namespace. - def [](name) - @task_manager.lookup(name, @scope) - end - - # Return the list of tasks defined in this and nested namespaces. - def tasks - @task_manager.tasks_in_scope(@scope) - end +## +# The NameSpace class will lookup task names in the scope defined by a +# +namespace+ command. + +class Rake::NameSpace + + ## + # Create a namespace lookup object using the given task manager + # and the list of scopes. + + def initialize(task_manager, scope_list) + @task_manager = task_manager + @scope = scope_list.dup + end + + ## + # Lookup a task named +name+ in the namespace. + + def [](name) + @task_manager.lookup(name, @scope) + end + + ## + # The scope of the namespace (a LinkedList) + + def scope + @scope.dup end + + ## + # Return the list of tasks defined in this and nested namespaces. + + def tasks + @task_manager.tasks_in_scope(@scope) + end + end + diff --git a/lib/rake/packagetask.rb b/lib/rake/packagetask.rb index 029caa6d49..e862952c05 100644 --- a/lib/rake/packagetask.rb +++ b/lib/rake/packagetask.rb @@ -11,27 +11,27 @@ module Rake # # The PackageTask will create the following targets: # - # [<b>:package</b>] + # +:package+ :: # Create all the requested package files. # - # [<b>:clobber_package</b>] + # +:clobber_package+ :: # Delete all the package files. This target is automatically # added to the main clobber target. # - # [<b>:repackage</b>] + # +:repackage+ :: # Rebuild the package files from scratch, even if they are not out # of date. # - # [<b>"<em>package_dir</em>/<em>name</em>-<em>version</em>.tgz"</b>] + # <tt>"<em>package_dir</em>/<em>name</em>-<em>version</em>.tgz"</tt> :: # Create a gzipped tar package (if <em>need_tar</em> is true). # - # [<b>"<em>package_dir</em>/<em>name</em>-<em>version</em>.tar.gz"</b>] + # <tt>"<em>package_dir</em>/<em>name</em>-<em>version</em>.tar.gz"</tt> :: # Create a gzipped tar package (if <em>need_tar_gz</em> is true). # - # [<b>"<em>package_dir</em>/<em>name</em>-<em>version</em>.tar.bz2"</b>] + # <tt>"<em>package_dir</em>/<em>name</em>-<em>version</em>.tar.bz2"</tt> :: # Create a bzip2'd tar package (if <em>need_tar_bz2</em> is true). # - # [<b>"<em>package_dir</em>/<em>name</em>-<em>version</em>.zip"</b>] + # <tt>"<em>package_dir</em>/<em>name</em>-<em>version</em>.zip"</tt> :: # Create a zip package archive (if <em>need_zip</em> is true). # # Example: @@ -127,7 +127,7 @@ module Rake file "#{package_dir}/#{file}" => [package_dir_path] + package_files do chdir(package_dir) do - sh %{#{@tar_command} #{flag}cvf #{file} #{package_name}} + sh @tar_command, "#{flag}cvf", file, package_name end end end @@ -138,7 +138,7 @@ module Rake file "#{package_dir}/#{zip_file}" => [package_dir_path] + package_files do chdir(package_dir) do - sh %{#{@zip_command} -r #{zip_file} #{package_name}} + sh @zip_command, "-r", zip_file, package_name end end end @@ -162,26 +162,38 @@ module Rake self end + # The name of this package + def package_name @version ? "#{@name}-#{@version}" : @name end + # The directory this package will be built in + def package_dir_path "#{package_dir}/#{package_name}" end + # The package name with .tgz added + def tgz_file "#{package_name}.tgz" end + # The package name with .tar.gz added + def tar_gz_file "#{package_name}.tar.gz" end + # The package name with .tar.bz2 added + def tar_bz2_file "#{package_name}.tar.bz2" end + # The package name with .zip added + def zip_file "#{package_name}.zip" end diff --git a/lib/rake/pathmap.rb b/lib/rake/pathmap.rb index 2275724341..9a840cda29 100644 --- a/lib/rake/pathmap.rb +++ b/lib/rake/pathmap.rb @@ -1 +1,3 @@ +# TODO: Remove in Rake 11 + require 'rake/ext/string' diff --git a/lib/rake/pseudo_status.rb b/lib/rake/pseudo_status.rb index 09d5c88c7e..16e1903bd6 100644 --- a/lib/rake/pseudo_status.rb +++ b/lib/rake/pseudo_status.rb @@ -1,8 +1,8 @@ module Rake - #################################################################### + ## # Exit status class for times the system just gives us a nil. - class PseudoStatus + class PseudoStatus # :nodoc: all attr_reader :exitstatus def initialize(code=0) diff --git a/lib/rake/rake_module.rb b/lib/rake/rake_module.rb index fcf5800064..3692753434 100644 --- a/lib/rake/rake_module.rb +++ b/lib/rake/rake_module.rb @@ -2,8 +2,6 @@ require 'rake/application' module Rake - # Rake module singleton methods. - # class << self # Current Rake Application def application @@ -15,6 +13,11 @@ module Rake @application = app end + def suggested_thread_count # :nodoc: + @cpu_count ||= Rake::CpuCounter.count + @cpu_count + 4 + end + # Return the original directory where the Rake application was started. def original_dir application.original_dir @@ -28,9 +31,7 @@ module Rake # Add files to the rakelib list def add_rakelib(*files) application.options.rakelib ||= [] - files.each do |file| - application.options.rakelib << file - end + application.options.rakelib.concat(files) end end diff --git a/lib/rake/rdoctask.rb b/lib/rake/rdoctask.rb index 50b7e269d5..8d7df4f12b 100644 --- a/lib/rake/rdoctask.rb +++ b/lib/rake/rdoctask.rb @@ -1,2 +1,4 @@ +# TODO: Remove in Rake 11 + fail "ERROR: 'rake/rdoctask' is obsolete and no longer supported. " + "Use 'rdoc/task' (available in RDoc 2.4.2+) instead." diff --git a/lib/rake/ruby182_test_unit_fix.rb b/lib/rake/ruby182_test_unit_fix.rb index e47feeb09c..40b30a6fde 100644 --- a/lib/rake/ruby182_test_unit_fix.rb +++ b/lib/rake/ruby182_test_unit_fix.rb @@ -1,3 +1,5 @@ +# TODO: Remove in rake 11 + # Local Rake override to fix bug in Ruby 0.8.2 module Test # :nodoc: # Local Rake override to fix bug in Ruby 0.8.2 diff --git a/lib/rake/runtest.rb b/lib/rake/runtest.rb index 3f01b28cad..4774b0e262 100644 --- a/lib/rake/runtest.rb +++ b/lib/rake/runtest.rb @@ -5,7 +5,12 @@ require 'rake/file_list' module Rake include Test::Unit::Assertions - def run_tests(pattern='test/test*.rb', log_enabled=false) + ## + # Deprecated way of running tests in process, but only for Test::Unit. + #-- + # TODO: Remove in rake 11 + + def run_tests(pattern='test/test*.rb', log_enabled=false) # :nodoc: FileList.glob(pattern).each do |fn| $stderr.puts fn if log_enabled begin diff --git a/lib/rake/scope.rb b/lib/rake/scope.rb index 33e1c08e7b..dbefcea465 100644 --- a/lib/rake/scope.rb +++ b/lib/rake/scope.rb @@ -1,5 +1,5 @@ module Rake - class Scope < LinkedList + class Scope < LinkedList # :nodoc: all # Path for the scope. def path diff --git a/lib/rake/task.rb b/lib/rake/task.rb index 5e4dd64d4e..9bcf725523 100644 --- a/lib/rake/task.rb +++ b/lib/rake/task.rb @@ -2,7 +2,7 @@ require 'rake/invocation_exception_mixin' module Rake - # ######################################################################### + ## # A Task is the basic unit of work in a Rakefile. Tasks have associated # actions (possibly more than one) and a list of prerequisites. When # invoked, a task will first ensure that all of its prerequisites have an @@ -34,14 +34,18 @@ module Rake name end - def inspect + def inspect # :nodoc: "<#{self.class} #{name} => [#{prerequisites.join(', ')}]>" end # List of sources for task. attr_writer :sources def sources - @sources ||= [] + if defined?(@sources) + @sources + else + prerequisites + end end # List of prerequisite tasks @@ -49,7 +53,7 @@ module Rake prerequisites.map { |pre| lookup_prerequisite(pre) } end - def lookup_prerequisite(prerequisite_name) + def lookup_prerequisite(prerequisite_name) # :nodoc: application[prerequisite_name, @scope] end private :lookup_prerequisite @@ -63,7 +67,7 @@ module Rake seen.values end - def collect_prerequisites(seen) + def collect_prerequisites(seen) # :nodoc: prerequisite_tasks.each do |pre| next if seen[pre.name] seen[pre.name] = pre @@ -74,7 +78,7 @@ module Rake # First source from a rule (nil if no sources) def source - @sources.first if defined?(@sources) + sources.first end # Create a task named +task_name+ with no actions or prerequisites. Use @@ -180,7 +184,7 @@ module Rake end protected :invoke_with_call_chain - def add_chain_to(exception, new_chain) + def add_chain_to(exception, new_chain) # :nodoc: exception.extend(InvocationExceptionMixin) unless exception.respond_to?(:chain) exception.chain = new_chain if exception.chain.nil? @@ -257,11 +261,12 @@ module Rake add_comment(comment) if comment && ! comment.empty? end - def comment=(comment) + def comment=(comment) # :nodoc: add_comment(comment) end - def add_comment(comment) + def add_comment(comment) # :nodoc: + return if comment.nil? @comments << comment unless @comments.include?(comment) end private :add_comment diff --git a/lib/rake/task_arguments.rb b/lib/rake/task_arguments.rb index 0094682579..fc0d657274 100644 --- a/lib/rake/task_arguments.rb +++ b/lib/rake/task_arguments.rb @@ -1,16 +1,16 @@ module Rake - #################################################################### + ## # TaskArguments manage the arguments passed to a task. # class TaskArguments include Enumerable + # Argument names attr_reader :names - # Create a TaskArgument object with a list of named arguments - # (given by :names) and a set of associated values (given by - # :values). :parent is the parent argument object. + # Create a TaskArgument object with a list of argument +names+ and a set + # of associated +values+. +parent+ is the parent argument object. def initialize(names, values, parent=nil) @names = names @parent = parent @@ -21,12 +21,12 @@ module Rake } end - # Retrive the complete array of sequential values + # Retrieve the complete array of sequential values def to_a @values.dup end - # Retrive the list of values not associated with named arguments + # Retrieve the list of values not associated with named arguments def extras @values[@names.length..-1] || [] end @@ -50,33 +50,42 @@ module Rake @hash = defaults.merge(@hash) end + # Enumerates the arguments and their values def each(&block) @hash.each(&block) end + # Extracts the argument values at +keys+ def values_at(*keys) keys.map { |k| lookup(k) } end + # Returns the value of the given argument via method_missing def method_missing(sym, *args) lookup(sym.to_sym) end + # Returns a Hash of arguments and their values def to_hash @hash end - def to_s + def to_s # :nodoc: @hash.inspect end - def inspect + def inspect # :nodoc: to_s end + # Returns true if +key+ is one of the arguments + def has_key?(key) + @hash.has_key?(key) + end + protected - def lookup(name) + def lookup(name) # :nodoc: if @hash.has_key?(name) @hash[name] elsif @parent @@ -85,5 +94,5 @@ module Rake end end - EMPTY_TASK_ARGS = TaskArguments.new([], []) + EMPTY_TASK_ARGS = TaskArguments.new([], []) # :nodoc: end diff --git a/lib/rake/task_manager.rb b/lib/rake/task_manager.rb index 06c243a7b2..af53e3f586 100644 --- a/lib/rake/task_manager.rb +++ b/lib/rake/task_manager.rb @@ -4,9 +4,12 @@ module Rake module TaskManager # Track the last comment made in the Rakefile. attr_accessor :last_description - alias :last_comment :last_description # Backwards compatibility - def initialize + # TODO: Remove in Rake 11 + + alias :last_comment :last_description # :nodoc: Backwards compatibility + + def initialize # :nodoc: super @tasks = Hash.new @rules = Array.new @@ -14,14 +17,22 @@ module Rake @last_description = nil end - def create_rule(*args, &block) + def create_rule(*args, &block) # :nodoc: pattern, args, deps = resolve_args(args) pattern = Regexp.new(Regexp.quote(pattern) + '$') if String === pattern @rules << [pattern, args, deps, block] end - def define_task(task_class, *args, &block) + def define_task(task_class, *args, &block) # :nodoc: task_name, arg_names, deps = resolve_args(args) + + original_scope = @scope + if String === task_name and + not task_class.ancestors.include? Rake::FileTask then + task_name, *definition_scope = *(task_name.split(":").reverse) + @scope = Scope.make(*(definition_scope + @scope.to_a)) + end + task_name = task_class.scope_name(@scope, task_name) deps = [deps] unless deps.respond_to?(:to_ary) deps = deps.map { |d| d.to_s } @@ -32,6 +43,8 @@ module Rake task.add_description(get_description(task)) end task.enhance(deps, &block) + ensure + @scope = original_scope end # Lookup a task. Return an existing task if found, otherwise @@ -49,7 +62,7 @@ module Rake fail "Don't know how to build task '#{task_name}'" end - def synthesize_file_task(task_name) + def synthesize_file_task(task_name) # :nodoc: return nil unless File.exist?(task_name) define_task(Rake::FileTask, task_name) end @@ -226,7 +239,7 @@ module Rake "_anon_#{@seed}" end - def trace_rule(level, message) + def trace_rule(level, message) # :nodoc: options.trace_output.puts "#{" " * level}#{message}" if Rake.application.options.trace_rules end @@ -265,7 +278,7 @@ module Rake task_name.ext(ext) when String ext - when Proc + when Proc, Method if ext.arity == 1 ext.call(task_name) else @@ -289,7 +302,7 @@ module Rake end class << self - attr_accessor :record_task_metadata + attr_accessor :record_task_metadata # :nodoc: TaskManager.record_task_metadata = false end end diff --git a/lib/rake/tasklib.rb b/lib/rake/tasklib.rb index 48d27df9ed..6203d9402b 100644 --- a/lib/rake/tasklib.rb +++ b/lib/rake/tasklib.rb @@ -14,6 +14,8 @@ module Rake # libraries depend on this so I can't remove it without breaking # other people's code. So for now it stays for backwards # compatibility. BUT DON'T USE IT. + #-- + # TODO: Remove in Rake 11 def paste(a, b) # :nodoc: (a.to_s + b.to_s).intern end diff --git a/lib/rake/testtask.rb b/lib/rake/testtask.rb index c693dd2626..2daa589634 100644 --- a/lib/rake/testtask.rb +++ b/lib/rake/testtask.rb @@ -1,5 +1,3 @@ -# Define a task library for running unit tests. - require 'rake' require 'rake/tasklib' @@ -67,6 +65,9 @@ module Rake # Array of commandline options to pass to ruby when running test loader. attr_accessor :ruby_opts + # Description of the test task. (default is 'Run tests') + attr_accessor :description + # Explicitly define the list of test files to be included in a # test. +list+ is expected to be an array of file names (a # FileList is acceptable). If both +pattern+ and +test_files+ are @@ -86,6 +87,7 @@ module Rake @warning = false @loader = :rake @ruby_opts = [] + @description = "Run tests" + (@name == :test ? "" : " for #{@name}") yield self if block_given? @pattern = 'test/test*.rb' if @pattern.nil? && @test_files.nil? define @@ -93,7 +95,7 @@ module Rake # Create the tasks defined by this task lib. def define - desc "Run tests" + (@name == :test ? "" : " for #{@name}") + desc @description task @name do FileUtilsExt.verbose(@verbose) do args = @@ -121,18 +123,18 @@ module Rake "") end - def ruby_opts_string + def ruby_opts_string # :nodoc: opts = @ruby_opts.dup opts.unshift("-I\"#{lib_path}\"") unless @libs.empty? opts.unshift("-w") if @warning opts.join(" ") end - def lib_path + def lib_path # :nodoc: @libs.join(File::PATH_SEPARATOR) end - def file_list_string + def file_list_string # :nodoc: file_list.map { |fn| "\"#{fn}\"" }.join(' ') end @@ -156,18 +158,18 @@ module Rake end || '' end - def ruby_version + def ruby_version # :nodoc: RUBY_VERSION end - def run_code + def run_code # :nodoc: case @loader when :direct "-e \"ARGV.each{|f| require f}\"" when :testrb "-S testrb #{fix}" when :rake - "-I\"#{rake_lib_dir}\" \"#{rake_loader}\"" + "#{rake_include_arg} \"#{rake_loader}\"" end end @@ -184,6 +186,15 @@ module Rake nil end + def rake_include_arg # :nodoc: + spec = Gem.loaded_specs['rake'] + if spec.respond_to?(:default_gem?) && spec.default_gem? + "" + else + "-I\"#{rake_lib_dir}\"" + end + end + def rake_lib_dir # :nodoc: find_dir('rake') or fail "unable to find rake lib" diff --git a/lib/rake/thread_pool.rb b/lib/rake/thread_pool.rb index 44bc7483e4..d2ac6e7ac2 100644 --- a/lib/rake/thread_pool.rb +++ b/lib/rake/thread_pool.rb @@ -5,10 +5,10 @@ require 'rake/promise' module Rake - class ThreadPool # :nodoc: all + class ThreadPool # :nodoc: all - # Creates a ThreadPool object. - # The parameter is the size of the pool. + # Creates a ThreadPool object. The +thread_count+ parameter is the size + # of the pool. def initialize(thread_count) @max_active_threads = [thread_count, 0].max @threads = Set.new @@ -25,9 +25,9 @@ module Rake # Creates a future executed by the +ThreadPool+. # # The args are passed to the block when executing (similarly to - # <tt>Thread#new</tt>) The return value is an object representing + # Thread#new) The return value is an object representing # a future which has been created and added to the queue in the - # pool. Sending <tt>#value</tt> to the object will sleep the + # pool. Sending #value to the object will sleep the # current thread until the future is finished and will return the # result (or raise an exception thrown from the future) def future(*args, &block) @@ -109,13 +109,19 @@ module Rake false end + def safe_thread_count + @threads_mon.synchronize do + @threads.count + end + end + def start_thread # :nodoc: @threads_mon.synchronize do next unless @threads.count < @max_active_threads t = Thread.new do begin - while @threads.count <= @max_active_threads + while safe_thread_count <= @max_active_threads break unless process_queue_item end ensure @@ -126,6 +132,7 @@ module Rake end end end + @threads << t stat( :spawned, @@ -152,10 +159,6 @@ module Rake def __queue__ # :nodoc: @queue end - - def __threads__ # :nodoc: - @threads.dup - end end end diff --git a/lib/rake/trace_output.rb b/lib/rake/trace_output.rb index 1cd19451ca..396096d4df 100644 --- a/lib/rake/trace_output.rb +++ b/lib/rake/trace_output.rb @@ -1,5 +1,5 @@ module Rake - module TraceOutput + module TraceOutput # :nodoc: all # Write trace output to output stream +out+. # diff --git a/lib/rake/version.rb b/lib/rake/version.rb index 05c934d785..b9b1b2d485 100644 --- a/lib/rake/version.rb +++ b/lib/rake/version.rb @@ -1,6 +1,4 @@ module Rake - VERSION = '10.1.0' - module Version # :nodoc: all MAJOR, MINOR, BUILD, *OTHER = Rake::VERSION.split '.' diff --git a/lib/rake/win32.rb b/lib/rake/win32.rb index edb33938b4..6b4873da2c 100644 --- a/lib/rake/win32.rb +++ b/lib/rake/win32.rb @@ -4,7 +4,7 @@ module Rake # Win 32 interface methods for Rake. Windows specific functionality # will be placed here to collect that knowledge in one spot. - module Win32 + module Win32 # :nodoc: all # Error indicating a problem in locating the home directory on a # Win32 system. |