[前][次][番号順一覧][スレッド一覧]

ruby-changes:7881

From: jim <ko1@a...>
Date: Thu, 18 Sep 2008 10:17:16 +0900 (JST)
Subject: [ruby-changes:7881] Ruby:r19402 (trunk): Updated Rake files to version 0.8.2

jim	2008-09-18 10:17:04 +0900 (Thu, 18 Sep 2008)

  New Revision: 19402

  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=19402

  Log:
    Updated Rake files to version 0.8.2

  Modified files:
    trunk/lib/rake/loaders/makefile.rb
    trunk/lib/rake/packagetask.rb
    trunk/lib/rake/rdoctask.rb
    trunk/lib/rake/tasklib.rb
    trunk/lib/rake/testtask.rb
    trunk/lib/rake.rb

Index: lib/rake/packagetask.rb
===================================================================
--- lib/rake/packagetask.rb	(revision 19401)
+++ lib/rake/packagetask.rb	(revision 19402)
@@ -122,6 +122,7 @@
           task :package => ["#{package_dir}/#{file}"]
           file "#{package_dir}/#{file}" => [package_dir_path] + package_files do
             chdir(package_dir) do
+              sh %{env}
               sh %{#{@tar_command} #{flag}cvf #{file} #{package_name}}
             end
           end
Index: lib/rake/testtask.rb
===================================================================
--- lib/rake/testtask.rb	(revision 19401)
+++ lib/rake/testtask.rb	(revision 19402)
@@ -136,7 +136,12 @@
     end
 
     def fix # :nodoc:
-      ''
+      case RUBY_VERSION
+      when '1.8.2'
+        find_file 'rake/ruby182_test_unit_fix'
+      else
+        nil
+      end || ''
     end
 
     def rake_loader # :nodoc:
Index: lib/rake/loaders/makefile.rb
===================================================================
--- lib/rake/loaders/makefile.rb	(revision 19401)
+++ lib/rake/loaders/makefile.rb	(revision 19402)
@@ -7,31 +7,26 @@
 
     # Load the makefile dependencies in +fn+.
     def load(fn)
-      buffer = ''
       open(fn) do |mf|
-        mf.each do |line|
-          next if line =~ /^\s*#/
-          buffer << line
-          if buffer =~ /\\$/
-            buffer.sub!(/\\\n/, ' ')
-            state = :append
-          else
-            process_line(buffer)
-            buffer = ''
-          end
+        lines = mf.read
+        lines.gsub!(/#[^\n]*\n/m, "")
+        lines.gsub!(/\\\n/, ' ')
+        lines.split("\n").each do |line|
+          process_line(line)
         end
       end
-      process_line(buffer) if buffer != ''
     end
 
     private
 
     # Process one logical line of makefile data.
     def process_line(line)
-      file_task, args = line.split(':')
+      file_tasks, args = line.split(':')
       return if args.nil?
       dependents = args.split
-      file file_task => dependents
+      file_tasks.strip.split.each do |file_task|
+        file file_task => dependents
+      end
     end
   end
 
Index: lib/rake/tasklib.rb
===================================================================
--- lib/rake/tasklib.rb	(revision 19401)
+++ lib/rake/tasklib.rb	(revision 19402)
@@ -6,11 +6,16 @@
 
   # Base class for Task Libraries.
   class TaskLib
-
     include Cloneable
 
-    # Make a symbol by pasting two strings together. 
-    def paste(a,b)
+    # Make a symbol by pasting two strings together.
+    #
+    # NOTE: DEPRECATED! This method is kinda stupid. I don't know why
+    # I didn't just use string interpolation. But now other task
+    # 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:
       (a.to_s + b.to_s).intern
     end
   end
Index: lib/rake/rdoctask.rb
===================================================================
--- lib/rake/rdoctask.rb	(revision 19401)
+++ lib/rake/rdoctask.rb	(revision 19402)
@@ -55,7 +55,7 @@
     # RDoc. (default is none)
     attr_accessor :main
 
-    # Name of template to be used by rdoc. (default is 'html')
+    # 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 [])
@@ -74,7 +74,7 @@
       @rdoc_dir = 'html'
       @main = nil
       @title = nil
-      @template = 'html'
+      @template = nil
       @external = false
       @options = []
       yield self if block_given?
@@ -91,18 +91,18 @@
       task name
       
       desc "Force a rebuild of the RDOC files"
-      task paste("re", name) => [paste("clobber_", name), name]
+      task "re#{name}" => ["clobber_#{name}", name]
       
       desc "Remove rdoc products" 
-      task paste("clobber_", name) do
+      task "clobber_#{name}" do
         rm_r rdoc_dir rescue nil
       end
-
-      task :clobber => [paste("clobber_", name)]
       
+      task :clobber => ["clobber_#{name}"]
+      
       directory @rdoc_dir
       task name => [rdoc_target]
-      file rdoc_target => @rdoc_files + [$rakefile] do
+      file rdoc_target => @rdoc_files + [Rake.application.rakefile] do
         rm_r @rdoc_dir rescue nil
         args = option_list + @rdoc_files
         if @external
Index: lib/rake.rb
===================================================================
--- lib/rake.rb	(revision 19401)
+++ lib/rake.rb	(revision 19402)
@@ -29,13 +29,13 @@
 # as a library via a require statement, but it can be distributed
 # independently as an application.
 
-RAKEVERSION = '0.8.0'
+RAKEVERSION = '0.8.2'
 
 require 'rbconfig'
-require 'getoptlong'
 require 'fileutils'
 require 'singleton'
-require 'thread'
+require 'monitor'
+require 'optparse'
 require 'ostruct'
 
 ######################################################################
@@ -72,7 +72,7 @@
 #
 class String
   rake_extension("ext") do
-    # Replace the file extension with +newext+.  If there is no extension on
+    # Replace the file extension with +newext+.  If there is no extenson on
     # the string, append the new extension to the end.  If the new extension
     # is not given, or is the empty string, remove any existing extension.
     #
@@ -145,7 +145,7 @@
     # * <b>%x</b> -- The file extension of the path.  An empty string if there
     #   is no extension.
     # * <b>%X</b> -- Everything *but* the file extension.
-    # * <b>%s</b> -- The alternate file separator if defined, otherwise use
+    # * <b>%s</b> -- The alternate file separater if defined, otherwise use
     #   the standard file separator.
     # * <b>%%</b> -- A percent sign.
     #
@@ -160,8 +160,8 @@
     #   'a/b/c/d/file.txt'.pathmap("%-2d")  => 'c/d'
     #
     # Also the %d, %p, $f, $n, %x, and %X operators can take a
-    # pattern/replacement argument to perform simple string substitutions on a
-    # particular part of the path.  The pattern and replacement are separated
+    # pattern/replacement argument to perform simple string substititions on a
+    # particular part of the path.  The pattern and replacement are speparated
     # by a comma and are enclosed by curly braces.  The replacement spec comes
     # after the % character but before the operator letter.  (e.g.
     # "%{old,new}d").  Muliple replacement specs should be separated by
@@ -239,6 +239,33 @@
 ##############################################################################
 module Rake
 
+  # Errors -----------------------------------------------------------
+
+  # Error indicating an ill-formed task declaration.
+  class TaskArgumentError < ArgumentError
+  end
+
+  # Error indicating a recursion overflow error in task selection.
+  class RuleRecursionOverflowError < StandardError
+    def initialize(*args)
+      super
+      @targets = []
+    end
+
+    def add_target(target)
+      @targets << target
+    end
+
+    def message
+      super + ": [" + @targets.reverse.join(' => ') + "]"
+    end
+  end
+
+  # Error indicating a problem in locating the home directory on a
+  # Win32 system.
+  class Win32HomeError < RuntimeError
+  end
+
   # --------------------------------------------------------------------------
   # Rake module singleton methods.
   #
@@ -266,16 +293,22 @@
   module Cloneable
     # Clone an object by making a new object and setting all the instance
     # variables to the same values.
-    def clone
+    def dup
       sibling = self.class.new
       instance_variables.each do |ivar|
         value = self.instance_variable_get(ivar)
         new_value = value.clone rescue value
         sibling.instance_variable_set(ivar, new_value)
       end
+      sibling.taint if tainted?
       sibling
     end
-    alias dup clone
+
+    def clone
+      sibling = dup
+      sibling.freeze if frozen?
+      sibling
+    end
   end
 
   ####################################################################
@@ -286,12 +319,15 @@
 
     attr_reader :names
 
+    # Create a TaskArgument object with a list of named arguments
+    # (given by :names) and a set of associated values (given by
+    # :values).  :parent is the parent argument object.
     def initialize(names, values, parent=nil)
       @names = names
       @parent = parent
       @hash = {}
       names.each_with_index { |name, i|
-        @hash[name.to_sym] = values[i]
+        @hash[name.to_sym] = values[i] unless values[i].nil?
       }
     end
 
@@ -307,6 +343,13 @@
       lookup(index.to_sym)
     end
 
+    # Specify a hash of default values for task arguments. Use the
+    # defaults only if there is no specific value for the given
+    # argument.
+    def with_defaults(defaults)
+      @hash = defaults.merge(@hash)
+    end
+
     def each(&block)
       @hash.each(&block)
     end
@@ -342,6 +385,8 @@
     end
   end
 
+  EMPTY_TASK_ARGS = TaskArguments.new([], [])
+
   ####################################################################
   # InvocationChain tracks the chain of task invocations to detect
   # circular dependencies.
@@ -409,6 +454,9 @@
     # List of prerequisites for a task.
     attr_reader :prerequisites
 
+    # List of actions attached to a task.
+    attr_reader :actions
+
     # Application owning this task.
     attr_accessor :application
 
@@ -446,12 +494,12 @@
     # +enhance+ to add actions and prerequisites.
     def initialize(task_name, app)
       @name = task_name.to_s
-      @prerequisites = FileList[]
+      @prerequisites = []
       @actions = []
       @already_invoked = false
       @full_comment = nil
       @comment = nil
-      @lock = Mutex.new
+      @lock = Monitor.new
       @application = app
       @scope = app.current_scope
       @arg_names = nil
@@ -488,6 +536,31 @@
       @arg_names || []
     end
 
+    # Reenable the task, allowing its tasks to be executed if the task
+    # is invoked again.
+    def reenable
+      @already_invoked = false
+    end
+
+    # Clear the existing prerequisites and actions of a rake task.
+    def clear
+      clear_prerequisites
+      clear_actions
+      self
+    end
+
+    # Clear the existing prerequisites of a rake task.
+    def clear_prerequisites
+      prerequisites.clear
+      self
+    end
+
+    # Clear the existing actions on a rake task.
+    def clear_actions
+      actions.clear
+      self
+    end
+
     # Invoke the task if it is needed.  Prerequites are invoked first.
     def invoke(*args)
       task_args = TaskArguments.new(arg_names, args)
@@ -496,7 +569,7 @@
 
     # Same as invoke, but explicitly pass a call chain to detect
     # circular dependencies.
-    def invoke_with_call_chain(task_args, invocation_chain)
+    def invoke_with_call_chain(task_args, invocation_chain) # :nodoc:
       new_chain = InvocationChain.append(self, invocation_chain)
       @lock.synchronize do
         if application.options.trace
@@ -511,7 +584,7 @@
     protected :invoke_with_call_chain
 
     # Invoke all the prerequisites of a task.
-    def invoke_prerequisites(task_args, invocation_chain)
+    def invoke_prerequisites(task_args, invocation_chain) # :nodoc:
       @prerequisites.each { |n|
         prereq = application[n, @scope]
         prereq_args = task_args.new_scope(prereq.arg_names)
@@ -529,7 +602,8 @@
     private :format_trace_flags
 
     # Execute the actions associated with this task.
-    def execute(args)
+    def execute(args=nil)
+      args ||= EMPTY_TASK_ARGS
       if application.options.dryrun
         puts "** Execute (dry run) #{name}"
         return
@@ -772,8 +846,8 @@
 #     end
 #  end
 #
-def file(args, &block)
-  Rake::FileTask.define_task(args, &block)
+def file(*args, &block)
+  Rake::FileTask.define_task(*args, &block)
 end
 
 # Declare a file creation task.
@@ -899,14 +973,38 @@
         ok or fail "Command failed with status (#{status.exitstatus}): [#{show_command}]"
       }
     end
+    if RakeFileUtils.verbose_flag == :default
+      options[:verbose] = false
+    else
+      options[:verbose] ||= RakeFileUtils.verbose_flag
+    end
+    options[:noop]    ||= RakeFileUtils.nowrite_flag
     rake_check_options options, :noop, :verbose
     rake_output_message cmd.join(" ") if options[:verbose]
     unless options[:noop]
-      res = system(*cmd)
+      res = rake_system(*cmd)
       block.call(res, $?)
     end
   end
 
+  def rake_system(*cmd)
+    if Rake.application.windows?
+      rake_win32_system(*cmd)
+    else
+      system(*cmd)
+    end
+  end
+  private :rake_system
+
+  def rake_win32_system(*cmd)
+    if cmd.size == 1
+      system("call #{cmd}")
+    else
+      system(*cmd)
+    end
+  end
+  private :rake_win32_system
+
   # Run a Ruby interpreter with the given arguments.
   #
   # Example:
@@ -917,7 +1015,7 @@
     if args.length > 1 then
       sh(*([RUBY] + args + [options]), &block)
     else
-      sh("#{RUBY.sub(/.*\s.*/m, '"\&"')} #{args.first}", options, &block)
+      sh("#{RUBY} #{args.first}", options, &block)
     end
   end
 
@@ -961,7 +1059,7 @@
   class << self
     attr_accessor :verbose_flag, :nowrite_flag
   end
-  RakeFileUtils.verbose_flag = true
+  RakeFileUtils.verbose_flag = :default
   RakeFileUtils.nowrite_flag = false
 
   $fileutils_verbose = true
@@ -969,10 +1067,10 @@
 
   FileUtils::OPT_TABLE.each do |name, opts|
     default_options = []
-    if opts.include?('verbose')
+    if opts.include?(:verbose) || opts.include?("verbose")
       default_options << ':verbose => RakeFileUtils.verbose_flag'
     end
-    if opts.include?('noop')
+    if opts.include?(:noop) || opts.include?("noop")
       default_options << ':noop => RakeFileUtils.nowrite_flag'
     end
 
@@ -1029,7 +1127,7 @@
     oldvalue
   end
 
-  # Use this function to prevent potentially destructive ruby code from
+  # Use this function to prevent protentially destructive ruby code from
   # running when the :nowrite flag is set.
   #
   # Example:
@@ -1094,21 +1192,6 @@
 ######################################################################
 module Rake
 
-  class RuleRecursionOverflowError < StandardError
-    def initialize(*args)
-      super
-      @targets = []
-    end
-
-    def add_target(target)
-      @targets << target
-    end
-
-    def message
-      super + ": [" + @targets.reverse.join(' => ') + "]"
-    end
-  end
-
   # #########################################################################
   # A FileList is essentially an array with a few helper methods defined to
   # make file manipulation a bit easier.
@@ -1352,7 +1435,7 @@
     private :resolve_exclude
 
     # Return a new FileList with the results of running +sub+ against each
-    # element of the original list.
+    # element of the oringal list.
     #
     # Example:
     #   FileList['a.c', 'b.c'].sub(/\.c$/, '.o')  => ['a.o', 'b.o']
@@ -1503,7 +1586,7 @@
   class << self
 
     # Yield each file or directory component.
-    def each_dir_parent(dir)
+    def each_dir_parent(dir)    # :nodoc:
       old_length = nil
       while dir != '.' && dir.length != old_length
         yield(dir)
@@ -1642,23 +1725,65 @@
     # Resolve the arguments for a task/rule.  Returns a triplet of
     # [task_name, arg_name_list, prerequisites].
     def resolve_args(args)
+      if args.last.is_a?(Hash)
+        deps = args.pop
+        resolve_args_with_dependencies(args, deps)
+      else
+        resolve_args_without_dependencies(args)
+      end
+    end
+
+    # Resolve task arguments for a task or rule when there are no
+    # dependencies declared.
+    #
+    # The patterns recognized by this argument resolving function are:
+    #
+    #   task :t
+    #   task :t, [:a]
+    #   task :t, :a                 (deprecated)
+    #
+    def resolve_args_without_dependencies(args)
       task_name = args.shift
-      arg_names = args #.map { |a| a.to_sym }
-      needs = []
-      if task_name.is_a?(Hash)
-        hash = task_name
-        task_name = hash.keys[0]
-        needs = hash[task_name]
+      if args.size == 1 && args.first.respond_to?(:to_ary)
+        arg_names = args.first.to_ary
+      else
+        arg_names = args
       end
-      if arg_names.last.is_a?(Hash)
-        hash = arg_names.pop
-        needs = hash[:needs]
-        fail "Unrecognized keys in task hash: #{hash.keys.inspect}" if hash.size > 1
+      [task_name, arg_names, []]
+    end
+    private :resolve_args_without_dependencies
+    
+    # Resolve task arguments for a task or rule when there are
+    # dependencies declared.
+    #
+    # The patterns recognized by this argument resolving function are:
+    #
+    #   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
+      if args.empty?
+        task_name = key
+        arg_names = []
+        deps = value
+      elsif key == :needs
+        task_name = args.shift
+        arg_names = args
+        deps = value
+      else
+        task_name = args.shift
+        arg_names = key
+        deps = value
       end
-      needs = [needs] unless needs.respond_to?(:to_ary)
-      [task_name, arg_names, needs]
+      deps = [deps] unless deps.respond_to?(:to_ary)
+      [task_name, arg_names, deps]
     end
-
+    private :resolve_args_with_dependencies
+    
     # If a rule can be found that matches the task name, enhance the
     # task with the prerequisites and actions from the rule.  Set the
     # source attribute of the task appropriately for the rule.  Return
@@ -1749,15 +1874,23 @@
       "_anon_#{@seed}"
     end
 
+    def trace_rule(level, message)
+      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)
       sources = make_sources(task_name, extensions)
       prereqs = sources.collect { |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(sources.first, level+1)
+        elsif parent = enhance_with_matching_rule(source, level+1)
+          trace_rule level, "(#{task_name} => #{source} ... ENHANCE)"
           parent.name
         else
+          trace_rule level, "(#{task_name} => #{source} ... FAIL)"
           return nil
         end
       }
@@ -1814,41 +1947,6 @@
 
     DEFAULT_RAKEFILES = ['rakefile', 'Rakefile', 'rakefile.rb', 'Rakefile.rb'].freeze
 
-    OPTIONS = [     # :nodoc:
-      ['--classic-namespace', '-C', GetoptLong::NO_ARGUMENT,
-        "Put Task and FileTask in the top level namespace"],
-      ['--describe',  '-D', GetoptLong::OPTIONAL_ARGUMENT,
-        "Describe the tasks (matching optional PATTERN), then exit."],
-      ['--rakefile', '-f', GetoptLong::OPTIONAL_ARGUMENT,
-        "Use FILE as the rakefile."],
-      ['--help',     '-h', '-H', GetoptLong::NO_ARGUMENT,
-        "Display this help message."],
-      ['--libdir',   '-I', GetoptLong::REQUIRED_ARGUMENT,
-        "Include LIBDIR in the search path for required modules."],
-      ['--dry-run',  '-n', GetoptLong::NO_ARGUMENT,
-        "Do a dry run without executing actions."],
-      ['--nosearch', '-N', GetoptLong::NO_ARGUMENT,
-        "Do not search parent directories for the Rakefile."],
-      ['--prereqs',  '-P', GetoptLong::NO_ARGUMENT,
-        "Display the tasks and dependencies, then exit."],
-      ['--quiet',    '-q', GetoptLong::NO_ARGUMENT,
-        "Do not log messages to standard output."],
-      ['--require',  '-r', GetoptLong::REQUIRED_ARGUMENT,
-        "Require MODULE before executing rakefile."],
-      ['--rakelibdir', '-R', GetoptLong::REQUIRED_ARGUMENT,
-        "Auto-import any .rake files in RAKELIBDIR. (default is 'rakelib')"],
-      ['--silent',   '-s', GetoptLong::NO_ARGUMENT,
-        "Like --quiet, but also suppresses the 'in directory' announcement."],
-      ['--tasks',    '-T', GetoptLong::OPTIONAL_ARGUMENT,
-        "Display the tasks (matching optional PATTERN) with descriptions, then exit."],
-      ['--trace',    '-t', GetoptLong::NO_ARGUMENT,
-        "Turn on invoke/execute tracing, enable full backtrace."],
-      ['--verbose',  '-v', GetoptLong::NO_ARGUMENT,
-        "Log message to standard output (default)."],
-      ['--version',  '-V', GetoptLong::NO_ARGUMENT,
-        "Display the program version."],
-    ]
-
     # Initialize a Rake::Application object.
     def initialize
       super
@@ -1861,8 +1959,10 @@
       @default_loader = Rake::DefaultLoader.new
       @original_dir = Dir.pwd
       @top_level_tasks = []
+      add_loader('rb', DefaultLoader.new)
       add_loader('rf', DefaultLoader.new)
       add_loader('rake', DefaultLoader.new)
+      @tty_output = STDOUT.tty?
     end
 
     # Run the Rake application.  The run method performs the following three steps:
@@ -1886,8 +1986,7 @@
     def init(app_name='rake')
       standard_exception_handling do
         @name = app_name
-        handle_options
-        collect_tasks
+        collect_tasks handle_options
       end
     end
 
@@ -1942,14 +2041,14 @@
       [name, args]
     end
 
-    # Provide standard exception handling for the given block.
+    # Provide standard execption handling for the given block.
     def standard_exception_handling
       begin
         yield
       rescue SystemExit => ex
         # Exit silently with current status
         exit(ex.status)
-      rescue SystemExit, GetoptLong::InvalidOption => ex
+      rescue SystemExit, OptionParser::InvalidOption => ex
         # Exit silently
         exit(1)
       rescue Exception => ex
@@ -1971,35 +2070,28 @@
     def have_rakefile
       @rakefiles.each do |fn|
         if File.exist?(fn) || fn == ''
-          @rakefile = fn
-          return true
+          return fn
         end
       end
-      return false
+      return nil
     end
 
-    # Display the rake command line help.
-    def help
-      puts "rake [-f rakefile] {options} targets..."
-      puts
-      puts "Options are ..."
-      puts
-      OPTIONS.sort.each do |long, *short, mode, desc|
-        case mode
-        when GetoptLong::REQUIRED_ARGUMENT
-          if desc =~ /\b([A-Z]{2,})\b/
-            long = long + "=#{$1}"
-          end
-        when GetoptLong::OPTIONAL_ARGUMENT
-          if desc =~ /\b([A-Z]{2,})\b/
-            long = long + "[=#{$1}]"
-          end
-        end
-        printf "  %-20s (%s)\n", long, short.join(", ")
-        printf "      %s\n", desc
-      end
+    # True if we are outputting to TTY, false otherwise
+    def tty_output?
+      @tty_output
     end
 
+    # Override the detected TTY output state (mostly for testing)
+    def tty_output=( tty_output_state )
+      @tty_output = tty_output_state
+    end
+
+    # We will truncate output if we are outputting to a TTY or if we've been
+    # given an explicit column width to honor
+    def truncate_output?
+      tty_output? || ENV['RAKE_COLUMNS']
+    end
+
     # Display the tasks and dependencies.
     def display_tasks_and_comments
       displayable_tasks = tasks.select { |t|
@@ -2015,19 +2107,51 @@
         end
       else
         width = displayable_tasks.collect { |t| t.name_with_args.length }.max || 10
-        max_column = 80 - name.size - width - 7
+        max_column = truncate_output? ? terminal_width - name.size - width - 7 : nil
         displayable_tasks.each do |t|
           printf "#{name} %-#{width}s  # %s\n",
-            t.name_with_args, truncate(t.comment, max_column)
+            t.name_with_args, max_column ? truncate(t.comment, max_column) : t.comment
         end
       end
     end
 
+    def terminal_width
+      if ENV['RAKE_COLUMNS']
+        result = ENV['RAKE_COLUMNS'].to_i
+      else
+        result = unix? ? dynamic_width : 80
+      end
+      (result < 10) ? 80 : result
+    rescue
+      80
+    end
+
+    # Calculate the dynamic width of the 
+    def dynamic_width
+      @dynamic_width ||= (dynamic_width_stty.nonzero? || dynamic_width_tput)
+    end
+
+    def dynamic_width_stty
+      %x{stty size 2>/dev/null}.split[1].to_i
+    end
+
+    def dynamic_width_tput
+      %x{tput cols 2>/dev/null}.to_i
+    end
+
+    def unix?
+      RUBY_PLATFORM =~ /(aix|darwin|linux|(net|free|open)bsd|cygwin|solaris|irix|hpux)/i
+    end
+    
+    def windows?
+      Config::CONFIG['host_os'] =~ /mswin/
+    end
+
     def truncate(string, width)
       if string.length <= width
         string
       else
-        string[0, width-3] + "..."
+        ( string[0, width-3] || "" ) + "..."
       end
     end
 
@@ -2039,77 +2163,141 @@
       end
     end
 
-    # Return a list of the command line options supported by the
-    # program.
-    def command_line_options
-      OPTIONS.collect { |lst| lst[0..-2] }
+    # A list of all the standard options used in rake, suitable for
+    # passing to OptionParser.
+    def standard_rake_options
+      [
+        ['--classic-namespace', '-C', "Put Task and FileTask in the top level namespace",
+          lambda { |value|
+            require 'rake/classic_namespace'
+            options.classic_namespace = true
+          }
+        ],
+        ['--describe', '-D [PATTERN]', "Describe the tasks (matching optional PATTERN), then exit.",
+          lambda { |value|
+            options.show_tasks = true
+            options.full_description = true
+            options.show_task_pattern = Regexp.new(value || '')
+          }
+        ],
+        ['--dry-run', '-n', "Do a dry run without executing actions.",
+          lambda { |value|
+            verbose(true)
+            nowrite(true)
+            options.dryrun = true
+            options.trace = true
+          }
+        ],
+        ['--execute',  '-e CODE', "Execute some Ruby code and exit.",
+          lambda { |value|
+            eval(value)
+            exit
+          }
+        ],
+        ['--execute-print',  '-p CODE', "Execute some Ruby code, print the result, then exit.",
+          lambda { |value|
+            puts eval(value)
+            exit
+          }
+        ],
+        ['--execute-continue',  '-E CODE',
+          "Execute some Ruby code, then continue with normal task processing.",
+          lambda { |value| eval(value) }            
+        ],
+        ['--libdir', '-I LIBDIR', "Include LIBDIR in the search path for required modules.",
+          lambda { |value| $:.push(value) }
+        ],
+        ['--prereqs', '-P', "Display the tasks and dependencies, then exit.",
+          lambda { |value| options.show_prereqs = true }
+        ],
+        ['--quiet', '-q', "Do not log messages to standard output.",
+          lambda { |value| verbose(false) }
+        ],
+        ['--rakefile', '-f [FILE]', "Use FILE as the rakefile.",
+          lambda { |value| 
+            value ||= ''
+            @rakefiles.clear 
+            @rakefiles << value
+          }
+        ],
+        ['--rakelibdir', '--rakelib', '-R RAKELIBDIR',
+          "Auto-import any .rake files in RAKELIBDIR. (default is 'rakelib')",
+          lambda { |value| options.rakelib = value.split(':') }
+        ],
+        ['--require', '-r MODULE', "Require MODULE before executing rakefile.",
+          lambda { |value|
+            begin
+              require value
+            rescue LoadError => ex
+              begin
+                rake_require value
+              rescue LoadError => ex2
+                raise ex
+              end
+            end
+          }
+        ],
+        ['--rules', "Trace the rules resolution.",
+          lambda { |value| options.trace_rules = true }
+        ],
+        ['--no-search', '--nosearch', '-N', "Do not search parent directories for the Rakefile.",
+          lambda { |value| options.nosearch = true }
+        ],
+        ['--silent', '-s', "Like --quiet, but also suppresses the 'in directory' announcement.",
+          lambda { |value|
+            verbose(false)
+            options.silent = true
+          }
+        ],
+        ['--system',  '-g',
+          "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.",
+          lambda { |value| options.ignore_system = true }
+        ],
+        ['--tasks', '-T [PATTERN]', "Display the tasks (matching optional PATTERN) with descriptions, then exit.",
+          lambda { |value|
+            options.show_tasks = true
+            options.show_task_pattern = Regexp.new(value || '')
+            options.full_description = false
+          }
+        ],
+        ['--trace', '-t', "Turn on invoke/execute tracing, enable full backtrace.",
+          lambda { |value|
+            options.trace = true
+            verbose(true)
+          }
+        ],
+        ['--verbose', '-v', "Log message to standard output (default).",
+          lambda { |value| verbose(true) }
+        ],
+        ['--version', '-V', "Display the program version.",
+          lambda { |value|
+            puts "rake, version #{RAKEVERSION}"
+            exit
+          }
+        ]
+      ]
     end
 
-    # Do the option defined by +opt+ and +value+.
-    def do_option(opt, value)
-      case opt
-      when '--describe'
-        options.show_tasks = true
-        options.show_task_pattern = Regexp.new(value || '.')
-        options.full_description = true
-      when '--dry-run'
-        verbose(true)
-        nowrite(true)
-        options.dryrun = true
-        options.trace = true
-      when '--help'
-        help
-        exit
-      when '--libdir'
-        $:.push(value)
-      when '--nosearch'
-        options.nosearch = true
-      when '--prereqs'
-        options.show_prereqs = true
-      when '--quiet'
-        verbose(false)
-      when '--rakefile'
-        @rakefiles.clear
-        @rakefiles << value
-      when '--rakelibdir'
-        options.rakelib = value.split(':')
-      when '--require'
-        begin
-          require value
-        rescue LoadError => ex
-          begin
-            rake_require value
-          rescue LoadError => ex2
-            raise ex
-          end
-        end
-      when '--silent'
-        verbose(false)
-        options.silent = true
-      when '--tasks'
-        options.show_tasks = true
-        options.show_task_pattern = Regexp.new(value || '.')
-        options.full_description = false
-      when '--trace'
-        options.trace = true
-        verbose(true)
-      when '--verbose'
-        verbose(true)
-      when '--version'
-        puts "rake, version #{RAKEVERSION}"
-        exit
-      when '--classic-namespace'
-        require 'rake/classic_namespace'
-        options.classic_namespace = true
-      end
-    end
-
     # Read and handle the command line options.
     def handle_options
       options.rakelib = ['rakelib']
 
-      opts = GetoptLong.new(*command_line_options)
-      opts.each { |opt, value| do_option(opt, value) }
+      opts = OptionParser.new
+      opts.banner = "rake [-f rakefile] {options} targets..."
+      opts.separator ""
+      opts.separator "Options are ..."
+      
+      opts.on_tail("-h", "--help", "-H", "Display this help message.") do
+        puts opts
+        exit
+      end
+      
+      standard_rake_options.each { |args| opts.on(*args) }
+      parsed_argv = opts.parse(ARGV)
 
       # If class namespaces are requested, set the global options
       # according to the values in the options structure.
@@ -2120,12 +2308,11 @@
         $dryrun = options.dryrun
         $silent = options.silent
       end
-    rescue NoMethodError => ex
-      raise GetoptLong::InvalidOption, "While parsing options, error = #{ex.class}:#{ex.message}"
+      parsed_argv
     end
 
     # Similar to the regular Ruby +require+ command, but will check
-    # for .rake files in addition to .rb files.
+    # for *.rake files in addition to *.rb files.
     def rake_require(file_name, paths=$LOAD_PATH, loaded=$")
       return false if loaded.include?(file_name)
       paths.each do |path|
@@ -2140,34 +2327,95 @@
       fail LoadError, "Can't find #{file_name}"
     end
 
-    def raw_load_rakefile # :nodoc:
+    def find_rakefile_location
       here = Dir.pwd
-      while ! have_rakefile
+      while ! (fn = have_rakefile)
         Dir.chdir("..")
         if Dir.pwd == here || options.nosearch
-          fail "No Rakefile found (looking for: #{@rakefiles.join(', ')})"
+          return nil
         end
         here = Dir.pwd
       end
-      puts "(in #{Dir.pwd})" unless options.silent
-      $rakefile = @rakefile
-      load File.expand_path(@rakefile) if @rakefile != ''
-      options.rakelib.each do |rlib|
-        Dir["#{rlib}/*.rake"].each do |name| add_import name end
+      [fn, here]
+    ensure
+      Dir.chdir(Rake.original_dir)
+    end
+
+    def raw_load_rakefile # :nodoc:
+      rakefile, location = find_rakefile_location
+      if (! options.ignore_system) &&
+          (options.load_system || rakefile.nil?) &&
+          directory?(system_dir)
+        puts "(in #{Dir.pwd})" unless options.silent
+        glob("#{system_dir}/*.rake") do |name|
+          add_import name
+        end
+      else
+        fail "No Rakefile found (looking for: #{@rakefiles.join(', ')})" if
+          rakefile.nil?
+        @rakefile = rakefile
+        Dir.chdir(location)
+        puts "(in #{Dir.pwd})" unless options.silent
+        $rakefile = @rakefile if options.classic_namespace
+        load File.expand_path(@rakefile) if @rakefile && @rakefile != ''
+        options.rakelib.each do |rlib|
+          glob("#{rlib}/*.rake") do |name|
+            add_import name
+          end
+        end
       end
       load_imports
     end
 
+    def glob(path, &block)
+      Dir[path.gsub("\\", '/')].each(&block)
+    end
+    private :glob
+
+    # The directory path containing the system wide rakefiles.
+    def system_dir
+      if ENV['RAKE_SYSTEM']
+        ENV['RAKE_SYSTEM']
+      elsif windows?
+        win32_system_dir
+      else
+        standard_system_dir
+      end
+    end
+ 
+    # The standard directory containing system wide rake files.
+    def standard_system_dir #:nodoc:
+      File.join(File.expand_path('~'), '.rake')
+    end
+    private :standard_system_dir
+
+    # The standard directory containing system wide rake files on Win
+    # 32 systems.
+    def win32_system_dir #:nodoc:
+      win32home = File.join(ENV['APPDATA'], 'Rake')
+      unless directory?(win32home)
+        raise Win32HomeError, "Unable to determine home path environment variable."
+      else
+        win32home
+      end
+    end
+    private :win32_system_dir
+
+    def directory?(path)
+      File.directory?(path)
+    end
+    private :directory?
+
     # Collect the list of tasks on the command line.  If no tasks are
     # given, return a list containing only the default task.
     # Environmental assignments are processed at this time as well.
-    def collect_tasks
+    def collect_tasks(argv)
       @top_level_tasks = []
-      ARGV.each do |arg|
+      argv.each do |arg|
         if arg =~ /^(\w+)=(.*)$/
           ENV[$1] = $2
         else
-          @top_level_tasks << arg
+          @top_level_tasks << arg unless arg =~ /^-/
         end
       end
       @top_level_tasks.push("default") if @top_level_tasks.size == 0

--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]