diff options
author | drbrain <drbrain@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2013-10-11 21:35:01 +0000 |
---|---|---|
committer | drbrain <drbrain@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2013-10-11 21:35:01 +0000 |
commit | 9cadc95b28da1cf6ca8f802292d12cc96a4f2c2d (patch) | |
tree | 73280968d3426b31c5d0b9da1d3e558aa6f9fcb9 /lib | |
parent | 52c1331763d8b9b8d6362987e6f8847b65ed7f57 (diff) | |
download | ruby-9cadc95b28da1cf6ca8f802292d12cc96a4f2c2d.tar.gz |
* NEWS (with all sufficient information):
* lib/rake: Update to rake 10.1.0
* bin/rake: ditto.
* test/rake: ditto.
* NEWS: Update NEWS to include rake 10.1.0 and links to release notes.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@43264 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'lib')
43 files changed, 569 insertions, 1954 deletions
diff --git a/lib/rake.rb b/lib/rake.rb index fff13fe460..531cfc82b8 100644 --- a/lib/rake.rb +++ b/lib/rake.rb @@ -40,6 +40,8 @@ require 'rake/ext/time' require 'rake/win32' +require 'rake/linked_list' +require 'rake/scope' require 'rake/task_argument_error' require 'rake/rule_recursion_overflow_error' require 'rake/rake_module' diff --git a/lib/rake/alt_system.rb b/lib/rake/alt_system.rb index 05af19863a..a42597bf09 100644 --- a/lib/rake/alt_system.rb +++ b/lib/rake/alt_system.rb @@ -39,7 +39,7 @@ module Rake::AltSystem end end - if WINDOWS and RUBY_VERSION < "1.9.0" + if WINDOWS && RUBY_VERSION < "1.9.0" RUNNABLE_EXTS = %w[com exe bat cmd] RUNNABLE_PATTERN = %r!\.(#{RUNNABLE_EXTS.join('|')})\Z!i @@ -73,9 +73,8 @@ module Rake::AltSystem file else RUNNABLE_EXTS.each { |ext| - if File.exist?(test = "#{file}.#{ext}") - return test - end + test = "#{file}.#{ext}" + return test if File.exist?(test) } nil end diff --git a/lib/rake/application.rb b/lib/rake/application.rb index 734e20ac31..b76244b7a3 100644 --- a/lib/rake/application.rb +++ b/lib/rake/application.rb @@ -35,7 +35,12 @@ module Rake # List of the top level task names (task names from the command line). attr_reader :top_level_tasks - DEFAULT_RAKEFILES = ['rakefile', 'Rakefile', 'rakefile.rb', 'Rakefile.rb'].freeze + DEFAULT_RAKEFILES = [ + 'rakefile', + 'Rakefile', + 'rakefile.rb', + 'Rakefile.rb' + ].freeze # Initialize a Rake::Application object. def initialize @@ -115,7 +120,8 @@ module Rake 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 + ThreadHistoryDisplay.new(thread_pool.history).show if + options.job_stats == :history end # Add a loader to handle imported files ending in the extension @@ -132,7 +138,7 @@ 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 || FIXNUM_MAX) end # private ---------------------------------------------------------------- @@ -156,19 +162,23 @@ module Rake # Provide standard exception handling for the given block. def standard_exception_handling - begin - yield - rescue SystemExit => ex - # Exit silently with current status - raise - rescue OptionParser::InvalidOption => ex - $stderr.puts ex.message - exit(false) - rescue Exception => ex - # Exit with error message - display_error_message(ex) - exit(false) - end + yield + rescue SystemExit + # Exit silently with current status + raise + rescue OptionParser::InvalidOption => ex + $stderr.puts ex.message + exit(false) + rescue Exception => ex + # Exit with error message + display_error_message(ex) + exit_because_of_exception(ex) + end + + # Exit the program because of an unhandle exception. + # (may be overridden by subclasses) + def exit_because_of_exception(ex) + exit(false) end # Display the error message that caused the exception. @@ -181,7 +191,8 @@ module Rake 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 + trace "(See full trace by running task with --trace)" unless + options.backtrace end # Warn about deprecated usage. @@ -190,10 +201,11 @@ module Rake # Rake.application.deprecate("import", "Rake.import", caller.first) # def deprecate(old_usage, new_usage, call_site) - return if options.ignore_deprecate - $stderr.puts "WARNING: '#{old_usage}' is deprecated. " + - "Please use '#{new_usage}' instead.\n" + - " at #{call_site}" + unless options.ignore_deprecate + $stderr.puts "WARNING: '#{old_usage}' is deprecated. " + + "Please use '#{new_usage}' instead.\n" + + " at #{call_site}" + end end # Does the exception have a task invocation chain? @@ -222,7 +234,7 @@ module Rake end # Override the detected TTY output state (mostly for testing) - def tty_output=( tty_output_state ) + def tty_output=(tty_output_state) @tty_output = tty_output_state end @@ -235,16 +247,22 @@ module Rake # Display the tasks and comments. def display_tasks_and_comments displayable_tasks = tasks.select { |t| - (options.show_all_tasks || 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 - width = displayable_tasks.collect { |t| t.name_with_args.length }.max || 10 - max_column = truncate_output? ? terminal_width - name.size - width - 7 : nil + width = displayable_tasks.map { |t| t.name_with_args.length }.max || 10 + if truncate_output? + max_column = terminal_width - name.size - width - 7 + else + max_column = nil + end displayable_tasks.each do |t| - printf "#{name} %-#{width}s # %s\n", - t.name_with_args, max_column ? truncate(t.comment, max_column) : t.comment + printf("#{name} %-#{width}s # %s\n", + t.name_with_args, + max_column ? truncate(t.comment, max_column) : t.comment) end when :describe displayable_tasks.each do |t| @@ -258,7 +276,7 @@ module Rake when :lines displayable_tasks.each do |t| t.locations.each do |loc| - printf "#{name} %-30s %s\n",t.name_with_args, loc + printf "#{name} %-30s %s\n", t.name_with_args, loc end end else @@ -291,7 +309,8 @@ module Rake end def unix? - RbConfig::CONFIG['host_os'] =~ /(aix|darwin|linux|(net|free|open)bsd|cygwin|solaris|irix|hpux)/i + RbConfig::CONFIG['host_os'] =~ + /(aix|darwin|linux|(net|free|open)bsd|cygwin|solaris|irix|hpux)/i end def windows? @@ -304,7 +323,7 @@ module Rake elsif string.length <= width string else - ( string[0, width-3] || "" ) + "..." + (string[0, width - 3] || "") + "..." end end @@ -333,34 +352,33 @@ module Rake def standard_rake_options sort_options( [ - ['--all', '-A', "Show all tasks, even uncommented ones", + ['--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.", + ['--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", + ['--comments', + "Show commented tasks only", lambda { |value| options.show_all_tasks = !value } ], - ['--describe', '-D [PATTERN]', "Describe the tasks (matching optional PATTERN), then exit.", + ['--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.", + ['--dry-run', '-n', + "Do a dry run without executing actions.", lambda { |value| Rake.verbose(true) Rake.nowrite(true) @@ -368,28 +386,35 @@ module Rake options.trace = true } ], - ['--execute', '-e CODE', "Execute some Ruby code and exit.", + ['--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.", + ['--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.", + "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 } + "Specifies the maximum number of tasks to execute in parallel. " + + "(default is 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", + "Display job statistics. " + + "LEVEL=history displays a complete job list", lambda { |value| if value =~ /^history/i options.job_stats = :history @@ -398,22 +423,28 @@ module Rake end } ], - ['--libdir', '-I LIBDIR', "Include LIBDIR in the search path for required modules.", + ['--libdir', '-I LIBDIR', + "Include LIBDIR in the search path for required modules.", lambda { |value| $:.push(value) } ], - ['--multitask', '-m', "Treat all tasks as multitasks.", + ['--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.", + ['--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.", + ['--prereqs', '-P', + "Display the tasks and dependencies, then exit.", lambda { |value| options.show_prereqs = true } ], - ['--quiet', '-q', "Do not log messages to standard output.", + ['--quiet', '-q', + "Do not log messages to standard output.", lambda { |value| Rake.verbose(false) } ], - ['--rakefile', '-f [FILE]', "Use FILE as the rakefile.", + ['--rakefile', '-f [FILE]', + "Use FILE as the rakefile.", lambda { |value| value ||= '' @rakefiles.clear @@ -421,15 +452,14 @@ module Rake } ], ['--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 { |_| } + "Auto-import any .rake files in RAKELIBDIR. " + + "(default is 'rakelib')", + lambda { |value| + options.rakelib = value.split(File::PATH_SEPARATOR) + } ], - ['--require', '-r MODULE', "Require MODULE before executing rakefile.", + ['--require', '-r MODULE', + "Require MODULE before executing rakefile.", lambda { |value| begin require value @@ -442,34 +472,45 @@ module Rake end } ], - ['--rules', "Trace the rules resolution.", + ['--rules', + "Trace the rules resolution.", lambda { |value| options.trace_rules = true } ], - ['--silent', '-s', "Like --quiet, but also suppresses the 'in directory' announcement.", + ['--silent', '-s', + "Like --quiet, but also suppresses the " + + "'in directory' announcement.", lambda { |value| Rake.verbose(false) options.silent = true } ], - ['--suppress-backtrace PATTERN', "Suppress backtrace lines matching regexp PATTERN. Ignored if --trace is on.", + ['--suppress-backtrace PATTERN', + "Suppress backtrace lines matching regexp PATTERN. " + + "Ignored if --trace is on.", lambda { |value| options.suppress_backtrace_pattern = Regexp.new(value) } ], ['--system', '-g', - "Using system wide (global) rakefiles (usually '~/.rake/*.rake').", + "Using system wide (global) rakefiles " + + "(usually '~/.rake/*.rake').", lambda { |value| options.load_system = true } ], ['--no-system', '--nosystem', '-G', - "Use standard project Rakefile search paths, ignore system wide rakefiles.", + "Use standard project Rakefile search paths, " + + "ignore system wide rakefiles.", lambda { |value| options.ignore_system = true } ], - ['--tasks', '-T [PATTERN]', "Display the tasks (matching optional PATTERN) with descriptions, then exit.", + ['--tasks', '-T [PATTERN]', + "Display the tasks (matching optional PATTERN) " + + "with descriptions, then exit.", lambda { |value| select_tasks_to_show(options, :tasks, value) } ], - ['--trace=[OUT]', '-t', "Turn on invoke/execute tracing, enable full backtrace. OUT can be stderr (default) or stdout.", + ['--trace=[OUT]', '-t', + "Turn on invoke/execute tracing, enable full backtrace. " + + "OUT can be stderr (default) or stdout.", lambda { |value| options.trace = true options.backtrace = true @@ -477,22 +518,26 @@ module Rake Rake.verbose(true) } ], - ['--verbose', '-v', "Log message to standard output.", + ['--verbose', '-v', + "Log message to standard output.", lambda { |value| Rake.verbose(true) } ], - ['--version', '-V', "Display the program version.", + ['--version', '-V', + "Display the program version.", lambda { |value| puts "rake, version #{RAKEVERSION}" exit } ], - ['--where', '-W [PATTERN]', "Describe the tasks (matching optional PATTERN), then exit.", + ['--where', '-W [PATTERN]', + "Describe the tasks (matching optional PATTERN), then exit.", lambda { |value| select_tasks_to_show(options, :lines, value) options.show_all_tasks = true } ], - ['--no-deprecation-warnings', '-X', "Disable the deprecation warnings.", + ['--no-deprecation-warnings', '-X', + "Disable the deprecation warnings.", lambda { |value| options.ignore_deprecate = true } @@ -515,7 +560,8 @@ module Rake when 'stderr', nil options.trace_output = $stderr else - fail CommandLineOptionError, "Unrecognized --#{trace_option} option '#{value}'" + fail CommandLineOptionError, + "Unrecognized --#{trace_option} option '#{value}'" end end private :select_trace_output @@ -526,7 +572,7 @@ module Rake options.trace_output = $stderr OptionParser.new do |opts| - opts.banner = "rake [-f rakefile] {options} targets..." + opts.banner = "#{Rake.application.name} [-f rakefile] {options} targets..." opts.separator "" opts.separator "Options are ..." @@ -538,16 +584,6 @@ module Rake standard_rake_options.each { |args| opts.on(*args) } opts.environment('RAKEOPT') end.parse! - - # If class namespaces are requested, set the global options - # according to the values in the options structure. - if options.classic_namespace - $show_tasks = options.show_tasks - $show_prereqs = options.show_prereqs - $trace = options.trace - $dryrun = options.dryrun - $silent = options.silent - end end # Similar to the regular Ruby +require+ command, but will check @@ -568,11 +604,9 @@ module Rake def find_rakefile_location here = Dir.pwd - while ! (fn = have_rakefile) + until (fn = have_rakefile) Dir.chdir("..") - if Dir.pwd == here || options.nosearch - return nil - end + return nil if Dir.pwd == here || options.nosearch here = Dir.pwd end [fn, here] @@ -600,8 +634,8 @@ module Rake @rakefile = rakefile Dir.chdir(location) print_rakefile_directory(location) - $rakefile = @rakefile if options.classic_namespace - Rake.load_rakefile(File.expand_path(@rakefile)) if @rakefile && @rakefile != '' + Rake.load_rakefile(File.expand_path(@rakefile)) if + @rakefile && @rakefile != '' options.rakelib.each do |rlib| glob("#{rlib}/*.rake") do |name| add_import name @@ -646,13 +680,19 @@ module Rake def collect_tasks @top_level_tasks = [] ARGV.each do |arg| - if arg =~ /^(\w+)=(.*)$/ + if arg =~ /^(\w+)=(.*)$/m ENV[$1] = $2 else @top_level_tasks << arg unless arg =~ /^-/ end end - @top_level_tasks.push("default") if @top_level_tasks.size == 0 + @top_level_tasks.push(default_task_name) if @top_level_tasks.empty? + end + + # Default task name ("default"). + # (May be overridden by subclasses) + def default_task_name + "default" end # Add a file to the list of files to be imported. @@ -664,9 +704,7 @@ module Rake def load_imports while fn = @pending_imports.shift next if @imported.member?(fn) - if fn_task = lookup(fn) - fn_task.invoke - end + fn_task = lookup(fn) and fn_task.invoke ext = File.extname(fn) loader = @loaders[ext] || @default_loader loader.load(fn) @@ -674,20 +712,8 @@ module Rake end end - # Warn about deprecated use of top level constant names. - def const_warning(const_name) - @const_warning ||= false - if ! @const_warning - $stderr.puts %{WARNING: Deprecated reference to top-level constant '#{const_name}' } + - %{found at: #{rakefile_location}} # ' - $stderr.puts %{ Use --classic-namespace on rake command} - $stderr.puts %{ or 'require "rake/classic_namespace"' in Rakefile} - end - @const_warning = true - end - def rakefile_location(backtrace=caller) - backtrace.map { |t| t[/([^:]+):/,1] } + backtrace.map { |t| t[/([^:]+):/, 1] } re = /^#{@rakefile}$/ re = /#{re.source}/i if windows? diff --git a/lib/rake/backtrace.rb b/lib/rake/backtrace.rb index e67132f67a..9b2ba6157f 100644 --- a/lib/rake/backtrace.rb +++ b/lib/rake/backtrace.rb @@ -1,13 +1,15 @@ module Rake module Backtrace - SUPPRESSED_PATHS = - RbConfig::CONFIG.values_at(*RbConfig::CONFIG. - keys.grep(/(prefix|libdir)/)).uniq + [ - File.join(File.dirname(__FILE__), ".."), - ].map { |f| Regexp.quote(File.expand_path(f)) } - SUPPRESSED_PATHS.reject! { |s| s.nil? || s =~ /^ *$/ } + SYS_KEYS = RbConfig::CONFIG.keys.grep(/(prefix|libdir)/) + SYS_PATHS = RbConfig::CONFIG.values_at(*SYS_KEYS).uniq + + [ File.join(File.dirname(__FILE__), "..") ] - SUPPRESS_PATTERN = %r!(\A#{SUPPRESSED_PATHS.join('|')}|bin/rake:\d+)!i + SUPPRESSED_PATHS = SYS_PATHS. + map { |s| s.gsub("\\", "/") }. + map { |f| File.expand_path(f) }. + reject { |s| s.nil? || s =~ /^ *$/ } + SUPPRESSED_PATHS_RE = SUPPRESSED_PATHS.map { |f| Regexp.quote(f) }.join("|") + SUPPRESS_PATTERN = %r!(\A(#{SUPPRESSED_PATHS_RE})|bin/rake:\d+)!i def self.collapse(backtrace) pattern = Rake.application.options.suppress_backtrace_pattern || diff --git a/lib/rake/classic_namespace.rb b/lib/rake/classic_namespace.rb deleted file mode 100644 index 6e71012da4..0000000000 --- a/lib/rake/classic_namespace.rb +++ /dev/null @@ -1,11 +0,0 @@ -# The following classes used to be in the top level namespace. -# Loading this file enables compatibility with older Rakefile that -# referenced Task from the top level. - -warn "WARNING: Classic namespaces are deprecated and will be removed from future versions of Rake." -# :stopdoc: -Task = Rake::Task -FileTask = Rake::FileTask -FileCreationTask = Rake::FileCreationTask -RakeApp = Rake::Application -# :startdoc: diff --git a/lib/rake/clean.rb b/lib/rake/clean.rb index 32846d4a6d..8001ce569a 100644 --- a/lib/rake/clean.rb +++ b/lib/rake/clean.rb @@ -14,19 +14,42 @@ require 'rake' # :stopdoc: -CLEAN = Rake::FileList["**/*~", "**/*.bak", "**/core"] + +module Rake + module Cleaner + extend FileUtils + + module_function + + def cleanup_files(file_names) + file_names.each do |file_name| + cleanup(file_name) + end + end + + def cleanup(file_name, opts={}) + begin + rm_r file_name, opts + rescue StandardError => ex + puts "Failed to remove #{file_name}: #{ex}" + end + end + end +end + +CLEAN = ::Rake::FileList["**/*~", "**/*.bak", "**/core"] CLEAN.clear_exclude.exclude { |fn| fn.pathmap("%f").downcase == 'core' && File.directory?(fn) } desc "Remove any temporary products." task :clean do - CLEAN.each { |fn| rm_r fn rescue nil } + Rake::Cleaner.cleanup_files(CLEAN) end -CLOBBER = Rake::FileList.new +CLOBBER = ::Rake::FileList.new desc "Remove any generated file." task :clobber => [:clean] do - CLOBBER.each { |fn| rm_r fn rescue nil } + Rake::Cleaner.cleanup_files(CLOBBER) end diff --git a/lib/rake/contrib/ftptools.rb b/lib/rake/contrib/ftptools.rb index d39cde8ed9..0dd50fdc8d 100644 --- a/lib/rake/contrib/ftptools.rb +++ b/lib/rake/contrib/ftptools.rb @@ -50,33 +50,21 @@ module Rake # :nodoc: def parse_mode(m) result = 0 (1..9).each do |i| - result = 2*result + ((m[i]==?-) ? 0 : 1) + result = 2 * result + ((m[i] == ?-) ? 0 : 1) end result end def determine_time(d1, d2, d3) now = self.class.time.now - if /:/ =~ d3 - result = Time.parse("#{d1} #{d2} #{now.year} #{d3}") - if result > now - result = Time.parse("#{d1} #{d2} #{now.year-1} #{d3}") - end - else + if /:/ !~ d3 result = Time.parse("#{d1} #{d2} #{d3}") + else + result = Time.parse("#{d1} #{d2} #{now.year} #{d3}") + result = Time.parse("#{d1} #{d2} #{now.year - 1} #{d3}") if + result > now end result -# elements = ParseDate.parsedate("#{d1} #{d2} #{d3}") -# if elements[0].nil? -# today = self.class.date.today -# if elements[1] > today.month -# elements[0] = today.year - 1 -# else -# elements[0] = today.year -# end -# end -# elements = elements.collect { |el| el.nil? ? 0 : el } -# Time.mktime(*elements[0,7]) end end diff --git a/lib/rake/contrib/sys.rb b/lib/rake/contrib/sys.rb index 5e31ea81b4..a3a9f69e25 100644 --- a/lib/rake/contrib/sys.rb +++ b/lib/rake/contrib/sys.rb @@ -1,192 +1,2 @@ -warn 'Sys has been deprecated in favor of FileUtils' - -#-- -# Copyright 2003-2010 by Jim Weirich (jim.weirich@gmail.com) -# All rights reserved. -#++ -# -begin - require 'ftools' -rescue LoadError -end -require 'rbconfig' -require 'rake/file_list' - -###################################################################### -# Sys provides a number of file manipulation tools for the convenience -# of writing Rakefiles. All commands in this module will announce -# their activity on standard output if the $verbose flag is set -# ($verbose = true is the default). You can control this by globally -# setting $verbose or by using the +verbose+ and +quiet+ methods. -# -# Sys has been deprecated in favor of the FileUtils module available -# in Ruby 1.8. -# -module Sys - RUBY = RbConfig::CONFIG['ruby_install_name'] - - # Install all the files matching +wildcard+ into the +dest_dir+ - # directory. The permission mode is set to +mode+. - def install(wildcard, dest_dir, mode) - FileList.glob(wildcard).each do |fn| - File.install(fn, dest_dir, mode, $verbose) - end - end - - # Run the system command +cmd+. - def run(cmd) - log cmd - system(cmd) or fail "Command Failed: [#{cmd}]" - end - - # Run a Ruby interpreter with the given arguments. - def ruby(*args) - run "#{RUBY} #{args.join(' ')}" - end - - # Copy a single file from +file_name+ to +dest_file+. - def copy(file_name, dest_file) - log "Copying file #{file_name} to #{dest_file}" - File.copy(file_name, dest_file) - end - - # Copy all files matching +wildcard+ into the directory +dest_dir+. - def copy_files(wildcard, dest_dir) - for_matching_files(wildcard, dest_dir) { |from, to| copy(from, to) } - end - - # Link +file_name+ to +dest_file+. - def link(file_name, dest_file) - log "Linking file #{file_name} to #{dest_file}" - File.link(file_name, dest_file) - end - - # Link all files matching +wildcard+ into the directory +dest_dir+. - def link_files(wildcard, dest_dir) - for_matching_files(wildcard, dest_dir) { |from, to| link(from, to) } - end - - # Symlink +file_name+ to +dest_file+. - def symlink(file_name, dest_file) - log "Symlinking file #{file_name} to #{dest_file}" - File.symlink(file_name, dest_file) - end - - # Symlink all files matching +wildcard+ into the directory +dest_dir+. - def symlink_files(wildcard, dest_dir) - for_matching_files(wildcard, dest_dir) { |from, to| link(from, to) } - end - - # Remove all files matching +wildcard+. If a matching file is a - # directory, it must be empty to be removed. used +delete_all+ to - # recursively delete directories. - def delete(*wildcards) - wildcards.each do |wildcard| - FileList.glob(wildcard).each do |fn| - if File.directory?(fn) - log "Deleting directory #{fn}" - Dir.delete(fn) - else - log "Deleting file #{fn}" - File.delete(fn) - end - end - end - end - - # Recursively delete all files and directories matching +wildcard+. - def delete_all(*wildcards) - wildcards.each do |wildcard| - FileList.glob(wildcard).each do |fn| - next if ! File.exist?(fn) - if File.directory?(fn) - FileList.glob("#{fn}/*").each do |subfn| - next if subfn=='.' || subfn=='..' - delete_all(subfn) - end - log "Deleting directory #{fn}" - Dir.delete(fn) - else - log "Deleting file #{fn}" - File.delete(fn) - end - end - end - end - - # Make the directories given in +dirs+. - def makedirs(*dirs) - dirs.each do |fn| - log "Making directory #{fn}" - File.makedirs(fn) - end - end - - # Make +dir+ the current working directory for the duration of - # executing the given block. - def indir(dir) - olddir = Dir.pwd - Dir.chdir(dir) - yield - ensure - Dir.chdir(olddir) - end - - # Split a file path into individual directory names. - # - # For example: - # split_all("a/b/c") => ['a', 'b', 'c'] - def split_all(path) - head, tail = File.split(path) - return [tail] if head == '.' || tail == '/' - return [head, tail] if head == '/' - return split_all(head) + [tail] - end - - # Write a message to standard error if $verbose is enabled. - def log(msg) - print " " if $trace && $verbose - $stderr.puts msg if $verbose - end - - # Perform a block with $verbose disabled. - def quiet(&block) - with_verbose(false, &block) - end - - # Perform a block with $verbose enabled. - def verbose(&block) - with_verbose(true, &block) - end - - # Perform a block with each file matching a set of wildcards. - def for_files(*wildcards) - wildcards.each do |wildcard| - FileList.glob(wildcard).each do |fn| - yield(fn) - end - end - end - - extend(self) - - private # ---------------------------------------------------------- - - def for_matching_files(wildcard, dest_dir) - FileList.glob(wildcard).each do |fn| - dest_file = File.join(dest_dir, fn) - parent = File.dirname(dest_file) - makedirs(parent) if ! File.directory?(parent) - yield(fn, dest_file) - end - end - - def with_verbose(v) - oldverbose = $verbose - $verbose = v - yield - ensure - $verbose = oldverbose - end - -end +fail "ERROR: 'rake/contrib/sys' is obsolete and no longer supported. " + + "Use 'FileUtils' instead." diff --git a/lib/rake/doc/MIT-LICENSE b/lib/rake/doc/MIT-LICENSE deleted file mode 100644 index 7273475396..0000000000 --- a/lib/rake/doc/MIT-LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -Copyright (c) 2003, 2004 Jim Weirich - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - diff --git a/lib/rake/doc/README.rdoc b/lib/rake/doc/README.rdoc deleted file mode 100644 index b97958d706..0000000000 --- a/lib/rake/doc/README.rdoc +++ /dev/null @@ -1,187 +0,0 @@ -= RAKE -- Ruby Make - -This package contains Rake, a simple ruby build program with capabilities -similar to make. - -Rake has the following features: - -* Rakefiles (rake's version of Makefiles) are completely defined in - standard Ruby syntax. No XML files to edit. No quirky Makefile - syntax to worry about (is that a tab or a space?) - -* Users can specify tasks with prerequisites. - -* Rake supports rule patterns to synthesize implicit tasks. - -* Flexible FileLists that act like arrays but know about manipulating - file names and paths. - -* A library of prepackaged tasks to make building rakefiles easier. For example, - tasks for building tarballs and publishing to FTP or SSH sites. (Formerly - tasks for building RDoc and Gems were included in rake but they're now - available in RDoc and RubyGems respectively.) - -* Supports parallel execution of tasks. - -== Installation - -=== Gem Installation - -Download and install rake with the following. - - gem install rake - -== Usage - -=== Simple Example - -First, you must write a "Rakefile" file which contains the build rules. Here's -a simple example: - - task :default => [:test] - - task :test do - ruby "test/unittest.rb" - end - -This Rakefile has two tasks: - -* A task named "test", which - upon invocation - will run a unit test file in - Ruby. -* A task named "default". This task does nothing by itself, but it has exactly - one dependency, namely the "test" task. Invoking the "default" task will - cause Rake to invoke the "test" task as well. - -Running the "rake" command without any options will cause it to run the -"default" task in the Rakefile: - - % ls - Rakefile test/ - % rake - (in /home/some_user/Projects/rake) - ruby test/unittest.rb - ....unit test output here... - -Type "rake --help" for all available options. - - -=== More Information - -* For details on Rake's command-line invocation, read - doc/command_line_usage.rdoc[https://github.com/jimweirich/rake/blob/master/doc/command_line_usage.rdoc] -* For details on writing Rakefiles, see - doc/rakefile.rdoc[https://github.com/jimweirich/rake/blob/master/doc/rakefile.rdoc]. -* For the original announcement of Rake, see - doc/rational.rdoc[https://github.com/jimweirich/rake/blob/master/doc/rational.rdoc]. -* For a glossary of terms, see - doc/glossary.rdoc[https://github.com/jimweirich/rake/blob/master/doc/glossary.rdoc]. - -== Development - -=== Source Repository - -Rake is currently hosted at github. The github web page is -http://github.com/jimweirich/rake. The public git clone URL is - -* git://github.com/jimweirich/rake.git - -=== Running the Rake Test Suite - -If you wish to run the unit and functional tests that come with Rake: - -* Install the 'flexmock' gem -* Install the 'session' gem in order to run the functional tests. -* CD into the top project directory of rake. -* Type one of the following: - - rake # If you have a version of rake installed - ruby -Ilib bin/rake # If you do not have a version of rake installed. - -=== Issues and Bug Reports - -Feature requests and bug reports can be made here - -* https://github.com/jimweirich/rake/issues - -Issues and bug reports can also be tracked here: - -* http://www.pivotaltracker.com/projects/28469 - -== Online Resources - -=== Rake References - -* Rake Documentation Home: http://docs.rubyrake.org -* Rake Project Page: http://rubyforge.org/projects/rake -* Rake API Documents: http://rake.rubyforge.org -* Rake Source Code Repo: http://github.com/jimweirich/rake -* Rake Git Repo Clone URL: git://github.com/jimweirich/rake.git -* Rake Bug Reports: https://github.com/jimweirich/rake/issues -* Rake Continuous Build Server: https://travis-ci.org/#!/jimweirich/rake - -=== Presentations and Articles about Rake - -* Jim Weirich's 2003 RubyConf presentation: - http://onestepback.org/articles/buildingwithrake/ -* Martin Fowler's article on Rake: http://martinfowler.com/articles/rake.html - -== Other Make Reinvisionings ... - -Rake is a late entry in the make replacement field. Here are links to -other projects with similar (and not so similar) goals. - -* http://directory.fsf.org/bras.html -- Bras, one of earliest - implementations of "make in a scripting language". -* http://www.a-a-p.org -- Make in Python -* http://www.aromatic.com/tools/jam.txt -- JAM, Java Automated Make -* http://ant.apache.org -- The Ant project -* http://ppt.perl.org/commands/make/index.html -- Make from the Perl - Power Tools implementation. -* http://search.cpan.org/search?query=PerlBuildSystem -- The Perl Build System -* http://make.rubyforge.org -- Rant, another Ruby make tool. - -== Credits - -[<b>Ryan Dlugosz</b>] For the initial conversation that sparked Rake. - -[<b>nobu.nokada@softhome.net</b>] For the initial patch for rule support. - -[<b>Tilman Sauerbeck <tilman@code-monkey.de></b>] For the recursive rule patch. - -[<b>Eric Hodel</b>] For aid in maintaining rake. - -== License - -Rake is available under an MIT-style license. - -See {MIT-LICENSE}[rdoc-ref:lib/rake/doc/MIT-LICENSE] for permissions. - -== Support - -The Rake homepage is http://rake.rubyforge.org. You can find the Rake -RubyForge page at http://rubyforge.org/projects/rake. - -Feel free to submit commits or feature requests. If you send a patch, -remember to update the corresponding unit tests. In fact, I prefer -new feature to be submitted in the form of new unit tests. - -For other information, feel free to ask on the ruby-talk mailing list -(which is mirrored to comp.lang.ruby) or contact -jim dot weirich at gmail.com. - ---- - -= Other stuff - -Author:: Jim Weirich <jim.weirich@gmail.com> -Requires:: Ruby 1.8.6 or later -License:: Copyright 2003-2011 by Jim Weirich. - Released under an MIT-style license. See the MIT-LICENSE - file included in the distribution. - -== Warranty - -This software is provided "as is" and without any express or -implied warranties, including, without limitation, the implied -warranties of merchantibility and fitness for a particular -purpose. diff --git a/lib/rake/doc/command_line_usage.rdoc b/lib/rake/doc/command_line_usage.rdoc deleted file mode 100644 index be930018c3..0000000000 --- a/lib/rake/doc/command_line_usage.rdoc +++ /dev/null @@ -1,152 +0,0 @@ -= Rake Command Line Usage - -Rake is invoked from the command line using: - - % rake [options ...] [VAR=VALUE ...] [targets ...] - -Options are: - -[<tt><em>name</em>=<em>value</em></tt>] - Set the environment variable <em>name</em> to <em>value</em> - during the execution of the <b>rake</b> command. You can access - the value by using ENV['<em>name</em>']. - -[<tt>--all</tt> (-A)] - Used in combination with the -T and -D options, will force - those options to show all the tasks, even the ones without comments. - -[<tt>--backtrace</tt>{=_output_} (-n)] - Enable a full backtrace (i.e. like --trace, but without the task - tracing details). The _output_ parameter is optional, but if - specified it controls where the backtrace output is sent. If - _output_ is <tt>stdout</tt>, then backtrace output is directed to - stardard output. If _output_ is <tt>stderr</tt>, or if it is - missing, then the backtrace output is sent to standard error. - -[<tt>--comments</tt>] - Used in combination with the -W options to force the output to - contain commented options only. This is the reverse of - <tt>--all</tt>. - -[<tt>--describe</tt> _pattern_ (-D)] - Describe the tasks (matching optional PATTERN), then exit. - -[<tt>--dry-run</tt> (-n)] - Do a dry run. Print the tasks invoked and executed, but do not - actually execute any of the actions. - -[<tt>--execute</tt> _code_ (-e)] - Execute some Ruby code and exit. - -[<tt>--execute-print</tt> _code_ (-p)] - Execute some Ruby code, print the result, and exit. - -[<tt>--execute-continue</tt> _code_ (-E)] - Execute some Ruby code, then continue with normal task processing. - -[<tt>--help</tt> (-H)] - Display some help text and exit. - -[<tt>--jobs</tt> _number_ (-j)] - Specifies the number of active concurrent tasks used. The - suggested value is equal to the number of CPUs. The concurrent - tasks are used to execute the <tt>multitask</tt> prerequisites. - Also see the <tt>-m</tt> option which turns all tasks into - multitasks. - - Sample values: - (no -j) : unlimited concurrent tasks (standard rake behavior) - -j : 2 concurrent tasks (exact number may change) - -j 16 : 16 concurrent tasks - -[<tt>--job-stats</tt> _level_] - - Display job statistics at the completion of the run. By default, - this will display the requested number of active tasks (from the - -j options) and the maximum number of tasks in play at any given - time. - - If the optional _level_ is <tt>history</tt>, then a complete trace - of task history will be displayed on standard output. - -[<tt>--libdir</tt> _directory_ (-I)] - Add _directory_ to the list of directories searched for require. - -[<tt>--multitask</tt> (-m)] - Treat all tasks as multitasks. ('make/drake' semantics) - -[<tt>--nosearch</tt> (-N)] - Do not search for a Rakefile in parent directories. - -[<tt>--prereqs</tt> (-P)] - Display a list of all tasks and their immediate prerequisites. - -[<tt>--quiet</tt> (-q)] - Do not echo commands from FileUtils. - -[<tt>--rakefile</tt> _filename_ (-f)] - Use _filename_ as the name of the rakefile. The default rakefile - names are +rakefile+ and +Rakefile+ (with +rakefile+ taking - precedence). If the rakefile is not found in the current - directory, +rake+ will search parent directories for a match. The - directory where the Rakefile is found will become the current - directory for the actions executed in the Rakefile. - -[<tt>--rakelibdir</tt> _rakelibdir_ (-R)] - Auto-import any .rake files in RAKELIBDIR. (default is 'rakelib') - -[<tt>--require</tt> _name_ (-r)] - Require _name_ before executing the Rakefile. - -[<tt>--rules</tt>] - Trace the rules resolution. - -[<tt>--silent (-s)</tt>] - Like --quiet, but also suppresses the 'in directory' announcement. - -[<tt>--suppress-backtrace _pattern_ </tt>] - Line matching the regular expression _pattern_ will be removed - from the backtrace output. Note that the --backtrace option is the - full backtrace without these lines suppressed. - -[<tt>--system</tt> (-g)] - Use the system wide (global) rakefiles. The project Rakefile is - ignored. By default, the system wide rakefiles are used only if no - project Rakefile is found. On Unix-like system, the system wide - rake files are located in $HOME/.rake. On a windows system they - are stored in $APPDATA/Rake. - -[<tt>--no-system</tt> (-G)] - Use the project level Rakefile, ignoring the system-wide (global) - rakefiles. - -[<tt>--tasks</tt> <em>pattern</em> (-T)] - Display a list of the major tasks and their comments. Comments - are defined using the "desc" command. If a pattern is given, then - only tasks matching the pattern are displayed. - -[<tt>--trace</tt>{=_output_} (-t)] - Turn on invoke/execute tracing. Also enable full backtrace on - errors. The _output_ parameter is optional, but if specified it - controls where the trace output is sent. If _output_ is - <tt>stdout</tt>, then trace output is directed to stardard output. - If _output_ is <tt>stderr</tt>, or if it is missing, then trace - output is sent to standard error. - -[<tt>--verbose</tt> (-v)] - Echo the Sys commands to standard output. - -[<tt>--version</tt> (-V)] - Display the program version and exit. - -[<tt>--where</tt> <em>pattern</em> (-W)] - Display tasks that match <em>pattern</em> and the file and line - number where the task is defined. By default this option will - display all tasks, not just the tasks that have descriptions. - -[<tt>--no-deprecation-warnings</tt> (-W)] - Do not display the deprecation warnings. - -In addition, any command line option of the form -<em>VAR</em>=<em>VALUE</em> will be added to the environment hash -<tt>ENV</tt> and may be tested in the Rakefile. diff --git a/lib/rake/doc/glossary.rdoc b/lib/rake/doc/glossary.rdoc deleted file mode 100644 index a811764091..0000000000 --- a/lib/rake/doc/glossary.rdoc +++ /dev/null @@ -1,51 +0,0 @@ -= Glossary - -[<b>action</b>] - Code to be executed in order to perform a task. Actions in a - rakefile are specified in a code block (usually delimited by - +do+/+end+ pairs. - -[<b>execute</b>] - When a task is executed, all of its actions are performed, in - the order they were defined. Note that unlike - <tt>invoke</tt>, <tt>execute</tt> always executes the actions - (without invoking or executing the prerequisites). - -[<b>file task</b> (FileTask)] - A file task is a task whose purpose is to create a file - (which has the same name as the task). When invoked, a file - task will only execute if one or more of the following - conditions are true. - - 1. The associated file does not exist. - 2. A prerequisite has a later time stamp than the existing file. - - Because normal Tasks always have the current time as - timestamp, a FileTask that has a normal Task prerequisite - will always execute. - -[<b>invoke</b>] - When a task is invoked, first we check to see if it has been - invoked before. if it has been, then nothing else is done. - If this is the first time its been invoked, then we invoke - each of its prerequisites. Finally, we check to see if we - need to execute the actions of this task by calling - <tt>needed?</tt>. Finally, if the task is needed, we execute - its actions. - - NOTE: Currently prerequisites are invoked even if the task is - not needed. This may change in the future. - -[<b>prerequisites</b>] - Every task has a set (possibly empty) of prerequisites. A - prerequisite P to Task T is itself a task that must be invoked - before Task T. - -[<b>rule</b>] - A rule is a recipe for synthesizing a task when no task is - explicitly defined. Rules generally synthesize file tasks. - -[<b>task</b> (Task)] - Basic unit of work in a rakefile. A task has a name, a set of - prerequisites and a list of actions to be performed. - diff --git a/lib/rake/doc/rakefile.rdoc b/lib/rake/doc/rakefile.rdoc deleted file mode 100644 index 01ecc92f63..0000000000 --- a/lib/rake/doc/rakefile.rdoc +++ /dev/null @@ -1,557 +0,0 @@ -= Rakefile Format (as of version 0.8.7) - -First of all, there is no special format for a Rakefile. A Rakefile -contains executable Ruby code. Anything legal in a ruby script is -allowed in a Rakefile. - -Now that we understand there is no special syntax in a Rakefile, there -are some conventions that are used in a Rakefile that are a little -unusual in a typical Ruby program. Since a Rakefile is tailored to -specifying tasks and actions, the idioms used in a Rakefile are -designed to support that. - -So, what goes into a Rakefile? - -== Tasks - -Tasks are the main unit of work in a Rakefile. Tasks have a name -(usually given as a symbol or a string), a list of prerequisites (more -symbols or strings) and a list of actions (given as a block). - -=== Simple Tasks - -A task is declared by using the +task+ method. +task+ takes a single -parameter that is the name of the task. - - task :name - -=== Tasks with Prerequisites - -Any prerequisites are given as a list (enclosed in square brackets) -following the name and an arrow (=>). - - task :name => [:prereq1, :prereq2] - -<b>NOTE:</b> Although this syntax looks a little funky, it is legal -Ruby. We are constructing a hash where the key is :name and the value -for that key is the list of prerequisites. It is equivalent to the -following ... - - hash = Hash.new - hash[:name] = [:prereq1, :prereq2] - task(hash) - -=== Tasks with Actions - -Actions are defined by passing a block to the +task+ method. Any Ruby -code can be placed in the block. The block may reference the task -object via the block parameter. - - task :name => [:prereq1, :prereq2] do |t| - # actions (may reference t) - end - -=== Multiple Definitions - -A task may be specified more than once. Each specification adds its -prerequisites and actions to the existing definition. This allows one -part of a rakefile to specify the actions and a different rakefile -(perhaps separately generated) to specify the dependencies. - -For example, the following is equivalent to the single task -specification given above. - - task :name - task :name => [:prereq1] - task :name => [:prereq2] - task :name do |t| - # actions - end - -== File Tasks - -Some tasks are designed to create a file from one or more other files. -Tasks that generate these files may be skipped if the file already -exists. File tasks are used to specify file creation tasks. - -File tasks are declared using the +file+ method (instead of the +task+ -method). In addition, file tasks are usually named with a string -rather than a symbol. - -The following file task creates a executable program (named +prog+) -given two object files name <tt>a.o</tt> and <tt>b.o</tt>. The tasks -for creating <tt>a.o</tt> and <tt>b.o</tt> are not shown. - - file "prog" => ["a.o", "b.o"] do |t| - sh "cc -o #{t.name} #{t.prerequisites.join(' ')}" - end - -== Directory Tasks - -It is common to need to create directories upon demand. The -+directory+ convenience method is a short-hand for creating a FileTask -that creates the directory. For example, the following declaration -... - - directory "testdata/examples/doc" - -is equivalent to ... - - file "testdata" do |t| mkdir t.name end - file "testdata/examples" do |t| mkdir t.name end - file "testdata/examples/doc" do |t| mkdir t.name end - -The +directory+ method does not accept prerequisites or actions, but -both prerequisites and actions can be added later. For example ... - - directory "testdata" - file "testdata" => ["otherdata"] - file "testdata" do - cp Dir["standard_data/*.data"], "testdata" - end - -== Tasks with Parallel Prerequisites - -Rake allows parallel execution of prerequisites using the following syntax: - - multitask :copy_files => [:copy_src, :copy_doc, :copy_bin] do - puts "All Copies Complete" - end - -In this example, +copy_files+ is a normal rake task. Its actions are -executed whenever all of its prerequisites are done. The big -difference is that the prerequisites (+copy_src+, +copy_bin+ and -+copy_doc+) are executed in parallel. Each of the prerequisites are -run in their own Ruby thread, possibly allowing faster overall runtime. - -=== Secondary Prerequisites - -If any of the primary prerequisites of a multitask have common secondary -prerequisites, all of the primary/parallel prerequisites will wait -until the common prerequisites have been run. - -For example, if the <tt>copy_<em>xxx</em></tt> tasks have the -following prerequisites: - - task :copy_src => [:prep_for_copy] - task :copy_bin => [:prep_for_copy] - task :copy_doc => [:prep_for_copy] - -Then the +prep_for_copy+ task is run before starting all the copies in -parallel. Once +prep_for_copy+ is complete, +copy_src+, +copy_bin+, -and +copy_doc+ are all run in parallel. Note that +prep_for_copy+ is -run only once, even though it is referenced in multiple threads. - -=== Thread Safety - -The Rake internal data structures are thread-safe with respect -to the multitask parallel execution, so there is no need for the user -to do extra synchronization for Rake's benefit. However, if there are -user data structures shared between the parallel prerequisites, the -user must do whatever is necessary to prevent race conditions. - -== Tasks with Arguments - -Prior to version 0.8.0, rake was only able to handle command line -arguments of the form NAME=VALUE that were passed into Rake via the -ENV hash. Many folks had asked for some kind of simple command line -arguments, perhaps using "--" to separate regular task names from -argument values on the command line. The problem is that there was no -easy way to associate positional arguments on the command line with -different tasks. Suppose both tasks :a and :b expect a command line -argument: does the first value go with :a? What if :b is run first? -Should it then get the first command line argument. - -Rake 0.8.0 solves this problem by explicitly passing values directly -to the tasks that need them. For example, if I had a release task -that required a version number, I could say: - - rake release[0.8.2] - -And the string "0.8.2" will be passed to the :release task. Multiple -arguments can be passed by separating them with a comma, for example: - - rake name[john,doe] - -Just a few words of caution. The rake task name and its arguments -need to be a single command line argument to rake. This generally -means no spaces. If spaces are needed, then the entire rake + -argument string should be quoted. Something like this: - - rake "name[billy bob, smith]" - -(Quoting rules vary between operating systems and shells, so make sure -you consult the proper docs for your OS/shell). - -=== Tasks Arguments and the Environment - -Task argument values can also be picked up from the environment. For -example, if the "release" task expected a parameter named -"release_version", then either - - rake release[0.8.2] - -or - - RELEASE_VERSION=0.8.2 rake release - -will work. Environment variable names must either match the task -parameter exactly, or match an all-uppercase version of the task -parameter. - -=== Tasks that Expect Parameters - -Parameters are only given to tasks that are setup to expect them. In -order to handle named parameters, the task declaration syntax for -tasks has been extended slightly. - -For example, a task that needs a first name and last name might be -declared as: - - task :name, [:first_name, :last_name] - -The first argument is still the name of the task (:name in this case). -The next two arguments are the names of the parameters expected by -:name in an array (:first_name and :last_name in the example). - -To access the values of the parameters, the block defining the task -behaviour can now accept a second parameter: - - task :name, [:first_name, :last_name] do |t, args| - puts "First name is #{args.first_name}" - puts "Last name is #{args.last_name}" - end - -The first argument of the block "t" is always bound to the current -task object. The second argument "args" is an open-struct like object -that allows access to the task arguments. Extra command line -arguments to a task are ignored. Missing command line arguments are -picked up from matching environment variables. If there are no -matching environment variables, they are given the nil value. - -If you wish to specify default values for the arguments, you can use -the with_defaults method in the task body. Here is the above example -where we specify default values for the first and last names: - - task :name, [:first_name, :last_name] do |t, args| - args.with_defaults(:first_name => "John", :last_name => "Dough") - puts "First name is #{args.first_name}" - puts "Last name is #{args.last_name}" - end - -=== Tasks that Expect Parameters and Have Prerequisites - -Tasks that use parameters have a slightly different format for -prerequisites. Use the arrow notation to indicate the prerequisites -for tasks with arguments. For example: - - task :name, [:first_name, :last_name] => [:pre_name] do |t, args| - args.with_defaults(:first_name => "John", :last_name => "Dough") - puts "First name is #{args.first_name}" - puts "Last name is #{args.last_name}" - end - -=== Deprecated Task Parameters Format - -There is an older format for declaring task parameters that omitted -the task argument array and used the :needs keyword to introduce the -dependencies. That format is still supported for compatibility, but -is not recommended for use. The older format may be dropped in future -versions of rake. - -== Accessing Task Programmatically - -Sometimes it is useful to manipulate tasks programmatically in a -Rakefile. To find a task object, use the <tt>:[]</tt> operator on the -<tt>Rake::Task</tt>. - -=== Programmatic Task Example - -For example, the following Rakefile defines two tasks. The :doit task -simply prints a simple "DONE" message. The :dont class will lookup -the doit class and remove (clear) all of its prerequisites and -actions. - - task :doit do - puts "DONE" - end - - task :dont do - Rake::Task[:doit].clear - end - -Running this example: - - $ rake doit - (in /Users/jim/working/git/rake/x) - DONE - $ rake dont doit - (in /Users/jim/working/git/rake/x) - $ - -The ability to programmatically manipulate tasks gives rake very -powerful meta-programming capabilities w.r.t. task execution, but -should be used with caution. - -== Rules - -When a file is named as a prerequisite, but does not have a file task -defined for it, Rake will attempt to synthesize a task by looking at a -list of rules supplied in the Rakefile. - -Suppose we were trying to invoke task "mycode.o", but no task is -defined for it. But the rakefile has a rule that look like this ... - - rule '.o' => ['.c'] do |t| - sh "cc #{t.source} -c -o #{t.name}" - end - -This rule will synthesize any task that ends in ".o". It has a -prerequisite a source file with an extension of ".c" must exist. If -Rake is able to find a file named "mycode.c", it will automatically -create a task that builds "mycode.o" from "mycode.c". - -If the file "mycode.c" does not exist, rake will attempt -to recursively synthesize a rule for it. - -When a task is synthesized from a rule, the +source+ attribute of the -task is set to the matching source file. This allows us to write -rules with actions that reference the source file. - -=== Advanced Rules - -Any regular expression may be used as the rule pattern. Additionally, -a proc may be used to calculate the name of the source file. This -allows for complex patterns and sources. - -The following rule is equivalent to the example above. - - rule( /\.o$/ => [ - proc {|task_name| task_name.sub(/\.[^.]+$/, '.c') } - ]) do |t| - sh "cc #{t.source} -c -o #{t.name}" - end - -<b>NOTE:</b> Because of a _quirk_ in Ruby syntax, parenthesis are -required on *rule* when the first argument is a regular expression. - -The following rule might be used for Java files ... - - rule '.class' => [ - proc { |tn| tn.sub(/\.class$/, '.java').sub(/^classes\//, 'src/') } - ] do |t| - java_compile(t.source, t.name) - end - -<b>NOTE:</b> +java_compile+ is a hypothetical method that invokes the -java compiler. - -== Importing Dependencies - -Any ruby file (including other rakefiles) can be included with a -standard Ruby +require+ command. The rules and declarations in the -required file are just added to the definitions already accumulated. - -Because the files are loaded _before_ the rake targets are evaluated, -the loaded files must be "ready to go" when the rake command is -invoked. This make generated dependency files difficult to use. By -the time rake gets around to updating the dependencies file, it is too -late to load it. - -The +Rake.import+ command addresses this by specifying a file to be -loaded _after_ the main rakefile is loaded, but _before_ any targets -on the command line are invoked. In addition, if the file name -matches an explicit task, that task is invoked before loading the -file. This allows dependency files to be generated and used in a -single rake command invocation. - -<b>NOTE:</b> Starting in Rake version 0.9.0, the top level +import+ -command is deprecated and we recommend using the scoped -"+Rake.import+" command mentioned above. Future versions of Rake will -drop support for the top level +import+ command. - -=== Example: - - require 'rake/loaders/makefile' - - file ".depends.mf" => [SRC_LIST] do |t| - sh "makedepend -f- -- #{CFLAGS} -- #{t.prerequisites} > #{t.name}" - end - - Rake.import ".depends.mf" - -If ".depends" does not exist, or is out of date w.r.t. the source -files, a new ".depends" file is generated using +makedepend+ before -loading. - -== Comments - -Standard Ruby comments (beginning with "#") can be used anywhere it is -legal in Ruby source code, including comments for tasks and rules. -However, if you wish a task to be described using the "-T" switch, -then you need to use the +desc+ command to describe the task. - -=== Example: - - desc "Create a distribution package" - task :package => [ ... ] do ... end - -The "-T" switch (or "--tasks" if you like to spell things out) will -display a list of tasks that have a description. If you use +desc+ to -describe your major tasks, you have a semi-automatic way of generating -a summary of your Rake file. - - traken$ rake -T - (in /home/.../rake) - rake clean # Remove any temporary products. - rake clobber # Remove any generated file. - rake clobber_rdoc # Remove rdoc products - rake contrib_test # Run tests for contrib_test - rake default # Default Task - rake install # Install the application - rake lines # Count lines in the main rake file - rake rdoc # Build the rdoc HTML Files - rake rerdoc # Force a rebuild of the RDOC files - rake test # Run tests - rake testall # Run all test targets - -Only tasks with descriptions will be displayed with the "-T" switch. -Use "-P" (or "--prereqs") to get a list of all tasks and their -prerequisites. - -== Namespaces - -As projects grow (and along with it, the number of tasks), it is -common for task names to begin to clash. For example, if you might -have a main program and a set of sample programs built by a single -Rakefile. By placing the tasks related to the main program in one -namespace, and the tasks for building the sample programs in a -different namespace, the task names will not will not interfere with -each other. - -For example: - - namespace "main" do - task :build do - # Build the main program - end - end - - namespace "samples" do - task :build do - # Build the sample programs - end - end - - task :build => ["main:build", "samples:build"] - -Referencing a task in a separate namespace can be achieved by -prefixing the task name with the namespace and a colon -(e.g. "main:build" refers to the :build task in the +main+ namespace). -Nested namespaces are supported, so - -Note that the name given in the +task+ command is always the unadorned -task name without any namespace prefixes. The +task+ command always -defines a task in the current namespace. - -=== FileTasks - -File task names are not scoped by the namespace command. Since the -name of a file task is the name of an actual file in the file system, -it makes little sense to include file task names in name space. -Directory tasks (created by the +directory+ command) are a type of -file task and are also not affected by namespaces. - -=== Name Resolution - -When looking up a task name, rake will start with the current -namespace and attempt to find the name there. If it fails to find a -name in the current namespace, it will search the parent namespaces -until a match is found (or an error occurs if there is no match). - -The "rake" namespace is a special implicit namespace that refers to -the toplevel names. - -If a task name begins with a "^" character, the name resolution will -start in the parent namespace. Multiple "^" characters are allowed. - -Here is an example file with multiple :run tasks and how various names -resolve in different locations. - - task :run - - namespace "one" do - task :run - - namespace "two" do - task :run - - # :run => "one:two:run" - # "two:run" => "one:two:run" - # "one:two:run" => "one:two:run" - # "one:run" => "one:run" - # "^run" => "one:run" - # "^^run" => "rake:run" (the top level task) - # "rake:run" => "rake:run" (the top level task) - end - - # :run => "one:run" - # "two:run" => "one:two:run" - # "^run" => "rake:run" - end - - # :run => "rake:run" - # "one:run" => "one:run" - # "one:two:run" => "one:two:run" - -== FileLists - -FileLists are the way Rake manages lists of files. You can treat a -FileList as an array of strings for the most part, but FileLists -support some additional operations. - -=== Creating a FileList - -Creating a file list is easy. Just give it the list of file names: - - fl = FileList['file1.rb', file2.rb'] - -Or give it a glob pattern: - - fl = FileList['*.rb'] - -== Odds and Ends - -=== do/end versus { } - -Blocks may be specified with either a +do+/+end+ pair, or with curly -braces in Ruby. We _strongly_ recommend using +do+/+end+ to specify the -actions for tasks and rules. Because the rakefile idiom tends to -leave off parentheses on the task/file/rule methods, unusual -ambiguities can arise when using curly braces. - -For example, suppose that the method +object_files+ returns a list of -object files in a project. Now we use +object_files+ as the -prerequisites in a rule specified with actions in curly braces. - - # DON'T DO THIS! - file "prog" => object_files { - # Actions are expected here (but it doesn't work)! - } - -Because curly braces have a higher precedence than +do+/+end+, the -block is associated with the +object_files+ method rather than the -+file+ method. - -This is the proper way to specify the task ... - - # THIS IS FINE - file "prog" => object_files do - # Actions go here - end - ----- - -== See - -* README.rdoc -- Main documentation for Rake. diff --git a/lib/rake/doc/rational.rdoc b/lib/rake/doc/rational.rdoc deleted file mode 100644 index 0e1c33873d..0000000000 --- a/lib/rake/doc/rational.rdoc +++ /dev/null @@ -1,151 +0,0 @@ -= Why rake? - -Ok, let me state from the beginning that I never intended to write this -code. I'm not convinced it is useful, and I'm not convinced anyone -would even be interested in it. All I can say is that Why's onion truck -must by been passing through the Ohio valley. - -What am I talking about? ... A Ruby version of Make. - -See, I can sense you cringing already, and I agree. The world certainly -doesn't need yet another reworking of the "make" program. I mean, we -already have "ant". Isn't that enough? - -It started yesterday. I was helping a coworker fix a problem in one of -the Makefiles we use in our project. Not a particularly tough problem, -but during the course of the conversation I began lamenting some of the -shortcomings of make. In particular, in one of my makefiles I wanted to -determine the name of a file dynamically and had to resort to some -simple scripting (in Ruby) to make it work. "Wouldn't it be nice if you -could just use Ruby inside a Makefile" I said. - -My coworker (a recent convert to Ruby) agreed, but wondered what it -would look like. So I sketched the following on the whiteboard... - - "What if you could specify the make tasks in Ruby, like this ..." - - task "build" do - java_compile(...args, etc ...) - end - - "The task function would register "build" as a target to be made, - and the block would be the action executed whenever the build - system determined that it was time to do the build target." - -We agreed that would be cool, but writing make from scratch would be WAY -too much work. And that was the end of that! - -... Except I couldn't get the thought out of my head. What exactly -would be needed to make the about syntax work as a make file? Hmmm, you -would need to register the tasks, you need some way of specifying -dependencies between tasks, and some way of kicking off the process. -Hey! What if we did ... and fifteen minutes later I had a working -prototype of Ruby make, complete with dependencies and actions. - -I showed the code to my coworker and we had a good laugh. It was just -about a page worth of code that reproduced an amazing amount of the -functionality of make. We were both truly stunned with the power of -Ruby. - -But it didn't do everything make did. In particular, it didn't have -timestamp based file dependencies (where a file is rebuilt if any of its -prerequisite files have a later timestamp). Obviously THAT would be a -pain to add and so Ruby Make would remain an interesting experiment. - -... Except as I walked back to my desk, I started thinking about what -file based dependencies would really need. Rats! I was hooked again, -and by adding a new class and two new methods, file/timestamp -dependencies were implemented. - -Ok, now I was really hooked. Last night (during CSI!) I massaged the -code and cleaned it up a bit. The result is a bare-bones replacement -for make in exactly 100 lines of code. - -For the curious, you can see it at ... -* doc/proto_rake.rdoc - -Oh, about the name. When I wrote the example Ruby Make task on my -whiteboard, my coworker exclaimed "Oh! I have the perfect name: Rake ... -Get it? Ruby-Make. Rake!" He said he envisioned the tasks as leaves -and Rake would clean them up ... or something like that. Anyways, the -name stuck. - -Some quick examples ... - -A simple task to delete backup files ... - - task :clean do - Dir['*~'].each {|fn| rm fn rescue nil} - end - -Note that task names are symbols (they are slightly easier to type -than quoted strings ... but you may use quoted string if you would -rather). Rake makes the methods of the FileUtils module directly -available, so we take advantage of the <tt>rm</tt> command. Also note -the use of "rescue nil" to trap and ignore errors in the <tt>rm</tt> -command. - -To run it, just type "rake clean". Rake will automatically find a -Rakefile in the current directory (or above!) and will invoke the -targets named on the command line. If there are no targets explicitly -named, rake will invoke the task "default". - -Here's another task with dependencies ... - - task :clobber => [:clean] do - rm_r "tempdir" - end - -Task :clobber depends upon task :clean, so :clean will be run before -:clobber is executed. - -Files are specified by using the "file" command. It is similar to the -task command, except that the task name represents a file, and the task -will be run only if the file doesn't exist, or if its modification time -is earlier than any of its prerequisites. - -Here is a file based dependency that will compile "hello.cc" to -"hello.o". - - file "hello.cc" - file "hello.o" => ["hello.cc"] do |t| - srcfile = t.name.sub(/\.o$/, ".cc") - sh %{g++ #{srcfile} -c -o #{t.name}} - end - -I normally specify file tasks with string (rather than symbols). Some -file names can't be represented by symbols. Plus it makes the -distinction between them more clear to the casual reader. - -Currently writing a task for each and every file in the project would be -tedious at best. I envision a set of libraries to make this job -easier. For instance, perhaps something like this ... - - require 'rake/ctools' - Dir['*.c'].each do |fn| - c_source_file(fn) - end - -where "c_source_file" will create all the tasks need to compile all the -C source files in a directory. Any number of useful libraries could be -created for rake. - -That's it. There's no documentation (other than whats in this -message). Does this sound interesting to anyone? If so, I'll continue -to clean it up and write it up and publish it on RAA. Otherwise, I'll -leave it as an interesting exercise and a tribute to the power of Ruby. - -Why /might/ rake be interesting to Ruby programmers. I don't know, -perhaps ... - -* No weird make syntax (only weird Ruby syntax :-) -* No need to edit or read XML (a la ant) -* Platform independent build scripts. -* Will run anywhere Ruby exists, so no need to have "make" installed. - If you stay away from the "sys" command and use things like - 'ftools', you can have a perfectly platform independent - build script. Also rake is only 100 lines of code, so it can - easily be packaged along with the rest of your code. - -So ... Sorry for the long rambling message. Like I said, I never -intended to write this code at all. diff --git a/lib/rake/dsl_definition.rb b/lib/rake/dsl_definition.rb index 143b0bcf7a..b24a821386 100644 --- a/lib/rake/dsl_definition.rb +++ b/lib/rake/dsl_definition.rb @@ -32,7 +32,6 @@ module Rake Rake::Task.define_task(*args, &block) end - # Declare a file task. # # Example: @@ -67,7 +66,7 @@ module Rake 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) + mkdir_p t.name unless File.exist?(t.name) end end result @@ -117,6 +116,7 @@ module Rake end # Describe the next rake task. + # Duplicate descriptions are discarded. # # Example: # desc "Run the Unit Tests" @@ -147,31 +147,7 @@ module Rake Rake.application.add_import(fn) end end - end - - DeprecatedCommands = Object.new.extend(DSL) - - module DeprecatedObjectDSL # :nodoc: - DSL.private_instance_methods(false).each do |name| - line = __LINE__+1 - class_eval %{ - def #{name}(*args, &block) - unless Rake.application.options.ignore_deprecate - unless @rake_dsl_warning - $stderr.puts "WARNING: Global access to Rake DSL methods is deprecated. Please include" - $stderr.puts " ... Rake::DSL into classes and modules which use the Rake DSL methods." - @rake_dsl_warning = true - end - $stderr.puts "WARNING: DSL method \#{self.class}##{name} called at \#{caller.first}" - end - Rake::DeprecatedCommands.send(:#{name}, *args, &block) - end - private :#{name} - }, __FILE__, line - end - end unless defined? Rake::REDUCE_COMPAT - extend FileUtilsExt end @@ -179,4 +155,3 @@ end # calls to task, etc. to work from a Rakefile without polluting the # object inheritance tree. self.extend Rake::DSL -include Rake::DeprecatedObjectDSL unless defined? Rake::REDUCE_COMPAT diff --git a/lib/rake/ext/core.rb b/lib/rake/ext/core.rb index 1f3a738906..c924c7eaba 100644 --- a/lib/rake/ext/core.rb +++ b/lib/rake/ext/core.rb @@ -19,7 +19,8 @@ class Module # def rake_extension(method) if method_defined?(method) - $stderr.puts "WARNING: Possible conflict with Rake extension: #{self}##{method} already exists" + $stderr.puts "WARNING: Possible conflict with Rake extension: " + + "#{self}##{method} already exists" else yield end diff --git a/lib/rake/ext/module.rb b/lib/rake/ext/module.rb index fc61bea555..e69de29bb2 100644 --- a/lib/rake/ext/module.rb +++ b/lib/rake/ext/module.rb @@ -1,39 +0,0 @@ -require 'rake/ext/core' -require 'rake/task' -require 'rake/file_task' -require 'rake/file_creation_task' -require 'rake/application' -require 'rake/task_manager' - -###################################################################### -# Rake extensions to Module. -# -class Module - - # Rename the original handler to make it available. - alias :rake_original_const_missing :const_missing - - # Check for deprecated uses of top level (i.e. in Object) uses of - # Rake class names. If someone tries to reference the constant - # name, display a warning and return the proper object. Using the - # --classic-namespace command line option will define these - # constants in Object and avoid this handler. - def const_missing(const_name) - case const_name - when :Task - Rake.application.const_warning(const_name) - Rake::Task - when :FileTask - Rake.application.const_warning(const_name) - Rake::FileTask - when :FileCreationTask - Rake.application.const_warning(const_name) - Rake::FileCreationTask - when :RakeApp - Rake.application.const_warning(const_name) - Rake::Application - else - rake_original_const_missing(const_name) - end - end -end unless defined? Rake::REDUCE_COMPAT diff --git a/lib/rake/ext/string.rb b/lib/rake/ext/string.rb index be8b463e1a..07ef167f82 100644 --- a/lib/rake/ext/string.rb +++ b/lib/rake/ext/string.rb @@ -13,9 +13,7 @@ class String # +ext+ is a user added method for the String class. def ext(newext='') return self.dup if ['.', '..'].include? self - if newext != '' - newext = (newext =~ /^\./) ? newext : ("." + newext) - end + newext = (newext =~ /^\./) ? newext : ("." + newext) if newext != '' self.chomp(File.extname(self)) << newext end end diff --git a/lib/rake/file_list.rb b/lib/rake/file_list.rb index 3eae5fb0d7..0b60925f09 100644 --- a/lib/rake/file_list.rb +++ b/lib/rake/file_list.rb @@ -41,10 +41,11 @@ module Rake # List of array methods (that are not in +Object+) that need to be # delegated. - ARRAY_METHODS = (Array.instance_methods - Object.instance_methods).map { |n| n.to_s } + ARRAY_METHODS = (Array.instance_methods - Object.instance_methods). + map { |n| n.to_s } # List of additional methods that must be delegated. - MUST_DEFINE = %w[to_a inspect <=>] + MUST_DEFINE = %w[inspect <=>] # List of methods that should not be delegated here (we define special # versions of them explicitly below). @@ -58,12 +59,13 @@ module Rake + - & | ] - DELEGATING_METHODS = (ARRAY_METHODS + MUST_DEFINE - MUST_NOT_DEFINE).collect{ |s| s.to_s }.sort.uniq + DELEGATING_METHODS = (ARRAY_METHODS + MUST_DEFINE - MUST_NOT_DEFINE). + map { |s| s.to_s }.sort.uniq # Now do the delegation. - DELEGATING_METHODS.each_with_index do |sym, i| + DELEGATING_METHODS.each do |sym| if SPECIAL_RETURN.include?(sym) - ln = __LINE__+1 + ln = __LINE__ + 1 class_eval %{ def #{sym}(*args, &block) resolve @@ -72,7 +74,7 @@ module Rake end }, __FILE__, ln else - ln = __LINE__+1 + ln = __LINE__ + 1 class_eval %{ def #{sym}(*args, &block) resolve @@ -149,10 +151,8 @@ module Rake patterns.each do |pat| @exclude_patterns << pat end - if block_given? - @exclude_procs << block - end - resolve_exclude if ! @pending + @exclude_procs << block if block_given? + resolve_exclude unless @pending self end @@ -219,7 +219,7 @@ module Rake private :resolve_add def resolve_exclude - reject! { |fn| exclude?(fn) } + reject! { |fn| excluded_from_list?(fn) } self end private :resolve_exclude @@ -231,7 +231,7 @@ module Rake # FileList['a.c', 'b.c'].sub(/\.c$/, '.o') => ['a.o', 'b.o'] # def sub(pat, rep) - inject(FileList.new) { |res, fn| res << fn.sub(pat,rep) } + inject(FileList.new) { |res, fn| res << fn.sub(pat, rep) } end # Return a new FileList with the results of running +gsub+ against each @@ -242,18 +242,18 @@ module Rake # => ['lib\\test\\file', 'x\\y'] # def gsub(pat, rep) - inject(FileList.new) { |res, fn| res << fn.gsub(pat,rep) } + inject(FileList.new) { |res, fn| res << fn.gsub(pat, rep) } end # Same as +sub+ except that the original file list is modified. def sub!(pat, rep) - each_with_index { |fn, i| self[i] = fn.sub(pat,rep) } + each_with_index { |fn, i| self[i] = fn.sub(pat, rep) } self end # Same as +gsub+ except that the original file list is modified. def gsub!(pat, rep) - each_with_index { |fn, i| self[i] = fn.gsub(pat,rep) } + each_with_index { |fn, i| self[i] = fn.gsub(pat, rep) } self end @@ -341,13 +341,19 @@ module Rake # Add matching glob patterns. def add_matching(pattern) FileList.glob(pattern).each do |fn| - self << fn unless exclude?(fn) + self << fn unless excluded_from_list?(fn) end end private :add_matching - # Should the given file name be excluded? - def exclude?(fn) + # Should the given file name be excluded from the list? + # + # NOTE: This method was formally named "exclude?", but Rails + # introduced an exclude? method as an array method and setup a + # conflict with file list. We renamed the method to avoid + # confusion. If you were using "FileList#exclude?" in your user + # code, you will need to update. + def excluded_from_list?(fn) return true if @exclude_patterns.any? do |pat| case pat when Regexp diff --git a/lib/rake/file_task.rb b/lib/rake/file_task.rb index 78902a86fd..3e717c24b7 100644 --- a/lib/rake/file_task.rb +++ b/lib/rake/file_task.rb @@ -29,7 +29,7 @@ module Rake # Are there any prerequisites with a later time than the given time stamp? def out_of_date?(stamp) - @prerequisites.any? { |n| application[n, @scope].timestamp > stamp} + @prerequisites.any? { |n| application[n, @scope].timestamp > stamp } end # ---------------------------------------------------------------- @@ -44,4 +44,3 @@ module Rake end end end - diff --git a/lib/rake/file_utils.rb b/lib/rake/file_utils.rb index 606bfb65b5..0f7f459d87 100644 --- a/lib/rake/file_utils.rb +++ b/lib/rake/file_utils.rb @@ -41,24 +41,26 @@ module FileUtils unless options[:noop] res = rake_system(*cmd) status = $? - status = PseudoStatus.new(1) if !res && status.nil? + status = Rake::PseudoStatus.new(1) if !res && status.nil? shell_runner.call(res, status) end end def create_shell_runner(cmd) # :nodoc: show_command = cmd.join(" ") - show_command = show_command[0,42] + "..." unless $trace - lambda { |ok, status| - ok or fail "Command failed with status (#{status.exitstatus}): [#{show_command}]" - } + show_command = show_command[0, 42] + "..." unless $trace + lambda do |ok, status| + ok or + fail "Command failed with status (#{status.exitstatus}): " + + "[#{show_command}]" + end end private :create_shell_runner def set_verbose_option(options) # :nodoc: unless options.key? :verbose options[:verbose] = - Rake::FileUtilsExt.verbose_flag == Rake::FileUtilsExt::DEFAULT || + (Rake::FileUtilsExt.verbose_flag == Rake::FileUtilsExt::DEFAULT) || Rake::FileUtilsExt.verbose_flag end end @@ -74,9 +76,9 @@ module FileUtils # Example: # ruby %{-pe '$_.upcase!' <README} # - def ruby(*args,&block) + def ruby(*args, &block) options = (Hash === args.last) ? args.pop : {} - if args.length > 1 then + if args.length > 1 sh(*([RUBY] + args + [options]), &block) else sh("#{RUBY} #{args.first}", options, &block) @@ -88,7 +90,7 @@ module FileUtils # Attempt to do a normal file link, but fall back to a copy if the link # fails. def safe_ln(*args) - unless LN_SUPPORTED[0] + if ! LN_SUPPORTED[0] cp(*args) else begin diff --git a/lib/rake/file_utils_ext.rb b/lib/rake/file_utils_ext.rb index b110f0952b..309159aec1 100644 --- a/lib/rake/file_utils_ext.rb +++ b/lib/rake/file_utils_ext.rb @@ -18,9 +18,6 @@ module Rake FileUtilsExt.verbose_flag = DEFAULT FileUtilsExt.nowrite_flag = false - $fileutils_verbose = true - $fileutils_nowrite = false - FileUtils.commands.each do |name| opts = FileUtils.options_of name default_options = [] @@ -90,7 +87,7 @@ module Rake oldvalue end - # Use this function to prevent potentially destructive Ruby code + # Use this function to prevent potentially destructive ruby code # from running when the :nowrite flag is set. # # Example: @@ -138,7 +135,8 @@ module Rake optdecl.each do |name| h.delete name end - raise ArgumentError, "no such option: #{h.keys.join(' ')}" unless h.empty? + raise ArgumentError, "no such option: #{h.keys.join(' ')}" unless + h.empty? end extend self diff --git a/lib/rake/gempackagetask.rb b/lib/rake/gempackagetask.rb index 5f1fc4def8..4ace0a6f0e 100644 --- a/lib/rake/gempackagetask.rb +++ b/lib/rake/gempackagetask.rb @@ -1,15 +1,2 @@ -# rake/gempackagetask is deprecated in favor of rubygems/package_task - -warn 'rake/gempackagetask is deprecated. Use rubygems/package_task instead' - -require 'rubygems' -require 'rubygems/package_task' - -require 'rake' - -# :stopdoc: - -module Rake - GemPackageTask = Gem::PackageTask -end - +fail "ERROR: 'rake/gempackagetask' is obsolete and no longer supported. " + + "Use 'rubygems/packagetask' instead." diff --git a/lib/rake/invocation_chain.rb b/lib/rake/invocation_chain.rb index 8a01ab4c29..dae9a35915 100644 --- a/lib/rake/invocation_chain.rb +++ b/lib/rake/invocation_chain.rb @@ -3,44 +3,50 @@ module Rake #################################################################### # InvocationChain tracks the chain of task invocations to detect # circular dependencies. - class InvocationChain - def initialize(value, tail) - @value = value - @tail = tail - end + class InvocationChain < LinkedList - def member?(obj) - @value == obj || @tail.member?(obj) + # Is the invocation already in the chain? + def member?(invocation) + head == invocation || tail.member?(invocation) end - def append(value) - if member?(value) - fail RuntimeError, "Circular dependency detected: #{to_s} => #{value}" + # Append an invocation to the chain of invocations. It is an error + # if the invocation already listed. + def append(invocation) + if member?(invocation) + fail RuntimeError, "Circular dependency detected: #{to_s} => #{invocation}" end - self.class.new(value, self) + conj(invocation) end + # Convert to string, ie: TOP => invocation => invocation def to_s - "#{prefix}#{@value}" + "#{prefix}#{head}" end - def self.append(value, chain) - chain.append(value) + # Class level append. + def self.append(invocation, chain) + chain.append(invocation) end private def prefix - "#{@tail.to_s} => " + "#{tail.to_s} => " end - class EmptyInvocationChain + # Null object for an empty chain. + class EmptyInvocationChain < LinkedList::EmptyLinkedList + @parent = InvocationChain + def member?(obj) false end - def append(value) - InvocationChain.new(value, self) + + def append(invocation) + conj(invocation) end + def to_s "TOP" end diff --git a/lib/rake/linked_list.rb b/lib/rake/linked_list.rb new file mode 100644 index 0000000000..26483703f4 --- /dev/null +++ b/lib/rake/linked_list.rb @@ -0,0 +1,103 @@ +module Rake + + # Polylithic linked list structure used to implement several data + # structures in Rake. + class LinkedList + include Enumerable + + attr_reader :head, :tail + + def initialize(head, tail=EMPTY) + @head = head + @tail = tail + 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. + def conj(item) + self.class.cons(item, self) + end + + # Is the list empty? + def empty? + false + end + + # Lists are structurally equivalent. + def ==(other) + current = self + while ! current.empty? && ! other.empty? + return false if current.head != other.head + current = current.tail + other = other.tail + end + current.empty? && other.empty? + end + + # Convert to string: LL(item, item...) + def to_s + items = map { |item| item.to_s }.join(", ") + "LL(#{items})" + end + + # Same as +to_s+, but with inspected items. + def inspect + items = map { |item| item.inspect }.join(", ") + "LL(#{items})" + end + + # For each item in the list. + def each + current = self + while ! current.empty? + yield(current.head) + current = current.tail + end + self + end + + # Make a list out of the given arguments. This method is + # polymorphic + def self.make(*args) + result = empty + args.reverse_each do |item| + result = cons(item, result) + end + result + end + + # Cons a new head onto the tail list. + def self.cons(head, tail) + new(head, tail) + end + + # The standard empty list class for the given LinkedList class. + def self.empty + self::EMPTY + end + + # Represent an empty list, using the Null Object Pattern. + # + # When inheriting from the LinkedList class, you should implement + # a type specific Empty class as well. Make sure you set the class + # instance variable @parent to the assocated list class (this + # allows conj, cons and make to work polymorphically). + class EmptyLinkedList < LinkedList + @parent = LinkedList + + def initialize + end + + def empty? + true + end + + def self.cons(head, tail) + @parent.cons(head, tail) + end + end + + EMPTY = EmptyLinkedList.new + end + +end diff --git a/lib/rake/name_space.rb b/lib/rake/name_space.rb index e4349e8a3d..e1cc0940b8 100644 --- a/lib/rake/name_space.rb +++ b/lib/rake/name_space.rb @@ -1,6 +1,6 @@ module Rake - # The NameSpace class will lookup task names in the scope + # The NameSpace class will lookup task names in the the scope # defined by a +namespace+ command. # class NameSpace diff --git a/lib/rake/packagetask.rb b/lib/rake/packagetask.rb index 08c1a8c025..029caa6d49 100644 --- a/lib/rake/packagetask.rb +++ b/lib/rake/packagetask.rb @@ -51,13 +51,16 @@ module Rake # Directory used to store the package files (default is 'pkg'). attr_accessor :package_dir - # True if a gzipped tar file (tgz) should be produced (default is false). + # True if a gzipped tar file (tgz) should be produced (default is + # false). attr_accessor :need_tar - # True if a gzipped tar file (tar.gz) should be produced (default is false). + # True if a gzipped tar file (tar.gz) should be produced (default + # is false). attr_accessor :need_tar_gz - # True if a bzip2'd tar file (tar.bz2) should be produced (default is false). + # True if a bzip2'd tar file (tar.bz2) should be produced (default + # is false). attr_accessor :need_tar_bz2 # True if a zip file should be produced (default is false) @@ -121,7 +124,8 @@ module Rake ].each do |(need, file, flag)| if need task :package => ["#{package_dir}/#{file}"] - file "#{package_dir}/#{file}" => [package_dir_path] + package_files do + file "#{package_dir}/#{file}" => + [package_dir_path] + package_files do chdir(package_dir) do sh %{#{@tar_command} #{flag}cvf #{file} #{package_name}} end @@ -131,7 +135,8 @@ module Rake if need_zip task :package => ["#{package_dir}/#{zip_file}"] - file "#{package_dir}/#{zip_file}" => [package_dir_path] + package_files do + file "#{package_dir}/#{zip_file}" => + [package_dir_path] + package_files do chdir(package_dir) do sh %{#{@zip_command} -r #{zip_file} #{package_name}} end @@ -145,7 +150,7 @@ module Rake @package_files.each do |fn| f = File.join(package_dir_path, fn) fdir = File.dirname(f) - mkdir_p(fdir) if !File.exist?(fdir) + mkdir_p(fdir) unless File.exist?(fdir) if File.directory?(fn) mkdir_p(f) else diff --git a/lib/rake/promise.rb b/lib/rake/promise.rb index 3258b91139..31c4563476 100644 --- a/lib/rake/promise.rb +++ b/lib/rake/promise.rb @@ -17,7 +17,7 @@ module Rake @mutex = Mutex.new @result = NOT_SET @error = NOT_SET - @args = args.collect { |a| begin; a.dup; rescue; a; end } + @args = args @block = block end diff --git a/lib/rake/pseudo_status.rb b/lib/rake/pseudo_status.rb index b58df3da18..09d5c88c7e 100644 --- a/lib/rake/pseudo_status.rb +++ b/lib/rake/pseudo_status.rb @@ -4,18 +4,23 @@ module Rake # Exit status class for times the system just gives us a nil. class PseudoStatus attr_reader :exitstatus + def initialize(code=0) @exitstatus = code end + def to_i @exitstatus << 8 end + def >>(n) to_i >> n end + def stopped? false end + def exited? true end diff --git a/lib/rake/rdoctask.rb b/lib/rake/rdoctask.rb index 261fa69b4d..50b7e269d5 100644 --- a/lib/rake/rdoctask.rb +++ b/lib/rake/rdoctask.rb @@ -1,234 +1,2 @@ -# rake/rdoctask is deprecated in favor of rdoc/task - -if Rake.application - Rake.application.deprecate('require \'rake/rdoctask\'', 'require \'rdoc/task\' (in RDoc 2.4.2+)', caller.first) -end - -require 'rubygems' - -begin - gem 'rdoc' - require 'rdoc' - require 'rdoc/task' -rescue LoadError, Gem::LoadError -end - -# :stopdoc: - -if defined?(RDoc::Task) then - module Rake - RDocTask = RDoc::Task unless const_defined? :RDocTask - end -else - require 'rake' - require 'rake/tasklib' - - module Rake - - # NOTE: Rake::RDocTask is deprecated in favor of RDoc:Task which is included - # in RDoc 2.4.2+. Use require 'rdoc/task' to require it. - # - # Create a documentation task that will generate the RDoc files for - # a project. - # - # The RDocTask will create the following targets: - # - # [<b><em>rdoc</em></b>] - # Main task for this RDOC task. - # - # [<b>:clobber_<em>rdoc</em></b>] - # Delete all the rdoc files. This target is automatically - # added to the main clobber target. - # - # [<b>:re<em>rdoc</em></b>] - # Rebuild the rdoc files from scratch, even if they are not out - # of date. - # - # Simple Example: - # - # Rake::RDocTask.new do |rd| - # rd.main = "README.rdoc" - # rd.rdoc_files.include("README.rdoc", "lib/**/*.rb") - # end - # - # The +rd+ object passed to the block is an RDocTask object. See the - # attributes list for the RDocTask class for available customization options. - # - # == Specifying different task names - # - # You may wish to give the task a different name, such as if you are - # generating two sets of documentation. For instance, if you want to have a - # development set of documentation including private methods: - # - # Rake::RDocTask.new(:rdoc_dev) do |rd| - # rd.main = "README.doc" - # rd.rdoc_files.include("README.rdoc", "lib/**/*.rb") - # rd.options << "--all" - # end - # - # The tasks would then be named :<em>rdoc_dev</em>, :clobber_<em>rdoc_dev</em>, and - # :re<em>rdoc_dev</em>. - # - # If you wish to have completely different task names, then pass a Hash as - # first argument. With the <tt>:rdoc</tt>, <tt>:clobber_rdoc</tt> and - # <tt>:rerdoc</tt> options, you can customize the task names to your liking. - # For example: - # - # Rake::RDocTask.new(:rdoc => "rdoc", :clobber_rdoc => "rdoc:clean", :rerdoc => "rdoc:force") - # - # This will create the tasks <tt>:rdoc</tt>, <tt>:rdoc_clean</tt> and - # <tt>:rdoc:force</tt>. - # - class RDocTask < TaskLib - # Name of the main, top level task. (default is :rdoc) - attr_accessor :name - - # Name of directory to receive the html output files. (default is "html") - attr_accessor :rdoc_dir - - # Title of RDoc documentation. (defaults to rdoc's default) - attr_accessor :title - - # Name of file to be used as the main, top level file of the - # RDoc. (default is none) - attr_accessor :main - - # Name of template to be used by rdoc. (defaults to rdoc's default) - attr_accessor :template - - # List of files to be included in the rdoc generation. (default is []) - attr_accessor :rdoc_files - - # Additional list of options to be passed rdoc. (default is []) - attr_accessor :options - - # Whether to run the rdoc process as an external shell (default is false) - attr_accessor :external - - attr_accessor :inline_source - - # Create an RDoc task with the given name. See the RDocTask class overview - # for documentation. - def initialize(name = :rdoc) # :yield: self - if name.is_a?(Hash) - invalid_options = name.keys.map { |k| k.to_sym } - [:rdoc, :clobber_rdoc, :rerdoc] - if !invalid_options.empty? - raise ArgumentError, "Invalid option(s) passed to RDocTask.new: #{invalid_options.join(", ")}" - end - end - - @name = name - @rdoc_files = Rake::FileList.new - @rdoc_dir = 'html' - @main = nil - @title = nil - @template = nil - @external = false - @inline_source = true - @options = [] - yield self if block_given? - define - end - - # Create the tasks defined by this task lib. - def define - if rdoc_task_name != "rdoc" - desc "Build the RDOC HTML Files" - else - desc "Build the #{rdoc_task_name} HTML Files" - end - task rdoc_task_name - - desc "Force a rebuild of the RDOC files" - task rerdoc_task_name => [clobber_task_name, rdoc_task_name] - - desc "Remove rdoc products" - task clobber_task_name do - rm_r rdoc_dir rescue nil - end - - task :clobber => [clobber_task_name] - - directory @rdoc_dir - task rdoc_task_name => [rdoc_target] - file rdoc_target => @rdoc_files + [Rake.application.rakefile] do - rm_r @rdoc_dir rescue nil - @before_running_rdoc.call if @before_running_rdoc - args = option_list + @rdoc_files - if @external - argstring = args.join(' ') - sh %{ruby -Ivendor vendor/rd #{argstring}} - else - require 'rdoc/rdoc' - RDoc::RDoc.new.document(args) - end - end - self - end - - def option_list - result = @options.dup - result << "-o" << @rdoc_dir - result << "--main" << quote(main) if main - result << "--title" << quote(title) if title - result << "-T" << quote(template) if template - result << "--inline-source" if inline_source && !@options.include?("--inline-source") && !@options.include?("-S") - result - end - - def quote(str) - if @external - "'#{str}'" - else - str - end - end - - def option_string - option_list.join(' ') - end - - # The block passed to this method will be called just before running the - # RDoc generator. It is allowed to modify RDocTask attributes inside the - # block. - def before_running_rdoc(&block) - @before_running_rdoc = block - end - - private - - def rdoc_target - "#{rdoc_dir}/index.html" - end - - def rdoc_task_name - case name - when Hash - (name[:rdoc] || "rdoc").to_s - else - name.to_s - end - end - - def clobber_task_name - case name - when Hash - (name[:clobber_rdoc] || "clobber_rdoc").to_s - else - "clobber_#{name}" - end - end - - def rerdoc_task_name - case name - when Hash - (name[:rerdoc] || "rerdoc").to_s - else - "re#{name}" - end - end - - end - end -end - +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 9e411ed51a..e47feeb09c 100644 --- a/lib/rake/ruby182_test_unit_fix.rb +++ b/lib/rake/ruby182_test_unit_fix.rb @@ -10,12 +10,14 @@ module Test # :nodoc: def collect_file(name, suites, already_gathered) # :nodoc: dir = File.dirname(File.expand_path(name)) $:.unshift(dir) unless $:.first == dir - if(@req) + if @req @req.require(name) else require(name) end - find_test_cases(already_gathered).each{|t| add_suite(suites, t.suite)} + find_test_cases(already_gathered).each do |t| + add_suite(suites, t.suite) + end ensure $:.delete_at $:.rindex(dir) end diff --git a/lib/rake/runtest.rb b/lib/rake/runtest.rb index bd816ccfde..3f01b28cad 100644 --- a/lib/rake/runtest.rb +++ b/lib/rake/runtest.rb @@ -6,7 +6,7 @@ module Rake include Test::Unit::Assertions def run_tests(pattern='test/test*.rb', log_enabled=false) - FileList.glob(pattern).each { |fn| + FileList.glob(pattern).each do |fn| $stderr.puts fn if log_enabled begin require fn @@ -15,7 +15,7 @@ module Rake $stderr.puts ex.backtrace assert false end - } + end end extend self diff --git a/lib/rake/scope.rb b/lib/rake/scope.rb new file mode 100644 index 0000000000..33e1c08e7b --- /dev/null +++ b/lib/rake/scope.rb @@ -0,0 +1,42 @@ +module Rake + class Scope < LinkedList + + # Path for the scope. + def path + map { |item| item.to_s }.reverse.join(":") + end + + # Path for the scope + the named path. + def path_with_task_name(task_name) + "#{path}:#{task_name}" + end + + # Trim +n+ innermost scope levels from the scope. In no case will + # this trim beyond the toplevel scope. + def trim(n) + result = self + while n > 0 && ! result.empty? + result = result.tail + n -= 1 + end + result + end + + # Scope lists always end with an EmptyScope object. See Null + # Object Pattern) + class EmptyScope < EmptyLinkedList + @parent = Scope + + def path + "" + end + + def path_with_task_name(task_name) + task_name + end + end + + # Singleton null object for an empty scope. + EMPTY = EmptyScope.new + end +end diff --git a/lib/rake/task.rb b/lib/rake/task.rb index ac0ce68c60..5e4dd64d4e 100644 --- a/lib/rake/task.rb +++ b/lib/rake/task.rb @@ -21,13 +21,6 @@ module Rake # Application owning this task. attr_accessor :application - # Comment for this task. Restricted to a single line of no more than 50 - # characters. - attr_reader :comment - - # Full text of the (possibly multi-line) comment. - attr_reader :full_comment - # Array of nested namespaces names used for task lookup by this task. attr_reader :scope @@ -53,7 +46,7 @@ module Rake # List of prerequisite tasks def prerequisite_tasks - prerequisites.collect { |pre| lookup_prerequisite(pre) } + prerequisites.map { |pre| lookup_prerequisite(pre) } end def lookup_prerequisite(prerequisite_name) @@ -61,6 +54,24 @@ module Rake end private :lookup_prerequisite + # List of all unique prerequisite tasks including prerequisite tasks' + # prerequisites. + # Includes self when cyclic dependencies are found. + def all_prerequisite_tasks + seen = {} + collect_prerequisites(seen) + seen.values + end + + def collect_prerequisites(seen) + prerequisite_tasks.each do |pre| + next if seen[pre.name] + seen[pre.name] = pre + pre.collect_prerequisites(seen) + end + end + protected :collect_prerequisites + # First source from a rule (nil if no sources) def source @sources.first if defined?(@sources) @@ -69,17 +80,16 @@ module Rake # Create a task named +task_name+ with no actions or prerequisites. Use # +enhance+ to add actions and prerequisites. def initialize(task_name, app) - @name = task_name.to_s - @prerequisites = [] - @actions = [] + @name = task_name.to_s + @prerequisites = [] + @actions = [] @already_invoked = false - @full_comment = nil - @comment = nil - @lock = Monitor.new - @application = app - @scope = app.current_scope - @arg_names = nil - @locations = [] + @comments = [] + @lock = Monitor.new + @application = app + @scope = app.current_scope + @arg_names = nil + @locations = [] end # Enhance a task with prerequisites or actions. Returns self. @@ -141,8 +151,7 @@ module Rake # Clear the existing comments on a rake task. def clear_comments - @full_comment = nil - @comment = nil + @comments = [] self end @@ -172,7 +181,8 @@ module Rake protected :invoke_with_call_chain def add_chain_to(exception, new_chain) - exception.extend(InvocationExceptionMixin) unless exception.respond_to?(:chain) + exception.extend(InvocationExceptionMixin) unless + exception.respond_to?(:chain) exception.chain = new_chain if exception.chain.nil? end private :add_chain_to @@ -190,8 +200,8 @@ module Rake end # Invoke all the prerequisites of a task in parallel. - def invoke_prerequisites_concurrently(task_args, invocation_chain) # :nodoc: - futures = prerequisite_tasks.collect do |p| + def invoke_prerequisites_concurrently(task_args, invocation_chain)# :nodoc: + futures = prerequisite_tasks.map do |p| prereq_args = task_args.new_scope(p.arg_names) application.thread_pool.future(p) do |r| r.invoke_with_call_chain(prereq_args, invocation_chain) @@ -216,9 +226,7 @@ module Rake application.trace "** Execute (dry run) #{name}" return end - if application.options.trace - application.trace "** Execute #{name}" - end + application.trace "** Execute #{name}" if application.options.trace application.enhance_with_matching_rule(name) if @actions.empty? @actions.each do |act| case act.arity @@ -238,38 +246,57 @@ module Rake # Timestamp for this task. Basic tasks return the current time for their # time stamp. Other tasks can be more sophisticated. def timestamp - prerequisite_tasks.collect { |pre| pre.timestamp }.max || Time.now + Time.now end # Add a description to the task. The description can consist of an option # argument list (enclosed brackets) and an optional comment. def add_description(description) - return if ! description + return unless description comment = description.strip add_comment(comment) if comment && ! comment.empty? end - # Writing to the comment attribute is the same as adding a description. - def comment=(description) - add_description(description) + def comment=(comment) + add_comment(comment) end - # Add a comment to the task. If a comment already exists, separate - # the new comment with " / ". def add_comment(comment) - if @full_comment - @full_comment << " / " - else - @full_comment = '' - end - @full_comment << comment - if @full_comment =~ /\A([^.]+?\.)( |$)/ - @comment = $1 + @comments << comment unless @comments.include?(comment) + end + private :add_comment + + # Full collection of comments. Multiple comments are separated by + # newlines. + def full_comment + transform_comments("\n") + end + + # First line (or sentence) of all comments. Multiple comments are + # separated by a "/". + def comment + transform_comments(" / ") { |c| first_sentence(c) } + end + + # Transform the list of comments as specified by the block and + # join with the separator. + def transform_comments(separator, &block) + if @comments.empty? + nil else - @comment = @full_comment + block ||= lambda { |c| c } + @comments.map(&block).join(separator) end end - private :add_comment + private :transform_comments + + # Get the first sentence in a string. The sentence is terminated + # by the first period or the end of the line. Decimal points do + # not count as periods. + def first_sentence(string) + string.split(/\.[ \t]|\.$|\n/).first + end + private :first_sentence # Set the names of the arguments for this task. +args+ should be # an array of symbols, one for each argument name. @@ -287,11 +314,11 @@ module Rake result << "timestamp: #{timestamp}\n" result << "pre-requisites: \n" prereqs = prerequisite_tasks - prereqs.sort! {|a,b| a.timestamp <=> b.timestamp} + prereqs.sort! { |a, b| a.timestamp <=> b.timestamp } prereqs.each do |p| result << "--#{p.name} (#{p.timestamp})\n" end - latest_prereq = prerequisite_tasks.collect { |pre| pre.timestamp }.max + latest_prereq = prerequisite_tasks.map { |pre| pre.timestamp }.max result << "latest-prerequisite time: #{latest_prereq}\n" result << "................................\n\n" return result @@ -342,7 +369,8 @@ module Rake # this kind of task. Generic tasks will accept the scope as # part of the name. def scope_name(scope, task_name) - (scope + [task_name]).join(':') +# (scope + [task_name]).join(':') + scope.path_with_task_name(task_name) end end # class << Rake::Task diff --git a/lib/rake/task_arguments.rb b/lib/rake/task_arguments.rb index 4417af2f8e..0094682579 100644 --- a/lib/rake/task_arguments.rb +++ b/lib/rake/task_arguments.rb @@ -15,16 +15,27 @@ module Rake @names = names @parent = parent @hash = {} + @values = values names.each_with_index { |name, i| @hash[name.to_sym] = values[i] unless values[i].nil? } end + # Retrive the complete array of sequential values + def to_a + @values.dup + end + + # Retrive the list of values not associated with named arguments + def extras + @values[@names.length..-1] || [] + end + # Create a new argument scope using the prerequisite argument # names. def new_scope(names) - values = names.collect { |n| self[n] } - self.class.new(names, values, self) + values = names.map { |n| self[n] } + self.class.new(names, values + extras, self) end # Find an argument value by name or index. diff --git a/lib/rake/task_manager.rb b/lib/rake/task_manager.rb index 5a9419d536..06c243a7b2 100644 --- a/lib/rake/task_manager.rb +++ b/lib/rake/task_manager.rb @@ -10,21 +10,21 @@ module Rake super @tasks = Hash.new @rules = Array.new - @scope = Array.new + @scope = Scope.make @last_description = nil end def create_rule(*args, &block) - pattern, _, deps = resolve_args(args) + pattern, args, deps = resolve_args(args) pattern = Regexp.new(Regexp.quote(pattern) + '$') if String === pattern - @rules << [pattern, deps, block] + @rules << [pattern, args, deps, block] end def define_task(task_class, *args, &block) task_name, arg_names, deps = resolve_args(args) task_name = task_class.scope_name(@scope, task_name) deps = [deps] unless deps.respond_to?(:to_ary) - deps = deps.collect {|d| d.to_s } + deps = deps.map { |d| d.to_s } task = intern(task_class, task_name) task.set_arg_names(arg_names) unless arg_names.empty? if Rake::TaskManager.record_task_metadata @@ -72,7 +72,6 @@ module Rake # # task :t # task :t, [:a] - # task :t, :a (deprecated) # def resolve_args_without_dependencies(args) task_name = args.shift @@ -92,24 +91,14 @@ module Rake # # task :t => [:d] # task :t, [a] => [:d] - # task :t, :needs => [:d] (deprecated) - # task :t, :a, :needs => [:d] (deprecated) # def resolve_args_with_dependencies(args, hash) # :nodoc: fail "Task Argument Error" if hash.size != 1 - key, value = hash.map { |k, v| [k,v] }.first + key, value = hash.map { |k, v| [k, v] }.first if args.empty? task_name = key arg_names = [] deps = value - elsif key == :needs - Rake.application.deprecate( - "task :t, arg, :needs => [deps]", - "task :t, [args] => [deps]", - caller.detect { |c| c !~ /\blib\/rake\b/ }) - task_name = args.shift - arg_names = args - deps = value else task_name = args.shift arg_names = key @@ -127,9 +116,9 @@ module Rake def enhance_with_matching_rule(task_name, level=0) fail Rake::RuleRecursionOverflowError, "Rule Recursion Too Deep" if level >= 16 - @rules.each do |pattern, extensions, block| + @rules.each do |pattern, args, extensions, block| if pattern.match(task_name) - task = attempt_rule(task_name, extensions, block, level) + task = attempt_rule(task_name, args, extensions, block, level) return task if task end end @@ -147,7 +136,7 @@ module Rake # List of all the tasks defined in the given scope (and its # sub-scopes). def tasks_in_scope(scope) - prefix = scope.join(":") + prefix = scope.path tasks.select { |t| /^#{prefix}:/ =~ t.name } @@ -168,10 +157,10 @@ module Rake initial_scope ||= @scope task_name = task_name.to_s if task_name =~ /^rake:/ - scopes = [] + scopes = Scope.make task_name = task_name.sub(/^rake:/, '') elsif task_name =~ /^(\^+)/ - scopes = initial_scope[0, initial_scope.size - $1.size] + scopes = initial_scope.trim($1.size) task_name = task_name.sub(/^(\^+)/, '') else scopes = initial_scope @@ -181,12 +170,12 @@ module Rake # Lookup the task name def lookup_in_scope(name, scope) - n = scope.size - while n >= 0 - tn = (scope[0,n] + [name]).join(':') + loop do + tn = scope.path_with_task_name(name) task = @tasks[tn] return task if task - n -= 1 + break if scope.empty? + scope = scope.tail end nil end @@ -195,19 +184,19 @@ module Rake # Return the list of scope names currently active in the task # manager. def current_scope - @scope.dup + @scope end # Evaluate the block in a nested namespace named +name+. Create # an anonymous namespace if +name+ is nil. def in_namespace(name) name ||= generate_name - @scope.push(name) + @scope = Scope.new(name, @scope) ns = NameSpace.new(self, @scope) yield(ns) ns ensure - @scope.pop + @scope = @scope.tail end private @@ -224,7 +213,7 @@ module Rake locations = caller i = 0 while locations[i] - return locations[i+1] if locations[i] =~ /rake\/dsl_definition.rb/ + return locations[i + 1] if locations[i] =~ /rake\/dsl_definition.rb/ i += 1 end nil @@ -238,18 +227,19 @@ module Rake end def trace_rule(level, message) - options.trace_output.puts "#{" "*level}#{message}" if Rake.application.options.trace_rules + options.trace_output.puts "#{" " * level}#{message}" if + Rake.application.options.trace_rules end # Attempt to create a rule given the list of prerequisites. - def attempt_rule(task_name, extensions, block, level) + def attempt_rule(task_name, args, extensions, block, level) sources = make_sources(task_name, extensions) - prereqs = sources.collect { |source| + prereqs = sources.map { |source| trace_rule level, "Attempting Rule #{task_name} => #{source}" if File.exist?(source) || Rake::Task.task_defined?(source) trace_rule level, "(#{task_name} => #{source} ... EXIST)" source - elsif parent = enhance_with_matching_rule(source, level+1) + elsif parent = enhance_with_matching_rule(source, level + 1) trace_rule level, "(#{task_name} => #{source} ... ENHANCE)" parent.name else @@ -257,7 +247,7 @@ module Rake return nil end } - task = FileTask.define_task({task_name => prereqs}, &block) + task = FileTask.define_task(task_name, {args => prereqs}, &block) task.sources = prereqs task end @@ -265,7 +255,7 @@ module Rake # Make a list of sources from the list of file name extensions / # translation procs. def make_sources(task_name, extensions) - result = extensions.collect { |ext| + result = extensions.map { |ext| case ext when /%/ task_name.pathmap(ext) diff --git a/lib/rake/tasklib.rb b/lib/rake/tasklib.rb index f1e17dad31..48d27df9ed 100644 --- a/lib/rake/tasklib.rb +++ b/lib/rake/tasklib.rb @@ -14,7 +14,7 @@ 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. - def paste(a,b) # :nodoc: + def paste(a, b) # :nodoc: (a.to_s + b.to_s).intern end end diff --git a/lib/rake/testtask.rb b/lib/rake/testtask.rb index ff4ef3b988..c693dd2626 100644 --- a/lib/rake/testtask.rb +++ b/lib/rake/testtask.rb @@ -64,7 +64,7 @@ module Rake # attr_accessor :loader - # Array of commandline options to pass to Ruby when running test loader. + # Array of commandline options to pass to ruby when running test loader. attr_accessor :ruby_opts # Explicitly define the list of test files to be included in a @@ -93,15 +93,18 @@ module Rake # Create the tasks defined by this task lib. def define - desc "Run tests" + (@name==:test ? "" : " for #{@name}") + desc "Run tests" + (@name == :test ? "" : " for #{@name}") task @name do FileUtilsExt.verbose(@verbose) do - args = "#{ruby_opts_string} #{run_code} #{file_list_string} #{option_list}" + args = + "#{ruby_opts_string} #{run_code} " + + "#{file_list_string} #{option_list}" ruby args do |ok, status| if !ok && status.respond_to?(:signaled?) && status.signaled? raise SignalException.new(status.termsig) elsif !ok - fail "Command failed with status (#{status.exitstatus}): [ruby #{args}]" + fail "Command failed with status (#{status.exitstatus}): " + + "[ruby #{args}]" end end end @@ -120,8 +123,8 @@ module Rake def ruby_opts_string opts = @ruby_opts.dup - opts.unshift( "-I\"#{lib_path}\"" ) unless @libs.empty? - opts.unshift( "-w" ) if @warning + opts.unshift("-I\"#{lib_path}\"") unless @libs.empty? + opts.unshift("-w") if @warning opts.join(" ") end @@ -130,12 +133,12 @@ module Rake end def file_list_string - file_list.collect { |fn| "\"#{fn}\"" }.join(' ') + file_list.map { |fn| "\"#{fn}\"" }.join(' ') end def file_list # :nodoc: if ENV['TEST'] - FileList[ ENV['TEST'] ] + FileList[ENV['TEST']] else result = [] result += @test_files.to_a if @test_files diff --git a/lib/rake/thread_history_display.rb b/lib/rake/thread_history_display.rb index 917e951064..c2af9ecef5 100644 --- a/lib/rake/thread_history_display.rb +++ b/lib/rake/thread_history_display.rb @@ -25,7 +25,7 @@ module Rake (stat[:time] * 1_000_000).round, stat[:thread], stat[:event], - stat[:data].map { |k,v| "#{k}:#{v}" }.join(" ")) + stat[:data].map do |k, v| "#{k}:#{v}" end.join(" ")) end end diff --git a/lib/rake/thread_pool.rb b/lib/rake/thread_pool.rb index 983a67a514..44bc7483e4 100644 --- a/lib/rake/thread_pool.rb +++ b/lib/rake/thread_pool.rb @@ -50,8 +50,10 @@ module Rake rescue Exception => e stat :joined $stderr.puts e - $stderr.print "Queue contains #{@queue.size} items. Thread pool contains #{@threads.count} threads\n" - $stderr.print "Current Thread #{Thread.current} status = #{Thread.current.status}\n" + $stderr.print "Queue contains #{@queue.size} items. " + + "Thread pool contains #{@threads.count} threads\n" + $stderr.print "Current Thread #{Thread.current} status = " + + "#{Thread.current.status}\n" $stderr.puts e.backtrace.join("\n") @threads.each do |t| $stderr.print "Thread #{t} status = #{t.status}\n" @@ -125,8 +127,12 @@ module Rake end end @threads << t - stat :spawned, :new_thread => t.object_id, :thread_count => @threads.count - @total_threads_in_play = @threads.count if @threads.count > @total_threads_in_play + stat( + :spawned, + :new_thread => t.object_id, + :thread_count => @threads.count) + @total_threads_in_play = @threads.count if + @threads.count > @total_threads_in_play end end diff --git a/lib/rake/trace_output.rb b/lib/rake/trace_output.rb index e4d61cfb93..1cd19451ca 100644 --- a/lib/rake/trace_output.rb +++ b/lib/rake/trace_output.rb @@ -11,7 +11,10 @@ module Rake if strings.empty? output = sep else - output = strings.map { |s| s.end_with?(sep) ? s : s + sep }.join + output = strings.map { |s| + next if s.nil? + s =~ /#{sep}$/ ? s : s + sep + }.join end out.print(output) end diff --git a/lib/rake/version.rb b/lib/rake/version.rb index 25d806a3c4..05c934d785 100644 --- a/lib/rake/version.rb +++ b/lib/rake/version.rb @@ -1,14 +1,9 @@ -# :include: doc/README.rdoc module Rake - VERSION = '0.9.6' + VERSION = '10.1.0' module Version # :nodoc: all - MAJOR, MINOR, BUILD, = Rake::VERSION.split '.' + MAJOR, MINOR, BUILD, *OTHER = Rake::VERSION.split '.' - NUMBERS = [ - MAJOR, - MINOR, - BUILD, - ] + NUMBERS = [MAJOR, MINOR, BUILD, *OTHER] end end diff --git a/lib/rake/win32.rb b/lib/rake/win32.rb index 98289a10b4..edb33938b4 100644 --- a/lib/rake/win32.rb +++ b/lib/rake/win32.rb @@ -40,8 +40,9 @@ module Rake win32_shared_path ||= ENV['APPDATA'] win32_shared_path ||= ENV['USERPROFILE'] - raise Win32HomeError, "Unable to determine home path environment variable." if - win32_shared_path.nil? or win32_shared_path.empty? + raise Win32HomeError, + "Unable to determine home path environment variable." if + win32_shared_path.nil? or win32_shared_path.empty? normalize(File.join(win32_shared_path, 'Rake')) end |