summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog4
-rw-r--r--NEWS6
-rw-r--r--lib/rake.rb2478
-rw-r--r--lib/rake/alt_system.rb109
-rw-r--r--lib/rake/application.rb594
-rw-r--r--lib/rake/classic_namespace.rb1
-rw-r--r--lib/rake/cloneable.rb25
-rw-r--r--lib/rake/contrib/compositepublisher.rb1
-rw-r--r--lib/rake/contrib/ftptools.rb6
-rw-r--r--lib/rake/contrib/publisher.rb6
-rw-r--r--lib/rake/contrib/sshpublisher.rb5
-rw-r--r--lib/rake/contrib/sys.rb191
-rw-r--r--lib/rake/default_loader.rb10
-rw-r--r--lib/rake/dsl_definition.rb167
-rw-r--r--lib/rake/early_time.rb18
-rw-r--r--lib/rake/ext/core.rb27
-rw-r--r--lib/rake/ext/module.rb39
-rw-r--r--lib/rake/ext/string.rb167
-rw-r--r--lib/rake/ext/time.rb14
-rw-r--r--lib/rake/file_creation_task.rb24
-rw-r--r--lib/rake/file_list.rb403
-rw-r--r--lib/rake/file_task.rb47
-rw-r--r--lib/rake/file_utils.rb112
-rw-r--r--lib/rake/file_utils_ext.rb142
-rw-r--r--lib/rake/gempackagetask.rb96
-rw-r--r--lib/rake/invocation_chain.rb51
-rw-r--r--lib/rake/invocation_exception_mixin.rb16
-rw-r--r--lib/rake/lib/project.rake21
-rw-r--r--lib/rake/loaders/makefile.rb8
-rw-r--r--lib/rake/multi_task.rb16
-rw-r--r--lib/rake/name_space.rb25
-rw-r--r--lib/rake/packagetask.rb5
-rw-r--r--lib/rake/pathmap.rb1
-rw-r--r--lib/rake/pseudo_status.rb24
-rw-r--r--lib/rake/rake_module.rb29
-rw-r--r--lib/rake/rake_test_loader.rb12
-rw-r--r--lib/rake/rdoctask.rb232
-rwxr-xr-xlib/rake/ruby182_test_unit_fix.rb25
-rw-r--r--lib/rake/rule_recursion_overflow_error.rb20
-rw-r--r--lib/rake/runtest.rb8
-rw-r--r--lib/rake/task.rb327
-rw-r--r--lib/rake/task_argument_error.rb7
-rw-r--r--lib/rake/task_arguments.rb74
-rw-r--r--lib/rake/task_manager.rb307
-rw-r--r--lib/rake/tasklib.rb1
-rw-r--r--lib/rake/testtask.rb83
-rw-r--r--lib/rake/version.rb10
-rw-r--r--lib/rake/win32.rb45
-rw-r--r--test/rake/capture_stdout.rb24
-rw-r--r--test/rake/check_expansion.rb5
-rw-r--r--test/rake/check_no_expansion.rb5
-rw-r--r--test/rake/data/chains/Rakefile15
-rw-r--r--test/rake/data/default/Rakefile19
-rw-r--r--test/rake/data/dryrun/Rakefile22
-rw-r--r--test/rake/data/file_creation_task/Rakefile33
-rw-r--r--test/rake/data/imports/Rakefile19
-rw-r--r--test/rake/data/imports/deps.mf1
-rw-r--r--test/rake/data/multidesc/Rakefile17
-rw-r--r--test/rake/data/namespace/Rakefile57
-rw-r--r--test/rake/data/rakelib/test1.rake3
-rw-r--r--test/rake/data/rbext/rakefile.rb3
-rw-r--r--test/rake/data/sample.mf14
-rw-r--r--test/rake/data/statusreturn/Rakefile8
-rw-r--r--test/rake/data/unittest/Rakefile1
-rw-r--r--test/rake/data/unittest/subdir/.gitignore2
-rw-r--r--test/rake/file_creation.rb (renamed from test/rake/filecreation.rb)22
-rw-r--r--test/rake/helper.rb500
-rw-r--r--test/rake/in_environment.rb30
-rw-r--r--test/rake/rake_test_setup.rb9
-rw-r--r--test/rake/reqfile.rb3
-rw-r--r--test/rake/reqfile2.rb3
-rw-r--r--test/rake/reqfile3.rb3
-rwxr-xr-xtest/rake/shellcommand.rb3
-rw-r--r--test/rake/test_application.rb687
-rw-r--r--test/rake/test_invocation_chain.rb75
-rw-r--r--test/rake/test_package_task.rb115
-rw-r--r--test/rake/test_rake.rb9
-rw-r--r--test/rake/test_rake_application.rb403
-rw-r--r--test/rake/test_rake_application_options.rb335
-rw-r--r--test/rake/test_rake_clean.rb (renamed from test/rake/test_clean.rb)6
-rw-r--r--test/rake/test_rake_definitions.rb (renamed from test/rake/test_definitions.rb)23
-rw-r--r--test/rake/test_rake_directory_task.rb45
-rw-r--r--test/rake/test_rake_dsl.rb73
-rw-r--r--test/rake/test_rake_early_time.rb (renamed from test/rake/test_earlytime.rb)6
-rw-r--r--test/rake/test_rake_extension.rb (renamed from test/rake/test_extension.rb)6
-rw-r--r--test/rake/test_rake_file_creation_task.rb (renamed from test/rake/test_file_creation_task.rb)16
-rw-r--r--test/rake/test_rake_file_list.rb (renamed from test/rake/test_filelist.rb)291
-rw-r--r--test/rake/test_rake_file_list_path_map.rb8
-rw-r--r--test/rake/test_rake_file_task.rb (renamed from test/rake/test_file_task.rb)87
-rw-r--r--test/rake/test_rake_file_utils.rb (renamed from test/rake/test_fileutils.rb)197
-rw-r--r--test/rake/test_rake_ftp_file.rb (renamed from test/rake/contrib/test_ftp.rb)22
-rw-r--r--test/rake/test_rake_functional.rb514
-rw-r--r--test/rake/test_rake_invocation_chain.rb52
-rw-r--r--test/rake/test_rake_makefile_loader.rb (renamed from test/rake/test_makefile_loader.rb)28
-rw-r--r--test/rake/test_rake_multi_task.rb (renamed from test/rake/test_multitask.rb)28
-rw-r--r--test/rake/test_rake_name_space.rb (renamed from test/rake/test_namespace.rb)9
-rw-r--r--test/rake/test_rake_package_task.rb79
-rw-r--r--test/rake/test_rake_path_map.rb (renamed from test/rake/test_pathmap.rb)58
-rw-r--r--test/rake/test_rake_path_map_explode.rb34
-rw-r--r--test/rake/test_rake_path_map_partial.rb18
-rw-r--r--test/rake/test_rake_pseudo_status.rb (renamed from test/rake/test_pseudo_status.rb)12
-rw-r--r--test/rake/test_rake_rdoc_task.rb83
-rw-r--r--test/rake/test_rake_require.rb40
-rw-r--r--test/rake/test_rake_rules.rb (renamed from test/rake/test_rules.rb)151
-rw-r--r--test/rake/test_rake_task.rb (renamed from test/rake/test_tasks.rb)247
-rw-r--r--test/rake/test_rake_task_argument_parsing.rb110
-rw-r--r--test/rake/test_rake_task_arguments.rb (renamed from test/rake/test_task_arguments.rb)24
-rw-r--r--test/rake/test_rake_task_lib.rb (renamed from test/rake/test_tasklib.rb)5
-rw-r--r--test/rake/test_rake_task_manager.rb (renamed from test/rake/test_task_manager.rb)60
-rw-r--r--test/rake/test_rake_task_manager_argument_resolution.rb36
-rw-r--r--test/rake/test_rake_task_with_arguments.rb162
-rw-r--r--test/rake/test_rake_test_task.rb116
-rw-r--r--test/rake/test_rake_top_level_functions.rb76
-rw-r--r--test/rake/test_rake_win32.rb72
-rw-r--r--test/rake/test_require.rb32
-rw-r--r--test/rake/test_sys.rb20
-rw-r--r--test/rake/test_test_task.rb81
-rw-r--r--test/rake/test_top_level_functions.rb91
-rw-r--r--test/rake/test_win32.rb45
119 files changed, 6775 insertions, 4772 deletions
diff --git a/ChangeLog b/ChangeLog
index d8b76ce617..a6da7eb1a8 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,7 @@
+Fri Jun 24 07:11:37 2011 Eric Hodel <drbrain@segment7.net>
+
+ * lib/rake: Import Rake 0.9.2
+
Fri Jun 24 00:44:15 2011 Tadayoshi Funaba <tadf@dotrb.org>
* ext/date/date_core.c (c_valid_{julian,gregorian}_p): fixed the range of month.
diff --git a/NEWS b/NEWS
index 8817111dea..072e5fdb50 100644
--- a/NEWS
+++ b/NEWS
@@ -184,8 +184,12 @@ with all sufficient information, see the ChangeLog file.
* optparse
* support for bash/zsh completion.
+* Rake
+ * Rake has been upgraded from 0.8.7 to 0.9.2. For full release notes see
+ https://github.com/jimweirich/rake/blob/master/CHANGES
+
* RDoc
- * RDoc has been upgraded to RDoc 3.6.1. For full release notes see
+ * RDoc has been upgraded from 2.5.8 to 3.6.1. For full release notes see
http://docs.seattlerb.org/rdoc/History_txt.html
* rexml
diff --git a/lib/rake.rb b/lib/rake.rb
index e597db5eb2..d88cf6cfe6 100644
--- a/lib/rake.rb
+++ b/lib/rake.rb
@@ -1,6 +1,6 @@
#--
-# Copyright 2003, 2004, 2005, 2006, 2007, 2008 by Jim Weirich (jim@weirichhouse.org)
+# Copyright 2003-2010 by Jim Weirich (jim.weirich@gmail.com)
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to
@@ -20,14 +20,10 @@
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
# IN THE SOFTWARE.
#++
-#
-# = Rake -- Ruby Make
-#
-# This is the main file for the Rake application. Normally it is referenced
-# as a library via a require statement, but it can be distributed
-# independently as an application.
-RAKEVERSION = '0.8.7'
+require 'rake/version'
+
+RAKEVERSION = Rake::VERSION
require 'rbconfig'
require 'fileutils'
@@ -36,2450 +32,34 @@ require 'monitor'
require 'optparse'
require 'ostruct'
-require 'rake/win32'
-
-$trace = false
-
-######################################################################
-# Rake extensions to Module.
-#
-class Module
- # Check for an existing method in the current class before extending. IF
- # the method already exists, then a warning is printed and the extension is
- # not added. Otherwise the block is yielded and any definitions in the
- # block will take effect.
- #
- # Usage:
- #
- # class String
- # rake_extension("xyz") do
- # def xyz
- # ...
- # end
- # end
- # end
- #
- def rake_extension(method)
- if method_defined?(method)
- $stderr.puts "WARNING: Possible conflict with Rake extension: #{self}##{method} already exists"
- else
- yield
- end
- end
-end # module Module
-
-
-######################################################################
-# User defined methods to be added to String.
-#
-class String
- rake_extension("ext") do
- # Replace the file extension with +newext+. If there is no extension on
- # the string, append the new extension to the end. If the new extension
- # is not given, or is the empty string, remove any existing extension.
- #
- # +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
- self.chomp(File.extname(self)) << newext
- end
- end
-
- rake_extension("pathmap") do
- # Explode a path into individual components. Used by +pathmap+.
- def pathmap_explode
- head, tail = File.split(self)
- return [self] if head == self
- return [tail] if head == '.' || tail == '/'
- return [head, tail] if head == '/'
- return head.pathmap_explode + [tail]
- end
- protected :pathmap_explode
-
- # Extract a partial path from the path. Include +n+ directories from the
- # front end (left hand side) if +n+ is positive. Include |+n+|
- # directories from the back end (right hand side) if +n+ is negative.
- def pathmap_partial(n)
- dirs = File.dirname(self).pathmap_explode
- partial_dirs =
- if n > 0
- dirs[0...n]
- elsif n < 0
- dirs.reverse[0...-n].reverse
- else
- "."
- end
- File.join(partial_dirs)
- end
- protected :pathmap_partial
-
- # Preform the pathmap replacement operations on the given path. The
- # patterns take the form 'pat1,rep1;pat2,rep2...'.
- def pathmap_replace(patterns, &block)
- result = self
- patterns.split(';').each do |pair|
- pattern, replacement = pair.split(',')
- pattern = Regexp.new(pattern)
- if replacement == '*' && block_given?
- result = result.sub(pattern, &block)
- elsif replacement
- result = result.sub(pattern, replacement)
- else
- result = result.sub(pattern, '')
- end
- end
- result
- end
- protected :pathmap_replace
-
- # Map the path according to the given specification. The specification
- # controls the details of the mapping. The following special patterns are
- # recognized:
- #
- # * <b>%p</b> -- The complete path.
- # * <b>%f</b> -- The base file name of the path, with its file extension,
- # but without any directories.
- # * <b>%n</b> -- The file name of the path without its file extension.
- # * <b>%d</b> -- The directory list of the path.
- # * <b>%x</b> -- The file extension of the path. An empty string if there
- # is no extension.
- # * <b>%X</b> -- Everything *but* the file extension.
- # * <b>%s</b> -- The alternate file separater if defined, otherwise use
- # the standard file separator.
- # * <b>%%</b> -- A percent sign.
- #
- # The %d specifier can also have a numeric prefix (e.g. '%2d'). If the
- # number is positive, only return (up to) +n+ directories in the path,
- # starting from the left hand side. If +n+ is negative, return (up to)
- # |+n+| directories from the right hand side of the path.
- #
- # Examples:
- #
- # 'a/b/c/d/file.txt'.pathmap("%2d") => 'a/b'
- # 'a/b/c/d/file.txt'.pathmap("%-2d") => 'c/d'
- #
- # Also the %d, %p, %f, %n, %x, and %X operators can take a
- # pattern/replacement argument to perform simple string 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
- # semi-colons (e.g. "%{old,new;src,bin}d").
- #
- # Regular expressions may be used for the pattern, and back refs may be
- # used in the replacement text. Curly braces, commas and semi-colons are
- # excluded from both the pattern and replacement text (let's keep parsing
- # reasonable).
- #
- # For example:
- #
- # "src/org/onestepback/proj/A.java".pathmap("%{^src,bin}X.class")
- #
- # returns:
- #
- # "bin/org/onestepback/proj/A.class"
- #
- # If the replacement text is '*', then a block may be provided to perform
- # some arbitrary calculation for the replacement.
- #
- # For example:
- #
- # "/path/to/file.TXT".pathmap("%X%{.*,*}x") { |ext|
- # ext.downcase
- # }
- #
- # Returns:
- #
- # "/path/to/file.txt"
- #
- def pathmap(spec=nil, &block)
- return self if spec.nil?
- result = ''
- spec.scan(/%\{[^}]*\}-?\d*[sdpfnxX%]|%-?\d+d|%.|[^%]+/) do |frag|
- case frag
- when '%f'
- result << File.basename(self)
- when '%n'
- result << File.basename(self).ext
- when '%d'
- result << File.dirname(self)
- when '%x'
- result << File.extname(self)
- when '%X'
- result << self.ext
- when '%p'
- result << self
- when '%s'
- result << (File::ALT_SEPARATOR || File::SEPARATOR)
- when '%-'
- # do nothing
- when '%%'
- result << "%"
- when /%(-?\d+)d/
- result << pathmap_partial($1.to_i)
- when /^%\{([^}]*)\}(\d*[dpfnxX])/
- patterns, operator = $1, $2
- result << pathmap('%' + operator).pathmap_replace(patterns, &block)
- when /^%/
- fail ArgumentError, "Unknown pathmap specifier #{frag} in '#{spec}'"
- else
- result << frag
- end
- end
- result
- end
- end
-end # class String
-
-##############################################################################
-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
-
- # --------------------------------------------------------------------------
- # Rake module singleton methods.
- #
- class << self
- # Current Rake Application
- def application
- @application ||= Rake::Application.new
- end
-
- # Set the current Rake application object.
- def application=(app)
- @application = app
- end
-
- # Return the original directory where the Rake application was started.
- def original_dir
- application.original_dir
- end
-
- end
-
- ####################################################################
- # Mixin for creating easily cloned objects.
- #
- module Cloneable
- # Clone an object by making a new object and setting all the instance
- # variables to the same values.
- 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
-
- def clone
- sibling = dup
- sibling.freeze if frozen?
- sibling
- end
- end
-
- ####################################################################
- # 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
- end
-
- ####################################################################
- # TaskAguments manage the arguments passed to a task.
- #
- class TaskArguments
- include Enumerable
-
- 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] unless values[i].nil?
- }
- 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)
- end
-
- # Find an argument value by name or index.
- def [](index)
- 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
-
- def method_missing(sym, *args, &block)
- lookup(sym.to_sym)
- end
-
- def to_hash
- @hash
- end
-
- def to_s
- @hash.inspect
- end
-
- def inspect
- to_s
- end
-
- protected
-
- def lookup(name)
- if @hash.has_key?(name)
- @hash[name]
- elsif ENV.has_key?(name.to_s)
- ENV[name.to_s]
- elsif ENV.has_key?(name.to_s.upcase)
- ENV[name.to_s.upcase]
- elsif @parent
- @parent.lookup(name)
- end
- end
- end
-
- EMPTY_TASK_ARGS = TaskArguments.new([], [])
-
- ####################################################################
- # InvocationChain tracks the chain of task invocations to detect
- # circular dependencies.
- class InvocationChain
- def initialize(value, tail)
- @value = value
- @tail = tail
- end
-
- def member?(obj)
- @value == obj || @tail.member?(obj)
- end
-
- def append(value)
- if member?(value)
- fail RuntimeError, "Circular dependency detected: #{to_s} => #{value}"
- end
- self.class.new(value, self)
- end
-
- def to_s
- "#{prefix}#{@value}"
- end
-
- def self.append(value, chain)
- chain.append(value)
- end
-
- private
-
- def prefix
- "#{@tail.to_s} => "
- end
-
- class EmptyInvocationChain
- def member?(obj)
- false
- end
- def append(value)
- InvocationChain.new(value, self)
- end
- def to_s
- "TOP"
- end
- end
-
- EMPTY = EmptyInvocationChain.new
-
- end # class InvocationChain
-
-end # module Rake
-
-module Rake
-
- ###########################################################################
- # A Task is the basic unit of work in a Rakefile. Tasks have associated
- # actions (possibly more than one) and a list of prerequisites. When
- # invoked, a task will first ensure that all of its prerequisites have an
- # opportunity to run and then it will execute its own actions.
- #
- # Tasks are not usually created directly using the new method, but rather
- # use the +file+ and +task+ convenience methods.
- #
- class Task
- # 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
-
- # 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
-
- # Return task name
- def to_s
- name
- end
-
- def inspect
- "<#{self.class} #{name} => [#{prerequisites.join(', ')}]>"
- end
-
- # List of sources for task.
- attr_writer :sources
- def sources
- @sources ||= []
- end
-
- # First source from a rule (nil if no sources)
- def source
- @sources.first if defined?(@sources)
- end
-
- # 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 = []
- @already_invoked = false
- @full_comment = nil
- @comment = nil
- @lock = Monitor.new
- @application = app
- @scope = app.current_scope
- @arg_names = nil
- end
-
- # Enhance a task with prerequisites or actions. Returns self.
- def enhance(deps=nil, &block)
- @prerequisites |= deps if deps
- @actions << block if block_given?
- self
- end
-
- # Name of the task, including any namespace qualifiers.
- def name
- @name.to_s
- end
-
- # Name of task with argument list description.
- def name_with_args # :nodoc:
- if arg_description
- "#{name}#{arg_description}"
- else
- name
- end
- end
-
- # Argument description (nil if none).
- def arg_description # :nodoc:
- @arg_names ? "[#{(arg_names || []).join(',')}]" : nil
- end
-
- # Name of arguments for this task.
- def arg_names
- @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)
- invoke_with_call_chain(task_args, InvocationChain::EMPTY)
- end
-
- # Same as invoke, but explicitly pass a call chain to detect
- # circular dependencies.
- def invoke_with_call_chain(task_args, invocation_chain) # :nodoc:
- new_chain = InvocationChain.append(self, invocation_chain)
- @lock.synchronize do
- if application.options.trace
- puts "** Invoke #{name} #{format_trace_flags}"
- end
- return if @already_invoked
- @already_invoked = true
- invoke_prerequisites(task_args, new_chain)
- execute(task_args) if needed?
- end
- end
- protected :invoke_with_call_chain
-
- # Invoke all the prerequisites of a task.
- def invoke_prerequisites(task_args, invocation_chain) # :nodoc:
- @prerequisites.each { |n|
- prereq = application[n, @scope]
- prereq_args = task_args.new_scope(prereq.arg_names)
- prereq.invoke_with_call_chain(prereq_args, invocation_chain)
- }
- end
-
- # Format the trace flags for display.
- def format_trace_flags
- flags = []
- flags << "first_time" unless @already_invoked
- flags << "not_needed" unless needed?
- flags.empty? ? "" : "(" + flags.join(", ") + ")"
- end
- private :format_trace_flags
-
- # Execute the actions associated with this task.
- def execute(args=nil)
- args ||= EMPTY_TASK_ARGS
- if application.options.dryrun
- puts "** Execute (dry run) #{name}"
- return
- end
- if application.options.trace
- puts "** Execute #{name}"
- end
- application.enhance_with_matching_rule(name) if @actions.empty?
- @actions.each do |act|
- case act.arity
- when 1
- act.call(self)
- else
- act.call(self, args)
- end
- end
- end
-
- # Is this task needed?
- def needed?
- true
- end
-
- # Timestamp for this task. Basic tasks return the current time for their
- # time stamp. Other tasks can be more sophisticated.
- def timestamp
- @prerequisites.collect { |p| application[p].timestamp }.max || 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
- 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)
- end
-
- # Add a comment to the task. If a comment alread 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
- else
- @comment = @full_comment
- end
- end
- private :add_comment
-
- # Set the names of the arguments for this task. +args+ should be
- # an array of symbols, one for each argument name.
- def set_arg_names(args)
- @arg_names = args.map { |a| a.to_sym }
- end
-
- # Return a string describing the internal state of a task. Useful for
- # debugging.
- def investigation
- result = "------------------------------\n"
- result << "Investigating #{name}\n"
- result << "class: #{self.class}\n"
- result << "task needed: #{needed?}\n"
- result << "timestamp: #{timestamp}\n"
- result << "pre-requisites: \n"
- prereqs = @prerequisites.collect {|name| application[name]}
- prereqs.sort! {|a,b| a.timestamp <=> b.timestamp}
- prereqs.each do |p|
- result << "--#{p.name} (#{p.timestamp})\n"
- end
- latest_prereq = @prerequisites.collect{|n| application[n].timestamp}.max
- result << "latest-prerequisite time: #{latest_prereq}\n"
- result << "................................\n\n"
- return result
- end
-
- # ----------------------------------------------------------------
- # Rake Module Methods
- #
- class << self
-
- # Clear the task list. This cause rake to immediately forget all the
- # tasks that have been assigned. (Normally used in the unit tests.)
- def clear
- Rake.application.clear
- end
-
- # List of all defined tasks.
- def tasks
- Rake.application.tasks
- end
-
- # Return a task with the given name. If the task is not currently
- # known, try to synthesize one from the defined rules. If no rules are
- # found, but an existing file matches the task name, assume it is a file
- # task with no dependencies or actions.
- def [](task_name)
- Rake.application[task_name]
- end
-
- # TRUE if the task name is already defined.
- def task_defined?(task_name)
- Rake.application.lookup(task_name) != nil
- end
-
- # Define a task given +args+ and an option block. If a rule with the
- # given name already exists, the prerequisites and actions are added to
- # the existing task. Returns the defined task.
- def define_task(*args, &block)
- Rake.application.define_task(self, *args, &block)
- end
-
- # Define a rule for synthesizing tasks.
- def create_rule(*args, &block)
- Rake.application.create_rule(*args, &block)
- end
-
- # Apply the scope to the task name according to the rules for
- # 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(':')
- end
-
- end # class << Rake::Task
- end # class Rake::Task
-
-
- ###########################################################################
- # A FileTask is a task that includes time based dependencies. If any of a
- # FileTask's prerequisites have a timestamp that is later than the file
- # represented by this task, then the file must be rebuilt (using the
- # supplied actions).
- #
- class FileTask < Task
-
- # Is this file task needed? Yes if it doesn't exist, or if its time stamp
- # is out of date.
- def needed?
- ! File.exist?(name) || out_of_date?(timestamp)
- end
-
- # Time stamp for file task.
- def timestamp
- if File.exist?(name)
- File.mtime(name.to_s)
- else
- Rake::EARLY
- end
- end
-
- private
-
- # Are there any prerequisites with a later time than the given time stamp?
- def out_of_date?(stamp)
- @prerequisites.any? { |n| application[n].timestamp > stamp}
- end
-
- # ----------------------------------------------------------------
- # Task class methods.
- #
- class << self
- # Apply the scope to the task name according to the rules for this kind
- # of task. File based tasks ignore the scope when creating the name.
- def scope_name(scope, task_name)
- task_name
- end
- end
- end # class Rake::FileTask
-
- ###########################################################################
- # A FileCreationTask is a file task that when used as a dependency will be
- # needed if and only if the file has not been created. Once created, it is
- # not re-triggered if any of its dependencies are newer, nor does trigger
- # any rebuilds of tasks that depend on it whenever it is updated.
- #
- class FileCreationTask < FileTask
- # Is this file task needed? Yes if it doesn't exist.
- def needed?
- ! File.exist?(name)
- end
-
- # Time stamp for file creation task. This time stamp is earlier
- # than any other time stamp.
- def timestamp
- Rake::EARLY
- end
- end
-
- ###########################################################################
- # Same as a regular task, but the immediate prerequisites are done in
- # parallel using Ruby threads.
- #
- class MultiTask < Task
- private
- def invoke_prerequisites(args, invocation_chain)
- threads = @prerequisites.collect { |p|
- Thread.new(p) { |r| application[r].invoke_with_call_chain(args, invocation_chain) }
- }
- threads.each { |t| t.join }
- end
- end
-end # module Rake
-
-## ###########################################################################
-# Task Definition Functions ...
-
-# Declare a basic task.
-#
-# Example:
-# task :clobber => [:clean] do
-# rm_rf "html"
-# end
-#
-def task(*args, &block)
- Rake::Task.define_task(*args, &block)
-end
-
-
-# Declare a file task.
-#
-# Example:
-# file "config.cfg" => ["config.template"] do
-# open("config.cfg", "w") do |outfile|
-# open("config.template") do |infile|
-# while line = infile.gets
-# outfile.puts line
-# end
-# end
-# end
-# end
-#
-def file(*args, &block)
- Rake::FileTask.define_task(*args, &block)
-end
-
-# Declare a file creation task.
-# (Mainly used for the directory command).
-def file_create(args, &block)
- Rake::FileCreationTask.define_task(args, &block)
-end
-
-# Declare a set of files tasks to create the given directories on demand.
-#
-# Example:
-# directory "testdata/doc"
-#
-def directory(dir)
- Rake.each_dir_parent(dir) do |d|
- file_create d do |t|
- mkdir_p t.name if ! File.exist?(t.name)
- end
- end
-end
-
-# Declare a task that performs its prerequisites in parallel. Multitasks does
-# *not* guarantee that its prerequisites will execute in any given order
-# (which is obvious when you think about it)
-#
-# Example:
-# multitask :deploy => [:deploy_gem, :deploy_rdoc]
-#
-def multitask(args, &block)
- Rake::MultiTask.define_task(args, &block)
-end
-
-# Create a new rake namespace and use it for evaluating the given block.
-# Returns a NameSpace object that can be used to lookup tasks defined in the
-# namespace.
-#
-# E.g.
-#
-# ns = namespace "nested" do
-# task :run
-# end
-# task_run = ns[:run] # find :run in the given namespace.
-#
-def namespace(name=nil, &block)
- Rake.application.in_namespace(name, &block)
-end
-
-# Declare a rule for auto-tasks.
-#
-# Example:
-# rule '.o' => '.c' do |t|
-# sh %{cc -o #{t.name} #{t.source}}
-# end
-#
-def rule(*args, &block)
- Rake::Task.create_rule(*args, &block)
-end
-
-# Describe the next rake task.
-#
-# Example:
-# desc "Run the Unit Tests"
-# task :test => [:build]
-# runtests
-# end
-#
-def desc(description)
- Rake.application.last_description = description
-end
-
-# Import the partial Rakefiles +fn+. Imported files are loaded _after_ the
-# current file is completely loaded. This allows the import statement to
-# appear anywhere in the importing file, and yet allowing the imported files
-# to depend on objects defined in the importing file.
-#
-# A common use of the import statement is to include files containing
-# dependency declarations.
-#
-# See also the --rakelibdir command line option.
-#
-# Example:
-# import ".depend", "my_rules"
-#
-def import(*fns)
- fns.each do |fn|
- Rake.application.add_import(fn)
- end
-end
-
-#############################################################################
-# This a FileUtils extension that defines several additional commands to be
-# added to the FileUtils utility functions.
-#
-module FileUtils
- RUBY_EXT = ((RbConfig::CONFIG['ruby_install_name'] =~ /\.(com|cmd|exe|bat|rb|sh)$/) ?
- "" :
- RbConfig::CONFIG['EXEEXT'])
-
- RUBY = File.join(
- RbConfig::CONFIG['bindir'],
- RbConfig::CONFIG['ruby_install_name'] + RUBY_EXT).
- sub(/.*\s.*/m, '"\&"')
-
- OPT_TABLE['sh'] = %w(noop verbose)
- OPT_TABLE['ruby'] = %w(noop verbose)
-
- # Run the system command +cmd+. If multiple arguments are given the command
- # is not run with the shell (same semantics as Kernel::exec and
- # Kernel::system).
- #
- # Example:
- # sh %{ls -ltr}
- #
- # sh 'ls', 'file with spaces'
- #
- # # check exit status after command runs
- # sh %{grep pattern file} do |ok, res|
- # if ! ok
- # puts "pattern not found (status = #{res.exitstatus})"
- # end
- # end
- #
- def sh(*cmd, &block)
- options = (Hash === cmd.last) ? cmd.pop : {}
- unless block_given?
- show_command = cmd.join(" ")
- show_command = show_command[0,42] + "..." unless $trace
- # TODO code application logic heref show_command.length > 45
- block = lambda { |ok, status|
- ok or fail "Command failed with status (#{status.exitstatus}): [#{show_command}]"
- }
- end
- if RakeFileUtils.verbose_flag == :default
- options[:verbose] = true
- 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 = rake_system(*cmd)
- status = $?
- status = PseudoStatus.new(1) if !res && status.nil?
- block.call(res, status)
- end
- end
-
- def rake_system(*cmd)
- system(*cmd)
- end
- private :rake_system
-
- # Run a Ruby interpreter with the given arguments.
- #
- # Example:
- # ruby %{-pe '$_.upcase!' <README}
- #
- def ruby(*args,&block)
- options = (Hash === args.last) ? args.pop : {}
- if args.length > 1 then
- sh(*([RUBY] + args + [options]), &block)
- else
- sh("#{RUBY} #{args.first}", options, &block)
- end
- end
-
- LN_SUPPORTED = [true]
-
- # 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]
- cp(*args)
- else
- begin
- ln(*args)
- rescue StandardError, NotImplementedError
- LN_SUPPORTED[0] = false
- cp(*args)
- end
- end
- end
-
- # Split a file path into individual directory names.
- #
- # 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
-end
+require 'rake/ext/module'
+require 'rake/ext/string'
+require 'rake/ext/time'
-#############################################################################
-# RakeFileUtils provides a custom version of the FileUtils methods that
-# respond to the <tt>verbose</tt> and <tt>nowrite</tt> commands.
-#
-module RakeFileUtils
- include FileUtils
-
- class << self
- attr_accessor :verbose_flag, :nowrite_flag
- end
- RakeFileUtils.verbose_flag = :default
- RakeFileUtils.nowrite_flag = false
-
- $fileutils_verbose = true
- $fileutils_nowrite = false
-
- FileUtils::OPT_TABLE.each do |name, opts|
- default_options = []
- if opts.include?(:verbose) || opts.include?("verbose")
- default_options << ':verbose => RakeFileUtils.verbose_flag'
- end
- if opts.include?(:noop) || opts.include?("noop")
- default_options << ':noop => RakeFileUtils.nowrite_flag'
- end
-
- next if default_options.empty?
- module_eval(<<-EOS, __FILE__, __LINE__ + 1)
- def #{name}( *args, &block )
- super(
- *rake_merge_option(args,
- #{default_options.join(', ')}
- ), &block)
- end
- EOS
- end
-
- # Get/set the verbose flag controlling output from the FileUtils utilities.
- # If verbose is true, then the utility method is echoed to standard output.
- #
- # Examples:
- # verbose # return the current value of the verbose flag
- # verbose(v) # set the verbose flag to _v_.
- # verbose(v) { code } # Execute code with the verbose flag set temporarily to _v_.
- # # Return to the original value when code is done.
- def verbose(value=nil)
- oldvalue = RakeFileUtils.verbose_flag
- RakeFileUtils.verbose_flag = value unless value.nil?
- if block_given?
- begin
- yield
- ensure
- RakeFileUtils.verbose_flag = oldvalue
- end
- end
- RakeFileUtils.verbose_flag
- end
-
- # Get/set the nowrite flag controlling output from the FileUtils utilities.
- # If verbose is true, then the utility method is echoed to standard output.
- #
- # Examples:
- # nowrite # return the current value of the nowrite flag
- # nowrite(v) # set the nowrite flag to _v_.
- # nowrite(v) { code } # Execute code with the nowrite flag set temporarily to _v_.
- # # Return to the original value when code is done.
- def nowrite(value=nil)
- oldvalue = RakeFileUtils.nowrite_flag
- RakeFileUtils.nowrite_flag = value unless value.nil?
- if block_given?
- begin
- yield
- ensure
- RakeFileUtils.nowrite_flag = oldvalue
- end
- end
- oldvalue
- end
-
- # Use this function to prevent protentially destructive ruby code from
- # running when the :nowrite flag is set.
- #
- # Example:
- #
- # when_writing("Building Project") do
- # project.build
- # end
- #
- # The following code will build the project under normal conditions. If the
- # nowrite(true) flag is set, then the example will print:
- # DRYRUN: Building Project
- # instead of actually building the project.
- #
- def when_writing(msg=nil)
- if RakeFileUtils.nowrite_flag
- puts "DRYRUN: #{msg}" if msg
- else
- yield
- end
- end
-
- # Merge the given options with the default values.
- def rake_merge_option(args, defaults)
- if Hash === args.last
- defaults.update(args.last)
- args.pop
- end
- args.push defaults
- args
- end
- private :rake_merge_option
-
- # Send the message to the default rake output (which is $stderr).
- def rake_output_message(message)
- $stderr.puts(message)
- end
- private :rake_output_message
-
- # Check that the options do not contain options not listed in +optdecl+. An
- # ArgumentError exception is thrown if non-declared options are found.
- def rake_check_options(options, *optdecl)
- h = options.dup
- optdecl.each do |name|
- h.delete name
- end
- raise ArgumentError, "no such option: #{h.keys.join(' ')}" unless h.empty?
- end
- private :rake_check_options
-
- extend self
-end
-
-#############################################################################
-# Include the FileUtils file manipulation functions in the top level module,
-# but mark them private so that they don't unintentionally define methods on
-# other objects.
-
-include RakeFileUtils
-private(*FileUtils.instance_methods(false))
-private(*RakeFileUtils.instance_methods(false))
-
-######################################################################
-module Rake
-
- ###########################################################################
- # A FileList is essentially an array with a few helper methods defined to
- # make file manipulation a bit easier.
- #
- # FileLists are lazy. When given a list of glob patterns for possible files
- # to be included in the file list, instead of searching the file structures
- # to find the files, a FileList holds the pattern for latter use.
- #
- # This allows us to define a number of FileList to match any number of
- # files, but only search out the actual files when then FileList itself is
- # actually used. The key is that the first time an element of the
- # FileList/Array is requested, the pending patterns are resolved into a real
- # list of file names.
- #
- class FileList
-
- include Cloneable
-
- # == Method Delegation
- #
- # The lazy evaluation magic of FileLists happens by implementing all the
- # array specific methods to call +resolve+ before delegating the heavy
- # lifting to an embedded array object (@items).
- #
- # In addition, there are two kinds of delegation calls. The regular kind
- # delegates to the @items array and returns the result directly. Well,
- # almost directly. It checks if the returned value is the @items object
- # itself, and if so will return the FileList object instead.
- #
- # The second kind of delegation call is used in methods that normally
- # return a new Array object. We want to capture the return value of these
- # methods and wrap them in a new FileList object. We enumerate these
- # methods in the +SPECIAL_RETURN+ list below.
-
- # 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 }
-
- # List of additional methods that must be delegated.
- MUST_DEFINE = %w[to_a inspect]
-
- # List of methods that should not be delegated here (we define special
- # versions of them explicitly below).
- MUST_NOT_DEFINE = %w[to_a to_ary partition *]
-
- # List of delegated methods that return new array values which need
- # wrapping.
- SPECIAL_RETURN = %w[
- map collect sort sort_by select find_all reject grep
- compact flatten uniq values_at
- + - & |
- ]
-
- DELEGATING_METHODS = (ARRAY_METHODS + MUST_DEFINE - MUST_NOT_DEFINE).collect{ |s| s.to_s }.sort.uniq
-
- # Now do the delegation.
- DELEGATING_METHODS.each_with_index do |sym, i|
- if SPECIAL_RETURN.include?(sym)
- define_method(sym) do |*args, &block|
- resolve
- result = @items.send(sym, *args, &block)
- FileList.new.import(result)
- end
- else
- define_method(sym) do |*args, &block|
- resolve
- result = @items.send(sym, *args, &block)
- result.object_id == @items.object_id ? self : result
- end
- end
- end
-
- # Create a file list from the globbable patterns given. If you wish to
- # perform multiple includes or excludes at object build time, use the
- # "yield self" pattern.
- #
- # Example:
- # file_list = FileList.new('lib/**/*.rb', 'test/test*.rb')
- #
- # pkg_files = FileList.new('lib/**/*') do |fl|
- # fl.exclude(/\bCVS\b/)
- # end
- #
- def initialize(*patterns)
- @pending_add = []
- @pending = false
- @exclude_patterns = DEFAULT_IGNORE_PATTERNS.dup
- @exclude_procs = DEFAULT_IGNORE_PROCS.dup
- @exclude_re = nil
- @items = []
- patterns.each { |pattern| include(pattern) }
- yield self if block_given?
- end
-
- # Add file names defined by glob patterns to the file list. If an array
- # is given, add each element of the array.
- #
- # Example:
- # file_list.include("*.java", "*.cfg")
- # file_list.include %w( math.c lib.h *.o )
- #
- def include(*filenames)
- # TODO: check for pending
- filenames.each do |fn|
- if fn.respond_to? :to_ary
- include(*fn.to_ary)
- else
- @pending_add << fn
- end
- end
- @pending = true
- self
- end
- alias :add :include
-
- # Register a list of file name patterns that should be excluded from the
- # list. Patterns may be regular expressions, glob patterns or regular
- # strings. In addition, a block given to exclude will remove entries that
- # return true when given to the block.
- #
- # Note that glob patterns are expanded against the file system. If a file
- # is explicitly added to a file list, but does not exist in the file
- # system, then an glob pattern in the exclude list will not exclude the
- # file.
- #
- # Examples:
- # FileList['a.c', 'b.c'].exclude("a.c") => ['b.c']
- # FileList['a.c', 'b.c'].exclude(/^a/) => ['b.c']
- #
- # If "a.c" is a file, then ...
- # FileList['a.c', 'b.c'].exclude("a.*") => ['b.c']
- #
- # If "a.c" is not a file, then ...
- # FileList['a.c', 'b.c'].exclude("a.*") => ['a.c', 'b.c']
- #
- def exclude(*patterns, &block)
- patterns.each do |pat|
- @exclude_patterns << pat
- end
- if block_given?
- @exclude_procs << block
- end
- resolve_exclude if ! @pending
- self
- end
-
-
- # Clear all the exclude patterns so that we exclude nothing.
- def clear_exclude
- @exclude_patterns = []
- @exclude_procs = []
- calculate_exclude_regexp if ! @pending
- self
- end
-
- # Define equality.
- def ==(array)
- to_ary == array
- end
-
- # Return the internal array object.
- def to_a
- resolve
- @items
- end
-
- # Return the internal array object.
- def to_ary
- to_a
- end
-
- # Lie about our class.
- def is_a?(klass)
- klass == Array || super(klass)
- end
- alias kind_of? is_a?
-
- # Redefine * to return either a string or a new file list.
- def *(other)
- result = @items * other
- case result
- when Array
- FileList.new.import(result)
- else
- result
- end
- end
-
- # Resolve all the pending adds now.
- def resolve
- if @pending
- @pending = false
- @pending_add.each do |fn| resolve_add(fn) end
- @pending_add = []
- resolve_exclude
- end
- self
- end
-
- def calculate_exclude_regexp
- ignores = []
- @exclude_patterns.each do |pat|
- case pat
- when Regexp
- ignores << pat
- when /[*?]/
- Dir[pat].each do |p| ignores << p end
- else
- ignores << Regexp.quote(pat)
- end
- end
- if ignores.empty?
- @exclude_re = /^$/
- else
- re_str = ignores.collect { |p| "(" + p.to_s + ")" }.join("|")
- @exclude_re = Regexp.new(re_str)
- end
- end
-
- def resolve_add(fn)
- case fn
- when %r{[*?\[\{]}
- add_matching(fn)
- else
- self << fn
- end
- end
- private :resolve_add
-
- def resolve_exclude
- calculate_exclude_regexp
- reject! { |fn| exclude?(fn) }
- self
- end
- private :resolve_exclude
-
- # Return a new FileList with the results of running +sub+ against each
- # element of the oringal list.
- #
- # Example:
- # 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) }
- end
-
- # Return a new FileList with the results of running +gsub+ against each
- # element of the original list.
- #
- # Example:
- # FileList['lib/test/file', 'x/y'].gsub(/\//, "\\")
- # => ['lib\\test\\file', 'x\\y']
- #
- def gsub(pat, rep)
- inject(FileList.new) { |res, fn| res << fn.gsub(pat,rep) }
- end
-
- # Same as +sub+ except that the oringal file list is modified.
- def 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) }
- self
- end
-
- # Apply the pathmap spec to each of the included file names, returning a
- # new file list with the modified paths. (See String#pathmap for
- # details.)
- def pathmap(spec=nil)
- collect { |fn| fn.pathmap(spec) }
- end
-
- # Return a new FileList with <tt>String#ext</tt> method applied
- # to each member of the array.
- #
- # This method is a shortcut for:
- #
- # array.collect { |item| item.ext(newext) }
- #
- # +ext+ is a user added method for the Array class.
- def ext(newext='')
- collect { |fn| fn.ext(newext) }
- end
-
-
- # Grep each of the files in the filelist using the given pattern. If a
- # block is given, call the block on each matching line, passing the file
- # name, line number, and the matching line of text. If no block is given,
- # a standard emac style file:linenumber:line message will be printed to
- # standard out.
- def egrep(pattern, *options)
- each do |fn|
- open(fn, "rb", *options) do |inf|
- count = 0
- inf.each do |line|
- count += 1
- if pattern.match(line)
- if block_given?
- yield fn, count, line
- else
- puts "#{fn}:#{count}:#{line}"
- end
- end
- end
- end
- end
- end
-
- # Return a new file list that only contains file names from the current
- # file list that exist on the file system.
- def existing
- select { |fn| File.exist?(fn) }
- end
-
- # Modify the current file list so that it contains only file name that
- # exist on the file system.
- def existing!
- resolve
- @items = @items.select { |fn| File.exist?(fn) }
- self
- end
-
- # FileList version of partition. Needed because the nested arrays should
- # be FileLists in this version.
- def partition(&block) # :nodoc:
- resolve
- result = @items.partition(&block)
- [
- FileList.new.import(result[0]),
- FileList.new.import(result[1]),
- ]
- end
-
- # Convert a FileList to a string by joining all elements with a space.
- def to_s
- resolve
- self.join(' ')
- end
-
- # Add matching glob patterns.
- def add_matching(pattern)
- Dir[pattern].each do |fn|
- self << fn unless exclude?(fn)
- end
- end
- private :add_matching
-
- # Should the given file name be excluded?
- def exclude?(fn)
- calculate_exclude_regexp unless @exclude_re
- fn =~ @exclude_re || @exclude_procs.any? { |p| p.call(fn) }
- end
-
- DEFAULT_IGNORE_PATTERNS = [
- /(^|[\/\\])CVS([\/\\]|$)/,
- /(^|[\/\\])\.svn([\/\\]|$)/,
- /\.bak$/,
- /~$/
- ]
- DEFAULT_IGNORE_PROCS = [
- proc { |fn| fn =~ /(^|[\/\\])core$/ && ! File.directory?(fn) }
- ]
-# @exclude_patterns = DEFAULT_IGNORE_PATTERNS.dup
-
- def import(array)
- @items = array
- self
- end
+require 'rake/win32'
- class << self
- # Create a new file list including the files listed. Similar to:
- #
- # FileList.new(*args)
- def [](*args)
- new(*args)
- end
- end
- end # FileList
-end
+require 'rake/task_argument_error'
+require 'rake/rule_recursion_overflow_error'
+require 'rake/rake_module'
+require 'rake/pseudo_status'
+require 'rake/task_arguments'
+require 'rake/invocation_chain'
+require 'rake/task'
+require 'rake/file_task'
+require 'rake/file_creation_task'
+require 'rake/multi_task'
+require 'rake/dsl_definition'
+require 'rake/file_utils_ext'
+require 'rake/file_list'
+require 'rake/default_loader'
+require 'rake/early_time'
+require 'rake/name_space'
+require 'rake/task_manager'
+require 'rake/application'
-module Rake
- class << self
+$trace = false
- # Yield each file or directory component.
- def each_dir_parent(dir) # :nodoc:
- old_length = nil
- while dir != '.' && dir.length != old_length
- yield(dir)
- old_length = dir.length
- dir = File.dirname(dir)
- end
- end
- end
-end # module Rake
+# Some top level Constants.
-# Alias FileList to be available at the top level.
FileList = Rake::FileList
-
-#############################################################################
-module Rake
-
- # Default Rakefile loader used by +import+.
- class DefaultLoader
- def load(fn)
- Kernel.load(File.expand_path(fn))
- end
- end
-
- # EarlyTime is a fake timestamp that occurs _before_ any other time value.
- class EarlyTime
- include Comparable
- include Singleton
-
- def <=>(other)
- -1
- end
-
- def to_s
- "<EARLY TIME>"
- end
- end
-
- EARLY = EarlyTime.instance
-end # module Rake
-
-#############################################################################
-# Extensions to time to allow comparisons with an early time class.
-#
-class Time
- alias rake_original_time_compare :<=>
- def <=>(other)
- if Rake::EarlyTime === other
- - other.<=>(self)
- else
- rake_original_time_compare(other)
- end
- end
-end # class Time
-
-module Rake
-
- ####################################################################
- # The NameSpace class will lookup task names in the the scope
- # defined by a +namespace+ command.
- #
- class NameSpace
-
- # Create a namespace lookup object using the given task manager
- # and the list of scopes.
- def initialize(task_manager, scope_list)
- @task_manager = task_manager
- @scope = scope_list.dup
- end
-
- # Lookup a task named +name+ in the namespace.
- def [](name)
- @task_manager.lookup(name, @scope)
- end
-
- # Return the list of tasks defined in this and nested namespaces.
- def tasks
- @task_manager.tasks_in_scope(@scope)
- end
- end # NameSpace
-
-
- ####################################################################
- # The TaskManager module is a mixin for managing tasks.
- module TaskManager
- # Track the last comment made in the Rakefile.
- attr_accessor :last_description
- alias :last_comment :last_description # Backwards compatibility
-
- def initialize
- super
- @tasks = Hash.new
- @rules = Array.new
- @scope = Array.new
- @last_description = nil
- end
-
- def create_rule(*args, &block)
- pattern, _, deps = resolve_args(args)
- pattern = Regexp.new(Regexp.quote(pattern) + '$') if String === pattern
- @rules << [pattern, 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 }
- task = intern(task_class, task_name)
- task.set_arg_names(arg_names) unless arg_names.empty?
- task.add_description(@last_description)
- @last_description = nil
- task.enhance(deps, &block)
- task
- end
-
- # Lookup a task. Return an existing task if found, otherwise
- # create a task of the current type.
- def intern(task_class, task_name)
- @tasks[task_name.to_s] ||= task_class.new(task_name, self)
- end
-
- # Find a matching task for +task_name+.
- def [](task_name, scopes=nil)
- task_name = task_name.to_s
- self.lookup(task_name, scopes) or
- enhance_with_matching_rule(task_name) or
- synthesize_file_task(task_name) or
- fail "Don't know how to build task '#{task_name}'"
- end
-
- def synthesize_file_task(task_name)
- return nil unless File.exist?(task_name)
- define_task(Rake::FileTask, task_name)
- end
-
- # 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
- if args.size == 1 && args.first.respond_to?(:to_ary)
- arg_names = args.first.to_ary
- else
- arg_names = args
- end
- [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
- 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
- # the enhanced task or nil of no rule was found.
- 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|
- if pattern.match(task_name)
- task = attempt_rule(task_name, extensions, block, level)
- return task if task
- end
- end
- nil
- rescue Rake::RuleRecursionOverflowError => ex
- ex.add_target(task_name)
- fail ex
- end
-
- # List of all defined tasks in this application.
- def tasks
- @tasks.values.sort_by { |t| t.name }
- end
-
- # List of all the tasks defined in the given scope (and its
- # sub-scopes).
- def tasks_in_scope(scope)
- prefix = scope.join(":")
- tasks.select { |t|
- /^#{prefix}:/ =~ t.name
- }
- end
-
- # Clear all tasks in this application.
- def clear
- @tasks.clear
- @rules.clear
- end
-
- # Lookup a task, using scope and the scope hints in the task name.
- # This method performs straight lookups without trying to
- # synthesize file tasks or rules. Special scope names (e.g. '^')
- # are recognized. If no scope argument is supplied, use the
- # current scope. Return nil if the task cannot be found.
- def lookup(task_name, initial_scope=nil)
- initial_scope ||= @scope
- task_name = task_name.to_s
- if task_name =~ /^rake:/
- scopes = []
- task_name = task_name.sub(/^rake:/, '')
- elsif task_name =~ /^(\^+)/
- scopes = initial_scope[0, initial_scope.size - $1.size]
- task_name = task_name.sub(/^(\^+)/, '')
- else
- scopes = initial_scope
- end
- lookup_in_scope(task_name, scopes)
- end
-
- # Lookup the task name
- def lookup_in_scope(name, scope)
- n = scope.size
- while n >= 0
- tn = (scope[0,n] + [name]).join(':')
- task = @tasks[tn]
- return task if task
- n -= 1
- end
- nil
- end
- private :lookup_in_scope
-
- # Return the list of scope names currently active in the task
- # manager.
- def current_scope
- @scope.dup
- 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)
- ns = NameSpace.new(self, @scope)
- yield(ns)
- ns
- ensure
- @scope.pop
- end
-
- private
-
- # Generate an anonymous namespace name.
- def generate_name
- @seed ||= 0
- @seed += 1
- "_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(source, level+1)
- trace_rule level, "(#{task_name} => #{source} ... ENHANCE)"
- parent.name
- else
- trace_rule level, "(#{task_name} => #{source} ... FAIL)"
- return nil
- end
- }
- task = FileTask.define_task({task_name => prereqs}, &block)
- task.sources = prereqs
- task
- end
-
- # Make a list of sources from the list of file name extensions /
- # translation procs.
- def make_sources(task_name, extensions)
- extensions.collect { |ext|
- case ext
- when /%/
- task_name.pathmap(ext)
- when %r{/}
- ext
- when /^\./
- task_name.ext(ext)
- when String
- ext
- when Proc
- if ext.arity == 1
- ext.call(task_name)
- else
- ext.call
- end
- else
- fail "Don't know how to handle rule dependent: #{ext.inspect}"
- end
- }.flatten
- end
-
- end # TaskManager
-
- ######################################################################
- # Rake main application object. When invoking +rake+ from the
- # command line, a Rake::Application object is created and run.
- #
- class Application
- include TaskManager
-
- # The name of the application (typically 'rake')
- attr_reader :name
-
- # The original directory where rake was invoked.
- attr_reader :original_dir
-
- # Name of the actual rakefile used.
- attr_reader :rakefile
-
- # 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
-
- # Initialize a Rake::Application object.
- def initialize
- super
- @name = 'rake'
- @rakefiles = DEFAULT_RAKEFILES.dup
- @rakefile = nil
- @pending_imports = []
- @imported = []
- @loaders = {}
- @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:
- #
- # * Initialize the command line options (+init+).
- # * Define the tasks (+load_rakefile+).
- # * Run the top level tasks (+run_tasks+).
- #
- # If you wish to build a custom rake command, you should call +init+ on your
- # application. The define any tasks. Finally, call +top_level+ to run your top
- # level tasks.
- def run
- init
- load_rakefile
- top_level
- end
-
- # Initialize the command line parameters and app name.
- def init(app_name='rake')
- standard_exception_handling do
- @name = app_name
- handle_options
- collect_tasks
- end
- end
-
- # Find the rakefile and then load it and any pending imports.
- def load_rakefile
- standard_exception_handling do
- raw_load_rakefile
- end
- end
-
- # Run the top level tasks of a Rake application.
- def top_level
- standard_exception_handling do
- if options.show_tasks
- display_tasks_and_comments
- elsif options.show_prereqs
- display_prerequisites
- else
- top_level_tasks.each { |task_name| invoke_task(task_name) }
- end
- end
- end
-
- # Add a loader to handle imported files ending in the extension
- # +ext+.
- def add_loader(ext, loader)
- ext = ".#{ext}" unless ext =~ /^\./
- @loaders[ext] = loader
- end
-
- # Application options from the command line
- def options
- @options ||= OpenStruct.new
- end
-
- # private ----------------------------------------------------------------
-
- def invoke_task(task_string)
- name, args = parse_task_string(task_string)
- t = self[name]
- t.invoke(*args)
- end
-
- def parse_task_string(string)
- if string =~ /^([^\[]+)(\[(.*)\])$/
- name = $1
- args = $3.split(/\s*,\s*/)
- else
- name = string
- args = []
- end
- [name, args]
- end
-
- # Provide standard execption handling for the given block.
- def standard_exception_handling
- begin
- yield
- rescue SystemExit => ex
- # Exit silently with current status
- raise
- rescue OptionParser::InvalidOption => ex
- # Exit silently
- exit(false)
- rescue Exception => ex
- # Exit with error message
- $stderr.puts "#{name} aborted!"
- $stderr.puts ex.message
- if options.trace or true
- $stderr.puts ex.backtrace.join("\n")
- else
- $stderr.puts ex.backtrace.find {|str| str =~ /#{@rakefile}/ } || ""
- $stderr.puts "(See full trace by running task with --trace)"
- end
- exit(false)
- end
- end
-
- # True if one of the files in RAKEFILES is in the current directory.
- # If a match is found, it is copied into @rakefile.
- def have_rakefile
- @rakefiles.each do |fn|
- if File.exist?(fn)
- others = Dir.glob(fn, File::FNM_CASEFOLD)
- return others.size == 1 ? others.first : fn
- elsif fn == ''
- return fn
- end
- end
- return nil
- 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 comments.
- def display_tasks_and_comments
- displayable_tasks = tasks.select { |t|
- t.comment && t.name =~ options.show_task_pattern
- }
- if options.full_description
- displayable_tasks.each do |t|
- puts "#{name} #{t.name_with_args}"
- t.full_comment.split("\n").each do |line|
- puts " #{line}"
- end
- puts
- end
- else
- width = displayable_tasks.collect { |t| t.name_with_args.length }.max || 10
- 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, 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?
- Win32.windows?
- end
-
- def truncate(string, width)
- if string.length <= width
- string
- else
- ( string[0, width-3] || "" ) + "..."
- end
- end
-
- # Display the tasks and prerequisites
- def display_prerequisites
- tasks.each do |t|
- puts "#{name} #{t.name}"
- t.prerequisites.each { |pre| puts " #{pre}" }
- end
- end
-
- # 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
- 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.",
- lambda { |value| verbose(true) }
- ],
- ['--version', '-V', "Display the program version.",
- lambda { |value|
- puts "rake, version #{RAKEVERSION}"
- exit
- }
- ]
- ]
- end
-
- # Read and handle the command line options.
- def handle_options
- options.rakelib = ['rakelib']
-
- OptionParser.new do |opts|
- 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) }
- 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
- # 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|
- fn = file_name + ".rake"
- full_path = File.join(path, fn)
- if File.exist?(full_path)
- load full_path
- loaded << fn
- return true
- end
- end
- fail LoadError, "Can't find #{file_name}"
- end
-
- def find_rakefile_location
- here = Dir.pwd
- while ! (fn = have_rakefile)
- Dir.chdir("..")
- if Dir.pwd == here || options.nosearch
- return nil
- end
- here = Dir.pwd
- 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?) &&
- system_dir && File.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
- @system_dir ||= ENV['RAKE_SYSTEM'] || standard_system_dir
- end
-
- # The standard directory containing system wide rake files.
- unless method_defined?(:standard_system_dir)
- def standard_system_dir #:nodoc:
- File.expand_path('~/.rake')
- end
- end
- private :standard_system_dir
-
- # 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
- @top_level_tasks = []
- ARGV.each do |arg|
- if arg =~ /^(\w+)=(.*)$/
- ENV[$1] = $2
- else
- @top_level_tasks << arg unless arg =~ /^-/
- end
- end
- @top_level_tasks.push("default") if @top_level_tasks.size == 0
- end
-
- # Add a file to the list of files to be imported.
- def add_import(fn)
- @pending_imports << fn
- end
-
- # Load the pending list of imported files.
- def load_imports
- while fn = @pending_imports.shift
- next if @imported.member?(fn)
- if fn_task = lookup(fn)
- fn_task.invoke
- end
- ext = File.extname(fn)
- loader = @loaders[ext] || @default_loader
- loader.load(fn)
- @imported << fn
- 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
- begin
- fail
- rescue RuntimeError => ex
- ex.backtrace.find {|str| str =~ /#{@rakefile}/ } || ""
- end
- end
- end
-end
-
-
-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
+RakeFileUtils = Rake::FileUtilsExt
diff --git a/lib/rake/alt_system.rb b/lib/rake/alt_system.rb
new file mode 100644
index 0000000000..05af19863a
--- /dev/null
+++ b/lib/rake/alt_system.rb
@@ -0,0 +1,109 @@
+#
+# Copyright (c) 2008 James M. Lawrence
+#
+# 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.
+#
+
+require 'rbconfig'
+
+#
+# Alternate implementations of system() and backticks `` on Windows
+# for ruby-1.8 and earlier.
+#
+module Rake::AltSystem
+ WINDOWS = RbConfig::CONFIG["host_os"] =~
+ %r!(msdos|mswin|djgpp|mingw|[Ww]indows)!
+
+ class << self
+ def define_module_function(name, &block)
+ define_method(name, &block)
+ module_function(name)
+ end
+ end
+
+ if WINDOWS and RUBY_VERSION < "1.9.0"
+ RUNNABLE_EXTS = %w[com exe bat cmd]
+ RUNNABLE_PATTERN = %r!\.(#{RUNNABLE_EXTS.join('|')})\Z!i
+
+ define_module_function :kernel_system, &Kernel.method(:system)
+ define_module_function :kernel_backticks, &Kernel.method(:'`')
+
+ module_function
+
+ def repair_command(cmd)
+ "call " + (
+ if cmd =~ %r!\A\s*\".*?\"!
+ # already quoted
+ cmd
+ elsif match = cmd.match(%r!\A\s*(\S+)!)
+ if match[1] =~ %r!/!
+ # avoid x/y.bat interpretation as x with option /y
+ %Q!"#{match[1]}"! + match.post_match
+ else
+ # a shell command will fail if quoted
+ cmd
+ end
+ else
+ # empty or whitespace
+ cmd
+ end
+ )
+ end
+
+ def find_runnable(file)
+ if file =~ RUNNABLE_PATTERN
+ file
+ else
+ RUNNABLE_EXTS.each { |ext|
+ if File.exist?(test = "#{file}.#{ext}")
+ return test
+ end
+ }
+ nil
+ end
+ end
+
+ def system(cmd, *args)
+ repaired = (
+ if args.empty?
+ [repair_command(cmd)]
+ elsif runnable = find_runnable(cmd)
+ [File.expand_path(runnable), *args]
+ else
+ # non-existent file
+ [cmd, *args]
+ end
+ )
+ kernel_system(*repaired)
+ end
+
+ def backticks(cmd)
+ kernel_backticks(repair_command(cmd))
+ end
+
+ define_module_function :'`', &method(:backticks)
+ else
+ # Non-Windows or ruby-1.9+: same as Kernel versions
+ define_module_function :system, &Kernel.method(:system)
+ define_module_function :backticks, &Kernel.method(:'`')
+ define_module_function :'`', &Kernel.method(:'`')
+ end
+end
diff --git a/lib/rake/application.rb b/lib/rake/application.rb
new file mode 100644
index 0000000000..a4954f27e7
--- /dev/null
+++ b/lib/rake/application.rb
@@ -0,0 +1,594 @@
+require 'shellwords'
+require 'optparse'
+
+require 'rake/task_manager'
+require 'rake/win32'
+
+module Rake
+
+ ######################################################################
+ # Rake main application object. When invoking +rake+ from the
+ # command line, a Rake::Application object is created and run.
+ #
+ class Application
+ include TaskManager
+
+ # The name of the application (typically 'rake')
+ attr_reader :name
+
+ # The original directory where rake was invoked.
+ attr_reader :original_dir
+
+ # Name of the actual rakefile used.
+ attr_reader :rakefile
+
+ # Number of columns on the terminal
+ attr_accessor :terminal_columns
+
+ # 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
+
+ # Initialize a Rake::Application object.
+ def initialize
+ super
+ @name = 'rake'
+ @rakefiles = DEFAULT_RAKEFILES.dup
+ @rakefile = nil
+ @pending_imports = []
+ @imported = []
+ @loaders = {}
+ @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?
+ @terminal_columns = ENV['RAKE_COLUMNS'].to_i
+ end
+
+ # Run the Rake application. The run method performs the following
+ # three steps:
+ #
+ # * Initialize the command line options (+init+).
+ # * Define the tasks (+load_rakefile+).
+ # * Run the top level tasks (+run_tasks+).
+ #
+ # If you wish to build a custom rake command, you should call
+ # +init+ on your application. Then define any tasks. Finally,
+ # call +top_level+ to run your top level tasks.
+ def run
+ standard_exception_handling do
+ init
+ load_rakefile
+ top_level
+ end
+ end
+
+ # Initialize the command line parameters and app name.
+ def init(app_name='rake')
+ standard_exception_handling do
+ @name = app_name
+ handle_options
+ collect_tasks
+ end
+ end
+
+ # Find the rakefile and then load it and any pending imports.
+ def load_rakefile
+ standard_exception_handling do
+ raw_load_rakefile
+ end
+ end
+
+ # Run the top level tasks of a Rake application.
+ def top_level
+ standard_exception_handling do
+ if options.show_tasks
+ display_tasks_and_comments
+ elsif options.show_prereqs
+ display_prerequisites
+ else
+ top_level_tasks.each { |task_name| invoke_task(task_name) }
+ end
+ end
+ end
+
+ # Add a loader to handle imported files ending in the extension
+ # +ext+.
+ def add_loader(ext, loader)
+ ext = ".#{ext}" unless ext =~ /^\./
+ @loaders[ext] = loader
+ end
+
+ # Application options from the command line
+ def options
+ @options ||= OpenStruct.new
+ end
+
+ # private ----------------------------------------------------------------
+
+ def invoke_task(task_string)
+ name, args = parse_task_string(task_string)
+ t = self[name]
+ t.invoke(*args)
+ end
+
+ def parse_task_string(string)
+ if string =~ /^([^\[]+)(\[(.*)\])$/
+ name = $1
+ args = $3.split(/\s*,\s*/)
+ else
+ name = string
+ args = []
+ end
+ [name, args]
+ end
+
+ # 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
+ end
+
+ # Display the error message that caused the exception.
+ def display_error_message(ex)
+ $stderr.puts "#{name} aborted!"
+ $stderr.puts ex.message
+ if options.trace
+ $stderr.puts ex.backtrace.join("\n")
+ else
+ $stderr.puts rakefile_location(ex.backtrace)
+ end
+ $stderr.puts "Tasks: #{ex.chain}" if has_chain?(ex)
+ $stderr.puts "(See full trace by running task with --trace)" unless options.trace
+ end
+
+ # Warn about deprecated usage.
+ #
+ # Example:
+ # 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}"
+ end
+
+ # Does the exception have a task invocation chain?
+ def has_chain?(exception)
+ exception.respond_to?(:chain) && exception.chain
+ end
+ private :has_chain?
+
+ # True if one of the files in RAKEFILES is in the current directory.
+ # If a match is found, it is copied into @rakefile.
+ def have_rakefile
+ @rakefiles.each do |fn|
+ if File.exist?(fn)
+ others = Dir.glob(fn, File::FNM_CASEFOLD)
+ return others.size == 1 ? others.first : fn
+ elsif fn == ''
+ return fn
+ end
+ end
+ return nil
+ 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? || @terminal_columns.nonzero?
+ end
+
+ # Display the tasks and comments.
+ def display_tasks_and_comments
+ displayable_tasks = tasks.select { |t|
+ 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
+
+ displayable_tasks.each do |t|
+ 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|
+ puts "#{name} #{t.name_with_args}"
+ t.full_comment.split("\n").each do |line|
+ puts " #{line}"
+ end
+ puts
+ end
+ when :lines
+ displayable_tasks.each do |t|
+ t.locations.each do |loc|
+ printf "#{name} %-30s %s\n",t.name_with_args, loc
+ end
+ end
+ else
+ fail "Unknown show task mode: '#{options.show_tasks}'"
+ end
+ end
+
+ def terminal_width
+ if @terminal_columns.nonzero?
+ result = @terminal_columns
+ 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?
+ RbConfig::CONFIG['host_os'] =~ /(aix|darwin|linux|(net|free|open)bsd|cygwin|solaris|irix|hpux)/i
+ end
+
+ def windows?
+ Win32.windows?
+ end
+
+ def truncate(string, width)
+ if string.length <= width
+ string
+ else
+ ( string[0, width-3] || "" ) + "..."
+ end
+ end
+
+ # Display the tasks and prerequisites
+ def display_prerequisites
+ tasks.each do |t|
+ puts "#{name} #{t.name}"
+ t.prerequisites.each { |pre| puts " #{pre}" }
+ end
+ end
+
+ # A list of all the standard options used in rake, suitable for
+ # passing to OptionParser.
+ def standard_rake_options
+ [
+ ['--classic-namespace', '-C', "Put Task and FileTask in the top level namespace",
+ lambda { |value|
+ require 'rake/classic_namespace'
+ options.classic_namespace = true
+ }
+ ],
+ ['--describe', '-D [PATTERN]', "Describe the tasks (matching optional PATTERN), then exit.",
+ lambda { |value|
+ options.show_tasks = :describe
+ options.show_task_pattern = Regexp.new(value || '')
+ TaskManager.record_task_metadata = true
+ }
+ ],
+ ['--dry-run', '-n', "Do a dry run without executing actions.",
+ lambda { |value|
+ Rake.verbose(true)
+ Rake.nowrite(true)
+ options.dryrun = true
+ options.trace = true
+ }
+ ],
+ ['--execute', '-e CODE', "Execute some Ruby code and exit.",
+ lambda { |value|
+ eval(value)
+ exit
+ }
+ ],
+ ['--execute-print', '-p CODE', "Execute some Ruby code, print the result, then exit.",
+ lambda { |value|
+ puts eval(value)
+ exit
+ }
+ ],
+ ['--execute-continue', '-E CODE',
+ "Execute some Ruby code, then continue with normal task processing.",
+ lambda { |value| eval(value) }
+ ],
+ ['--libdir', '-I LIBDIR', "Include LIBDIR in the search path for required modules.",
+ lambda { |value| $:.push(value) }
+ ],
+ ['--no-search', '--nosearch', '-N', "Do not search parent directories for the Rakefile.",
+ lambda { |value| options.nosearch = true }
+ ],
+ ['--prereqs', '-P', "Display the tasks and dependencies, then exit.",
+ lambda { |value| options.show_prereqs = true }
+ ],
+ ['--quiet', '-q', "Do not log messages to standard output.",
+ lambda { |value| Rake.verbose(false) }
+ ],
+ ['--rakefile', '-f [FILE]', "Use FILE as the rakefile.",
+ lambda { |value|
+ value ||= ''
+ @rakefiles.clear
+ @rakefiles << value
+ }
+ ],
+ ['--rakelibdir', '--rakelib', '-R RAKELIBDIR',
+ "Auto-import any .rake files in RAKELIBDIR. (default is 'rakelib')",
+ 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
+ raise ex
+ end
+ end
+ }
+ ],
+ ['--rules', "Trace the rules resolution.",
+ lambda { |value| options.trace_rules = true }
+ ],
+ ['--silent', '-s', "Like --quiet, but also suppresses the 'in directory' announcement.",
+ lambda { |value|
+ Rake.verbose(false)
+ options.silent = true
+ }
+ ],
+ ['--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 = :tasks
+ options.show_task_pattern = Regexp.new(value || '')
+ Rake::TaskManager.record_task_metadata = true
+ }
+ ],
+ ['--trace', '-t', "Turn on invoke/execute tracing, enable full backtrace.",
+ lambda { |value|
+ options.trace = true
+ Rake.verbose(true)
+ }
+ ],
+ ['--verbose', '-v', "Log message to standard output.",
+ lambda { |value| Rake.verbose(true) }
+ ],
+ ['--version', '-V', "Display the program version.",
+ lambda { |value|
+ puts "rake, version #{RAKEVERSION}"
+ exit
+ }
+ ],
+ ['--where', '-W [PATTERN]', "Describe the tasks (matching optional PATTERN), then exit.",
+ lambda { |value|
+ options.show_tasks = :lines
+ options.show_task_pattern = Regexp.new(value || '')
+ Rake::TaskManager.record_task_metadata = true
+ }
+ ],
+ ['--no-deprecation-warnings', '-X', "Disable the deprecation warnings.",
+ lambda { |value|
+ options.ignore_deprecate = true
+ }
+ ],
+ ]
+ end
+
+ # Read and handle the command line options.
+ def handle_options
+ options.rakelib = ['rakelib']
+
+ OptionParser.new do |opts|
+ 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) }
+ 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
+ # for *.rake files in addition to *.rb files.
+ def rake_require(file_name, paths=$LOAD_PATH, loaded=$")
+ fn = file_name + ".rake"
+ return false if loaded.include?(fn)
+ paths.each do |path|
+ full_path = File.join(path, fn)
+ if File.exist?(full_path)
+ Rake.load_rakefile(full_path)
+ loaded << fn
+ return true
+ end
+ end
+ fail LoadError, "Can't find #{file_name}"
+ end
+
+ def find_rakefile_location
+ here = Dir.pwd
+ while ! (fn = have_rakefile)
+ Dir.chdir("..")
+ if Dir.pwd == here || options.nosearch
+ return nil
+ end
+ here = Dir.pwd
+ end
+ [fn, here]
+ ensure
+ Dir.chdir(Rake.original_dir)
+ end
+
+ def print_rakefile_directory(location)
+ $stderr.puts "(in #{Dir.pwd})" unless
+ options.silent or original_dir == location
+ end
+
+ def raw_load_rakefile # :nodoc:
+ rakefile, location = find_rakefile_location
+ if (! options.ignore_system) &&
+ (options.load_system || rakefile.nil?) &&
+ system_dir && File.directory?(system_dir)
+ print_rakefile_directory(location)
+ 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)
+ print_rakefile_directory(location)
+ $rakefile = @rakefile if options.classic_namespace
+ Rake.load_rakefile(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
+ @system_dir ||=
+ begin
+ if ENV['RAKE_SYSTEM']
+ ENV['RAKE_SYSTEM']
+ else
+ standard_system_dir
+ end
+ end
+ end
+
+ # The standard directory containing system wide rake files.
+ if Win32.windows?
+ def standard_system_dir #:nodoc:
+ Win32.win32_system_dir
+ end
+ else
+ def standard_system_dir #:nodoc:
+ File.join(File.expand_path('~'), '.rake')
+ end
+ end
+ private :standard_system_dir
+
+ # 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
+ @top_level_tasks = []
+ ARGV.each do |arg|
+ if arg =~ /^(\w+)=(.*)$/
+ ENV[$1] = $2
+ else
+ @top_level_tasks << arg unless arg =~ /^-/
+ end
+ end
+ @top_level_tasks.push("default") if @top_level_tasks.size == 0
+ end
+
+ # Add a file to the list of files to be imported.
+ def add_import(fn)
+ @pending_imports << fn
+ end
+
+ # Load the pending list of imported files.
+ def load_imports
+ while fn = @pending_imports.shift
+ next if @imported.member?(fn)
+ if fn_task = lookup(fn)
+ fn_task.invoke
+ end
+ ext = File.extname(fn)
+ loader = @loaders[ext] || @default_loader
+ loader.load(fn)
+ @imported << fn
+ 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] }
+
+ re = /^#{@rakefile}$/
+ re = /#{re.source}/i if windows?
+
+ backtrace.find { |str| str =~ re } || ''
+ end
+ end
+end
diff --git a/lib/rake/classic_namespace.rb b/lib/rake/classic_namespace.rb
index feb7569966..d87aba0f33 100644
--- a/lib/rake/classic_namespace.rb
+++ b/lib/rake/classic_namespace.rb
@@ -2,6 +2,7 @@
# 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."
Task = Rake::Task
FileTask = Rake::FileTask
FileCreationTask = Rake::FileCreationTask
diff --git a/lib/rake/cloneable.rb b/lib/rake/cloneable.rb
new file mode 100644
index 0000000000..19c780bff6
--- /dev/null
+++ b/lib/rake/cloneable.rb
@@ -0,0 +1,25 @@
+module Rake
+ # ##########################################################################
+ # Mixin for creating easily cloned objects.
+ #
+ module Cloneable
+ # Clone an object by making a new object and setting all the instance
+ # variables to the same values.
+ 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
+
+ def clone
+ sibling = dup
+ sibling.freeze if frozen?
+ sibling
+ end
+ end
+end
diff --git a/lib/rake/contrib/compositepublisher.rb b/lib/rake/contrib/compositepublisher.rb
index 31ef080dd7..69952a0808 100644
--- a/lib/rake/contrib/compositepublisher.rb
+++ b/lib/rake/contrib/compositepublisher.rb
@@ -18,3 +18,4 @@ module Rake
end
end
+
diff --git a/lib/rake/contrib/ftptools.rb b/lib/rake/contrib/ftptools.rb
index 12e4ff25de..78420c7412 100644
--- a/lib/rake/contrib/ftptools.rb
+++ b/lib/rake/contrib/ftptools.rb
@@ -99,7 +99,7 @@ module Rake # :nodoc:
end
end
- # Create an FTP uploader targetting the directory +path+ on +host+
+ # Create an FTP uploader targeting the directory +path+ on +host+
# using the given account and password. +path+ will be the root
# path of the uploader.
def initialize(path, host, account, password)
@@ -118,7 +118,7 @@ module Rake # :nodoc:
current_dir = File.join(route)
if @created[current_dir].nil?
@created[current_dir] = true
- puts "Creating Directory #{current_dir}" if @verbose
+ $stderr.puts "Creating Directory #{current_dir}" if @verbose
@ftp.mkdir(current_dir) rescue nil
end
end
@@ -141,7 +141,7 @@ module Rake # :nodoc:
# Upload a single file to the uploader's root path.
def upload(file)
- puts "Uploading #{file}" if @verbose
+ $stderr.puts "Uploading #{file}" if @verbose
dir = File.dirname(file)
makedirs(dir)
@ftp.putbinaryfile(file, file) unless File.directory?(file)
diff --git a/lib/rake/contrib/publisher.rb b/lib/rake/contrib/publisher.rb
index 7f69d3a654..baa9a3607d 100644
--- a/lib/rake/contrib/publisher.rb
+++ b/lib/rake/contrib/publisher.rb
@@ -1,10 +1,6 @@
-# Copyright 2003, 2004, 2005, 2006, 2007, 2008 by Jim Weirich (jim@weirichhouse.org)
+# Copyright 2003-2010 by Jim Weirich (jim.weirich@gmail.com)
# All rights reserved.
-# Permission is granted for use, copying, modification, distribution,
-# and distribution of modified versions of this work as long as the
-# above copyright notice is included.
-
# Configuration information about an upload host system.
# * name :: Name of host system.
# * webdir :: Base directory for the web information for the
diff --git a/lib/rake/contrib/sshpublisher.rb b/lib/rake/contrib/sshpublisher.rb
index e679716c7b..bd6adc127e 100644
--- a/lib/rake/contrib/sshpublisher.rb
+++ b/lib/rake/contrib/sshpublisher.rb
@@ -1,3 +1,4 @@
+require 'rake/dsl_definition'
require 'rake/contrib/compositepublisher'
module Rake
@@ -5,6 +6,8 @@ module Rake
# Publish an entire directory to an existing remote directory using
# SSH.
class SshDirPublisher
+ include Rake::DSL
+
def initialize(host, remote_dir, local_dir)
@host = host
@remote_dir = remote_dir
@@ -27,6 +30,8 @@ module Rake
# Publish a list of files to an existing remote directory.
class SshFilePublisher
+ include Rake::DSL
+
# Create a publisher using the give host information.
def initialize(host, remote_dir, local_dir, *files)
@host = host
diff --git a/lib/rake/contrib/sys.rb b/lib/rake/contrib/sys.rb
new file mode 100644
index 0000000000..41963f1fef
--- /dev/null
+++ b/lib/rake/contrib/sys.rb
@@ -0,0 +1,191 @@
+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'
+
+######################################################################
+# 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)
+ Dir[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|
+ Dir[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|
+ Dir[wildcard].each do |fn|
+ next if ! File.exist?(fn)
+ if File.directory?(fn)
+ Dir["#{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|
+ Dir[wildcard].each do |fn|
+ yield(fn)
+ end
+ end
+ end
+
+ extend(self)
+
+ private # ----------------------------------------------------------
+
+ def for_matching_files(wildcard, dest_dir)
+ Dir[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
diff --git a/lib/rake/default_loader.rb b/lib/rake/default_loader.rb
new file mode 100644
index 0000000000..5dd3c05617
--- /dev/null
+++ b/lib/rake/default_loader.rb
@@ -0,0 +1,10 @@
+module Rake
+
+ # Default Rakefile loader used by +import+.
+ class DefaultLoader
+ def load(fn)
+ Rake.load_rakefile(File.expand_path(fn))
+ end
+ end
+
+end
diff --git a/lib/rake/dsl_definition.rb b/lib/rake/dsl_definition.rb
new file mode 100644
index 0000000000..e0b9c6fd0e
--- /dev/null
+++ b/lib/rake/dsl_definition.rb
@@ -0,0 +1,167 @@
+# Rake DSL functions.
+require 'rake/file_utils_ext'
+
+module Rake
+ module DSL
+
+ # Include the FileUtils file manipulation functions in the top
+ # level module, but mark them private so that they don't
+ # unintentionally define methods on other objects.
+
+ include FileUtilsExt
+ private(*FileUtils.instance_methods(false))
+ private(*FileUtilsExt.instance_methods(false))
+
+ private
+
+ # Declare a basic task.
+ #
+ # Example:
+ # task :clobber => [:clean] do
+ # rm_rf "html"
+ # end
+ #
+ def task(*args, &block)
+ Rake::Task.define_task(*args, &block)
+ end
+
+
+ # Declare a file task.
+ #
+ # Example:
+ # file "config.cfg" => ["config.template"] do
+ # open("config.cfg", "w") do |outfile|
+ # open("config.template") do |infile|
+ # while line = infile.gets
+ # outfile.puts line
+ # end
+ # end
+ # end
+ # end
+ #
+ def file(*args, &block)
+ Rake::FileTask.define_task(*args, &block)
+ end
+
+ # Declare a file creation task.
+ # (Mainly used for the directory command).
+ def file_create(args, &block)
+ Rake::FileCreationTask.define_task(args, &block)
+ end
+
+ # Declare a set of files tasks to create the given directories on
+ # demand.
+ #
+ # Example:
+ # directory "testdata/doc"
+ #
+ def directory(dir)
+ Rake.each_dir_parent(dir) do |d|
+ file_create d do |t|
+ mkdir_p t.name if ! File.exist?(t.name)
+ end
+ end
+ end
+
+ # Declare a task that performs its prerequisites in
+ # parallel. Multitasks does *not* guarantee that its prerequisites
+ # will execute in any given order (which is obvious when you think
+ # about it)
+ #
+ # Example:
+ # multitask :deploy => [:deploy_gem, :deploy_rdoc]
+ #
+ def multitask(args, &block)
+ Rake::MultiTask.define_task(args, &block)
+ end
+
+ # Create a new rake namespace and use it for evaluating the given
+ # block. Returns a NameSpace object that can be used to lookup
+ # tasks defined in the namespace.
+ #
+ # E.g.
+ #
+ # ns = namespace "nested" do
+ # task :run
+ # end
+ # task_run = ns[:run] # find :run in the given namespace.
+ #
+ def namespace(name=nil, &block)
+ name = name.to_s if name.kind_of?(Symbol)
+ name = name.to_str if name.respond_to?(:to_str)
+ unless name.kind_of?(String) || name.nil?
+ raise ArgumentError, "Expected a String or Symbol for a namespace name"
+ end
+ Rake.application.in_namespace(name, &block)
+ end
+
+ # Declare a rule for auto-tasks.
+ #
+ # Example:
+ # rule '.o' => '.c' do |t|
+ # sh %{cc -o #{t.name} #{t.source}}
+ # end
+ #
+ def rule(*args, &block)
+ Rake::Task.create_rule(*args, &block)
+ end
+
+ # Describe the next rake task.
+ #
+ # Example:
+ # desc "Run the Unit Tests"
+ # task :test => [:build]
+ # runtests
+ # end
+ #
+ def desc(description)
+ Rake.application.last_description = description
+ end
+
+ # Import the partial Rakefiles +fn+. Imported files are loaded
+ # _after_ the current file is completely loaded. This allows the
+ # import statement to appear anywhere in the importing file, and yet
+ # allowing the imported files to depend on objects defined in the
+ # importing file.
+ #
+ # A common use of the import statement is to include files
+ # containing dependency declarations.
+ #
+ # See also the --rakelibdir command line option.
+ #
+ # Example:
+ # import ".depend", "my_rules"
+ #
+ def import(*fns)
+ fns.each do |fn|
+ Rake.application.add_import(fn)
+ end
+ end
+ end
+
+ module DeprecatedObjectDSL
+ Commands = Object.new.extend DSL
+ 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::DeprecatedObjectDSL::Commands.send(:#{name}, *args, &block)
+ end
+ private :#{name}
+ }, __FILE__, line
+ end
+ end
+
+ extend FileUtilsExt
+end
+
+self.extend Rake::DSL
+include Rake::DeprecatedObjectDSL
diff --git a/lib/rake/early_time.rb b/lib/rake/early_time.rb
new file mode 100644
index 0000000000..8c0e7d3339
--- /dev/null
+++ b/lib/rake/early_time.rb
@@ -0,0 +1,18 @@
+module Rake
+
+ # EarlyTime is a fake timestamp that occurs _before_ any other time value.
+ class EarlyTime
+ include Comparable
+ include Singleton
+
+ def <=>(other)
+ -1
+ end
+
+ def to_s
+ "<EARLY TIME>"
+ end
+ end
+
+ EARLY = EarlyTime.instance
+end
diff --git a/lib/rake/ext/core.rb b/lib/rake/ext/core.rb
new file mode 100644
index 0000000000..1f3a738906
--- /dev/null
+++ b/lib/rake/ext/core.rb
@@ -0,0 +1,27 @@
+######################################################################
+# Core extension library
+#
+class Module
+ # Check for an existing method in the current class before extending. IF
+ # the method already exists, then a warning is printed and the extension is
+ # not added. Otherwise the block is yielded and any definitions in the
+ # block will take effect.
+ #
+ # Usage:
+ #
+ # class String
+ # rake_extension("xyz") do
+ # def xyz
+ # ...
+ # end
+ # end
+ # end
+ #
+ def rake_extension(method)
+ if method_defined?(method)
+ $stderr.puts "WARNING: Possible conflict with Rake extension: #{self}##{method} already exists"
+ else
+ yield
+ end
+ end
+end
diff --git a/lib/rake/ext/module.rb b/lib/rake/ext/module.rb
new file mode 100644
index 0000000000..3f64aef6c8
--- /dev/null
+++ b/lib/rake/ext/module.rb
@@ -0,0 +1,39 @@
+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
diff --git a/lib/rake/ext/string.rb b/lib/rake/ext/string.rb
new file mode 100644
index 0000000000..fb22a9deb1
--- /dev/null
+++ b/lib/rake/ext/string.rb
@@ -0,0 +1,167 @@
+require 'rake/ext/core'
+
+######################################################################
+# Rake extension methods for String.
+#
+class String
+ rake_extension("ext") do
+ # Replace the file extension with +newext+. If there is no extension on
+ # the string, append the new extension to the end. If the new extension
+ # is not given, or is the empty string, remove any existing extension.
+ #
+ # +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
+ self.chomp(File.extname(self)) << newext
+ end
+ end
+
+ rake_extension("pathmap") do
+ # Explode a path into individual components. Used by +pathmap+.
+ def pathmap_explode
+ head, tail = File.split(self)
+ return [self] if head == self
+ return [tail] if head == '.' || tail == '/'
+ return [head, tail] if head == '/'
+ return head.pathmap_explode + [tail]
+ end
+ protected :pathmap_explode
+
+ # Extract a partial path from the path. Include +n+ directories from the
+ # front end (left hand side) if +n+ is positive. Include |+n+|
+ # directories from the back end (right hand side) if +n+ is negative.
+ def pathmap_partial(n)
+ dirs = File.dirname(self).pathmap_explode
+ partial_dirs =
+ if n > 0
+ dirs[0...n]
+ elsif n < 0
+ dirs.reverse[0...-n].reverse
+ else
+ "."
+ end
+ File.join(partial_dirs)
+ end
+ protected :pathmap_partial
+
+ # Preform the pathmap replacement operations on the given path. The
+ # patterns take the form 'pat1,rep1;pat2,rep2...'.
+ def pathmap_replace(patterns, &block)
+ result = self
+ patterns.split(';').each do |pair|
+ pattern, replacement = pair.split(',')
+ pattern = Regexp.new(pattern)
+ if replacement == '*' && block_given?
+ result = result.sub(pattern, &block)
+ elsif replacement
+ result = result.sub(pattern, replacement)
+ else
+ result = result.sub(pattern, '')
+ end
+ end
+ result
+ end
+ protected :pathmap_replace
+
+ # Map the path according to the given specification. The specification
+ # controls the details of the mapping. The following special patterns are
+ # recognized:
+ #
+ # * <b>%p</b> -- The complete path.
+ # * <b>%f</b> -- The base file name of the path, with its file extension,
+ # but without any directories.
+ # * <b>%n</b> -- The file name of the path without its file extension.
+ # * <b>%d</b> -- The directory list of the path.
+ # * <b>%x</b> -- The file extension of the path. An empty string if there
+ # is no extension.
+ # * <b>%X</b> -- Everything *but* the file extension.
+ # * <b>%s</b> -- The alternate file separator if defined, otherwise use
+ # the standard file separator.
+ # * <b>%%</b> -- A percent sign.
+ #
+ # The %d specifier can also have a numeric prefix (e.g. '%2d'). If the
+ # number is positive, only return (up to) +n+ directories in the path,
+ # starting from the left hand side. If +n+ is negative, return (up to)
+ # |+n+| directories from the right hand side of the path.
+ #
+ # Examples:
+ #
+ # 'a/b/c/d/file.txt'.pathmap("%2d") => 'a/b'
+ # 'a/b/c/d/file.txt'.pathmap("%-2d") => 'c/d'
+ #
+ # Also the %d, %p, %f, %n, %x, and %X operators can take a
+ # pattern/replacement argument to perform simple string substitutions on a
+ # particular part of the path. The pattern and replacement are separated
+ # by a comma and are enclosed by curly braces. The replacement spec comes
+ # after the % character but before the operator letter. (e.g.
+ # "%{old,new}d"). Multiple replacement specs should be separated by
+ # semi-colons (e.g. "%{old,new;src,bin}d").
+ #
+ # Regular expressions may be used for the pattern, and back refs may be
+ # used in the replacement text. Curly braces, commas and semi-colons are
+ # excluded from both the pattern and replacement text (let's keep parsing
+ # reasonable).
+ #
+ # For example:
+ #
+ # "src/org/onestepback/proj/A.java".pathmap("%{^src,bin}X.class")
+ #
+ # returns:
+ #
+ # "bin/org/onestepback/proj/A.class"
+ #
+ # If the replacement text is '*', then a block may be provided to perform
+ # some arbitrary calculation for the replacement.
+ #
+ # For example:
+ #
+ # "/path/to/file.TXT".pathmap("%X%{.*,*}x") { |ext|
+ # ext.downcase
+ # }
+ #
+ # Returns:
+ #
+ # "/path/to/file.txt"
+ #
+ def pathmap(spec=nil, &block)
+ return self if spec.nil?
+ result = ''
+ spec.scan(/%\{[^}]*\}-?\d*[sdpfnxX%]|%-?\d+d|%.|[^%]+/) do |frag|
+ case frag
+ when '%f'
+ result << File.basename(self)
+ when '%n'
+ result << File.basename(self).ext
+ when '%d'
+ result << File.dirname(self)
+ when '%x'
+ result << File.extname(self)
+ when '%X'
+ result << self.ext
+ when '%p'
+ result << self
+ when '%s'
+ result << (File::ALT_SEPARATOR || File::SEPARATOR)
+ when '%-'
+ # do nothing
+ when '%%'
+ result << "%"
+ when /%(-?\d+)d/
+ result << pathmap_partial($1.to_i)
+ when /^%\{([^}]*)\}(\d*[dpfnxX])/
+ patterns, operator = $1, $2
+ result << pathmap('%' + operator).pathmap_replace(patterns, &block)
+ when /^%/
+ fail ArgumentError, "Unknown pathmap specifier #{frag} in '#{spec}'"
+ else
+ result << frag
+ end
+ end
+ result
+ end
+ end
+end # class String
+
diff --git a/lib/rake/ext/time.rb b/lib/rake/ext/time.rb
new file mode 100644
index 0000000000..ca3ea2a795
--- /dev/null
+++ b/lib/rake/ext/time.rb
@@ -0,0 +1,14 @@
+# ###########################################################################
+# Extensions to time to allow comparisons with an early time class.
+#
+class Time
+ alias rake_original_time_compare :<=>
+ def <=>(other)
+ if Rake::EarlyTime === other
+ - other.<=>(self)
+ else
+ rake_original_time_compare(other)
+ end
+ end
+end # class Time
+
diff --git a/lib/rake/file_creation_task.rb b/lib/rake/file_creation_task.rb
new file mode 100644
index 0000000000..c87e2192bb
--- /dev/null
+++ b/lib/rake/file_creation_task.rb
@@ -0,0 +1,24 @@
+require 'rake/file_task'
+require 'rake/early_time'
+
+module Rake
+
+ # A FileCreationTask is a file task that when used as a dependency will be
+ # needed if and only if the file has not been created. Once created, it is
+ # not re-triggered if any of its dependencies are newer, nor does trigger
+ # any rebuilds of tasks that depend on it whenever it is updated.
+ #
+ class FileCreationTask < FileTask
+ # Is this file task needed? Yes if it doesn't exist.
+ def needed?
+ ! File.exist?(name)
+ end
+
+ # Time stamp for file creation task. This time stamp is earlier
+ # than any other time stamp.
+ def timestamp
+ Rake::EARLY
+ end
+ end
+
+end
diff --git a/lib/rake/file_list.rb b/lib/rake/file_list.rb
new file mode 100644
index 0000000000..9f780346f3
--- /dev/null
+++ b/lib/rake/file_list.rb
@@ -0,0 +1,403 @@
+require 'rake/cloneable'
+require 'rake/file_utils_ext'
+require 'rake/pathmap'
+
+######################################################################
+module Rake
+
+ # #########################################################################
+ # A FileList is essentially an array with a few helper methods defined to
+ # make file manipulation a bit easier.
+ #
+ # FileLists are lazy. When given a list of glob patterns for possible files
+ # to be included in the file list, instead of searching the file structures
+ # to find the files, a FileList holds the pattern for latter use.
+ #
+ # This allows us to define a number of FileList to match any number of
+ # files, but only search out the actual files when then FileList itself is
+ # actually used. The key is that the first time an element of the
+ # FileList/Array is requested, the pending patterns are resolved into a real
+ # list of file names.
+ #
+ class FileList
+
+ include Cloneable
+
+ # == Method Delegation
+ #
+ # The lazy evaluation magic of FileLists happens by implementing all the
+ # array specific methods to call +resolve+ before delegating the heavy
+ # lifting to an embedded array object (@items).
+ #
+ # In addition, there are two kinds of delegation calls. The regular kind
+ # delegates to the @items array and returns the result directly. Well,
+ # almost directly. It checks if the returned value is the @items object
+ # itself, and if so will return the FileList object instead.
+ #
+ # The second kind of delegation call is used in methods that normally
+ # return a new Array object. We want to capture the return value of these
+ # methods and wrap them in a new FileList object. We enumerate these
+ # methods in the +SPECIAL_RETURN+ list below.
+
+ # 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 }
+
+ # List of additional methods that must be delegated.
+ MUST_DEFINE = %w[to_a inspect <=>]
+
+ # List of methods that should not be delegated here (we define special
+ # versions of them explicitly below).
+ MUST_NOT_DEFINE = %w[to_a to_ary partition *]
+
+ # List of delegated methods that return new array values which need
+ # wrapping.
+ SPECIAL_RETURN = %w[
+ map collect sort sort_by select find_all reject grep
+ compact flatten uniq values_at
+ + - & |
+ ]
+
+ DELEGATING_METHODS = (ARRAY_METHODS + MUST_DEFINE - MUST_NOT_DEFINE).collect{ |s| s.to_s }.sort.uniq
+
+ # Now do the delegation.
+ DELEGATING_METHODS.each_with_index do |sym, i|
+ if SPECIAL_RETURN.include?(sym)
+ ln = __LINE__+1
+ class_eval %{
+ def #{sym}(*args, &block)
+ resolve
+ result = @items.send(:#{sym}, *args, &block)
+ FileList.new.import(result)
+ end
+ }, __FILE__, ln
+ else
+ ln = __LINE__+1
+ class_eval %{
+ def #{sym}(*args, &block)
+ resolve
+ result = @items.send(:#{sym}, *args, &block)
+ result.object_id == @items.object_id ? self : result
+ end
+ }, __FILE__, ln
+ end
+ end
+
+ # Create a file list from the globbable patterns given. If you wish to
+ # perform multiple includes or excludes at object build time, use the
+ # "yield self" pattern.
+ #
+ # Example:
+ # file_list = FileList.new('lib/**/*.rb', 'test/test*.rb')
+ #
+ # pkg_files = FileList.new('lib/**/*') do |fl|
+ # fl.exclude(/\bCVS\b/)
+ # end
+ #
+ def initialize(*patterns)
+ @pending_add = []
+ @pending = false
+ @exclude_patterns = DEFAULT_IGNORE_PATTERNS.dup
+ @exclude_procs = DEFAULT_IGNORE_PROCS.dup
+ @items = []
+ patterns.each { |pattern| include(pattern) }
+ yield self if block_given?
+ end
+
+ # Add file names defined by glob patterns to the file list. If an array
+ # is given, add each element of the array.
+ #
+ # Example:
+ # file_list.include("*.java", "*.cfg")
+ # file_list.include %w( math.c lib.h *.o )
+ #
+ def include(*filenames)
+ # TODO: check for pending
+ filenames.each do |fn|
+ if fn.respond_to? :to_ary
+ include(*fn.to_ary)
+ else
+ @pending_add << fn
+ end
+ end
+ @pending = true
+ self
+ end
+ alias :add :include
+
+ # Register a list of file name patterns that should be excluded from the
+ # list. Patterns may be regular expressions, glob patterns or regular
+ # strings. In addition, a block given to exclude will remove entries that
+ # return true when given to the block.
+ #
+ # Note that glob patterns are expanded against the file system. If a file
+ # is explicitly added to a file list, but does not exist in the file
+ # system, then an glob pattern in the exclude list will not exclude the
+ # file.
+ #
+ # Examples:
+ # FileList['a.c', 'b.c'].exclude("a.c") => ['b.c']
+ # FileList['a.c', 'b.c'].exclude(/^a/) => ['b.c']
+ #
+ # If "a.c" is a file, then ...
+ # FileList['a.c', 'b.c'].exclude("a.*") => ['b.c']
+ #
+ # If "a.c" is not a file, then ...
+ # FileList['a.c', 'b.c'].exclude("a.*") => ['a.c', 'b.c']
+ #
+ def exclude(*patterns, &block)
+ patterns.each do |pat|
+ @exclude_patterns << pat
+ end
+ if block_given?
+ @exclude_procs << block
+ end
+ resolve_exclude if ! @pending
+ self
+ end
+
+
+ # Clear all the exclude patterns so that we exclude nothing.
+ def clear_exclude
+ @exclude_patterns = []
+ @exclude_procs = []
+ self
+ end
+
+ # Define equality.
+ def ==(array)
+ to_ary == array
+ end
+
+ # Return the internal array object.
+ def to_a
+ resolve
+ @items
+ end
+
+ # Return the internal array object.
+ def to_ary
+ to_a
+ end
+
+ # Lie about our class.
+ def is_a?(klass)
+ klass == Array || super(klass)
+ end
+ alias kind_of? is_a?
+
+ # Redefine * to return either a string or a new file list.
+ def *(other)
+ result = @items * other
+ case result
+ when Array
+ FileList.new.import(result)
+ else
+ result
+ end
+ end
+
+ # Resolve all the pending adds now.
+ def resolve
+ if @pending
+ @pending = false
+ @pending_add.each do |fn| resolve_add(fn) end
+ @pending_add = []
+ resolve_exclude
+ end
+ self
+ end
+
+ def resolve_add(fn)
+ case fn
+ when %r{[*?\[\{]}
+ add_matching(fn)
+ else
+ self << fn
+ end
+ end
+ private :resolve_add
+
+ def resolve_exclude
+ reject! { |fn| exclude?(fn) }
+ self
+ end
+ private :resolve_exclude
+
+ # Return a new FileList with the results of running +sub+ against each
+ # element of the original list.
+ #
+ # Example:
+ # 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) }
+ end
+
+ # Return a new FileList with the results of running +gsub+ against each
+ # element of the original list.
+ #
+ # Example:
+ # FileList['lib/test/file', 'x/y'].gsub(/\//, "\\")
+ # => ['lib\\test\\file', 'x\\y']
+ #
+ def 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) }
+ 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) }
+ self
+ end
+
+ # Apply the pathmap spec to each of the included file names, returning a
+ # new file list with the modified paths. (See String#pathmap for
+ # details.)
+ def pathmap(spec=nil)
+ collect { |fn| fn.pathmap(spec) }
+ end
+
+ # Return a new FileList with <tt>String#ext</tt> method applied to
+ # each member of the array.
+ #
+ # This method is a shortcut for:
+ #
+ # array.collect { |item| item.ext(newext) }
+ #
+ # +ext+ is a user added method for the Array class.
+ def ext(newext='')
+ collect { |fn| fn.ext(newext) }
+ end
+
+
+ # Grep each of the files in the filelist using the given pattern. If a
+ # block is given, call the block on each matching line, passing the file
+ # name, line number, and the matching line of text. If no block is given,
+ # a standard emacs style file:linenumber:line message will be printed to
+ # standard out. Returns the number of matched items.
+ def egrep(pattern, *options)
+ matched = 0
+ each do |fn|
+ begin
+ open(fn, "rb", *options) do |inf|
+ count = 0
+ inf.each do |line|
+ count += 1
+ if pattern.match(line)
+ matched += 1
+ if block_given?
+ yield fn, count, line
+ else
+ puts "#{fn}:#{count}:#{line}"
+ end
+ end
+ end
+ end
+ rescue StandardError => ex
+ $stderr.puts "Error while processing '#{fn}': #{ex}"
+ end
+ end
+ matched
+ end
+
+ # Return a new file list that only contains file names from the current
+ # file list that exist on the file system.
+ def existing
+ select { |fn| File.exist?(fn) }
+ end
+
+ # Modify the current file list so that it contains only file name that
+ # exist on the file system.
+ def existing!
+ resolve
+ @items = @items.select { |fn| File.exist?(fn) }
+ self
+ end
+
+ # FileList version of partition. Needed because the nested arrays should
+ # be FileLists in this version.
+ def partition(&block) # :nodoc:
+ resolve
+ result = @items.partition(&block)
+ [
+ FileList.new.import(result[0]),
+ FileList.new.import(result[1]),
+ ]
+ end
+
+ # Convert a FileList to a string by joining all elements with a space.
+ def to_s
+ resolve
+ self.join(' ')
+ end
+
+ # Add matching glob patterns.
+ def add_matching(pattern)
+ Dir[pattern].each do |fn|
+ self << fn unless exclude?(fn)
+ end
+ end
+ private :add_matching
+
+ # Should the given file name be excluded?
+ def exclude?(fn)
+ return true if @exclude_patterns.any? do |pat|
+ case pat
+ when Regexp
+ fn =~ pat
+ when /[*?]/
+ File.fnmatch?(pat, fn, File::FNM_PATHNAME)
+ else
+ fn == pat
+ end
+ end
+ @exclude_procs.any? { |p| p.call(fn) }
+ end
+
+ DEFAULT_IGNORE_PATTERNS = [
+ /(^|[\/\\])CVS([\/\\]|$)/,
+ /(^|[\/\\])\.svn([\/\\]|$)/,
+ /\.bak$/,
+ /~$/
+ ]
+ DEFAULT_IGNORE_PROCS = [
+ proc { |fn| fn =~ /(^|[\/\\])core$/ && ! File.directory?(fn) }
+ ]
+
+ def import(array)
+ @items = array
+ self
+ end
+
+ class << self
+ # Create a new file list including the files listed. Similar to:
+ #
+ # FileList.new(*args)
+ def [](*args)
+ new(*args)
+ end
+ end
+ end
+end
+
+module Rake
+ class << self
+
+ # Yield each file or directory component.
+ def each_dir_parent(dir) # :nodoc:
+ old_length = nil
+ while dir != '.' && dir.length != old_length
+ yield(dir)
+ old_length = dir.length
+ dir = File.dirname(dir)
+ end
+ end
+ end
+end # module Rake
diff --git a/lib/rake/file_task.rb b/lib/rake/file_task.rb
new file mode 100644
index 0000000000..78902a86fd
--- /dev/null
+++ b/lib/rake/file_task.rb
@@ -0,0 +1,47 @@
+require 'rake/task.rb'
+require 'rake/early_time'
+
+module Rake
+ # #########################################################################
+ # A FileTask is a task that includes time based dependencies. If any of a
+ # FileTask's prerequisites have a timestamp that is later than the file
+ # represented by this task, then the file must be rebuilt (using the
+ # supplied actions).
+ #
+ class FileTask < Task
+
+ # Is this file task needed? Yes if it doesn't exist, or if its time stamp
+ # is out of date.
+ def needed?
+ ! File.exist?(name) || out_of_date?(timestamp)
+ end
+
+ # Time stamp for file task.
+ def timestamp
+ if File.exist?(name)
+ File.mtime(name.to_s)
+ else
+ Rake::EARLY
+ end
+ end
+
+ private
+
+ # 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}
+ end
+
+ # ----------------------------------------------------------------
+ # Task class methods.
+ #
+ class << self
+ # Apply the scope to the task name according to the rules for this kind
+ # of task. File based tasks ignore the scope when creating the name.
+ def scope_name(scope, task_name)
+ task_name
+ end
+ end
+ end
+end
+
diff --git a/lib/rake/file_utils.rb b/lib/rake/file_utils.rb
new file mode 100644
index 0000000000..9e0198e644
--- /dev/null
+++ b/lib/rake/file_utils.rb
@@ -0,0 +1,112 @@
+require 'rbconfig'
+require 'fileutils'
+
+# ###########################################################################
+# This a FileUtils extension that defines several additional commands to be
+# added to the FileUtils utility functions.
+#
+module FileUtils
+ # Path to the currently running Ruby program
+ RUBY = File.join(
+ RbConfig::CONFIG['bindir'],
+ RbConfig::CONFIG['ruby_install_name'] + RbConfig::CONFIG['EXEEXT']).
+ sub(/.*\s.*/m, '"\&"')
+
+ OPT_TABLE['sh'] = %w(noop verbose)
+ OPT_TABLE['ruby'] = %w(noop verbose)
+
+ # Run the system command +cmd+. If multiple arguments are given the command
+ # is not run with the shell (same semantics as Kernel::exec and
+ # Kernel::system).
+ #
+ # Example:
+ # sh %{ls -ltr}
+ #
+ # sh 'ls', 'file with spaces'
+ #
+ # # check exit status after command runs
+ # sh %{grep pattern file} do |ok, res|
+ # if ! ok
+ # puts "pattern not found (status = #{res.exitstatus})"
+ # end
+ # end
+ #
+ def sh(*cmd, &block)
+ options = (Hash === cmd.last) ? cmd.pop : {}
+ shell_runner = block_given? ? block : create_shell_runner(cmd)
+ set_verbose_option(options)
+ options[:noop] ||= Rake::FileUtilsExt.nowrite_flag
+ Rake.rake_check_options options, :noop, :verbose
+ Rake.rake_output_message cmd.join(" ") if options[:verbose]
+ unless options[:noop]
+ res = rake_system(*cmd)
+ status = $?
+ status = PseudoStatus.new(1) if !res && status.nil?
+ shell_runner.call(res, status)
+ end
+ end
+
+ def create_shell_runner(cmd)
+ 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}]"
+ }
+ end
+ private :create_shell_runner
+
+ def set_verbose_option(options)
+ if options[:verbose].nil?
+ options[:verbose] = Rake::FileUtilsExt.verbose_flag.nil? || Rake::FileUtilsExt.verbose_flag
+ end
+ end
+ private :set_verbose_option
+
+ def rake_system(*cmd)
+ Rake::AltSystem.system(*cmd)
+ end
+ private :rake_system
+
+ # Run a Ruby interpreter with the given arguments.
+ #
+ # Example:
+ # ruby %{-pe '$_.upcase!' <README}
+ #
+ def ruby(*args,&block)
+ options = (Hash === args.last) ? args.pop : {}
+ if args.length > 1 then
+ sh(*([RUBY] + args + [options]), &block)
+ else
+ sh("#{RUBY} #{args.first}", options, &block)
+ end
+ end
+
+ LN_SUPPORTED = [true]
+
+ # 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]
+ cp(*args)
+ else
+ begin
+ ln(*args)
+ rescue StandardError, NotImplementedError
+ LN_SUPPORTED[0] = false
+ cp(*args)
+ end
+ end
+ end
+
+ # Split a file path into individual directory names.
+ #
+ # 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
+end
diff --git a/lib/rake/file_utils_ext.rb b/lib/rake/file_utils_ext.rb
new file mode 100644
index 0000000000..7c22f80687
--- /dev/null
+++ b/lib/rake/file_utils_ext.rb
@@ -0,0 +1,142 @@
+require 'rake/file_utils'
+
+module Rake
+ #
+ # FileUtilsExt provides a custom version of the FileUtils methods
+ # that respond to the <tt>verbose</tt> and <tt>nowrite</tt>
+ # commands.
+ #
+ module FileUtilsExt
+ include FileUtils
+
+ class << self
+ attr_accessor :verbose_flag, :nowrite_flag
+ end
+ FileUtilsExt.verbose_flag = nil
+ FileUtilsExt.nowrite_flag = false
+
+ $fileutils_verbose = true
+ $fileutils_nowrite = false
+
+ FileUtils::OPT_TABLE.each do |name, opts|
+ default_options = []
+ if opts.include?(:verbose) || opts.include?("verbose")
+ default_options << ':verbose => FileUtilsExt.verbose_flag'
+ end
+ if opts.include?(:noop) || opts.include?("noop")
+ default_options << ':noop => FileUtilsExt.nowrite_flag'
+ end
+
+ next if default_options.empty?
+ module_eval(<<-EOS, __FILE__, __LINE__ + 1)
+ def #{name}( *args, &block )
+ super(
+ *rake_merge_option(args,
+ #{default_options.join(', ')}
+ ), &block)
+ end
+ EOS
+ end
+
+ # Get/set the verbose flag controlling output from the FileUtils
+ # utilities. If verbose is true, then the utility method is
+ # echoed to standard output.
+ #
+ # Examples:
+ # verbose # return the current value of the
+ # # verbose flag
+ # verbose(v) # set the verbose flag to _v_.
+ # verbose(v) { code } # Execute code with the verbose flag set
+ # # temporarily to _v_. Return to the
+ # # original value when code is done.
+ def verbose(value=nil)
+ oldvalue = FileUtilsExt.verbose_flag
+ FileUtilsExt.verbose_flag = value unless value.nil?
+ if block_given?
+ begin
+ yield
+ ensure
+ FileUtilsExt.verbose_flag = oldvalue
+ end
+ end
+ FileUtilsExt.verbose_flag
+ end
+
+ # Get/set the nowrite flag controlling output from the FileUtils
+ # utilities. If verbose is true, then the utility method is
+ # echoed to standard output.
+ #
+ # Examples:
+ # nowrite # return the current value of the
+ # # nowrite flag
+ # nowrite(v) # set the nowrite flag to _v_.
+ # nowrite(v) { code } # Execute code with the nowrite flag set
+ # # temporarily to _v_. Return to the
+ # # original value when code is done.
+ def nowrite(value=nil)
+ oldvalue = FileUtilsExt.nowrite_flag
+ FileUtilsExt.nowrite_flag = value unless value.nil?
+ if block_given?
+ begin
+ yield
+ ensure
+ FileUtilsExt.nowrite_flag = oldvalue
+ end
+ end
+ oldvalue
+ end
+
+ # Use this function to prevent potentially destructive ruby code
+ # from running when the :nowrite flag is set.
+ #
+ # Example:
+ #
+ # when_writing("Building Project") do
+ # project.build
+ # end
+ #
+ # The following code will build the project under normal
+ # conditions. If the nowrite(true) flag is set, then the example
+ # will print:
+ #
+ # DRYRUN: Building Project
+ #
+ # instead of actually building the project.
+ #
+ def when_writing(msg=nil)
+ if FileUtilsExt.nowrite_flag
+ $stderr.puts "DRYRUN: #{msg}" if msg
+ else
+ yield
+ end
+ end
+
+ # Merge the given options with the default values.
+ def rake_merge_option(args, defaults)
+ if Hash === args.last
+ defaults.update(args.last)
+ args.pop
+ end
+ args.push defaults
+ args
+ end
+
+ # Send the message to the default rake output (which is $stderr).
+ def rake_output_message(message)
+ $stderr.puts(message)
+ end
+
+ # Check that the options do not contain options not listed in
+ # +optdecl+. An ArgumentError exception is thrown if non-declared
+ # options are found.
+ def rake_check_options(options, *optdecl)
+ h = options.dup
+ optdecl.each do |name|
+ h.delete name
+ end
+ raise ArgumentError, "no such option: #{h.keys.join(' ')}" unless h.empty?
+ end
+
+ extend self
+ end
+end
diff --git a/lib/rake/gempackagetask.rb b/lib/rake/gempackagetask.rb
index 3a99ff2b87..51e92236fc 100644
--- a/lib/rake/gempackagetask.rb
+++ b/lib/rake/gempackagetask.rb
@@ -1,95 +1,13 @@
-# Define a package task library to aid in the definition of GEM
-# packages.
+# 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'
-require 'rake/packagetask'
-require 'rubygems/user_interaction'
-require 'rubygems/builder'
module Rake
-
- # Create a package based upon a Gem spec. Gem packages, as well as
- # zip files and tar/gzipped packages can be produced by this task.
- #
- # In addition to the Rake targets generated by PackageTask, a
- # GemPackageTask will also generate the following tasks:
- #
- # [<b>"<em>package_dir</em>/<em>name</em>-<em>version</em>.gem"</b>]
- # Create a Ruby GEM package with the given name and version.
- #
- # Example using a Ruby GEM spec:
- #
- # require 'rubygems'
- #
- # spec = Gem::Specification.new do |s|
- # s.platform = Gem::Platform::RUBY
- # s.summary = "Ruby based make-like utility."
- # s.name = 'rake'
- # s.version = PKG_VERSION
- # s.requirements << 'none'
- # s.require_path = 'lib'
- # s.autorequire = 'rake'
- # s.files = PKG_FILES
- # s.description = <<EOF
- # Rake is a Make-like program implemented in Ruby. Tasks
- # and dependencies are specified in standard Ruby syntax.
- # EOF
- # end
- #
- # Rake::GemPackageTask.new(spec) do |pkg|
- # pkg.need_zip = true
- # pkg.need_tar = true
- # end
- #
- class GemPackageTask < PackageTask
- # Ruby GEM spec containing the metadata for this package. The
- # name, version and package_files are automatically determined
- # from the GEM spec and don't need to be explicitly provided.
- attr_accessor :gem_spec
-
- # Create a GEM Package task library. Automatically define the gem
- # if a block is given. If no block is supplied, then +define+
- # needs to be called to define the task.
- def initialize(gem_spec)
- init(gem_spec)
- yield self if block_given?
- define if block_given?
- end
-
- # Initialization tasks without the "yield self" or define
- # operations.
- def init(gem)
- super(gem.name, gem.version)
- @gem_spec = gem
- @package_files += gem_spec.files if gem_spec.files
- end
-
- # Create the Rake tasks and actions specified by this
- # GemPackageTask. (+define+ is automatically called if a block is
- # given to +new+).
- def define
- super
- task :package => [:gem]
- desc "Build the gem file #{gem_file}"
- task :gem => ["#{package_dir}/#{gem_file}"]
- file "#{package_dir}/#{gem_file}" => [package_dir] + @gem_spec.files do
- when_writing("Creating GEM") {
- Gem::Builder.new(gem_spec).build
- verbose(true) {
- mv gem_file, "#{package_dir}/#{gem_file}"
- }
- }
- end
- end
-
- def gem_file
- if @gem_spec.platform == Gem::Platform::RUBY
- "#{package_name}.gem"
- else
- "#{package_name}-#{@gem_spec.platform}.gem"
- end
- end
-
- end
+ GemPackageTask = Gem::PackageTask
end
+
diff --git a/lib/rake/invocation_chain.rb b/lib/rake/invocation_chain.rb
new file mode 100644
index 0000000000..8a01ab4c29
--- /dev/null
+++ b/lib/rake/invocation_chain.rb
@@ -0,0 +1,51 @@
+module Rake
+
+ ####################################################################
+ # InvocationChain tracks the chain of task invocations to detect
+ # circular dependencies.
+ class InvocationChain
+ def initialize(value, tail)
+ @value = value
+ @tail = tail
+ end
+
+ def member?(obj)
+ @value == obj || @tail.member?(obj)
+ end
+
+ def append(value)
+ if member?(value)
+ fail RuntimeError, "Circular dependency detected: #{to_s} => #{value}"
+ end
+ self.class.new(value, self)
+ end
+
+ def to_s
+ "#{prefix}#{@value}"
+ end
+
+ def self.append(value, chain)
+ chain.append(value)
+ end
+
+ private
+
+ def prefix
+ "#{@tail.to_s} => "
+ end
+
+ class EmptyInvocationChain
+ def member?(obj)
+ false
+ end
+ def append(value)
+ InvocationChain.new(value, self)
+ end
+ def to_s
+ "TOP"
+ end
+ end
+
+ EMPTY = EmptyInvocationChain.new
+ end
+end
diff --git a/lib/rake/invocation_exception_mixin.rb b/lib/rake/invocation_exception_mixin.rb
new file mode 100644
index 0000000000..84ff3353ba
--- /dev/null
+++ b/lib/rake/invocation_exception_mixin.rb
@@ -0,0 +1,16 @@
+module Rake
+ module InvocationExceptionMixin
+ # Return the invocation chain (list of Rake tasks) that were in
+ # effect when this exception was detected by rake. May be null if
+ # no tasks were active.
+ def chain
+ @rake_invocation_chain ||= nil
+ end
+
+ # Set the invocation chain in effect when this exception was
+ # detected.
+ def chain=(value)
+ @rake_invocation_chain = value
+ end
+ end
+end
diff --git a/lib/rake/lib/project.rake b/lib/rake/lib/project.rake
new file mode 100644
index 0000000000..a5497328a7
--- /dev/null
+++ b/lib/rake/lib/project.rake
@@ -0,0 +1,21 @@
+task "create:project" => ["lib", "test", "Rakefile"]
+
+directory "lib"
+directory "test"
+
+file "Rakefile" do
+ File.open("Rakefile", "w") do |out|
+ out.puts %{# -*- ruby -*-
+
+require 'rake/clean'
+require 'rake/testtask'
+
+task :default => :test
+
+Rake::TestTask.new do |t|
+ t.verbose = false
+ t.test_files = FileList['test/test_*.rb']
+end
+}
+ end
+end
diff --git a/lib/rake/loaders/makefile.rb b/lib/rake/loaders/makefile.rb
index 9a2ac8090e..4ece4323af 100644
--- a/lib/rake/loaders/makefile.rb
+++ b/lib/rake/loaders/makefile.rb
@@ -2,11 +2,13 @@ module Rake
# Makefile loader to be used with the import file loader.
class MakefileLoader
+ include Rake::DSL
+
SPACE_MARK = "\0"
# Load the makefile dependencies in +fn+.
def load(fn)
- lines = open(fn) {|mf| mf.read}
+ lines = File.read fn
lines.gsub!(/\\ /, SPACE_MARK)
lines.gsub!(/#[^\n]*\n/m, "")
lines.gsub!(/\\\n/, ' ')
@@ -21,7 +23,7 @@ module Rake
def process_line(line)
file_tasks, args = line.split(':', 2)
return if args.nil?
- dependents = args.split.map {|arg| respace(arg)}
+ dependents = args.split.map { |d| respace(d) }
file_tasks.scan(/\S+/) do |file_task|
file_task = respace(file_task)
file file_task => dependents
@@ -29,7 +31,7 @@ module Rake
end
def respace(str)
- str.tr(SPACE_MARK, ' ')
+ str.tr SPACE_MARK, ' '
end
end
diff --git a/lib/rake/multi_task.rb b/lib/rake/multi_task.rb
new file mode 100644
index 0000000000..21c8de732f
--- /dev/null
+++ b/lib/rake/multi_task.rb
@@ -0,0 +1,16 @@
+module Rake
+
+ # Same as a regular task, but the immediate prerequisites are done in
+ # parallel using Ruby threads.
+ #
+ class MultiTask < Task
+ private
+ def invoke_prerequisites(args, invocation_chain)
+ threads = @prerequisites.collect { |p|
+ Thread.new(p) { |r| application[r, @scope].invoke_with_call_chain(args, invocation_chain) }
+ }
+ threads.each { |t| t.join }
+ end
+ end
+
+end
diff --git a/lib/rake/name_space.rb b/lib/rake/name_space.rb
new file mode 100644
index 0000000000..e1cc0940b8
--- /dev/null
+++ b/lib/rake/name_space.rb
@@ -0,0 +1,25 @@
+module Rake
+
+ # The NameSpace class will lookup task names in the the scope
+ # defined by a +namespace+ command.
+ #
+ class NameSpace
+
+ # Create a namespace lookup object using the given task manager
+ # and the list of scopes.
+ def initialize(task_manager, scope_list)
+ @task_manager = task_manager
+ @scope = scope_list.dup
+ end
+
+ # Lookup a task named +name+ in the namespace.
+ def [](name)
+ @task_manager.lookup(name, @scope)
+ end
+
+ # Return the list of tasks defined in this and nested namespaces.
+ def tasks
+ @task_manager.tasks_in_scope(@scope)
+ end
+ end
+end
diff --git a/lib/rake/packagetask.rb b/lib/rake/packagetask.rb
index e77345c198..08c1a8c025 100644
--- a/lib/rake/packagetask.rb
+++ b/lib/rake/packagetask.rb
@@ -72,7 +72,10 @@ module Rake
# Zip command for zipped archives. The default is 'zip'.
attr_accessor :zip_command
- # Create a Package Task with the given name and version.
+ # Create a Package Task with the given name and version. Use +:noversion+
+ # as the version to build a package without a version or to provide a
+ # fully-versioned package name.
+
def initialize(name=nil, version=nil)
init(name, version)
yield self if block_given?
diff --git a/lib/rake/pathmap.rb b/lib/rake/pathmap.rb
new file mode 100644
index 0000000000..2275724341
--- /dev/null
+++ b/lib/rake/pathmap.rb
@@ -0,0 +1 @@
+require 'rake/ext/string'
diff --git a/lib/rake/pseudo_status.rb b/lib/rake/pseudo_status.rb
new file mode 100644
index 0000000000..b58df3da18
--- /dev/null
+++ b/lib/rake/pseudo_status.rb
@@ -0,0 +1,24 @@
+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
+ end
+
+end
diff --git a/lib/rake/rake_module.rb b/lib/rake/rake_module.rb
new file mode 100644
index 0000000000..a9d210c637
--- /dev/null
+++ b/lib/rake/rake_module.rb
@@ -0,0 +1,29 @@
+require 'rake/application'
+
+module Rake
+
+ # Rake module singleton methods.
+ #
+ class << self
+ # Current Rake Application
+ def application
+ @application ||= Rake::Application.new
+ end
+
+ # Set the current Rake application object.
+ def application=(app)
+ @application = app
+ end
+
+ # Return the original directory where the Rake application was started.
+ def original_dir
+ application.original_dir
+ end
+
+ # Load a rakefile.
+ def load_rakefile(path)
+ load(path)
+ end
+ end
+
+end
diff --git a/lib/rake/rake_test_loader.rb b/lib/rake/rake_test_loader.rb
index 8d7dad3c94..045a12fdce 100644
--- a/lib/rake/rake_test_loader.rb
+++ b/lib/rake/rake_test_loader.rb
@@ -1,5 +1,13 @@
-#!/usr/bin/env ruby
+require 'rake'
# Load the test files from the command line.
-ARGV.each { |f| load f unless f =~ /^-/ }
+ARGV.each do |f|
+ next if f =~ /^-/
+
+ if f =~ /\*/
+ FileList[f].to_a.each { |fn| require File.expand_path(fn) }
+ else
+ require File.expand_path(f)
+ end
+end
diff --git a/lib/rake/rdoctask.rb b/lib/rake/rdoctask.rb
index 59758b85cd..5faf836b37 100644
--- a/lib/rake/rdoctask.rb
+++ b/lib/rake/rdoctask.rb
@@ -1,4 +1,232 @@
-warn 'rake/rdoctask is deprecated. Use rdoc/task instead'
+# rake/rdoctask is deprecated in favor of rdoc/task
-require 'rdoc/task'
+if Rake.application
+ Rake.application.deprecate('require \'rake/rdoctask\'', 'require \'rdoc/task\' (in RDoc 2.4.2+)', __FILE__)
+end
+
+require 'rubygems'
+
+begin
+ gem 'rdoc'
+ require 'rdoc'
+ require 'rdoc/task'
+rescue LoadError, Gem::LoadError
+end
+
+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
diff --git a/lib/rake/ruby182_test_unit_fix.rb b/lib/rake/ruby182_test_unit_fix.rb
new file mode 100755
index 0000000000..9e411ed51a
--- /dev/null
+++ b/lib/rake/ruby182_test_unit_fix.rb
@@ -0,0 +1,25 @@
+# Local Rake override to fix bug in Ruby 0.8.2
+module Test # :nodoc:
+ # Local Rake override to fix bug in Ruby 0.8.2
+ module Unit # :nodoc:
+ # Local Rake override to fix bug in Ruby 0.8.2
+ module Collector # :nodoc:
+ # Local Rake override to fix bug in Ruby 0.8.2
+ class Dir # :nodoc:
+ undef collect_file
+ def collect_file(name, suites, already_gathered) # :nodoc:
+ dir = File.dirname(File.expand_path(name))
+ $:.unshift(dir) unless $:.first == dir
+ if(@req)
+ @req.require(name)
+ else
+ require(name)
+ end
+ find_test_cases(already_gathered).each{|t| add_suite(suites, t.suite)}
+ ensure
+ $:.delete_at $:.rindex(dir)
+ end
+ end
+ end
+ end
+end
diff --git a/lib/rake/rule_recursion_overflow_error.rb b/lib/rake/rule_recursion_overflow_error.rb
new file mode 100644
index 0000000000..da4318da9d
--- /dev/null
+++ b/lib/rake/rule_recursion_overflow_error.rb
@@ -0,0 +1,20 @@
+
+module Rake
+
+ # 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
+
+end
diff --git a/lib/rake/runtest.rb b/lib/rake/runtest.rb
index f6928d57b8..2b98a60cae 100644
--- a/lib/rake/runtest.rb
+++ b/lib/rake/runtest.rb
@@ -6,12 +6,12 @@ module Rake
def run_tests(pattern='test/test*.rb', log_enabled=false)
Dir["#{pattern}"].each { |fn|
- puts fn if log_enabled
+ $stderr.puts fn if log_enabled
begin
- load fn
+ require fn
rescue Exception => ex
- puts "Error in #{fn}: #{ex.message}"
- puts ex.backtrace
+ $stderr.puts "Error in #{fn}: #{ex.message}"
+ $stderr.puts ex.backtrace
assert false
end
}
diff --git a/lib/rake/task.rb b/lib/rake/task.rb
new file mode 100644
index 0000000000..f977d18711
--- /dev/null
+++ b/lib/rake/task.rb
@@ -0,0 +1,327 @@
+require 'rake/invocation_exception_mixin'
+
+module Rake
+
+ # #########################################################################
+ # A Task is the basic unit of work in a Rakefile. Tasks have associated
+ # actions (possibly more than one) and a list of prerequisites. When
+ # invoked, a task will first ensure that all of its prerequisites have an
+ # opportunity to run and then it will execute its own actions.
+ #
+ # Tasks are not usually created directly using the new method, but rather
+ # use the +file+ and +task+ convenience methods.
+ #
+ class Task
+ # 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
+
+ # 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
+
+ # File/Line locations of each of the task definitions for this
+ # task (only valid if the task was defined with the detect
+ # location option set).
+ attr_reader :locations
+
+ # Return task name
+ def to_s
+ name
+ end
+
+ def inspect
+ "<#{self.class} #{name} => [#{prerequisites.join(', ')}]>"
+ end
+
+ # List of sources for task.
+ attr_writer :sources
+ def sources
+ @sources ||= []
+ end
+
+ # List of prerequisite tasks
+ def prerequisite_tasks
+ prerequisites.collect { |pre| lookup_prerequisite(pre) }
+ end
+
+ def lookup_prerequisite(prerequisite_name)
+ application[prerequisite_name, @scope]
+ end
+ private :lookup_prerequisite
+
+ # First source from a rule (nil if no sources)
+ def source
+ @sources.first if defined?(@sources)
+ end
+
+ # 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 = []
+ @already_invoked = false
+ @full_comment = nil
+ @comment = nil
+ @lock = Monitor.new
+ @application = app
+ @scope = app.current_scope
+ @arg_names = nil
+ @locations = []
+ end
+
+ # Enhance a task with prerequisites or actions. Returns self.
+ def enhance(deps=nil, &block)
+ @prerequisites |= deps if deps
+ @actions << block if block_given?
+ self
+ end
+
+ # Name of the task, including any namespace qualifiers.
+ def name
+ @name.to_s
+ end
+
+ # Name of task with argument list description.
+ def name_with_args # :nodoc:
+ if arg_description
+ "#{name}#{arg_description}"
+ else
+ name
+ end
+ end
+
+ # Argument description (nil if none).
+ def arg_description # :nodoc:
+ @arg_names ? "[#{(arg_names || []).join(',')}]" : nil
+ end
+
+ # Name of arguments for this task.
+ def arg_names
+ @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. Prerequisites are invoked first.
+ def invoke(*args)
+ task_args = TaskArguments.new(arg_names, args)
+ invoke_with_call_chain(task_args, InvocationChain::EMPTY)
+ end
+
+ # Same as invoke, but explicitly pass a call chain to detect
+ # circular dependencies.
+ def invoke_with_call_chain(task_args, invocation_chain) # :nodoc:
+ new_chain = InvocationChain.append(self, invocation_chain)
+ @lock.synchronize do
+ if application.options.trace
+ $stderr.puts "** Invoke #{name} #{format_trace_flags}"
+ end
+ return if @already_invoked
+ @already_invoked = true
+ invoke_prerequisites(task_args, new_chain)
+ execute(task_args) if needed?
+ end
+ rescue Exception => ex
+ add_chain_to(ex, new_chain)
+ raise ex
+ end
+ protected :invoke_with_call_chain
+
+ def add_chain_to(exception, new_chain)
+ exception.extend(InvocationExceptionMixin) unless exception.respond_to?(:chain)
+ exception.chain = new_chain if exception.chain.nil?
+ end
+ private :add_chain_to
+
+ # Invoke all the prerequisites of a task.
+ def invoke_prerequisites(task_args, invocation_chain) # :nodoc:
+ prerequisite_tasks.each { |prereq|
+ prereq_args = task_args.new_scope(prereq.arg_names)
+ prereq.invoke_with_call_chain(prereq_args, invocation_chain)
+ }
+ end
+
+ # Format the trace flags for display.
+ def format_trace_flags
+ flags = []
+ flags << "first_time" unless @already_invoked
+ flags << "not_needed" unless needed?
+ flags.empty? ? "" : "(" + flags.join(", ") + ")"
+ end
+ private :format_trace_flags
+
+ # Execute the actions associated with this task.
+ def execute(args=nil)
+ args ||= EMPTY_TASK_ARGS
+ if application.options.dryrun
+ $stderr.puts "** Execute (dry run) #{name}"
+ return
+ end
+ if application.options.trace
+ $stderr.puts "** Execute #{name}"
+ end
+ application.enhance_with_matching_rule(name) if @actions.empty?
+ @actions.each do |act|
+ case act.arity
+ when 1
+ act.call(self)
+ else
+ act.call(self, args)
+ end
+ end
+ end
+
+ # Is this task needed?
+ def needed?
+ true
+ end
+
+ # 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
+ 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
+ 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)
+ 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
+ else
+ @comment = @full_comment
+ end
+ end
+ private :add_comment
+
+ # Set the names of the arguments for this task. +args+ should be
+ # an array of symbols, one for each argument name.
+ def set_arg_names(args)
+ @arg_names = args.map { |a| a.to_sym }
+ end
+
+ # Return a string describing the internal state of a task. Useful for
+ # debugging.
+ def investigation
+ result = "------------------------------\n"
+ result << "Investigating #{name}\n"
+ result << "class: #{self.class}\n"
+ result << "task needed: #{needed?}\n"
+ result << "timestamp: #{timestamp}\n"
+ result << "pre-requisites: \n"
+ prereqs = prerequisite_tasks
+ 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
+ result << "latest-prerequisite time: #{latest_prereq}\n"
+ result << "................................\n\n"
+ return result
+ end
+
+ # ----------------------------------------------------------------
+ # Rake Module Methods
+ #
+ class << self
+
+ # Clear the task list. This cause rake to immediately forget all the
+ # tasks that have been assigned. (Normally used in the unit tests.)
+ def clear
+ Rake.application.clear
+ end
+
+ # List of all defined tasks.
+ def tasks
+ Rake.application.tasks
+ end
+
+ # Return a task with the given name. If the task is not currently
+ # known, try to synthesize one from the defined rules. If no rules are
+ # found, but an existing file matches the task name, assume it is a file
+ # task with no dependencies or actions.
+ def [](task_name)
+ Rake.application[task_name]
+ end
+
+ # TRUE if the task name is already defined.
+ def task_defined?(task_name)
+ Rake.application.lookup(task_name) != nil
+ end
+
+ # Define a task given +args+ and an option block. If a rule with the
+ # given name already exists, the prerequisites and actions are added to
+ # the existing task. Returns the defined task.
+ def define_task(*args, &block)
+ Rake.application.define_task(self, *args, &block)
+ end
+
+ # Define a rule for synthesizing tasks.
+ def create_rule(*args, &block)
+ Rake.application.create_rule(*args, &block)
+ end
+
+ # Apply the scope to the task name according to the rules for
+ # 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(':')
+ end
+
+ end # class << Rake::Task
+ end # class Rake::Task
+end
diff --git a/lib/rake/task_argument_error.rb b/lib/rake/task_argument_error.rb
new file mode 100644
index 0000000000..3e1dda64db
--- /dev/null
+++ b/lib/rake/task_argument_error.rb
@@ -0,0 +1,7 @@
+module Rake
+
+ # Error indicating an ill-formed task declaration.
+ class TaskArgumentError < ArgumentError
+ end
+
+end
diff --git a/lib/rake/task_arguments.rb b/lib/rake/task_arguments.rb
new file mode 100644
index 0000000000..ab404d67f5
--- /dev/null
+++ b/lib/rake/task_arguments.rb
@@ -0,0 +1,74 @@
+module Rake
+
+ ####################################################################
+ # TaskArguments manage the arguments passed to a task.
+ #
+ class TaskArguments
+ include Enumerable
+
+ 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] unless values[i].nil?
+ }
+ 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)
+ end
+
+ # Find an argument value by name or index.
+ def [](index)
+ 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
+
+ def method_missing(sym, *args, &block)
+ lookup(sym.to_sym)
+ end
+
+ def to_hash
+ @hash
+ end
+
+ def to_s
+ @hash.inspect
+ end
+
+ def inspect
+ to_s
+ end
+
+ protected
+
+ def lookup(name)
+ if @hash.has_key?(name)
+ @hash[name]
+ elsif @parent
+ @parent.lookup(name)
+ end
+ end
+ end
+
+ EMPTY_TASK_ARGS = TaskArguments.new([], [])
+end
diff --git a/lib/rake/task_manager.rb b/lib/rake/task_manager.rb
new file mode 100644
index 0000000000..4c3c26aa3a
--- /dev/null
+++ b/lib/rake/task_manager.rb
@@ -0,0 +1,307 @@
+module Rake
+
+ # The TaskManager module is a mixin for managing tasks.
+ module TaskManager
+ # Track the last comment made in the Rakefile.
+ attr_accessor :last_description
+ alias :last_comment :last_description # Backwards compatibility
+
+ def initialize
+ super
+ @tasks = Hash.new
+ @rules = Array.new
+ @scope = Array.new
+ @last_description = nil
+ end
+
+ def create_rule(*args, &block)
+ pattern, _, deps = resolve_args(args)
+ pattern = Regexp.new(Regexp.quote(pattern) + '$') if String === pattern
+ @rules << [pattern, 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 }
+ task = intern(task_class, task_name)
+ task.set_arg_names(arg_names) unless arg_names.empty?
+ if Rake::TaskManager.record_task_metadata
+ add_location(task)
+ task.add_description(get_description(task))
+ end
+ task.enhance(deps, &block)
+ end
+
+ # Lookup a task. Return an existing task if found, otherwise
+ # create a task of the current type.
+ def intern(task_class, task_name)
+ @tasks[task_name.to_s] ||= task_class.new(task_name, self)
+ end
+
+ # Find a matching task for +task_name+.
+ def [](task_name, scopes=nil)
+ task_name = task_name.to_s
+ self.lookup(task_name, scopes) or
+ enhance_with_matching_rule(task_name) or
+ synthesize_file_task(task_name) or
+ fail "Don't know how to build task '#{task_name}'"
+ end
+
+ def synthesize_file_task(task_name)
+ return nil unless File.exist?(task_name)
+ define_task(Rake::FileTask, task_name)
+ end
+
+ # 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
+ if args.size == 1 && args.first.respond_to?(:to_ary)
+ arg_names = args.first.to_ary
+ else
+ arg_names = args
+ end
+ [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
+ 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
+ deps = value
+ end
+ 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
+ # the enhanced task or nil of no rule was found.
+ 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|
+ if pattern.match(task_name)
+ task = attempt_rule(task_name, extensions, block, level)
+ return task if task
+ end
+ end
+ nil
+ rescue Rake::RuleRecursionOverflowError => ex
+ ex.add_target(task_name)
+ fail ex
+ end
+
+ # List of all defined tasks in this application.
+ def tasks
+ @tasks.values.sort_by { |t| t.name }
+ end
+
+ # List of all the tasks defined in the given scope (and its
+ # sub-scopes).
+ def tasks_in_scope(scope)
+ prefix = scope.join(":")
+ tasks.select { |t|
+ /^#{prefix}:/ =~ t.name
+ }
+ end
+
+ # Clear all tasks in this application.
+ def clear
+ @tasks.clear
+ @rules.clear
+ end
+
+ # Lookup a task, using scope and the scope hints in the task name.
+ # This method performs straight lookups without trying to
+ # synthesize file tasks or rules. Special scope names (e.g. '^')
+ # are recognized. If no scope argument is supplied, use the
+ # current scope. Return nil if the task cannot be found.
+ def lookup(task_name, initial_scope=nil)
+ initial_scope ||= @scope
+ task_name = task_name.to_s
+ if task_name =~ /^rake:/
+ scopes = []
+ task_name = task_name.sub(/^rake:/, '')
+ elsif task_name =~ /^(\^+)/
+ scopes = initial_scope[0, initial_scope.size - $1.size]
+ task_name = task_name.sub(/^(\^+)/, '')
+ else
+ scopes = initial_scope
+ end
+ lookup_in_scope(task_name, scopes)
+ end
+
+ # Lookup the task name
+ def lookup_in_scope(name, scope)
+ n = scope.size
+ while n >= 0
+ tn = (scope[0,n] + [name]).join(':')
+ task = @tasks[tn]
+ return task if task
+ n -= 1
+ end
+ nil
+ end
+ private :lookup_in_scope
+
+ # Return the list of scope names currently active in the task
+ # manager.
+ def current_scope
+ @scope.dup
+ 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)
+ ns = NameSpace.new(self, @scope)
+ yield(ns)
+ ns
+ ensure
+ @scope.pop
+ end
+
+ private
+
+ # Add a location to the locations field of the given task.
+ def add_location(task)
+ loc = find_location
+ task.locations << loc if loc
+ task
+ end
+
+ # Find the location that called into the dsl layer.
+ def find_location
+ locations = caller
+ i = 0
+ while locations[i]
+ return locations[i+1] if locations[i] =~ /rake\/dsl_definition.rb/
+ i += 1
+ end
+ nil
+ end
+
+ # Generate an anonymous namespace name.
+ def generate_name
+ @seed ||= 0
+ @seed += 1
+ "_anon_#{@seed}"
+ end
+
+ def trace_rule(level, message)
+ $stderr.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(source, level+1)
+ trace_rule level, "(#{task_name} => #{source} ... ENHANCE)"
+ parent.name
+ else
+ trace_rule level, "(#{task_name} => #{source} ... FAIL)"
+ return nil
+ end
+ }
+ task = FileTask.define_task({task_name => prereqs}, &block)
+ task.sources = prereqs
+ task
+ end
+
+ # Make a list of sources from the list of file name extensions /
+ # translation procs.
+ def make_sources(task_name, extensions)
+ result = extensions.collect { |ext|
+ case ext
+ when /%/
+ task_name.pathmap(ext)
+ when %r{/}
+ ext
+ when /^\./
+ task_name.ext(ext)
+ when String
+ ext
+ when Proc
+ if ext.arity == 1
+ ext.call(task_name)
+ else
+ ext.call
+ end
+ else
+ fail "Don't know how to handle rule dependent: #{ext.inspect}"
+ end
+ }
+ result.flatten
+ end
+
+
+ private
+
+ # Return the current description, clearing it in the process.
+ def get_description(task)
+ desc = @last_description
+ @last_description = nil
+ desc
+ end
+
+ class << self
+ attr_accessor :record_task_metadata
+ TaskManager.record_task_metadata = false
+ end
+ end
+
+end
diff --git a/lib/rake/tasklib.rb b/lib/rake/tasklib.rb
index a5a4494369..f1e17dad31 100644
--- a/lib/rake/tasklib.rb
+++ b/lib/rake/tasklib.rb
@@ -5,6 +5,7 @@ module Rake
# Base class for Task Libraries.
class TaskLib
include Cloneable
+ include Rake::DSL
# Make a symbol by pasting two strings together.
#
diff --git a/lib/rake/testtask.rb b/lib/rake/testtask.rb
index c400205ff3..04d3ae473a 100644
--- a/lib/rake/testtask.rb
+++ b/lib/rake/testtask.rb
@@ -93,33 +93,37 @@ module Rake
# Create the tasks defined by this task lib.
def define
- lib_path = @libs.join(File::PATH_SEPARATOR)
desc "Run tests" + (@name==:test ? "" : " for #{@name}")
task @name do
- run_code = ''
- RakeFileUtils.verbose(@verbose) do
- run_code =
- case @loader
- when :direct
- "-e 'ARGV.each{|f| load f}'"
- when :testrb
- "-S testrb"
- when :rake
- rake_loader
- end
- @ruby_opts.unshift( "-I\"#{lib_path}\"" )
- @ruby_opts.unshift( "-w" ) if @warning
- ruby @ruby_opts.join(" ") +
- " \"#{run_code}\" " +
- file_list.collect { |fn| "\"#{fn}\"" }.join(' ') +
- " #{option_list}"
+ FileUtilsExt.verbose(@verbose) do
+ ruby "#{ruby_opts_string} #{run_code} #{file_list_string} #{option_list}"
end
end
self
end
def option_list # :nodoc:
- ENV['TESTOPTS'] || @options || ""
+ (ENV['TESTOPTS'] ||
+ ENV['TESTOPT'] ||
+ ENV['TEST_OPTS'] ||
+ ENV['TEST_OPT'] ||
+ @options ||
+ "")
+ end
+
+ def ruby_opts_string
+ opts = @ruby_opts.dup
+ opts.unshift( "-I\"#{lib_path}\"" ) unless @libs.empty?
+ opts.unshift( "-w" ) if @warning
+ opts.join(" ")
+ end
+
+ def lib_path
+ @libs.join(File::PATH_SEPARATOR)
+ end
+
+ def file_list_string
+ file_list.collect { |fn| "\"#{fn}\"" }.join(' ')
end
def file_list # :nodoc:
@@ -128,8 +132,32 @@ module Rake
else
result = []
result += @test_files.to_a if @test_files
- result += FileList[ @pattern ].to_a if @pattern
- FileList[result]
+ result << @pattern if @pattern
+ result
+ end
+ end
+
+ def fix # :nodoc:
+ case ruby_version
+ when '1.8.2'
+ "\"#{find_file 'rake/ruby182_test_unit_fix'}\""
+ else
+ nil
+ end || ''
+ end
+
+ def ruby_version
+ RUBY_VERSION
+ end
+
+ def run_code
+ case @loader
+ when :direct
+ "-e \"ARGV.each{|f| require f}\""
+ when :testrb
+ "-S testrb #{fix}"
+ when :rake
+ "-I\"#{rake_lib_dir}\" \"#{rake_loader}\""
end
end
@@ -146,5 +174,18 @@ module Rake
nil
end
+ def rake_lib_dir # :nodoc:
+ find_dir('rake') or
+ fail "unable to find rake lib"
+ end
+
+ def find_dir(fn) # :nodoc:
+ $LOAD_PATH.each do |path|
+ file_path = File.join(path, "#{fn}.rb")
+ return path if File.exist? file_path
+ end
+ nil
+ end
+
end
end
diff --git a/lib/rake/version.rb b/lib/rake/version.rb
new file mode 100644
index 0000000000..dbad21e52d
--- /dev/null
+++ b/lib/rake/version.rb
@@ -0,0 +1,10 @@
+module Rake
+ module Version
+ NUMBERS = [
+ MAJOR = 0,
+ MINOR = 9,
+ BUILD = 2,
+ ]
+ end
+ VERSION = Version::NUMBERS.join('.')
+end
diff --git a/lib/rake/win32.rb b/lib/rake/win32.rb
index 0ab31c2822..98289a10b4 100644
--- a/lib/rake/win32.rb
+++ b/lib/rake/win32.rb
@@ -1,46 +1,55 @@
+
module Rake
+ require 'rake/alt_system'
# Win 32 interface methods for Rake. Windows specific functionality
# will be placed here to collect that knowledge in one spot.
module Win32
+
+ # Error indicating a problem in locating the home directory on a
+ # Win32 system.
+ class Win32HomeError < RuntimeError
+ end
+
class << self
# True if running on a windows system.
- if File::ALT_SEPARATOR == '\\' # assume other DOSish systems are extinct.
- def windows?; true end
- else
- def windows?; false end
+ def windows?
+ AltSystem::WINDOWS
+ end
+
+ # Run a command line on windows.
+ def rake_system(*cmd)
+ AltSystem.system(*cmd)
end
- end
- class << self
# The standard directory containing system wide rake files on
# Win 32 systems. Try the following environment variables (in
# order):
#
- # * APPDATA
# * HOME
# * HOMEDRIVE + HOMEPATH
+ # * APPDATA
# * USERPROFILE
#
- # If the above are not defined, retruns the personal folder.
+ # If the above are not defined, the return nil.
def win32_system_dir #:nodoc:
- win32_shared_path = ENV['APPDATA']
- if !win32_shared_path or win32_shared_path.empty?
- win32_shared_path = '~'
+ win32_shared_path = ENV['HOME']
+ if win32_shared_path.nil? && ENV['HOMEDRIVE'] && ENV['HOMEPATH']
+ win32_shared_path = ENV['HOMEDRIVE'] + ENV['HOMEPATH']
end
- File.expand_path('Rake', win32_shared_path)
+
+ 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?
+ normalize(File.join(win32_shared_path, 'Rake'))
end
# Normalize a win32 path so that the slashes are all forward slashes.
def normalize(path)
- path.tr('\\', '/')
+ path.gsub(/\\/, '/')
end
- end if windows?
- end
- if Win32.windows?
- def standard_system_dir
- Win32.win32_system_dir
end
end
end
diff --git a/test/rake/capture_stdout.rb b/test/rake/capture_stdout.rb
deleted file mode 100644
index f54ec42f69..0000000000
--- a/test/rake/capture_stdout.rb
+++ /dev/null
@@ -1,24 +0,0 @@
-require 'stringio'
-
-# Mix-in for capturing standard output.
-module CaptureStdout
- def capture_stdout
- s = StringIO.new
- oldstdout = $stdout
- $stdout = s
- yield
- s.string
- ensure
- $stdout = oldstdout
- end
-
- def capture_stderr
- s = StringIO.new
- oldstderr = $stderr
- $stderr = s
- yield
- s.string
- ensure
- $stderr = oldstderr
- end
-end
diff --git a/test/rake/check_expansion.rb b/test/rake/check_expansion.rb
deleted file mode 100644
index 659cf71e51..0000000000
--- a/test/rake/check_expansion.rb
+++ /dev/null
@@ -1,5 +0,0 @@
-if ARGV[0] != ARGV[1]
- exit 1
-else
- exit 0
-end
diff --git a/test/rake/check_no_expansion.rb b/test/rake/check_no_expansion.rb
deleted file mode 100644
index 24f586a7f5..0000000000
--- a/test/rake/check_no_expansion.rb
+++ /dev/null
@@ -1,5 +0,0 @@
-if ARGV[0] != ARGV[1]
- exit 0
-else
- exit 1
-end
diff --git a/test/rake/data/chains/Rakefile b/test/rake/data/chains/Rakefile
deleted file mode 100644
index 31bdc2578d..0000000000
--- a/test/rake/data/chains/Rakefile
+++ /dev/null
@@ -1,15 +0,0 @@
-# -*- ruby -*-
-
-task :default => "play.app"
-
-file "play.scpt" => "base" do |t|
- cp t.prerequisites.first, t.name
-end
-
-rule ".app" => ".scpt" do |t|
- cp t.source, t.name
-end
-
-file 'base' do
- touch 'base'
-end
diff --git a/test/rake/data/default/Rakefile b/test/rake/data/default/Rakefile
deleted file mode 100644
index 22ed5e0ca9..0000000000
--- a/test/rake/data/default/Rakefile
+++ /dev/null
@@ -1,19 +0,0 @@
-#!/usr/bin/env ruby
-
-if ENV['TESTTOPSCOPE']
- puts "TOPSCOPE"
-end
-
-task :default do
- puts "DEFAULT"
-end
-
-task :other => [:default] do
- puts "OTHER"
-end
-
-task :task_scope do
- if ENV['TESTTASKSCOPE']
- puts "TASKSCOPE"
- end
-end
diff --git a/test/rake/data/dryrun/Rakefile b/test/rake/data/dryrun/Rakefile
deleted file mode 100644
index 0a68a0d606..0000000000
--- a/test/rake/data/dryrun/Rakefile
+++ /dev/null
@@ -1,22 +0,0 @@
-#
-
-task :default => ["temp_main"]
-
-file "temp_main" => [:all_apps] do touch "temp_main" end
-
-task :all_apps => [:one, :two]
-task :one => ["temp_one"]
-task :two => ["temp_two"]
-
-file "temp_one" do |t|
- touch "temp_one"
-end
-file "temp_two" do |t|
- touch "temp_two"
-end
-
-task :clean do
- ["temp_one", "temp_two", "temp_main"].each do |file|
- rm_f file
- end
-end
diff --git a/test/rake/data/file_creation_task/Rakefile b/test/rake/data/file_creation_task/Rakefile
deleted file mode 100644
index 94641b6972..0000000000
--- a/test/rake/data/file_creation_task/Rakefile
+++ /dev/null
@@ -1,33 +0,0 @@
-#!/usr/bin/env ruby
-
-N = 2
-
-task :default => :run
-
-BUILD_DIR = 'build'
-task :clean do
- rm_rf 'build'
- rm_rf 'src'
-end
-
-task :run
-
-TARGET_DIR = 'build/copies'
-
-FileList['src/*'].each do |src|
- directory TARGET_DIR
- target = File.join TARGET_DIR, File.basename(src)
- file target => [src, TARGET_DIR] do
- cp src, target
- # sleep 3 if src !~ /foo#{N-1}$/ # I'm commenting out this sleep, it doesn't seem to do anything.
- end
- task :run => target
-end
-
-task :prep => :clean do
- mkdir_p 'src'
- N.times do |n|
- puts "DBG: Touching src/foo#{n}"
- touch "src/foo#{n}"
- end
-end
diff --git a/test/rake/data/imports/Rakefile b/test/rake/data/imports/Rakefile
deleted file mode 100644
index 6a60f612bc..0000000000
--- a/test/rake/data/imports/Rakefile
+++ /dev/null
@@ -1,19 +0,0 @@
-# -*- ruby -*-
-
-require 'rake/loaders/makefile'
-
-task :default
-
-task :other do
- puts "OTHER"
-end
-
-file "dynamic_deps" do |t|
- open(t.name, "w") do |f| f.puts "puts 'DYNAMIC'" end
-end
-
-import "dynamic_deps"
-import "static_deps"
-import "static_deps"
-import "deps.mf"
-puts "FIRST"
diff --git a/test/rake/data/imports/deps.mf b/test/rake/data/imports/deps.mf
deleted file mode 100644
index 04643d0d8e..0000000000
--- a/test/rake/data/imports/deps.mf
+++ /dev/null
@@ -1 +0,0 @@
-default: other
diff --git a/test/rake/data/multidesc/Rakefile b/test/rake/data/multidesc/Rakefile
deleted file mode 100644
index 5342481922..0000000000
--- a/test/rake/data/multidesc/Rakefile
+++ /dev/null
@@ -1,17 +0,0 @@
-#!/usr/bin/env ruby
-
-task :b
-
-desc "A"
-task :a
-
-desc "B"
-task :b
-
-desc "A2"
-task :a
-
-task :c
-
-desc "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
-task :d
diff --git a/test/rake/data/namespace/Rakefile b/test/rake/data/namespace/Rakefile
deleted file mode 100644
index 6de98edae9..0000000000
--- a/test/rake/data/namespace/Rakefile
+++ /dev/null
@@ -1,57 +0,0 @@
-#!/usr/bin/env ruby
-
-desc "copy"
-task :copy do
- puts "COPY"
-end
-
-namespace "nest" do
- desc "nest copy"
- task :copy do
- puts "NEST COPY"
- end
- task :xx => :copy
-end
-
-anon_ns = namespace do
- desc "anonymous copy task"
- task :copy do
- puts "ANON COPY"
- end
-end
-
-desc "Top level task to run the anonymous version of copy"
-task :anon => anon_ns[:copy]
-
-namespace "very" do
- namespace "nested" do
- task "run" => "rake:copy"
- end
-end
-
-namespace "a" do
- desc "Run task in the 'a' namespace"
- task "run" do
- puts "IN A"
- end
-end
-
-namespace "b" do
- desc "Run task in the 'b' namespace"
- task "run" => "a:run" do
- puts "IN B"
- end
-end
-
-namespace "file1" do
- file "xyz.rb" do
- puts "XYZ1"
- end
-end
-
-namespace "file2" do
- file "xyz.rb" do
- puts "XYZ2"
- end
-end
-
diff --git a/test/rake/data/rakelib/test1.rake b/test/rake/data/rakelib/test1.rake
deleted file mode 100644
index bb1c419b40..0000000000
--- a/test/rake/data/rakelib/test1.rake
+++ /dev/null
@@ -1,3 +0,0 @@
-task :default do
- puts "TEST1"
-end
diff --git a/test/rake/data/rbext/rakefile.rb b/test/rake/data/rbext/rakefile.rb
deleted file mode 100644
index 670604d733..0000000000
--- a/test/rake/data/rbext/rakefile.rb
+++ /dev/null
@@ -1,3 +0,0 @@
-task :default do
- puts "OK"
-end
diff --git a/test/rake/data/sample.mf b/test/rake/data/sample.mf
deleted file mode 100644
index 778e9d456f..0000000000
--- a/test/rake/data/sample.mf
+++ /dev/null
@@ -1,14 +0,0 @@
-# Comments
-a: a1 a2 a3 a4
-b: b1 b2 b3 \
- b4 b5 b6\
-# Mid: Comment
-b7
-
- a : a5 a6 a7
-c: c1
-d: d1 d2 \
-
-e f : e1 f1
-
-g\ 0: g1 g\ 2 g\ 3 g4
diff --git a/test/rake/data/statusreturn/Rakefile b/test/rake/data/statusreturn/Rakefile
deleted file mode 100644
index 68023052f8..0000000000
--- a/test/rake/data/statusreturn/Rakefile
+++ /dev/null
@@ -1,8 +0,0 @@
-#!/usr/bin/env ruby
-
-task :exit5 do
- exit(5)
-end
-
-task :normal do
-end
diff --git a/test/rake/data/unittest/Rakefile b/test/rake/data/unittest/Rakefile
deleted file mode 100644
index 9c3b8ac11c..0000000000
--- a/test/rake/data/unittest/Rakefile
+++ /dev/null
@@ -1 +0,0 @@
-# Empty Rakefile for Unit Test
diff --git a/test/rake/data/unittest/subdir/.gitignore b/test/rake/data/unittest/subdir/.gitignore
deleted file mode 100644
index d6b7ef32c8..0000000000
--- a/test/rake/data/unittest/subdir/.gitignore
+++ /dev/null
@@ -1,2 +0,0 @@
-*
-!.gitignore
diff --git a/test/rake/filecreation.rb b/test/rake/file_creation.rb
index e4c6e347da..facc57a038 100644
--- a/test/rake/filecreation.rb
+++ b/test/rake/file_creation.rb
@@ -1,15 +1,18 @@
module FileCreation
- OLDFILE = "testdata/old"
- NEWFILE = "testdata/new"
+ OLDFILE = "old"
+ NEWFILE = "new"
def create_timed_files(oldfile, *newfiles)
- return if File.exist?(oldfile) && newfiles.all? { |newfile| File.exist?(newfile) }
- old_time = create_file(oldfile)
+ return if (File.exist?(oldfile) &&
+ newfiles.all? { |newfile|
+ File.exist?(newfile) && File.stat(newfile).mtime > File.stat(oldfile).mtime
+ })
+ now = Time.now
+
+ create_file(oldfile, now - 60)
+
newfiles.each do |newfile|
- while create_file(newfile) <= old_time
- sleep(0.1)
- File.delete(newfile) rescue nil
- end
+ create_file(newfile, now)
end
end
@@ -18,9 +21,10 @@ module FileCreation
File.stat(dirname).mtime
end
- def create_file(name)
+ def create_file(name, file_time=nil)
create_dir(File.dirname(name))
FileUtils.touch(name) unless File.exist?(name)
+ File.utime(file_time, file_time, name) unless file_time.nil?
File.stat(name).mtime
end
diff --git a/test/rake/helper.rb b/test/rake/helper.rb
new file mode 100644
index 0000000000..70b06d7fe2
--- /dev/null
+++ b/test/rake/helper.rb
@@ -0,0 +1,500 @@
+require 'rubygems'
+require 'minitest/unit'
+require 'flexmock/test_unit_integration'
+require 'minitest/autorun'
+require 'rake'
+require 'tmpdir'
+require File.expand_path('../file_creation', __FILE__)
+
+class Rake::TestCase < MiniTest::Unit::TestCase
+ include FlexMock::ArgumentTypes
+ include FlexMock::MockContainer
+
+ include FileCreation
+
+ include Rake::DSL
+
+ class TaskManager
+ include Rake::TaskManager
+ end
+
+ def setup
+ ARGV.clear
+
+ @orig_PWD = Dir.pwd
+ @orig_APPDATA = ENV['APPDATA']
+ @orig_HOME = ENV['HOME']
+ @orig_HOMEDRIVE = ENV['HOMEDRIVE']
+ @orig_HOMEPATH = ENV['HOMEPATH']
+ @orig_RAKE_COLUMNS = ENV['RAKE_COLUMNS']
+ @orig_RAKE_SYSTEM = ENV['RAKE_SYSTEM']
+ @orig_RAKEOPT = ENV['RAKEOPT']
+ @orig_USERPROFILE = ENV['USERPROFILE']
+ ENV.delete 'RAKE_COLUMNS'
+ ENV.delete 'RAKE_SYSTEM'
+ ENV.delete 'RAKEOPT'
+
+ tmpdir = Dir.chdir Dir.tmpdir do Dir.pwd end
+ @tempdir = File.join tmpdir, "test_rake_#{$$}"
+
+ FileUtils.mkdir_p @tempdir
+
+ Dir.chdir @tempdir
+
+ Rake.application = Rake::Application.new
+ Rake::TaskManager.record_task_metadata = true
+ end
+
+ def teardown
+ flexmock_teardown
+
+ Dir.chdir @orig_PWD
+ FileUtils.rm_rf @tempdir
+
+ if @orig_APPDATA then
+ ENV['APPDATA'] = @orig_APPDATA
+ else
+ ENV.delete 'APPDATA'
+ end
+
+ ENV['HOME'] = @orig_HOME
+ ENV['HOMEDRIVE'] = @orig_HOMEDRIVE
+ ENV['HOMEPATH'] = @orig_HOMEPATH
+ ENV['RAKE_COLUMNS'] = @orig_RAKE_COLUMNS
+ ENV['RAKE_SYSTEM'] = @orig_RAKE_SYSTEM
+ ENV['RAKEOPT'] = @orig_RAKEOPT
+ ENV['USERPROFILE'] = @orig_USERPROFILE
+ end
+
+ def ignore_deprecations
+ Rake.application.options.ignore_deprecate = true
+ yield
+ ensure
+ Rake.application.options.ignore_deprecate = false
+ end
+
+ def rake_system_dir
+ @system_dir = 'system'
+
+ FileUtils.mkdir_p @system_dir
+
+ open File.join(@system_dir, 'sys1.rake'), 'w' do |io|
+ io << <<-SYS
+task "sys1" do
+ puts "SYS1"
+end
+ SYS
+ end
+
+ ENV['RAKE_SYSTEM'] = @system_dir
+ end
+
+ def rakefile contents
+ open 'Rakefile', 'w' do |io|
+ io << contents
+ end
+ end
+
+ def rakefile_access
+ rakefile <<-ACCESS
+TOP_LEVEL_CONSTANT = 0
+
+def a_top_level_function
+end
+
+task :default => [:work, :obj, :const]
+
+task :work do
+ begin
+ a_top_level_function
+ puts "GOOD:M Top level methods can be called in tasks"
+ rescue NameError => ex
+ puts "BAD:M Top level methods can not be called in tasks"
+ end
+end
+
+# TODO: remove `disabled_' when DeprecatedObjectDSL removed
+task :obj
+task :disabled_obj do
+ begin
+ Object.new.instance_eval { task :xyzzy }
+ puts "BAD:D Rake DSL are polluting objects"
+ rescue StandardError => ex
+ puts "GOOD:D Rake DSL are not polluting objects"
+ end
+end
+
+task :const do
+ begin
+ TOP_LEVEL_CONSTANT
+ puts "GOOD:C Top level constants are available in tasks"
+ rescue StandardError => ex
+ puts "BAD:C Top level constants are NOT available in tasks"
+ end
+end
+ ACCESS
+ end
+
+ def rakefile_chains
+ rakefile <<-DEFAULT
+task :default => "play.app"
+
+file "play.scpt" => "base" do |t|
+ cp t.prerequisites.first, t.name
+end
+
+rule ".app" => ".scpt" do |t|
+ cp t.source, t.name
+end
+
+file 'base' do
+ touch 'base'
+end
+ DEFAULT
+ end
+
+ def rakefile_comments
+ rakefile <<-COMMENTS
+# comment for t1
+task :t1 do
+end
+
+# no comment or task because there's a blank line
+
+task :t2 do
+end
+
+desc "override comment for t3"
+# this is not the description
+multitask :t3 do
+end
+
+# this is not the description
+desc "override comment for t4"
+file :t4 do
+end
+ COMMENTS
+ end
+
+ def rakefile_default
+ rakefile <<-DEFAULT
+if ENV['TESTTOPSCOPE']
+ puts "TOPSCOPE"
+end
+
+task :default do
+ puts "DEFAULT"
+end
+
+task :other => [:default] do
+ puts "OTHER"
+end
+
+task :task_scope do
+ if ENV['TESTTASKSCOPE']
+ puts "TASKSCOPE"
+ end
+end
+ DEFAULT
+ end
+
+ def rakefile_dryrun
+ rakefile <<-DRYRUN
+task :default => ["temp_main"]
+
+file "temp_main" => [:all_apps] do touch "temp_main" end
+
+task :all_apps => [:one, :two]
+task :one => ["temp_one"]
+task :two => ["temp_two"]
+
+file "temp_one" do |t|
+ touch "temp_one"
+end
+file "temp_two" do |t|
+ touch "temp_two"
+end
+
+task :clean do
+ ["temp_one", "temp_two", "temp_main"].each do |file|
+ rm_f file
+ end
+end
+ DRYRUN
+
+ FileUtils.touch 'temp_main'
+ FileUtils.touch 'temp_two'
+ end
+
+ def rakefile_extra
+ rakefile 'task :default'
+
+ FileUtils.mkdir_p 'rakelib'
+
+ open File.join('rakelib', 'extra.rake'), 'w' do |io|
+ io << <<-EXTRA_RAKE
+# Added for testing
+
+namespace :extra do
+ desc "An Extra Task"
+ task :extra do
+ puts "Read all about it"
+ end
+end
+ EXTRA_RAKE
+ end
+ end
+
+ def rakefile_file_creation
+ rakefile <<-'FILE_CREATION'
+N = 2
+
+task :default => :run
+
+BUILD_DIR = 'build'
+task :clean do
+ rm_rf 'build'
+ rm_rf 'src'
+end
+
+task :run
+
+TARGET_DIR = 'build/copies'
+
+FileList['src/*'].each do |src|
+ directory TARGET_DIR
+ target = File.join TARGET_DIR, File.basename(src)
+ file target => [src, TARGET_DIR] do
+ cp src, target
+ # sleep 3 if src !~ /foo#{N-1}$/ # I'm commenting out this sleep, it doesn't seem to do anything.
+ end
+ task :run => target
+end
+
+task :prep => :clean do
+ mkdir_p 'src'
+ N.times do |n|
+ puts "DBG: Touching src/foo#{n}"
+ touch "src/foo#{n}"
+ end
+end
+ FILE_CREATION
+ end
+
+ def rakefile_imports
+ rakefile <<-IMPORTS
+require 'rake/loaders/makefile'
+
+task :default
+
+task :other do
+ puts "OTHER"
+end
+
+file "dynamic_deps" do |t|
+ open(t.name, "w") do |f| f.puts "puts 'DYNAMIC'" end
+end
+
+import "dynamic_deps"
+import "static_deps"
+import "static_deps"
+import "deps.mf"
+puts "FIRST"
+ IMPORTS
+
+ open 'deps.mf', 'w' do |io|
+ io << <<-DEPS
+default: other
+ DEPS
+ end
+
+ open "static_deps", "w" do |f|
+ f.puts 'puts "STATIC"'
+ end
+ end
+
+ def rakefile_multidesc
+ rakefile <<-MULTIDESC
+task :b
+
+desc "A"
+task :a
+
+desc "B"
+task :b
+
+desc "A2"
+task :a
+
+task :c
+
+desc "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
+task :d
+ MULTIDESC
+ end
+
+ def rakefile_namespace
+ rakefile <<-NAMESPACE
+desc "copy"
+task :copy do
+ puts "COPY"
+end
+
+namespace "nest" do
+ desc "nest copy"
+ task :copy do
+ puts "NEST COPY"
+ end
+ task :xx => :copy
+end
+
+anon_ns = namespace do
+ desc "anonymous copy task"
+ task :copy do
+ puts "ANON COPY"
+ end
+end
+
+desc "Top level task to run the anonymous version of copy"
+task :anon => anon_ns[:copy]
+
+namespace "very" do
+ namespace "nested" do
+ task "run" => "rake:copy"
+ end
+end
+
+namespace "a" do
+ desc "Run task in the 'a' namespace"
+ task "run" do
+ puts "IN A"
+ end
+end
+
+namespace "b" do
+ desc "Run task in the 'b' namespace"
+ task "run" => "a:run" do
+ puts "IN B"
+ end
+end
+
+namespace "file1" do
+ file "xyz.rb" do
+ puts "XYZ1"
+ end
+end
+
+namespace "file2" do
+ file "xyz.rb" do
+ puts "XYZ2"
+ end
+end
+
+namespace "scopedep" do
+ task :prepare do
+ touch "scopedep.rb"
+ puts "PREPARE"
+ end
+ file "scopedep.rb" => [:prepare] do
+ puts "SCOPEDEP"
+ end
+end
+ NAMESPACE
+ end
+
+ def rakefile_nosearch
+ FileUtils.touch 'dummy'
+ end
+
+ def rakefile_rakelib
+ FileUtils.mkdir_p 'rakelib'
+
+ Dir.chdir 'rakelib' do
+ open 'test1.rb', 'w' do |io|
+ io << <<-TEST1
+task :default do
+ puts "TEST1"
+end
+ TEST1
+ end
+
+ open 'test2.rake', 'w' do |io|
+ io << <<-TEST1
+task :default do
+ puts "TEST2"
+end
+ TEST1
+ end
+ end
+ end
+
+ def rakefile_rbext
+ open 'rakefile.rb', 'w' do |io|
+ io << 'task :default do puts "OK" end'
+ end
+ end
+
+ def rakefile_statusreturn
+ rakefile <<-STATUSRETURN
+task :exit5 do
+ exit(5)
+end
+
+task :normal do
+end
+ STATUSRETURN
+ end
+
+ def rakefile_unittest
+ rakefile '# Empty Rakefile for Unit Test'
+
+ readme = File.join 'subdir', 'README'
+ FileUtils.mkdir_p File.dirname readme
+
+ FileUtils.touch readme
+ end
+
+ def rakefile_verbose
+ rakefile <<-VERBOSE
+task :standalone_verbose_true do
+ verbose true
+ sh "ruby -e '0'"
+end
+
+task :standalone_verbose_false do
+ verbose false
+ sh "ruby -e '0'"
+end
+
+task :inline_verbose_default do
+ sh "ruby -e '0'"
+end
+
+task :inline_verbose_false do
+ sh "ruby -e '0'", :verbose => false
+end
+
+task :inline_verbose_true do
+ sh "ruby -e '0'", :verbose => true
+end
+
+task :block_verbose_true do
+ verbose(true) do
+ sh "ruby -e '0'"
+ end
+end
+
+task :block_verbose_false do
+ verbose(false) do
+ sh "ruby -e '0'"
+ end
+end
+ VERBOSE
+ end
+
+end
+
+# workarounds for 1.8
+$" << 'test/helper.rb'
+Test::Unit.run = true if Test::Unit.respond_to? :run=
+
diff --git a/test/rake/in_environment.rb b/test/rake/in_environment.rb
deleted file mode 100644
index f6fd8fb731..0000000000
--- a/test/rake/in_environment.rb
+++ /dev/null
@@ -1,30 +0,0 @@
-module InEnvironment
- private
-
- # Create an environment for a test. At the completion of the yielded
- # block, the environment is restored to its original conditions.
- def in_environment(settings)
- original_settings = set_env(settings)
- yield
- ensure
- set_env(original_settings) if original_settings
- end
-
- # Set the environment according to the settings hash.
- def set_env(settings) # :nodoc:
- result = {}
- settings.each do |k, v|
- result[k] = ENV[k]
- if k == 'PWD'
- result[k] = Dir.pwd
- Dir.chdir(v)
- elsif v.nil?
- ENV.delete(k)
- else
- ENV[k] = v
- end
- end
- result
- end
-
-end
diff --git a/test/rake/rake_test_setup.rb b/test/rake/rake_test_setup.rb
deleted file mode 100644
index de94d56b40..0000000000
--- a/test/rake/rake_test_setup.rb
+++ /dev/null
@@ -1,9 +0,0 @@
-# Common setup for all test files.
-
-# require 'flexmock/test_unit'
-
-module TestMethods
- def assert_exception(ex, msg=nil, &block)
- assert_raise(ex, msg, &block)
- end
-end
diff --git a/test/rake/reqfile.rb b/test/rake/reqfile.rb
deleted file mode 100644
index 5372544b66..0000000000
--- a/test/rake/reqfile.rb
+++ /dev/null
@@ -1,3 +0,0 @@
-# For --require testing
-
-TESTING_REQUIRE << 1
diff --git a/test/rake/reqfile2.rb b/test/rake/reqfile2.rb
deleted file mode 100644
index 65993907ac..0000000000
--- a/test/rake/reqfile2.rb
+++ /dev/null
@@ -1,3 +0,0 @@
-# For --require testing
-
-TESTING_REQUIRE << 2
diff --git a/test/rake/reqfile3.rb b/test/rake/reqfile3.rb
deleted file mode 100644
index 11fc16b2ab..0000000000
--- a/test/rake/reqfile3.rb
+++ /dev/null
@@ -1,3 +0,0 @@
-# For --require testing
-
-TESTING_REQUIRE << 3
diff --git a/test/rake/shellcommand.rb b/test/rake/shellcommand.rb
deleted file mode 100755
index 58db8a0871..0000000000
--- a/test/rake/shellcommand.rb
+++ /dev/null
@@ -1,3 +0,0 @@
-#!/usr/bin/env ruby
-
-exit((ARGV[0] || "0").to_i)
diff --git a/test/rake/test_application.rb b/test/rake/test_application.rb
deleted file mode 100644
index 27c7d8df05..0000000000
--- a/test/rake/test_application.rb
+++ /dev/null
@@ -1,687 +0,0 @@
-require 'test/unit'
-require 'rake'
-require_relative 'capture_stdout'
-require_relative 'in_environment'
-
-TESTING_REQUIRE = [ ]
-
-######################################################################
-class Rake::TestApplication < Test::Unit::TestCase
- include CaptureStdout
- include InEnvironment
- BASEDIR = File.dirname(__FILE__)
-
- def defmock(*names, &block)
- class << (@mock ||= Object.new); self; end.class_eval do
- names.each do |name|
- define_method(name, block)
- end
- end
- @mock
- end
-
- def setup
- @app = Rake::Application.new
- @app.options.rakelib = []
- end
-
- def test_constant_warning
- err = capture_stderr do @app.instance_eval { const_warning("Task") } end
- assert_match(/warning/i, err)
- assert_match(/deprecated/i, err)
- assert_match(/Task/i, err)
- end
-
- def test_display_tasks
- @app.options.show_task_pattern = //
- @app.last_description = "COMMENT"
- @app.define_task(Rake::Task, "t")
- out = capture_stdout do @app.instance_eval { display_tasks_and_comments } end
- assert_match(/^rake t/, out)
- assert_match(/# COMMENT/, out)
- end
-
- def test_display_tasks_with_long_comments
- in_environment('RAKE_COLUMNS' => '80') do
- @app.options.show_task_pattern = //
- @app.last_description = "1234567890" * 8
- @app.define_task(Rake::Task, "t")
- out = capture_stdout do @app.instance_eval { display_tasks_and_comments } end
- assert_match(/^rake t/, out)
- assert_match(/# 12345678901234567890123456789012345678901234567890123456789012345\.\.\./, out)
- end
- end
-
- def test_display_tasks_with_task_name_wider_than_tty_display
- in_environment('RAKE_COLUMNS' => '80') do
- @app.options.show_task_pattern = //
- description = "something short"
- task_name = "task name" * 80
- @app.last_description = "something short"
- @app.define_task(Rake::Task, task_name )
- out = capture_stdout do @app.instance_eval { display_tasks_and_comments } end
- # Ensure the entire task name is output and we end up showing no description
- assert_match(/rake #{task_name} # .../, out)
- end
- end
-
- def test_display_tasks_with_very_long_task_name_to_a_non_tty_shows_name_and_comment
- @app.options.show_task_pattern = //
- @app.tty_output = false
- description = "something short"
- task_name = "task name" * 80
- @app.last_description = "something short"
- @app.define_task(Rake::Task, task_name )
- out = capture_stdout do @app.instance_eval { display_tasks_and_comments } end
- # Ensure the entire task name is output and we end up showing no description
- assert_match(/rake #{task_name} # #{description}/, out)
- end
-
- def test_display_tasks_with_long_comments_to_a_non_tty_shows_entire_comment
- @app.options.show_task_pattern = //
- @app.tty_output = false
- @app.last_description = "1234567890" * 8
- @app.define_task(Rake::Task, "t")
- out = capture_stdout do @app.instance_eval { display_tasks_and_comments } end
- assert_match(/^rake t/, out)
- assert_match(/# #{@app.last_description}/, out)
- end
-
- def test_display_tasks_with_long_comments_to_a_non_tty_with_columns_set_truncates_comments
- in_environment("RAKE_COLUMNS" => '80') do
- @app.options.show_task_pattern = //
- @app.tty_output = false
- @app.last_description = "1234567890" * 8
- @app.define_task(Rake::Task, "t")
- out = capture_stdout do @app.instance_eval { display_tasks_and_comments } end
- assert_match(/^rake t/, out)
- assert_match(/# 12345678901234567890123456789012345678901234567890123456789012345\.\.\./, out)
- end
- end
-
- def test_display_tasks_with_full_descriptions
- @app.options.show_task_pattern = //
- @app.options.full_description = true
- @app.last_description = "COMMENT"
- @app.define_task(Rake::Task, "t")
- out = capture_stdout do @app.instance_eval { display_tasks_and_comments } end
- assert_match(/^rake t$/, out)
- assert_match(/^ {4}COMMENT$/, out)
- end
-
- def test_finding_rakefile
- in_environment("PWD" => File.join(BASEDIR, "data/unittest")) do
- assert_match(/Rakefile/i, @app.instance_eval { have_rakefile })
- end
- end
-
- def test_not_finding_rakefile
- @app.instance_eval { @rakefiles = ['NEVER_FOUND'] }
- assert( ! @app.instance_eval do have_rakefile end )
- assert_nil @app.rakefile
- end
-
- def test_load_rakefile
- in_environment("PWD" => File.join(BASEDIR, "data/unittest")) do
- @app.instance_eval do
- handle_options
- options.silent = true
- load_rakefile
- end
- assert_equal "rakefile", @app.rakefile.downcase
- assert_match(%r(unittest$), Dir.pwd)
- end
- end
-
- def test_load_rakefile_from_subdir
- in_environment("PWD" => File.join(BASEDIR, "data/unittest/subdir")) do
- @app.instance_eval do
- handle_options
- options.silent = true
- load_rakefile
- end
- assert_equal "rakefile", @app.rakefile.downcase
- assert_match(%r(unittest$), Dir.pwd)
- end
- end
-
- def test_load_rakefile_not_found
- in_environment("PWD" => "/", "RAKE_SYSTEM" => 'not_exist') do
- @app.instance_eval do
- handle_options
- options.silent = true
- end
- ex = assert_raise(RuntimeError) do
- @app.instance_eval do raw_load_rakefile end
- end
- assert_match(/no rakefile found/i, ex.message)
- end
- end
-
- def test_load_from_system_rakefile
- system_dir = File.expand_path('../data/default', __FILE__)
- in_environment('RAKE_SYSTEM' => system_dir) do
- @app.options.rakelib = []
- @app.instance_eval do
- handle_options
- options.silent = true
- options.load_system = true
- options.rakelib = []
- load_rakefile
- end
- assert_equal system_dir, @app.system_dir
- assert_nil @app.rakefile
- end
- end
-
- def test_windows
- assert ! (@app.windows? && @app.unix?)
- end
-
- def test_loading_imports
- args = []
- mock = defmock(:load) {|*a| args << a}
- @app.instance_eval do
- add_loader("dummy", mock)
- add_import("x.dummy")
- load_imports
- end
- assert_equal([["x.dummy"]], args)
- end
-
- def test_building_imported_files_on_demand
- args = []
- callback = false
- mock = defmock(:load) {|*a| args << a}
- @app.instance_eval do
- intern(Rake::Task, "x.dummy").enhance do callback = true end
- add_loader("dummy", mock)
- add_import("x.dummy")
- load_imports
- end
- assert_equal([["x.dummy"]], args)
- assert(callback)
- end
-
- def test_handle_options_should_strip_options_from_ARGV
- assert !@app.options.trace
-
- valid_option = '--trace'
- ARGV.clear
- ARGV << valid_option
-
- @app.handle_options
-
- assert !ARGV.include?(valid_option)
- assert @app.options.trace
- end
-
- def test_good_run
- ran = false
- ARGV.clear
- ARGV << '--rakelib=""'
- @app.options.silent = true
- @app.instance_eval do
- intern(Rake::Task, "default").enhance { ran = true }
- end
- in_environment("PWD" => File.join(BASEDIR, "data/default")) do
- @app.run
- end
- assert ran
- end
-
- def test_display_task_run
- ran = false
- ARGV.clear
- ARGV << '-f' << '-s' << '--tasks' << '--rakelib=""'
- @app.last_description = "COMMENT"
- @app.define_task(Rake::Task, "default")
- out = capture_stdout { @app.run }
- assert @app.options.show_tasks
- assert ! ran
- assert_match(/rake default/, out)
- assert_match(/# COMMENT/, out)
- end
-
- def test_display_prereqs
- ran = false
- ARGV.clear
- ARGV << '-f' << '-s' << '--prereqs' << '--rakelib=""'
- @app.last_description = "COMMENT"
- t = @app.define_task(Rake::Task, "default")
- t.enhance([:a, :b])
- @app.define_task(Rake::Task, "a")
- @app.define_task(Rake::Task, "b")
- out = capture_stdout { @app.run }
- assert @app.options.show_prereqs
- assert ! ran
- assert_match(/rake a$/, out)
- assert_match(/rake b$/, out)
- assert_match(/rake default\n( *(a|b)\n){2}/m, out)
- end
-
- def test_bad_run
- @app.intern(Rake::Task, "default").enhance { fail }
- ARGV.clear
- ARGV << '-f' << '-s' << '--rakelib=""'
- assert_raise(SystemExit) {
- err = capture_stderr { @app.run }
- assert_match(/see full trace/, err)
- }
- ensure
- ARGV.clear
- end
-
- def test_bad_run_with_trace
- @app.intern(Rake::Task, "default").enhance { fail }
- ARGV.clear
- ARGV << '-f' << '-s' << '-t'
- assert_raise(SystemExit) {
- err = capture_stderr { capture_stdout { @app.run } }
- assert_no_match(/see full trace/, err)
- }
- ensure
- ARGV.clear
- end
-
- def test_run_with_bad_options
- @app.intern(Rake::Task, "default").enhance { fail }
- ARGV.clear
- ARGV << '-f' << '-s' << '--xyzzy'
- assert_raise(SystemExit) {
- err = capture_stderr { capture_stdout { @app.run } }
- }
- ensure
- ARGV.clear
- end
-end
-
-
-######################################################################
-class Rake::TestApplicationOptions < Test::Unit::TestCase
- include CaptureStdout
-
- def setup
- clear_argv
- RakeFileUtils.verbose_flag = false
- RakeFileUtils.nowrite_flag = false
- TESTING_REQUIRE.clear
- end
-
- def teardown
- clear_argv
- RakeFileUtils.verbose_flag = false
- RakeFileUtils.nowrite_flag = false
- end
-
- def clear_argv
- while ! ARGV.empty?
- ARGV.pop
- end
- end
-
- def test_default_options
- opts = command_line
- assert_nil opts.classic_namespace
- assert_nil opts.dryrun
- assert_nil opts.full_description
- assert_nil opts.ignore_system
- assert_nil opts.load_system
- assert_nil opts.nosearch
- assert_equal ['rakelib'], opts.rakelib
- assert_nil opts.show_prereqs
- assert_nil opts.show_task_pattern
- assert_nil opts.show_tasks
- assert_nil opts.silent
- assert_nil opts.trace
- assert_equal ['rakelib'], opts.rakelib
- assert ! RakeFileUtils.verbose_flag
- assert ! RakeFileUtils.nowrite_flag
- end
-
- def test_dry_run
- flags('--dry-run', '-n') do |opts|
- assert opts.dryrun
- assert opts.trace
- assert RakeFileUtils.verbose_flag
- assert RakeFileUtils.nowrite_flag
- end
- end
-
- def test_describe
- flags('--describe') do |opts|
- assert opts.full_description
- assert opts.show_tasks
- assert_equal(//.to_s, opts.show_task_pattern.to_s)
- end
- end
-
- def test_describe_with_pattern
- flags('--describe=X') do |opts|
- assert opts.full_description
- assert opts.show_tasks
- assert_equal(/X/.to_s, opts.show_task_pattern.to_s)
- end
- end
-
- def test_execute
- $xyzzy = 0
- flags('--execute=$xyzzy=1', '-e $xyzzy=1') do |opts|
- assert_equal 1, $xyzzy
- assert_equal :exit, @exit
- $xyzzy = 0
- end
- end
-
- def test_execute_and_continue
- $xyzzy = 0
- flags('--execute-continue=$xyzzy=1', '-E $xyzzy=1') do |opts|
- assert_equal 1, $xyzzy
- assert_not_equal :exit, @exit
- $xyzzy = 0
- end
- end
-
- def test_execute_and_print
- $xyzzy = 0
- flags('--execute-print=$xyzzy="pugh"', '-p $xyzzy="pugh"') do |opts|
- assert_equal 'pugh', $xyzzy
- assert_equal :exit, @exit
- assert_match(/^pugh$/, @out)
- $xyzzy = 0
- end
- end
-
- def test_help
- flags('--help', '-H', '-h') do |opts|
- assert_match(/\Arake/, @out)
- assert_match(/\boptions\b/, @out)
- assert_match(/\btargets\b/, @out)
- assert_equal :exit, @exit
- assert_equal :exit, @exit
- end
- end
-
- def test_libdir
- flags(['--libdir', 'xx'], ['-I', 'xx'], ['-Ixx']) do |opts|
- $:.include?('xx')
- end
- ensure
- $:.delete('xx')
- end
-
- def test_rakefile
- flags(['--rakefile', 'RF'], ['--rakefile=RF'], ['-f', 'RF'], ['-fRF']) do |opts|
- assert_equal ['RF'], @app.instance_eval { @rakefiles }
- end
- end
-
- def test_rakelib
- flags(['--rakelibdir', 'A:B:C'], ['--rakelibdir=A:B:C'], ['-R', 'A:B:C'], ['-RA:B:C']) do |opts|
- assert_equal ['A', 'B', 'C'], opts.rakelib
- end
- end
-
- def test_require
- flags(['--require', File.expand_path('../reqfile', __FILE__)],
- "-r#{File.expand_path('../reqfile2', __FILE__)}",
- "-r#{File.expand_path('../reqfile3', __FILE__)}") do |opts|
- end
- assert TESTING_REQUIRE.include?(1)
- assert TESTING_REQUIRE.include?(2)
- assert TESTING_REQUIRE.include?(3)
- assert_equal 3, TESTING_REQUIRE.size
- end
-
- def test_missing_require
- ex = assert_raise(LoadError) do
- flags(['--require', File.expand_path('../missing', __FILE__)]) do |opts|
- end
- end
- assert_match(/cannot load such file/, ex.message)
- assert_match(/#{File.basename(File.dirname(__FILE__))}\/missing/, ex.message)
- end
-
- def test_prereqs
- flags('--prereqs', '-P') do |opts|
- assert opts.show_prereqs
- end
- end
-
- def test_quiet
- flags('--quiet', '-q') do |opts|
- assert ! RakeFileUtils.verbose_flag
- assert ! opts.silent
- end
- end
-
- def test_no_search
- flags('--nosearch', '--no-search', '-N') do |opts|
- assert opts.nosearch
- end
- end
-
- def test_silent
- flags('--silent', '-s') do |opts|
- assert ! RakeFileUtils.verbose_flag
- assert opts.silent
- end
- end
-
- def test_system
- flags('--system', '-g') do |opts|
- assert opts.load_system
- end
- end
-
- def test_no_system
- flags('--no-system', '-G') do |opts|
- assert opts.ignore_system
- end
- end
-
- def test_trace
- flags('--trace', '-t') do |opts|
- assert opts.trace
- assert RakeFileUtils.verbose_flag
- assert ! RakeFileUtils.nowrite_flag
- end
- end
-
- def test_trace_rules
- flags('--rules') do |opts|
- assert opts.trace_rules
- end
- end
-
- def test_tasks
- flags('--tasks', '-T') do |opts|
- assert opts.show_tasks
- assert_equal(//.to_s, opts.show_task_pattern.to_s)
- end
- flags(['--tasks', 'xyz'], ['-Txyz']) do |opts|
- assert opts.show_tasks
- assert_equal(/xyz/, opts.show_task_pattern)
- end
- end
-
- def test_verbose
- flags('--verbose', '-V') do |opts|
- assert RakeFileUtils.verbose_flag
- assert ! opts.silent
- end
- end
-
- def test_version
- flags('--version', '-V') do |opts|
- assert_match(/\bversion\b/, @out)
- assert_match(/\b#{RAKEVERSION}\b/, @out)
- assert_equal :exit, @exit
- end
- end
-
- def test_classic_namespace
- flags(['--classic-namespace'], ['-C', '-T', '-P', '-n', '-s', '-t']) do |opts|
- assert opts.classic_namespace
- assert_equal opts.show_tasks, $show_tasks
- assert_equal opts.show_prereqs, $show_prereqs
- assert_equal opts.trace, $trace
- assert_equal opts.dryrun, $dryrun
- assert_equal opts.silent, $silent
- end
- end
-
- def test_bad_option
- capture_stderr do
- ex = assert_raise(OptionParser::InvalidOption) do
- flags('--bad-option')
- end
- if ex.message =~ /^While/ # Ruby 1.9 error message
- assert_match(/while parsing/i, ex.message)
- else # Ruby 1.8 error message
- assert_match(/(invalid|unrecognized) option/i, ex.message)
- assert_match(/--bad-option/, ex.message)
- end
- end
- end
-
- def test_task_collection
- command_line("a", "b")
- assert_equal ["a", "b"], @tasks.sort
- end
-
- def test_default_task_collection
- command_line()
- assert_equal ["default"], @tasks
- end
-
- def test_environment_definition
- ENV.delete('TESTKEY')
- command_line("a", "TESTKEY=12")
- assert_equal ["a"], @tasks.sort
- assert '12', ENV['TESTKEY']
- end
-
- private
-
- def flags(*sets)
- sets.each do |set|
- ARGV.clear
- @out = capture_stdout {
- @exit = catch(:system_exit) { opts = command_line(*set) }
- }
- yield(@app.options) if block_given?
- end
- end
-
- def command_line(*options)
- options.each do |opt| ARGV << opt end
- @app = Rake::Application.new
- def @app.exit(*args)
- throw :system_exit, :exit
- end
- @app.instance_eval do
- handle_options
- collect_tasks
- end
- @tasks = @app.top_level_tasks
- @app.options
- end
-end
-
-class Rake::TestTaskArgumentParsing < Test::Unit::TestCase
- def setup
- @app = Rake::Application.new
- end
-
- def test_name_only
- name, args = @app.parse_task_string("name")
- assert_equal "name", name
- assert_equal [], args
- end
-
- def test_empty_args
- name, args = @app.parse_task_string("name[]")
- assert_equal "name", name
- assert_equal [], args
- end
-
- def test_one_argument
- name, args = @app.parse_task_string("name[one]")
- assert_equal "name", name
- assert_equal ["one"], args
- end
-
- def test_two_arguments
- name, args = @app.parse_task_string("name[one,two]")
- assert_equal "name", name
- assert_equal ["one", "two"], args
- end
-
- def test_can_handle_spaces_between_args
- name, args = @app.parse_task_string("name[one, two,\tthree , \tfour]")
- assert_equal "name", name
- assert_equal ["one", "two", "three", "four"], args
- end
-
- def test_keeps_embedded_spaces
- name, args = @app.parse_task_string("name[a one ana, two]")
- assert_equal "name", name
- assert_equal ["a one ana", "two"], args
- end
-
-end
-
-class Rake::TestTaskArgumentParsing < Test::Unit::TestCase
- include InEnvironment
-
- def test_terminal_width_using_env
- app = Rake::Application.new
- in_environment('RAKE_COLUMNS' => '1234') do
- assert_equal 1234, app.terminal_width
- end
- end
-
- def test_terminal_width_using_stty
- app = Rake::Application.new
- def app.unix?() true end
- def app.dynamic_width_stty() 1235 end
- def app.dynamic_width_tput() 0 end
- in_environment('RAKE_COLUMNS' => nil) do
- assert_equal 1235, app.terminal_width
- end
- end
-
- def test_terminal_width_using_tput
- app = Rake::Application.new
- def app.unix?() true end
- def app.dynamic_width_stty() 0 end
- def app.dynamic_width_tput() 1236 end
- in_environment('RAKE_COLUMNS' => nil) do
- assert_equal 1236, app.terminal_width
- end
- end
-
- def test_terminal_width_using_hardcoded_80
- app = Rake::Application.new
- def app.unix?() false end
- in_environment('RAKE_COLUMNS' => nil) do
- assert_equal 80, app.terminal_width
- end
- end
-
- def test_terminal_width_with_failure
- app = Rake::Application.new
- called = false
- class << app; self; end.class_eval do
- define_method(:unix?) {|*a|
- called = a
- raise RuntimeError
- }
- end
- in_environment('RAKE_COLUMNS' => nil) do
- assert_equal 80, app.terminal_width
- end
- assert_equal([], called)
- end
-end
diff --git a/test/rake/test_invocation_chain.rb b/test/rake/test_invocation_chain.rb
deleted file mode 100644
index 2b06493773..0000000000
--- a/test/rake/test_invocation_chain.rb
+++ /dev/null
@@ -1,75 +0,0 @@
-require 'test/unit'
-require 'rake'
-
-######################################################################
-class Rake::TestAnEmptyInvocationChain < Test::Unit::TestCase
-
- def setup
- @empty = Rake::InvocationChain::EMPTY
- end
-
- def test_should_be_able_to_add_members
- assert_nothing_raised do
- @empty.append("A")
- end
- end
-
- def test_to_s
- assert_equal "TOP", @empty.to_s
- end
-end
-
-######################################################################
-class Rake::TestAnInvocationChainWithOneMember < Test::Unit::TestCase
-
- def setup
- @empty = Rake::InvocationChain::EMPTY
- @first_member = "A"
- @chain = @empty.append(@first_member)
- end
-
- def test_should_report_first_member_as_a_member
- assert @chain.member?(@first_member)
- end
-
- def test_should_fail_when_adding_original_member
- ex = assert_raise RuntimeError do
- @chain.append(@first_member)
- end
- assert_match(/circular +dependency/i, ex.message)
- assert_match(/A.*=>.*A/, ex.message)
- end
-
- def test_to_s
- assert_equal "TOP => A", @chain.to_s
- end
-
-end
-
-######################################################################
-class Rake::TestAnInvocationChainWithMultipleMember < Test::Unit::TestCase
-
- def setup
- @first_member = "A"
- @second_member = "B"
- ch = Rake::InvocationChain::EMPTY.append(@first_member)
- @chain = ch.append(@second_member)
- end
-
- def test_should_report_first_member_as_a_member
- assert @chain.member?(@first_member)
- end
-
- def test_should_report_second_member_as_a_member
- assert @chain.member?(@second_member)
- end
-
- def test_should_fail_when_adding_original_member
- ex = assert_raise RuntimeError do
- @chain.append(@first_member)
- end
- assert_match(/A.*=>.*B.*=>.*A/, ex.message)
- end
-end
-
-
diff --git a/test/rake/test_package_task.rb b/test/rake/test_package_task.rb
deleted file mode 100644
index 0ed20e42c0..0000000000
--- a/test/rake/test_package_task.rb
+++ /dev/null
@@ -1,115 +0,0 @@
-require 'tmpdir'
-require 'fileutils'
-require 'test/unit'
-require 'rake/packagetask'
-
-class Rake::TestPackageTask < Test::Unit::TestCase
- include Rake
-
- def test_create
- pwd = Dir.pwd
- tmpdir = Dir.mktmpdir("rake")
- Dir.chdir(tmpdir)
- Dir.mkdir("bin")
- open("bin/rake", "wb") {}
- pkg = Rake::PackageTask.new("pkgr", "1.2.3") { |p|
- p.package_files << "install.rb"
- p.package_files.include(
- '[A-Z]*',
- 'bin/**/*',
- 'lib/**/*.rb',
- 'test/**/*.rb',
- 'doc/**/*',
- 'build/rubyapp.rb',
- '*.blurb')
- p.package_files.exclude(/\bCVS\b/)
- p.package_files.exclude(/~$/)
- p.package_dir = 'pkg'
- p.need_tar = true
- p.need_tar_gz = true
- p.need_tar_bz2 = true
- p.need_zip = true
- }
- assert_equal "pkg", pkg.package_dir
- assert pkg.package_files.include?("bin/rake")
- assert "pkgr", pkg.name
- assert "1.2.3", pkg.version
- assert Task[:package]
- assert Task['pkg/pkgr-1.2.3.tgz']
- assert Task['pkg/pkgr-1.2.3.tar.gz']
- assert Task['pkg/pkgr-1.2.3.tar.bz2']
- assert Task['pkg/pkgr-1.2.3.zip']
- assert Task["pkg/pkgr-1.2.3"]
- assert Task[:clobber_package]
- assert Task[:repackage]
- ensure
- Dir.chdir(pwd)
- FileUtils.rm_rf(tmpdir)
- end
-
- def test_missing_version
- assert_raise(RuntimeError) {
- pkg = Rake::PackageTask.new("pkgr") { |p| }
- }
- end
-
- def test_no_version
- pkg = Rake::PackageTask.new("pkgr", :noversion) { |p| }
- assert "pkgr", pkg.send(:package_name)
- end
-
- def test_clone
- pkg = Rake::PackageTask.new("x", :noversion)
- p2 = pkg.clone
- pkg.package_files << "y"
- p2.package_files << "x"
- assert_equal ["y"], pkg.package_files
- assert_equal ["x"], p2.package_files
- end
-end
-
-
-require 'rake/gempackagetask'
-
-class Rake::TestGemPackageTask < Test::Unit::TestCase
- def test_gem_package
- gem = Gem::Specification.new do |g|
- g.name = "pkgr"
- g.version = "1.2.3"
- g.files = FileList["x"].resolve
- end
- pkg = Rake::GemPackageTask.new(gem) do |p|
- p.package_files << "y"
- end
- assert_equal ["x", "y"], pkg.package_files
- assert_equal "pkgr-1.2.3.gem", pkg.gem_file
- end
-
- def test_gem_package_with_current_platform
- gem = Gem::Specification.new do |g|
- g.name = "pkgr"
- g.version = "1.2.3"
- g.files = FileList["x"].resolve
- g.platform = Gem::Platform::CURRENT
- end
- pkg = Rake::GemPackageTask.new(gem) do |p|
- p.package_files << "y"
- end
- assert_equal ["x", "y"], pkg.package_files
- assert_match(/^pkgr-1\.2\.3-(\S+)\.gem$/, pkg.gem_file)
- end
-
- def test_gem_package_with_ruby_platform
- gem = Gem::Specification.new do |g|
- g.name = "pkgr"
- g.version = "1.2.3"
- g.files = FileList["x"].resolve
- g.platform = Gem::Platform::RUBY
- end
- pkg = Rake::GemPackageTask.new(gem) do |p|
- p.package_files << "y"
- end
- assert_equal ["x", "y"], pkg.package_files
- assert_equal "pkgr-1.2.3.gem", pkg.gem_file
- end
-end
diff --git a/test/rake/test_rake.rb b/test/rake/test_rake.rb
index 44fecee559..b2a3928b26 100644
--- a/test/rake/test_rake.rb
+++ b/test/rake/test_rake.rb
@@ -1,7 +1,6 @@
-require 'test/unit'
-require 'rake'
+require File.expand_path('../helper', __FILE__)
-class Rake::TestRake < Test::Unit::TestCase
+class TestRake < Rake::TestCase
def test_each_dir_parent
assert_equal ['a'], alldirs('a')
assert_equal ['a/b', 'a'], alldirs('a/b')
@@ -27,13 +26,15 @@ class Rake::TestRake < Test::Unit::TestCase
old_app = Rake.application
fake_app = Object.new
Rake.application = fake_app
+
assert_equal fake_app, Rake.application
+
ensure
Rake.application = old_app
end
def test_original_dir_reports_current_dir
- assert_equal Dir.pwd, Rake.original_dir
+ assert_equal @tempdir, Rake.original_dir
end
end
diff --git a/test/rake/test_rake_application.rb b/test/rake/test_rake_application.rb
new file mode 100644
index 0000000000..c030c30292
--- /dev/null
+++ b/test/rake/test_rake_application.rb
@@ -0,0 +1,403 @@
+require File.expand_path('../helper', __FILE__)
+
+class TestRakeApplication < Rake::TestCase
+
+ def setup
+ super
+
+ @app = Rake.application
+ @app.options.rakelib = []
+ end
+
+ def test_constant_warning
+ _, err = capture_io do @app.instance_eval { const_warning("Task") } end
+ assert_match(/warning/i, err)
+ assert_match(/deprecated/i, err)
+ assert_match(/Task/i, err)
+ end
+
+ def test_display_tasks
+ @app.options.show_tasks = :tasks
+ @app.options.show_task_pattern = //
+ @app.last_description = "COMMENT"
+ @app.define_task(Rake::Task, "t")
+ out, = capture_io do @app.instance_eval { display_tasks_and_comments } end
+ assert_match(/^rake t/, out)
+ assert_match(/# COMMENT/, out)
+ end
+
+ def test_display_tasks_with_long_comments
+ @app.terminal_columns = 80
+ @app.options.show_tasks = :tasks
+ @app.options.show_task_pattern = //
+ @app.last_description = "1234567890" * 8
+ @app.define_task(Rake::Task, "t")
+
+ out, = capture_io do @app.instance_eval { display_tasks_and_comments } end
+
+ assert_match(/^rake t/, out)
+ assert_match(/# 12345678901234567890123456789012345678901234567890123456789012345\.\.\./, out)
+ end
+
+ def test_display_tasks_with_task_name_wider_than_tty_display
+ @app.terminal_columns = 80
+ @app.options.show_tasks = :tasks
+ @app.options.show_task_pattern = //
+ task_name = "task name" * 80
+ @app.last_description = "something short"
+ @app.define_task(Rake::Task, task_name )
+
+ out, = capture_io do @app.instance_eval { display_tasks_and_comments } end
+
+ # Ensure the entire task name is output and we end up showing no description
+ assert_match(/rake #{task_name} # .../, out)
+ end
+
+ def test_display_tasks_with_very_long_task_name_to_a_non_tty_shows_name_and_comment
+ @app.options.show_tasks = :tasks
+ @app.options.show_task_pattern = //
+ @app.tty_output = false
+ description = "something short"
+ task_name = "task name" * 80
+ @app.last_description = "something short"
+ @app.define_task(Rake::Task, task_name )
+
+ out, = capture_io do @app.instance_eval { display_tasks_and_comments } end
+
+ # Ensure the entire task name is output and we end up showing no description
+ assert_match(/rake #{task_name} # #{description}/, out)
+ end
+
+ def test_display_tasks_with_long_comments_to_a_non_tty_shows_entire_comment
+ @app.options.show_tasks = :tasks
+ @app.options.show_task_pattern = //
+ @app.tty_output = false
+ @app.last_description = "1234567890" * 8
+ @app.define_task(Rake::Task, "t")
+ out, = capture_io do @app.instance_eval { display_tasks_and_comments } end
+ assert_match(/^rake t/, out)
+ assert_match(/# #{@app.last_description}/, out)
+ end
+
+ def test_display_tasks_with_long_comments_to_a_non_tty_with_columns_set_truncates_comments
+ @app.terminal_columns = 80
+ @app.options.show_tasks = :tasks
+ @app.options.show_task_pattern = //
+ @app.tty_output = false
+ @app.last_description = "1234567890" * 8
+ @app.define_task(Rake::Task, "t")
+
+ out, = capture_io do @app.instance_eval { display_tasks_and_comments } end
+
+ assert_match(/^rake t/, out)
+ assert_match(/# 12345678901234567890123456789012345678901234567890123456789012345\.\.\./, out)
+ end
+
+ def test_describe_tasks
+ @app.options.show_tasks = :describe
+ @app.options.show_task_pattern = //
+ @app.last_description = "COMMENT"
+ @app.define_task(Rake::Task, "t")
+ out, = capture_io do @app.instance_eval { display_tasks_and_comments } end
+ assert_match(/^rake t$/, out)
+ assert_match(/^ {4}COMMENT$/, out)
+ end
+
+ def test_show_lines
+ @app.options.show_tasks = :lines
+ @app.options.show_task_pattern = //
+ @app.last_description = "COMMENT"
+ @app.define_task(Rake::Task, "t")
+ @app['t'].locations << "HERE:1"
+ out, = capture_io do @app.instance_eval { display_tasks_and_comments } end
+ assert_match(/^rake t +[^:]+:\d+ *$/, out)
+ end
+
+ def test_finding_rakefile
+ rakefile_default
+
+ assert_match(/Rakefile/i, @app.instance_eval { have_rakefile })
+ end
+
+ def test_not_finding_rakefile
+ @app.instance_eval { @rakefiles = ['NEVER_FOUND'] }
+ assert( ! @app.instance_eval do have_rakefile end )
+ assert_nil @app.rakefile
+ end
+
+ def test_load_rakefile
+ rakefile_unittest
+
+ @app.instance_eval do
+ handle_options
+ options.silent = true
+ load_rakefile
+ end
+
+ assert_equal "rakefile", @app.rakefile.downcase
+ assert_equal @tempdir, Dir.pwd
+ end
+
+ def test_load_rakefile_doesnt_print_rakefile_directory_from_same_dir
+ rakefile_unittest
+
+ _, err = capture_io do
+ @app.instance_eval do
+ # pretend we started from the unittest dir
+ @original_dir = File.expand_path(".")
+ raw_load_rakefile
+ end
+ end
+
+ assert_empty err
+ end
+
+ def test_load_rakefile_from_subdir
+ rakefile_unittest
+ Dir.chdir 'subdir'
+
+ @app.instance_eval do
+ handle_options
+ options.silent = true
+ load_rakefile
+ end
+
+ assert_equal "rakefile", @app.rakefile.downcase
+ assert_equal @tempdir, Dir.pwd
+ end
+
+ def test_load_rakefile_prints_rakefile_directory_from_subdir
+ rakefile_unittest
+ Dir.chdir 'subdir'
+
+ app = Rake::Application.new
+ app.options.rakelib = []
+
+ _, err = capture_io do
+ app.instance_eval do
+ raw_load_rakefile
+ end
+ end
+
+ assert_equal "(in #{@tempdir}\)\n", err
+ end
+
+ def test_load_rakefile_doesnt_print_rakefile_directory_from_subdir_if_silent
+ rakefile_unittest
+ Dir.chdir 'subdir'
+
+ _, err = capture_io do
+ @app.instance_eval do
+ handle_options
+ options.silent = true
+ raw_load_rakefile
+ end
+ end
+
+ assert_empty err
+ end
+
+ def test_load_rakefile_not_found
+ Dir.chdir @tempdir
+ ENV['RAKE_SYSTEM'] = 'not_exist'
+
+ @app.instance_eval do
+ handle_options
+ options.silent = true
+ end
+
+ ex = assert_raises(RuntimeError) do
+ @app.instance_eval do raw_load_rakefile end
+ end
+
+ assert_match(/no rakefile found/i, ex.message)
+ end
+
+ def test_load_from_system_rakefile
+ rake_system_dir
+
+ @app.instance_eval do
+ handle_options
+ options.silent = true
+ options.load_system = true
+ options.rakelib = []
+ load_rakefile
+ end
+
+ assert_equal @system_dir, @app.system_dir
+ assert_nil @app.rakefile
+ rescue SystemExit
+ flunk 'failed to load rakefile'
+ end
+
+ def test_load_from_calculated_system_rakefile
+ rakefile_default
+ flexmock(@app, :standard_system_dir => "__STD_SYS_DIR__")
+
+ ENV['RAKE_SYSTEM'] = nil
+
+ @app.instance_eval do
+ handle_options
+ options.silent = true
+ options.load_system = true
+ options.rakelib = []
+ load_rakefile
+ end
+
+ assert_equal "__STD_SYS_DIR__", @app.system_dir
+ rescue SystemExit
+ flunk 'failed to find system rakefile'
+ end
+
+ def test_terminal_columns
+ old_RAKE_COLUMNS = ENV['RAKE_COLUMNS']
+
+ ENV['RAKE_COLUMNS'] = '42'
+
+ app = Rake::Application.new
+
+ assert_equal 42, app.terminal_columns
+ ensure
+ if old_RAKE_COLUMNS then
+ ENV['RAKE_COLUMNS'].delete
+ else
+ ENV['RAKE_COLUMNS'] = old_RAKE_COLUMNS
+ end
+ end
+
+ def test_windows
+ assert ! (@app.windows? && @app.unix?)
+ end
+
+ def test_loading_imports
+ mock = flexmock("loader")
+ mock.should_receive(:load).with("x.dummy").once
+ @app.instance_eval do
+ add_loader("dummy", mock)
+ add_import("x.dummy")
+ load_imports
+ end
+ end
+
+ def test_building_imported_files_on_demand
+ mock = flexmock("loader")
+ mock.should_receive(:load).with("x.dummy").once
+ mock.should_receive(:make_dummy).with_no_args.once
+ @app.instance_eval do
+ intern(Rake::Task, "x.dummy").enhance do mock.make_dummy end
+ add_loader("dummy", mock)
+ add_import("x.dummy")
+ load_imports
+ end
+ end
+
+ def test_handle_options_should_strip_options_from_ARGV
+ assert !@app.options.trace
+
+ valid_option = '--trace'
+ ARGV.clear
+ ARGV << valid_option
+
+ @app.handle_options
+
+ assert !ARGV.include?(valid_option)
+ assert @app.options.trace
+ end
+
+ def test_good_run
+ ran = false
+
+ ARGV << '--rakelib=""'
+
+ @app.options.silent = true
+
+ @app.instance_eval do
+ intern(Rake::Task, "default").enhance { ran = true }
+ end
+
+ rakefile_default
+
+ out, err = capture_io do
+ @app.run
+ end
+
+ assert ran
+ assert_empty err
+ assert_equal "DEFAULT\n", out
+ end
+
+ def test_display_task_run
+ ran = false
+ ARGV.clear
+ ARGV << '-f' << '-s' << '--tasks' << '--rakelib=""'
+ @app.last_description = "COMMENT"
+ @app.define_task(Rake::Task, "default")
+ out, = capture_io { @app.run }
+ assert @app.options.show_tasks
+ assert ! ran
+ assert_match(/rake default/, out)
+ assert_match(/# COMMENT/, out)
+ end
+
+ def test_display_prereqs
+ ran = false
+ ARGV.clear
+ ARGV << '-f' << '-s' << '--prereqs' << '--rakelib=""'
+ @app.last_description = "COMMENT"
+ t = @app.define_task(Rake::Task, "default")
+ t.enhance([:a, :b])
+ @app.define_task(Rake::Task, "a")
+ @app.define_task(Rake::Task, "b")
+ out, = capture_io { @app.run }
+ assert @app.options.show_prereqs
+ assert ! ran
+ assert_match(/rake a$/, out)
+ assert_match(/rake b$/, out)
+ assert_match(/rake default\n( *(a|b)\n){2}/m, out)
+ end
+
+ def test_bad_run
+ @app.intern(Rake::Task, "default").enhance { fail }
+ ARGV.clear
+ ARGV << '-f' << '-s' << '--rakelib=""'
+ assert_raises(SystemExit) {
+ _, err = capture_io { @app.run }
+ assert_match(/see full trace/, err)
+ }
+ ensure
+ ARGV.clear
+ end
+
+ def test_bad_run_with_trace
+ @app.intern(Rake::Task, "default").enhance { fail }
+ ARGV.clear
+ ARGV << '-f' << '-s' << '-t'
+ assert_raises(SystemExit) {
+ _, err = capture_io { @app.run }
+ refute_match(/see full trace/, err)
+ }
+ ensure
+ ARGV.clear
+ end
+
+ def test_run_with_bad_options
+ @app.intern(Rake::Task, "default").enhance { fail }
+ ARGV.clear
+ ARGV << '-f' << '-s' << '--xyzzy'
+ assert_raises(SystemExit) {
+ capture_io { @app.run }
+ }
+ ensure
+ ARGV.clear
+ end
+
+ def test_deprecation_message
+ _, err = capture_io do
+ @app.deprecate("a", "b", "c")
+ end
+ assert_match(/'a' is deprecated/i, err)
+ assert_match(/use 'b' instead/i, err)
+ assert_match(/at c$/i, err)
+ end
+end
+
diff --git a/test/rake/test_rake_application_options.rb b/test/rake/test_rake_application_options.rb
new file mode 100644
index 0000000000..c1471f443e
--- /dev/null
+++ b/test/rake/test_rake_application_options.rb
@@ -0,0 +1,335 @@
+require File.expand_path('../helper', __FILE__)
+
+TESTING_REQUIRE = [ ]
+
+class TestRakeApplicationOptions < Rake::TestCase
+
+ def setup
+ super
+
+ clear_argv
+ Rake::FileUtilsExt.verbose_flag = false
+ Rake::FileUtilsExt.nowrite_flag = false
+ TESTING_REQUIRE.clear
+ end
+
+ def teardown
+ clear_argv
+ Rake::FileUtilsExt.verbose_flag = false
+ Rake::FileUtilsExt.nowrite_flag = false
+
+ super
+ end
+
+ def clear_argv
+ while ! ARGV.empty?
+ ARGV.pop
+ end
+ end
+
+ def test_default_options
+ opts = command_line
+ assert_nil opts.classic_namespace
+ assert_nil opts.dryrun
+ assert_nil opts.ignore_system
+ assert_nil opts.load_system
+ assert_nil opts.nosearch
+ assert_equal ['rakelib'], opts.rakelib
+ assert_nil opts.show_prereqs
+ assert_nil opts.show_task_pattern
+ assert_nil opts.show_tasks
+ assert_nil opts.silent
+ assert_nil opts.trace
+ assert_equal ['rakelib'], opts.rakelib
+ assert ! Rake::FileUtilsExt.verbose_flag
+ assert ! Rake::FileUtilsExt.nowrite_flag
+ end
+
+ def test_dry_run
+ flags('--dry-run', '-n') do |opts|
+ assert opts.dryrun
+ assert opts.trace
+ assert Rake::FileUtilsExt.verbose_flag
+ assert Rake::FileUtilsExt.nowrite_flag
+ end
+ end
+
+ def test_describe
+ flags('--describe') do |opts|
+ assert_equal :describe, opts.show_tasks
+ assert_equal(//.to_s, opts.show_task_pattern.to_s)
+ end
+ end
+
+ def test_describe_with_pattern
+ flags('--describe=X') do |opts|
+ assert_equal :describe, opts.show_tasks
+ assert_equal(/X/.to_s, opts.show_task_pattern.to_s)
+ end
+ end
+
+ def test_execute
+ $xyzzy = 0
+ flags('--execute=$xyzzy=1', '-e $xyzzy=1') do |opts|
+ assert_equal 1, $xyzzy
+ assert_equal :exit, @exit
+ $xyzzy = 0
+ end
+ end
+
+ def test_execute_and_continue
+ $xyzzy = 0
+ flags('--execute-continue=$xyzzy=1', '-E $xyzzy=1') do |opts|
+ assert_equal 1, $xyzzy
+ refute_equal :exit, @exit
+ $xyzzy = 0
+ end
+ end
+
+ def test_execute_and_print
+ $xyzzy = 0
+ out, = capture_io do
+ flags('--execute-print=$xyzzy="pugh"', '-p $xyzzy="pugh"') do |opts|
+ assert_equal 'pugh', $xyzzy
+ assert_equal :exit, @exit
+ $xyzzy = 0
+ end
+ end
+
+ assert_match(/^pugh$/, out)
+ end
+
+ def test_help
+ out, = capture_io do
+ flags '--help', '-H', '-h'
+ end
+
+ assert_match(/\Arake/, out)
+ assert_match(/\boptions\b/, out)
+ assert_match(/\btargets\b/, out)
+ assert_equal :exit, @exit
+ end
+
+ def test_libdir
+ flags(['--libdir', 'xx'], ['-I', 'xx'], ['-Ixx']) do |opts|
+ $:.include?('xx')
+ end
+ ensure
+ $:.delete('xx')
+ end
+
+ def test_rakefile
+ flags(['--rakefile', 'RF'], ['--rakefile=RF'], ['-f', 'RF'], ['-fRF']) do |opts|
+ assert_equal ['RF'], @app.instance_eval { @rakefiles }
+ end
+ end
+
+ def test_rakelib
+ flags(['--rakelibdir', 'A:B:C'], ['--rakelibdir=A:B:C'], ['-R', 'A:B:C'], ['-RA:B:C']) do |opts|
+ assert_equal ['A', 'B', 'C'], opts.rakelib
+ end
+ end
+
+ def test_require
+ $LOAD_PATH.unshift @tempdir
+
+ open 'reqfile.rb', 'w' do |io| io << 'TESTING_REQUIRE << 1' end
+ open 'reqfile2.rb', 'w' do |io| io << 'TESTING_REQUIRE << 2' end
+ open 'reqfile3.rake', 'w' do |io| io << 'TESTING_REQUIRE << 3' end
+
+ flags(['--require', 'reqfile'], '-rreqfile2', '-rreqfile3')
+
+ assert_includes TESTING_REQUIRE, 1
+ assert_includes TESTING_REQUIRE, 2
+ assert_includes TESTING_REQUIRE, 3
+
+ assert_equal 3, TESTING_REQUIRE.size
+ ensure
+ $LOAD_PATH.delete @tempdir
+ end
+
+ def test_missing_require
+ ex = assert_raises(LoadError) do
+ flags(['--require', 'test/missing']) do |opts|
+ end
+ end
+ assert_match(/such file/, ex.message)
+ assert_match(/test\/missing/, ex.message)
+ end
+
+ def test_prereqs
+ flags('--prereqs', '-P') do |opts|
+ assert opts.show_prereqs
+ end
+ end
+
+ def test_quiet
+ flags('--quiet', '-q') do |opts|
+ assert ! Rake::FileUtilsExt.verbose_flag
+ assert ! opts.silent
+ end
+ end
+
+ def test_no_search
+ flags('--nosearch', '--no-search', '-N') do |opts|
+ assert opts.nosearch
+ end
+ end
+
+ def test_silent
+ flags('--silent', '-s') do |opts|
+ assert ! Rake::FileUtilsExt.verbose_flag
+ assert opts.silent
+ end
+ end
+
+ def test_system
+ flags('--system', '-g') do |opts|
+ assert opts.load_system
+ end
+ end
+
+ def test_no_system
+ flags('--no-system', '-G') do |opts|
+ assert opts.ignore_system
+ end
+ end
+
+ def test_trace
+ flags('--trace', '-t') do |opts|
+ assert opts.trace
+ assert Rake::FileUtilsExt.verbose_flag
+ assert ! Rake::FileUtilsExt.nowrite_flag
+ end
+ end
+
+ def test_trace_rules
+ flags('--rules') do |opts|
+ assert opts.trace_rules
+ end
+ end
+
+ def test_tasks
+ flags('--tasks', '-T') do |opts|
+ assert_equal :tasks, opts.show_tasks
+ assert_equal(//.to_s, opts.show_task_pattern.to_s)
+ end
+ flags(['--tasks', 'xyz'], ['-Txyz']) do |opts|
+ assert_equal :tasks, opts.show_tasks
+ assert_equal(/xyz/.to_s, opts.show_task_pattern.to_s)
+ end
+ end
+
+ def test_where
+ flags('--where', '-W') do |opts|
+ assert_equal :lines, opts.show_tasks
+ assert_equal(//.to_s, opts.show_task_pattern.to_s)
+ end
+ flags(['--where', 'xyz'], ['-Wxyz']) do |opts|
+ assert_equal :lines, opts.show_tasks
+ assert_equal(/xyz/.to_s, opts.show_task_pattern.to_s)
+ end
+ end
+
+ def test_no_deprecated_messages
+ flags('--no-deprecation-warnings', '-X') do |opts|
+ assert opts.ignore_deprecate
+ end
+ end
+
+ def test_verbose
+ out, = capture_io do
+ flags('--verbose', '-V') do |opts|
+ assert Rake::FileUtilsExt.verbose_flag
+ assert ! opts.silent
+ end
+ end
+
+ assert_equal "rake, version #{Rake::VERSION}\n", out
+ end
+
+ def test_version
+ out, = capture_io do
+ flags '--version', '-V'
+ end
+
+ assert_match(/\bversion\b/, out)
+ assert_match(/\b#{RAKEVERSION}\b/, out)
+ assert_equal :exit, @exit
+ end
+
+ def test_classic_namespace
+ _, err = capture_io do
+ flags(['--classic-namespace'],
+ ['-C', '-T', '-P', '-n', '-s', '-t']) do |opts|
+ assert opts.classic_namespace
+ assert_equal opts.show_tasks, $show_tasks
+ assert_equal opts.show_prereqs, $show_prereqs
+ assert_equal opts.trace, $trace
+ assert_equal opts.dryrun, $dryrun
+ assert_equal opts.silent, $silent
+ end
+ end
+
+ assert_match(/deprecated/, err)
+ end
+
+ def test_bad_option
+ _, err = capture_io do
+ ex = assert_raises(OptionParser::InvalidOption) do
+ flags('--bad-option')
+ end
+
+ if ex.message =~ /^While/ # Ruby 1.9 error message
+ assert_match(/while parsing/i, ex.message)
+ else # Ruby 1.8 error message
+ assert_match(/(invalid|unrecognized) option/i, ex.message)
+ assert_match(/--bad-option/, ex.message)
+ end
+ end
+
+ assert_equal '', err
+ end
+
+ def test_task_collection
+ command_line("a", "b")
+ assert_equal ["a", "b"], @tasks.sort
+ end
+
+ def test_default_task_collection
+ command_line()
+ assert_equal ["default"], @tasks
+ end
+
+ def test_environment_definition
+ ENV.delete('TESTKEY')
+ command_line("a", "TESTKEY=12")
+ assert_equal ["a"], @tasks.sort
+ assert '12', ENV['TESTKEY']
+ end
+
+ def flags(*sets)
+ sets.each do |set|
+ ARGV.clear
+
+ @exit = catch(:system_exit) { command_line(*set) }
+
+ yield(@app.options) if block_given?
+ end
+ end
+
+ def command_line(*options)
+ options.each do |opt| ARGV << opt end
+ @app = Rake::Application.new
+ def @app.exit(*args)
+ throw :system_exit, :exit
+ end
+ @app.instance_eval do
+ handle_options
+ collect_tasks
+ end
+ @tasks = @app.top_level_tasks
+ @app.options
+ end
+end
+
diff --git a/test/rake/test_clean.rb b/test/rake/test_rake_clean.rb
index 0e8b81c2c7..1541c69359 100644
--- a/test/rake/test_clean.rb
+++ b/test/rake/test_rake_clean.rb
@@ -1,9 +1,11 @@
-require 'test/unit'
+require File.expand_path('../helper', __FILE__)
require 'rake/clean'
-class Rake::TestClean < Test::Unit::TestCase
+class TestRakeClean < Rake::TestCase
include Rake
def test_clean
+ load 'rake/clean.rb', true
+
assert Task['clean'], "Should define clean"
assert Task['clobber'], "Should define clobber"
assert Task['clobber'].prerequisites.include?("clean"),
diff --git a/test/rake/test_definitions.rb b/test/rake/test_rake_definitions.rb
index a5440dcadc..839c40419e 100644
--- a/test/rake/test_definitions.rb
+++ b/test/rake/test_rake_definitions.rb
@@ -1,15 +1,14 @@
-require 'test/unit'
+require File.expand_path('../helper', __FILE__)
require 'fileutils'
-require 'rake'
-require_relative 'filecreation'
-######################################################################
-class Rake::TestDefinitions < Test::Unit::TestCase
+class TestRakeDefinitions < Rake::TestCase
include Rake
- EXISTINGFILE = "testdata/existing"
+ EXISTINGFILE = "existing"
def setup
+ super
+
Task.clear
end
@@ -24,10 +23,10 @@ class Rake::TestDefinitions < Test::Unit::TestCase
def test_file_task
done = false
- file "testdata/one" => "testdata/two" do done = true end
- file "testdata/two"
- file "testdata/three" => ["testdata/one", "testdata/two"]
- check_tasks("testdata/one", "testdata/two", "testdata/three")
+ file "one" => "two" do done = true end
+ file "two"
+ file "three" => ["one", "two"]
+ check_tasks("one", "two", "three")
assert done, "Should be done"
end
@@ -56,8 +55,8 @@ class Rake::TestDefinitions < Test::Unit::TestCase
end
def test_missing_dependencies
- task :x => ["testdata/missing"]
- assert_raise(RuntimeError) { Task[:x].invoke }
+ task :x => ["missing"]
+ assert_raises(RuntimeError) { Task[:x].invoke }
end
def test_implicit_file_dependencies
diff --git a/test/rake/test_rake_directory_task.rb b/test/rake/test_rake_directory_task.rb
new file mode 100644
index 0000000000..7f641f53ca
--- /dev/null
+++ b/test/rake/test_rake_directory_task.rb
@@ -0,0 +1,45 @@
+require File.expand_path('../helper', __FILE__)
+require 'fileutils'
+
+class TestRakeDirectoryTask < Rake::TestCase
+ include Rake
+
+ def test_directory
+ desc "DESC"
+
+ directory "a/b/c"
+
+ assert_equal FileCreationTask, Task["a"].class
+ assert_equal FileCreationTask, Task["a/b"].class
+ assert_equal FileCreationTask, Task["a/b/c"].class
+
+ assert_nil Task["a"].comment
+ assert_nil Task["a/b"].comment
+ assert_equal "DESC", Task["a/b/c"].comment
+
+ verbose(false) {
+ Task['a/b'].invoke
+ }
+
+ assert File.exist?("a/b")
+ refute File.exist?("a/b/c")
+ end
+
+ if Rake::Win32.windows?
+ def test_directory_win32
+ desc "WIN32 DESC"
+ directory 'c:/a/b/c'
+ assert_equal FileCreationTask, Task['c:'].class
+ assert_equal FileCreationTask, Task['c:/a'].class
+ assert_equal FileCreationTask, Task['c:/a/b/c'].class
+ assert_nil Task['c:/'].comment
+ assert_equal "WIN32 DESC", Task['c:/a/b/c'].comment
+ assert_nil Task['c:/a/b'].comment
+ verbose(false) {
+ Task['c:/a/b'].invoke
+ }
+ assert File.exist?('c:/a/b')
+ refute File.exist?('c:/a/b/c')
+ end
+ end
+end
diff --git a/test/rake/test_rake_dsl.rb b/test/rake/test_rake_dsl.rb
new file mode 100644
index 0000000000..294ff2bd0d
--- /dev/null
+++ b/test/rake/test_rake_dsl.rb
@@ -0,0 +1,73 @@
+require File.expand_path('../helper', __FILE__)
+
+class TestRakeDsl < Rake::TestCase
+
+ def setup
+ super
+ Rake::Task.clear
+ end
+
+ def test_namespace_command
+ namespace "n" do
+ task "t"
+ end
+ refute_nil Rake::Task["n:t"]
+ end
+
+ def test_namespace_command_with_bad_name
+ ex = assert_raises(ArgumentError) do
+ namespace 1 do end
+ end
+ assert_match(/string/i, ex.message)
+ assert_match(/symbol/i, ex.message)
+ end
+
+ def test_namespace_command_with_a_string_like_object
+ name = Object.new
+ def name.to_str
+ "bob"
+ end
+ namespace name do
+ task "t"
+ end
+ refute_nil Rake::Task["bob:t"]
+ end
+
+ class Foo
+ def initialize
+ task :foo_deprecated_a => "foo_deprecated_b" do
+ print "a"
+ end
+ file "foo_deprecated_b" do
+ print "b"
+ end
+ end
+ end
+
+ def test_deprecated_object_dsl
+ out, err = capture_io do
+ Foo.new
+ Rake.application.invoke_task :foo_deprecated_a
+ end
+ assert_equal("ba", out)
+ assert_match(/deprecated/, err)
+ assert_match(/Foo\#task/, err)
+ assert_match(/Foo\#file/, err)
+ assert_match(/test_rake_dsl\.rb:\d+/, err)
+ end
+
+ def test_deprecated_object_dsl_with_suppressed_warnings
+ Rake.application.options.ignore_deprecate = true
+ out, err = capture_io do
+ Foo.new
+ Rake.application.invoke_task :foo_deprecated_a
+ end
+ assert_equal("ba", out)
+ refute_match(/deprecated/, err)
+ refute_match(/Foo\#task/, err)
+ refute_match(/Foo\#file/, err)
+ refute_match(/test_rake_dsl\.rb:\d+/, err)
+ ensure
+ Rake.application.options.ignore_deprecate = false
+ end
+end
diff --git a/test/rake/test_earlytime.rb b/test/rake/test_rake_early_time.rb
index d94523cffd..18c4dad324 100644
--- a/test/rake/test_earlytime.rb
+++ b/test/rake/test_rake_early_time.rb
@@ -1,10 +1,8 @@
-require 'test/unit'
-require 'rake'
+require File.expand_path('../helper', __FILE__)
-class Rake::TestEarlyTime < Test::Unit::TestCase
+class TestRakeEarlyTime < Rake::TestCase
def test_create
early = Rake::EarlyTime.instance
- time = Time.mktime(1970, 1, 1, 0, 0, 0)
assert early <= Time.now
assert early < Time.now
assert early != Time.now
diff --git a/test/rake/test_extension.rb b/test/rake/test_rake_extension.rb
index 3b10a4c6ed..18d55f19f9 100644
--- a/test/rake/test_extension.rb
+++ b/test/rake/test_rake_extension.rb
@@ -1,9 +1,7 @@
-require 'test/unit'
-require 'rake'
+require File.expand_path('../helper', __FILE__)
require 'stringio'
-######################################################################
-class Rake::TestExtension < Test::Unit::TestCase
+class TestRakeExtension < Rake::TestCase
module Redirect
def error_redirect
diff --git a/test/rake/test_file_creation_task.rb b/test/rake/test_rake_file_creation_task.rb
index 1f2af90399..d486d2f0d4 100644
--- a/test/rake/test_file_creation_task.rb
+++ b/test/rake/test_rake_file_creation_task.rb
@@ -1,21 +1,17 @@
-require 'test/unit'
+require File.expand_path('../helper', __FILE__)
require 'fileutils'
-require 'rake'
-require_relative 'filecreation'
######################################################################
-class Rake::TestFileCreationTask < Test::Unit::TestCase
+class TestRakeFileCreationTask < Rake::TestCase
include Rake
- include FileCreation
+ include Rake::DSL
- DUMMY_DIR = 'testdata/dummy_dir'
+ DUMMY_DIR = 'dummy_dir'
def setup
- Task.clear
- end
+ super
- def teardown
- FileUtils.rm_rf DUMMY_DIR
+ Task.clear
end
def test_file_needed
diff --git a/test/rake/test_filelist.rb b/test/rake/test_rake_file_list.rb
index 2b1ad44237..08939fb6ed 100644
--- a/test/rake/test_filelist.rb
+++ b/test/rake/test_rake_file_list.rb
@@ -1,28 +1,34 @@
-require 'test/unit'
-require 'tmpdir'
-require 'rake'
+require File.expand_path('../helper', __FILE__)
-require_relative 'capture_stdout'
-
-class Rake::TestFileList < Test::Unit::TestCase
+class TestRakeFileList < Rake::TestCase
FileList = Rake::FileList
- include CaptureStdout
def setup
- @oldwd = Dir.pwd
- @tmpwd = Dir.mktmpdir
- Dir.chdir(@tmpwd)
- create_test_data
- end
+ super
+
+ FileUtils.mkdir "CVS" rescue nil
+ FileUtils.mkdir ".svn" rescue nil
+ @cdir = "cfiles"
+ FileUtils.mkdir @cdir rescue nil
+ FileUtils.touch ".dummy"
+ FileUtils.touch "x.bak"
+ FileUtils.touch "x~"
+ FileUtils.touch "core"
+ FileUtils.touch "x.c"
+ FileUtils.touch "xyz.c"
+ FileUtils.touch "abc.c"
+ FileUtils.touch "abc.h"
+ FileUtils.touch "abc.x"
+ FileUtils.touch "existing"
+
+ open 'xyzzy.txt', 'w' do |io|
+ io.puts 'x'
+ io.puts 'XYZZY'
+ end
- def teardown
-# FileList.select_default_ignore_patterns
- FileUtils.rm_rf("testdata")
- Dir.chdir(@oldwd)
- FileUtils.rm_rf(@tmpwd)
end
- def test_delgating_methods_do_not_include_to_a_or_to_ary
+ def test_delegating_methods_do_not_include_to_a_or_to_ary
assert ! FileList::DELEGATING_METHODS.include?("to_a"), "should not include to_a"
assert ! FileList::DELEGATING_METHODS.include?(:to_a), "should not include to_a"
assert ! FileList::DELEGATING_METHODS.include?("to_ary"), "should not include to_ary"
@@ -35,8 +41,8 @@ class Rake::TestFileList < Test::Unit::TestCase
end
def test_create_with_args
- fl = FileList.new("testdata/*.c", "x")
- assert_equal ["testdata/abc.c", "testdata/x.c", "testdata/xyz.c", "x"].sort,
+ fl = FileList.new("*.c", "x")
+ assert_equal ["abc.c", "x.c", "xyz.c", "x"].sort,
fl.sort
end
@@ -46,14 +52,14 @@ class Rake::TestFileList < Test::Unit::TestCase
end
def test_create_with_brackets
- fl = FileList["testdata/*.c", "x"]
- assert_equal ["testdata/abc.c", "testdata/x.c", "testdata/xyz.c", "x"].sort,
+ fl = FileList["*.c", "x"]
+ assert_equal ["abc.c", "x.c", "xyz.c", "x"].sort,
fl.sort
end
def test_create_with_brackets_and_filelist
- fl = FileList[FileList["testdata/*.c", "x"]]
- assert_equal ["testdata/abc.c", "testdata/x.c", "testdata/xyz.c", "x"].sort,
+ fl = FileList[FileList["*.c", "x"]]
+ assert_equal ["abc.c", "x.c", "xyz.c", "x"].sort,
fl.sort
end
@@ -63,8 +69,8 @@ class Rake::TestFileList < Test::Unit::TestCase
end
def test_include_with_another_filelist
- fl = FileList.new.include(FileList["testdata/*.c", "x"])
- assert_equal ["testdata/abc.c", "testdata/x.c", "testdata/xyz.c", "x"].sort,
+ fl = FileList.new.include(FileList["*.c", "x"])
+ assert_equal ["abc.c", "x.c", "xyz.c", "x"].sort,
fl.sort
end
@@ -92,86 +98,87 @@ class Rake::TestFileList < Test::Unit::TestCase
def test_match
fl = FileList.new
- fl.include(File.expand_path('../test*.rb', __FILE__))
- assert fl.include?(__FILE__)
- assert fl.size > 3
- fl.each { |fn| assert_match(/\.rb$/, fn) }
+ fl.include '*.c'
+
+ assert_equal %w[abc.c x.c xyz.c], fl.sort
end
def test_add_matching
fl = FileList.new
fl << "a.java"
- fl.include(File.dirname(__FILE__)+"/*.rb")
- assert_equal "a.java", fl[0]
- assert fl.size > 2
- assert fl.include?(__FILE__)
+ fl.include '*.c'
+
+ assert_equal %w[a.java abc.c x.c xyz.c], fl.sort
end
def test_multiple_patterns
- create_test_data
fl = FileList.new
- fl.include('*.c', '*xist*')
+ fl.include('*.z', '*foo*')
+
assert_equal [], fl
- fl.include('testdata/*.c', 'testdata/*xist*')
- assert_equal [
- 'testdata/x.c', 'testdata/xyz.c', 'testdata/abc.c', 'testdata/existing'
- ].sort, fl.sort
+
+ fl.include('*.c', '*xist*')
+ assert_equal %w[x.c xyz.c abc.c existing].sort, fl.sort
end
def test_square_bracket_pattern
fl = FileList.new
- fl.include("testdata/abc.[ch]")
+ fl.include("abc.[ch]")
assert fl.size == 2
- assert fl.include?("testdata/abc.c")
- assert fl.include?("testdata/abc.h")
+ assert fl.include?("abc.c")
+ assert fl.include?("abc.h")
end
def test_curly_bracket_pattern
fl = FileList.new
- fl.include("testdata/abc.{c,h}")
+ fl.include("abc.{c,h}")
assert fl.size == 2
- assert fl.include?("testdata/abc.c")
- assert fl.include?("testdata/abc.h")
+ assert fl.include?("abc.c")
+ assert fl.include?("abc.h")
end
def test_reject
fl = FileList.new
- fl.include %w(testdata/x.c testdata/abc.c testdata/xyz.c testdata/existing)
- fl.reject! { |fn| fn =~ %r{/x} }
- assert_equal [
- 'testdata/abc.c', 'testdata/existing'
- ], fl
+ fl.include %w(x.c abc.c xyz.c existing)
+ fl.reject! { |fn| fn =~ /^x/ }
+ assert_equal %w[abc.c existing], fl
end
def test_exclude
- fl = FileList['testdata/x.c', 'testdata/abc.c', 'testdata/xyz.c', 'testdata/existing']
+ fl = FileList['x.c', 'abc.c', 'xyz.c', 'existing']
fl.each { |fn| touch fn, :verbose => false }
- x = fl.exclude(%r{/x.+\.})
+
+ x = fl.exclude(%r{^x.+\.})
+
assert_equal FileList, x.class
- assert_equal %w(testdata/x.c testdata/abc.c testdata/existing), fl
+ assert_equal %w(x.c abc.c existing), fl
assert_equal fl.object_id, x.object_id
- fl.exclude('testdata/*.c')
- assert_equal ['testdata/existing'], fl
- fl.exclude('testdata/existing')
+
+ fl.exclude('*.c')
+
+ assert_equal ['existing'], fl
+
+ fl.exclude('existing')
+
assert_equal [], fl
end
def test_excluding_via_block
- fl = FileList['testdata/a.c', 'testdata/b.c', 'testdata/xyz.c']
+ fl = FileList['a.c', 'b.c', 'xyz.c']
fl.exclude { |fn| fn.pathmap('%n') == 'xyz' }
assert fl.exclude?("xyz.c"), "Should exclude xyz.c"
- assert_equal ['testdata/a.c', 'testdata/b.c'], fl
+ assert_equal ['a.c', 'b.c'], fl
end
def test_exclude_return_on_create
- fl = FileList['testdata/*'].exclude(/.*\.[hcx]$/)
- assert_equal ['testdata/existing', 'testdata/cfiles'].sort, fl.sort
+ fl = FileList['*'].exclude(/.*\.[hcx]$/)
+ assert_equal %w[cfiles existing xyzzy.txt], fl.sort
assert_equal FileList, fl.class
end
def test_exclude_with_string_return_on_create
- fl = FileList['testdata/*'].exclude('testdata/abc.c')
- assert_equal %w(testdata/existing testdata/cfiles testdata/x.c testdata/abc.h testdata/abc.x testdata/xyz.c).sort, fl.sort
+ fl = FileList['*'].exclude('abc.c')
+ assert_equal %w[abc.h abc.x cfiles existing x.c xyz.c xyzzy.txt], fl.sort
assert_equal FileList, fl.class
end
@@ -179,8 +186,8 @@ class Rake::TestFileList < Test::Unit::TestCase
fl = FileList.new
fl.clear_exclude
fl.include("**/*~", "**/*.bak", "**/core")
- assert fl.member?("testdata/core"), "Should include core"
- assert fl.member?("testdata/x.bak"), "Should include .bak files"
+ assert fl.member?("core"), "Should include core"
+ assert fl.member?("x.bak"), "Should include .bak files"
end
def test_unique
@@ -207,54 +214,54 @@ class Rake::TestFileList < Test::Unit::TestCase
end
def test_to_s_pending
- fl = FileList['testdata/abc.*']
+ fl = FileList['abc.*']
result = fl.to_s
- assert_match(%r{testdata/abc\.c}, result)
- assert_match(%r{testdata/abc\.h}, result)
- assert_match(%r{testdata/abc\.x}, result)
- assert_match(%r{(testdata/abc\..\b ?){2}}, result)
+ assert_match(%r{abc\.c}, result)
+ assert_match(%r{abc\.h}, result)
+ assert_match(%r{abc\.x}, result)
+ assert_match(%r{(abc\..\b ?){2}}, result)
end
def test_inspect_pending
- fl = FileList['testdata/abc.*']
+ fl = FileList['abc.*']
result = fl.inspect
- assert_match(%r{"testdata/abc\.c"}, result)
- assert_match(%r{"testdata/abc\.h"}, result)
- assert_match(%r{"testdata/abc\.x"}, result)
- assert_match(%r|^\[("testdata/abc\..", ){2}"testdata/abc\.."\]$|, result)
+ assert_match(%r{"abc\.c"}, result)
+ assert_match(%r{"abc\.h"}, result)
+ assert_match(%r{"abc\.x"}, result)
+ assert_match(%r|^\[("abc\..", ){2}"abc\.."\]$|, result)
end
def test_sub
- fl = FileList["testdata/*.c"]
+ fl = FileList["*.c"]
f2 = fl.sub(/\.c$/, ".o")
assert_equal FileList, f2.class
- assert_equal ["testdata/abc.o", "testdata/x.o", "testdata/xyz.o"].sort,
+ assert_equal ["abc.o", "x.o", "xyz.o"].sort,
f2.sort
f3 = fl.gsub(/\.c$/, ".o")
assert_equal FileList, f3.class
- assert_equal ["testdata/abc.o", "testdata/x.o", "testdata/xyz.o"].sort,
+ assert_equal ["abc.o", "x.o", "xyz.o"].sort,
f3.sort
end
def test_claim_to_be_a_kind_of_array
- fl = FileList['testdata/*.c']
+ fl = FileList['*.c']
assert fl.is_a?(Array)
assert fl.kind_of?(Array)
end
def test_claim_to_be_a_kind_of_filelist
- fl = FileList['testdata/*.c']
+ fl = FileList['*.c']
assert fl.is_a?(FileList)
assert fl.kind_of?(FileList)
end
def test_claim_to_be_a_filelist_instance
- fl = FileList['testdata/*.c']
+ fl = FileList['*.c']
assert fl.instance_of?(FileList)
end
def test_dont_claim_to_be_an_array_instance
- fl = FileList['testdata/*.c']
+ fl = FileList['*.c']
assert ! fl.instance_of?(Array)
end
@@ -310,73 +317,89 @@ class Rake::TestFileList < Test::Unit::TestCase
end
def test_gsub
- create_test_data
- fl = FileList["testdata/*.c"]
+ fl = FileList["*.c"]
f2 = fl.gsub(/a/, "A")
- assert_equal ["testdAtA/Abc.c", "testdAtA/x.c", "testdAtA/xyz.c"].sort,
+ assert_equal ["Abc.c", "x.c", "xyz.c"].sort,
f2.sort
end
def test_gsub!
- create_test_data
- f = FileList["testdata/*.c"]
+ f = FileList["*.c"]
f.gsub!(/a/, "A")
- assert_equal ["testdAtA/Abc.c", "testdAtA/x.c", "testdAtA/xyz.c"].sort,
+ assert_equal ["Abc.c", "x.c", "xyz.c"].sort,
f.sort
end
+ def test_egrep_returns_0_if_no_matches
+ files = FileList['test/lib/*_test.rb'].exclude("test/lib/filelist_test.rb")
+ assert_equal 0, files.egrep(/XYZZY/) { }
+ end
+
def test_egrep_with_output
- files = FileList[File.expand_path('../test*.rb', __FILE__)]
- the_line_number = __LINE__ + 1
- out = capture_stdout do files.egrep(/PUGH/) end
- assert_match(/:#{the_line_number}:/, out)
+ files = FileList['*.txt']
+
+ out, = capture_io do
+ files.egrep(/XYZZY/)
+ end
+
+ assert_equal "xyzzy.txt:2:XYZZY\n", out
end
def test_egrep_with_block
- files = FileList[File.expand_path('../test*.rb', __FILE__)]
- found = false
- the_line_number = __LINE__ + 1
- files.egrep(/XYZZY/) do |fn, ln, line |
- assert_equal __FILE__, fn
- assert_equal the_line_number, ln
- assert_match(/files\.egrep/, line)
- found = true
+ files = FileList['*.txt']
+ found = nil
+
+ files.egrep(/XYZZY/) do |fn, ln, line|
+ found = [fn, ln, line]
+ end
+
+ assert_equal ["xyzzy.txt", 2, "XYZZY\n"], found
+ end
+
+ def test_egrep_with_error
+ files = FileList['*.txt']
+
+ _, err = capture_io do
+ files.egrep(/XYZZY/) do |fn, ln, line |
+ raise "_EGREP_FAILURE_"
+ end
end
- assert found, "should have found a matching line"
+
+ assert_equal "Error while processing 'xyzzy.txt': _EGREP_FAILURE_\n", err
end
def test_existing
- fl = FileList['testdata/abc.c', 'testdata/notthere.c']
- assert_equal ["testdata/abc.c"], fl.existing
+ fl = FileList['abc.c', 'notthere.c']
+ assert_equal ["abc.c"], fl.existing
assert fl.existing.is_a?(FileList)
end
def test_existing!
- fl = FileList['testdata/abc.c', 'testdata/notthere.c']
+ fl = FileList['abc.c', 'notthere.c']
result = fl.existing!
- assert_equal ["testdata/abc.c"], fl
+ assert_equal ["abc.c"], fl
assert_equal fl.object_id, result.object_id
end
def test_ignore_special
- f = FileList['testdata/*']
- assert ! f.include?("testdata/CVS"), "Should not contain CVS"
- assert ! f.include?("testdata/.svn"), "Should not contain .svn"
- assert ! f.include?("testdata/.dummy"), "Should not contain dot files"
- assert ! f.include?("testdata/x.bak"), "Should not contain .bak files"
- assert ! f.include?("testdata/x~"), "Should not contain ~ files"
- assert ! f.include?("testdata/core"), "Should not contain core files"
+ f = FileList['*']
+ assert ! f.include?("CVS"), "Should not contain CVS"
+ assert ! f.include?(".svn"), "Should not contain .svn"
+ assert ! f.include?(".dummy"), "Should not contain dot files"
+ assert ! f.include?("x.bak"), "Should not contain .bak files"
+ assert ! f.include?("x~"), "Should not contain ~ files"
+ assert ! f.include?("core"), "Should not contain core files"
end
def test_clear_ignore_patterns
- f = FileList['testdata/*', 'testdata/.svn']
+ f = FileList['*', '.svn']
f.clear_exclude
- assert f.include?("testdata/abc.c")
- assert f.include?("testdata/xyz.c")
- assert f.include?("testdata/CVS")
- assert f.include?("testdata/.svn")
- assert f.include?("testdata/x.bak")
- assert f.include?("testdata/x~")
+ assert f.include?("abc.c")
+ assert f.include?("xyz.c")
+ assert f.include?("CVS")
+ assert f.include?(".svn")
+ assert f.include?("x.bak")
+ assert f.include?("x~")
end
def test_exclude_with_alternate_file_seps
@@ -414,8 +437,8 @@ class Rake::TestFileList < Test::Unit::TestCase
end
def test_flatten
- assert_equal ['a', 'testdata/x.c', 'testdata/xyz.c', 'testdata/abc.c'].sort,
- ['a', FileList['testdata/*.c']].flatten.sort
+ assert_equal ['a', 'x.c', 'xyz.c', 'abc.c'].sort,
+ ['a', FileList['*.c']].flatten.sort
end
def test_clone_and_dup
@@ -449,7 +472,7 @@ class Rake::TestFileList < Test::Unit::TestCase
a = FileList['a', 'b', 'c']
a.freeze
c = a.clone
- assert_raise(TypeError, RuntimeError) do
+ assert_raises(TypeError, RuntimeError) do
c << 'more'
end
end
@@ -592,7 +615,7 @@ class Rake::TestFileList < Test::Unit::TestCase
end
def test_file_utils_can_use_filelists
- cfiles = FileList['testdata/*.c']
+ cfiles = FileList['*.c']
cp cfiles, @cdir, :verbose => false
@@ -601,25 +624,5 @@ class Rake::TestFileList < Test::Unit::TestCase
assert File.exist?(File.join(@cdir, 'x.c'))
end
- def create_test_data
- verbose(false) do
-
- mkdir "testdata" unless File.exist? "testdata"
- mkdir "testdata/CVS" rescue nil
- mkdir "testdata/.svn" rescue nil
- @cdir = "testdata/cfiles"
- mkdir @cdir rescue nil
- touch "testdata/.dummy"
- touch "testdata/x.bak"
- touch "testdata/x~"
- touch "testdata/core"
- touch "testdata/x.c"
- touch "testdata/xyz.c"
- touch "testdata/abc.c"
- touch "testdata/abc.h"
- touch "testdata/abc.x"
- touch "testdata/existing"
- end
- end
-
end
+
diff --git a/test/rake/test_rake_file_list_path_map.rb b/test/rake/test_rake_file_list_path_map.rb
new file mode 100644
index 0000000000..5935dc2689
--- /dev/null
+++ b/test/rake/test_rake_file_list_path_map.rb
@@ -0,0 +1,8 @@
+require File.expand_path('../helper', __FILE__)
+
+class TestRakeFileListPathMap < Rake::TestCase
+ def test_file_list_supports_pathmap
+ assert_equal ['a', 'b'], FileList['dir/a.rb', 'dir/b.rb'].pathmap("%n")
+ end
+end
+
diff --git a/test/rake/test_file_task.rb b/test/rake/test_rake_file_task.rb
index 132bd88853..e586551237 100644
--- a/test/rake/test_file_task.rb
+++ b/test/rake/test_rake_file_task.rb
@@ -1,14 +1,12 @@
-require 'test/unit'
+require File.expand_path('../helper', __FILE__)
require 'fileutils'
-require 'rake'
-require_relative 'filecreation'
-######################################################################
-class Rake::TestFileTask < Test::Unit::TestCase
+class TestRakeFileTask < Rake::TestCase
include Rake
- include FileCreation
def setup
+ super
+
Task.clear
@runs = Array.new
FileUtils.rm_f NEWFILE
@@ -16,22 +14,26 @@ class Rake::TestFileTask < Test::Unit::TestCase
end
def test_file_need
- name = "testdata/dummy"
+ name = "dummy"
file name
+
ftask = Task[name]
+
assert_equal name.to_s, ftask.name
File.delete(ftask.name) rescue nil
+
assert ftask.needed?, "file should be needed"
+
open(ftask.name, "w") { |f| f.puts "HI" }
+
assert_equal nil, ftask.prerequisites.collect{|n| Task[n].timestamp}.max
assert ! ftask.needed?, "file should not be needed"
+ ensure
File.delete(ftask.name) rescue nil
end
def test_file_times_new_depends_on_old
- until File.exist?(OLDFILE) && File.exist?(NEWFILE)
- create_timed_files(OLDFILE, NEWFILE)
- end
+ create_timed_files(OLDFILE, NEWFILE)
t1 = Rake.application.intern(FileTask, NEWFILE).enhance([OLDFILE])
t2 = Rake.application.intern(FileTask, OLDFILE)
@@ -40,9 +42,7 @@ class Rake::TestFileTask < Test::Unit::TestCase
end
def test_file_times_old_depends_on_new
- until File.exist?(OLDFILE) && File.exist?(NEWFILE)
- create_timed_files(OLDFILE, NEWFILE)
- end
+ create_timed_files(OLDFILE, NEWFILE)
t1 = Rake.application.intern(FileTask,OLDFILE).enhance([NEWFILE])
t2 = Rake.application.intern(FileTask, NEWFILE)
@@ -66,11 +66,19 @@ class Rake::TestFileTask < Test::Unit::TestCase
end
def test_existing_file_depends_on_non_existing_file
+ @ran = false
+
create_file(OLDFILE)
delete_file(NEWFILE)
- file NEWFILE
+ file NEWFILE do
+ @ran = true
+ end
+
file OLDFILE => NEWFILE
- assert_nothing_raised do Task[OLDFILE].invoke end
+
+ Task[OLDFILE].invoke
+
+ assert @ran
end
# I have currently disabled this test. I'm not convinced that
@@ -92,52 +100,3 @@ class Rake::TestFileTask < Test::Unit::TestCase
end
-######################################################################
-class Rake::TestDirectoryTask < Test::Unit::TestCase
- include Rake
-
- def setup
- rm_rf "testdata2", :verbose=>false
- end
-
- def teardown
- rm_rf "testdata2", :verbose=>false
- end
-
- def test_directory
- desc "DESC"
- directory "testdata2/a/b/c"
- assert_equal FileCreationTask, Task["testdata2"].class
- assert_equal FileCreationTask, Task["testdata2/a"].class
- assert_equal FileCreationTask, Task["testdata2/a/b/c"].class
- assert_nil Task["testdata2"].comment
- assert_equal "DESC", Task["testdata2/a/b/c"].comment
- assert_nil Task["testdata2/a/b"].comment
- verbose(false) {
- Task['testdata2/a/b'].invoke
- }
- assert File.exist?("testdata2/a/b")
- assert ! File.exist?("testdata2/a/b/c")
- end
-
- if Rake::Win32.windows?
- def test_directory_win32
- desc "WIN32 DESC"
- FileUtils.mkdir_p("testdata2")
- Dir.chdir("testdata2") do
- directory 'c:/testdata2/a/b/c'
- assert_equal FileCreationTask, Task['c:/testdata2'].class
- assert_equal FileCreationTask, Task['c:/testdata2/a'].class
- assert_equal FileCreationTask, Task['c:/testdata2/a/b/c'].class
- assert_nil Task['c:/testdata2'].comment
- assert_equal "WIN32 DESC", Task['c:/testdata2/a/b/c'].comment
- assert_nil Task['c:/testdata2/a/b'].comment
- verbose(false) {
- Task['c:/testdata2/a/b'].invoke
- }
- assert File.exist?('c:/testdata2/a/b')
- assert ! File.exist?('c:/testdata2/a/b/c')
- end
- end
- end
-end
diff --git a/test/rake/test_fileutils.rb b/test/rake/test_rake_file_utils.rb
index b6106c0978..fb7a4a5307 100644
--- a/test/rake/test_fileutils.rb
+++ b/test/rake/test_rake_file_utils.rb
@@ -1,65 +1,47 @@
-require 'rake'
-require 'test/unit'
-require_relative 'filecreation'
+require File.expand_path('../helper', __FILE__)
require 'fileutils'
require 'stringio'
-class Rake::TestFileUtils < Test::Unit::TestCase
- include FileCreation
- BASEDIR = File.dirname(__FILE__)
- ShellCommand = "#{BASEDIR}/shellcommand.rb"
- ENV_RUBY = ENV['RUBY']
-
- def setup
- if ruby = ENV_RUBY
- @oldruby = FileUtils.class_eval {remove_const :RUBY}
- FileUtils.class_eval {const_set(:RUBY, ruby)}
- else
- @oldruby = nil
- end
- end
+class TestRakeFileUtils < Rake::TestCase
def teardown
- FileUtils.rm_rf("testdata")
FileUtils::LN_SUPPORTED[0] = true
- if @oldruby
- ruby = @oldruby
- FileUtils.class_eval {remove_const :RUBY}
- FileUtils.class_eval {const_set(:RUBY, ruby)}
- end
+
+ super
end
def test_rm_one_file
- create_file("testdata/a")
- FileUtils.rm_rf "testdata/a"
- assert ! File.exist?("testdata/a")
+ create_file("a")
+ FileUtils.rm_rf "a"
+ refute File.exist?("a")
end
def test_rm_two_files
- create_file("testdata/a")
- create_file("testdata/b")
- FileUtils.rm_rf ["testdata/a", "testdata/b"]
- assert ! File.exist?("testdata/a")
- assert ! File.exist?("testdata/b")
+ create_file("a")
+ create_file("b")
+ FileUtils.rm_rf ["a", "b"]
+ refute File.exist?("a")
+ refute File.exist?("b")
end
def test_rm_filelist
- list = Rake::FileList.new << "testdata/a" << "testdata/b"
+ list = Rake::FileList.new << "a" << "b"
list.each { |fn| create_file(fn) }
FileUtils.rm_r list
- assert ! File.exist?("testdata/a")
- assert ! File.exist?("testdata/b")
+ refute File.exist?("a")
+ refute File.exist?("b")
end
def test_ln
- create_dir("testdata")
- open("testdata/a", "w") { |f| f.puts "TEST_LN" }
- RakeFileUtils.safe_ln("testdata/a", "testdata/b", :verbose => false)
- assert_equal "TEST_LN\n", open("testdata/b") { |f| f.read }
+ open("a", "w") { |f| f.puts "TEST_LN" }
+
+ Rake::FileUtilsExt.safe_ln("a", "b", :verbose => false)
+
+ assert_equal "TEST_LN\n", File.read('b')
end
class BadLink
- include RakeFileUtils
+ include Rake::FileUtilsExt
attr_reader :cp_args
def initialize(klass)
@failure_class = klass
@@ -92,7 +74,7 @@ class Rake::TestFileUtils < Test::Unit::TestCase
def test_safe_ln_fails_on_script_error
FileUtils::LN_SUPPORTED[0] = true
c = BadLink.new(ScriptError)
- assert_raise(ScriptError) do c.safe_ln "a", "b" end
+ assert_raises(ScriptError) do c.safe_ln "a", "b" end
end
def test_verbose
@@ -118,21 +100,21 @@ class Rake::TestFileUtils < Test::Unit::TestCase
end
def test_file_utils_methods_are_available_at_top_level
- create_file("testdata/a")
- verbose(false) do
- rm_rf "testdata/a"
- end
- assert ! File.exist?("testdata/a")
+ create_file("a")
+ rm_rf "a"
+ refute File.exist?("a")
end
def test_fileutils_methods_dont_leak
obj = Object.new
- assert_raise(NoMethodError) { obj.copy } # from FileUtils
- assert_raise(NoMethodError) { obj.ruby } # from RubyFileUtils
+ assert_raises(NoMethodError) { obj.copy } # from FileUtils
+ assert_raises(NoMethodError) { obj.ruby "-v" } # from RubyFileUtils
end
def test_sh
- verbose(false) { sh %{#{RUBY} #{ShellCommand}} }
+ shellcommand
+
+ verbose(false) { sh %{#{FileUtils::RUBY} shellcommand.rb} }
assert true, "should not fail"
end
@@ -148,37 +130,48 @@ class Rake::TestFileUtils < Test::Unit::TestCase
def self.run(*args)
new.run(*args)
end
+ def self.ruby(*args)
+ Sh.run(RUBY, *args)
+ end
end
def test_sh_with_a_single_string_argument
+ check_expansion
+
ENV['RAKE_TEST_SH'] = 'someval'
verbose(false) {
- sh %{#{RUBY} #{BASEDIR}/check_expansion.rb #{env_var} someval}
+ sh %{#{FileUtils::RUBY} check_expansion.rb #{env_var} someval}
}
end
def test_sh_with_multiple_arguments
+ check_no_expansion
ENV['RAKE_TEST_SH'] = 'someval'
+
verbose(false) {
- Sh.run RUBY, File.expand_path('../check_no_expansion.rb', __FILE__), env_var, 'someval'
+ Sh.ruby 'check_no_expansion.rb', env_var, 'someval'
}
end
def test_sh_failure
- assert_raise(RuntimeError) {
- verbose(false) { Sh.run "#{RUBY} #{File.expand_path('../shellcommand.rb', __FILE__)} 1" }
+ shellcommand
+
+ assert_raises(RuntimeError) {
+ verbose(false) { Sh.run %{#{FileUtils::RUBY} shellcommand.rb 1} }
}
end
def test_sh_special_handling
+ shellcommand
+
count = 0
verbose(false) {
- sh(%{#{RUBY} #{ShellCommand}}) do |ok, res|
+ sh(%{#{FileUtils::RUBY} shellcommand.rb}) do |ok, res|
assert(ok)
assert_equal 0, res.exitstatus
count += 1
end
- sh(%{#{RUBY} #{ShellCommand} 1}) do |ok, res|
+ sh(%{#{FileUtils::RUBY} shellcommand.rb 1}) do |ok, res|
assert(!ok)
assert_equal 1, res.exitstatus
count += 1
@@ -188,75 +181,113 @@ class Rake::TestFileUtils < Test::Unit::TestCase
end
def test_sh_noop
- verbose(false) { sh %{#{ShellCommand} 1}, :noop=>true }
+ shellcommand
+
+ verbose(false) { sh %{shellcommand.rb 1}, :noop=>true }
assert true, "should not fail"
end
def test_sh_bad_option
- ex = assert_raise(ArgumentError) {
- verbose(false) { sh %{#{ShellCommand}}, :bad_option=>true }
+ shellcommand
+
+ ex = assert_raises(ArgumentError) {
+ verbose(false) { sh %{shellcommand.rb}, :bad_option=>true }
}
assert_match(/bad_option/, ex.message)
end
def test_sh_verbose
- out = redirect_stderr {
+ shellcommand
+
+ _, err = capture_io do
verbose(true) {
- sh %{#{ShellCommand}}, :noop=>true
+ sh %{shellcommand.rb}, :noop=>true
}
- }
- assert_match(/^#{Regexp.quote(ShellCommand)}$/o, out)
+ end
+
+ assert_equal "shellcommand.rb\n", err
end
def test_sh_no_verbose
- out = redirect_stderr {
+ shellcommand
+
+ _, err = capture_io do
verbose(false) {
- sh %{#{ShellCommand}}, :noop=>true
+ sh %{shellcommand.rb}, :noop=>true
}
- }
- assert_equal '', out
+ end
+
+ assert_equal '', err
end
def test_ruby_with_a_single_string_argument
+ check_expansion
+
ENV['RAKE_TEST_SH'] = 'someval'
+
verbose(false) {
- ruby %{#{BASEDIR}/check_expansion.rb #{env_var} someval}
+ ruby %{check_expansion.rb #{env_var} someval}
}
end
def test_ruby_with_multiple_arguments
+ check_no_expansion
+
ENV['RAKE_TEST_SH'] = 'someval'
verbose(false) {
- ruby "#{BASEDIR}/check_no_expansion.rb", env_var, 'someval'
+ ruby 'check_no_expansion.rb', env_var, 'someval'
}
end
def test_split_all
- assert_equal ['a'], RakeFileUtils.split_all('a')
- assert_equal ['..'], RakeFileUtils.split_all('..')
- assert_equal ['/'], RakeFileUtils.split_all('/')
- assert_equal ['a', 'b'], RakeFileUtils.split_all('a/b')
- assert_equal ['/', 'a', 'b'], RakeFileUtils.split_all('/a/b')
- assert_equal ['..', 'a', 'b'], RakeFileUtils.split_all('../a/b')
+ assert_equal ['a'], Rake::FileUtilsExt.split_all('a')
+ assert_equal ['..'], Rake::FileUtilsExt.split_all('..')
+ assert_equal ['/'], Rake::FileUtilsExt.split_all('/')
+ assert_equal ['a', 'b'], Rake::FileUtilsExt.split_all('a/b')
+ assert_equal ['/', 'a', 'b'], Rake::FileUtilsExt.split_all('/a/b')
+ assert_equal ['..', 'a', 'b'], Rake::FileUtilsExt.split_all('../a/b')
end
- private
+ def command name, text
+ open name, 'w', 0750 do |io|
+ io << text
+ end
+ end
- def redirect_stderr
- old_err = $stderr
- $stderr = StringIO.new
- yield
- $stderr.string
- ensure
- $stderr = old_err
+ def check_no_expansion
+ command 'check_no_expansion.rb', <<-CHECK_EXPANSION
+if ARGV[0] != ARGV[1]
+ exit 0
+else
+ exit 1
+end
+ CHECK_EXPANSION
end
- def windows?
- ! File::ALT_SEPARATOR.nil?
+ def check_expansion
+ command 'check_expansion.rb', <<-CHECK_EXPANSION
+if ARGV[0] != ARGV[1]
+ exit 1
+else
+ exit 0
+end
+ CHECK_EXPANSION
+ end
+
+ def shellcommand
+ command 'shellcommand.rb', <<-SHELLCOMMAND
+#!/usr/bin/env ruby
+
+exit((ARGV[0] || "0").to_i)
+ SHELLCOMMAND
end
def env_var
windows? ? '%RAKE_TEST_SH%' : '$RAKE_TEST_SH'
end
+ def windows?
+ ! File::ALT_SEPARATOR.nil?
+ end
+
end
diff --git a/test/rake/contrib/test_ftp.rb b/test/rake/test_rake_ftp_file.rb
index 0346dd71ca..7f41faf0dd 100644
--- a/test/rake/contrib/test_ftp.rb
+++ b/test/rake/test_rake_ftp_file.rb
@@ -1,19 +1,22 @@
+require File.expand_path('../helper', __FILE__)
require 'date'
require 'time'
-require 'test/unit'
require 'rake/contrib/ftptools'
-class Rake::TestFtpFile < Test::Unit::TestCase
- class FakeDate
- def self.today
- Date.new(2003,10,3)
- end
- def self.now
- Time.local(2003,10,3,12,00,00)
- end
+class FakeDate
+ def self.today
+ Date.new(2003,10,3)
end
+ def self.now
+ Time.local(2003,10,3,12,00,00)
+ end
+end
+
+class TestRakeFtpFile < Rake::TestCase
def setup
+ super
+
Rake::FtpFile.class_eval { @date_class = FakeDate; @time_class = FakeDate }
end
@@ -53,3 +56,4 @@ class Rake::TestFtpFile < Test::Unit::TestCase
assert !file.directory?
end
end
+
diff --git a/test/rake/test_rake_functional.rb b/test/rake/test_rake_functional.rb
new file mode 100644
index 0000000000..e27d3cf68b
--- /dev/null
+++ b/test/rake/test_rake_functional.rb
@@ -0,0 +1,514 @@
+begin
+ old_verbose = $VERBOSE
+ $VERBOSE = nil
+ require 'session'
+rescue LoadError
+ if File::ALT_SEPARATOR
+ puts "Unable to run functional tests on MS Windows. Skipping."
+ else
+ puts "Unable to run functional tests -- please run \"gem install session\""
+ end
+ensure
+ $VERBOSE = old_verbose
+end
+
+if defined?(Session)
+ if File::ALT_SEPARATOR
+ puts "Unable to run functional tests on MS Windows. Skipping."
+ end
+end
+
+require File.expand_path('../helper', __FILE__)
+require 'fileutils'
+
+# Version 2.1.9 of session has a bug where the @debug instance
+# variable is not initialized, causing warning messages. This snippet
+# of code fixes that problem.
+module Session
+ class AbstractSession
+ alias old_initialize initialize
+ def initialize(*args)
+ @debug = nil
+ old_initialize(*args)
+ end
+ end
+end if defined? Session
+
+class TestRakeFunctional < Rake::TestCase
+
+ def setup
+ @rake_path = File.expand_path("bin/rake")
+ lib_path = File.expand_path("lib")
+ @ruby_options = ["-I#{lib_path}", "-I."]
+ @verbose = ENV['VERBOSE']
+
+ if @verbose
+ puts
+ puts
+ puts '-' * 80
+ puts @__name__
+ puts '-' * 80
+ end
+
+ super
+ end
+
+ def test_rake_default
+ rakefile_default
+
+ rake
+
+ assert_match(/^DEFAULT$/, @out)
+ assert_status
+ end
+
+ def test_rake_error_on_bad_task
+ rakefile_default
+
+ rake "xyz"
+
+ assert_match(/rake aborted/, @err)
+ assert_status(1)
+ end
+
+ def test_env_available_at_top_scope
+ rakefile_default
+
+ rake "TESTTOPSCOPE=1"
+
+ assert_match(/^TOPSCOPE$/, @out)
+ assert_status
+ end
+
+ def test_env_available_at_task_scope
+ rakefile_default
+
+ rake "TESTTASKSCOPE=1 task_scope"
+
+ assert_match(/^TASKSCOPE$/, @out)
+ assert_status
+ end
+
+ def test_multi_desc
+ ENV['RAKE_COLUMNS'] = '80'
+ rakefile_multidesc
+
+ rake "-T"
+
+ assert_match %r{^rake a *# A / A2 *$}, @out
+ assert_match %r{^rake b *# B *$}, @out
+ refute_match %r{^rake c}, @out
+ assert_match %r{^rake d *# x{65}\.\.\.$}, @out
+ end
+
+ def test_long_description
+ rakefile_multidesc
+
+ rake "--describe"
+
+ assert_match %r{^rake a\n *A / A2 *$}m, @out
+ assert_match %r{^rake b\n *B *$}m, @out
+ assert_match %r{^rake d\n *x{80}}m, @out
+ refute_match %r{^rake c\n}m, @out
+ end
+
+ def test_proper_namespace_access
+ rakefile_access
+
+ rake
+
+ assert_not_match %r{^BAD:}, @out
+ end
+
+ def test_rbext
+ rakefile_rbext
+
+ rake "-N"
+
+ assert_match %r{^OK$}, @out
+ end
+
+ def test_system
+ rake_system_dir
+
+ rake '-g', "sys1"
+
+ assert_match %r{^SYS1}, @out
+ end
+
+ def test_system_excludes_rakelib_files_too
+ rake_system_dir
+
+ rake '-g', "sys1", '-T', 'extra'
+
+ refute_match %r{extra:extra}, @out
+ end
+
+ def test_by_default_rakelib_files_are_included
+ rake_system_dir
+ rakefile_extra
+
+ rake '-T', 'extra', '--trace'
+
+ assert_match %r{extra:extra}, @out
+ end
+
+ def test_implicit_system
+ rake_system_dir
+ Dir.chdir @tempdir
+
+ rake "sys1", "--trace"
+
+ assert_match %r{^SYS1}, @out
+ end
+
+ def test_no_system
+ rake_system_dir
+ rakefile_extra
+
+ rake '-G', "sys1"
+
+ assert_match %r{^Don't know how to build task}, @err # emacs wart: '
+ end
+
+ def test_nosearch_with_rakefile_uses_local_rakefile
+ rakefile_default
+
+ rake "--nosearch"
+
+ assert_match %r{^DEFAULT}, @out
+ end
+
+ def test_nosearch_without_rakefile_finds_system
+ rakefile_nosearch
+ rake_system_dir
+
+ rake "--nosearch", "sys1"
+
+ assert_match %r{^SYS1}, @out
+ end
+
+ def test_nosearch_without_rakefile_and_no_system_fails
+ rakefile_nosearch
+ ENV['RAKE_SYSTEM'] = 'not_exist'
+
+ rake "--nosearch"
+
+ assert_match %r{^No Rakefile found}, @err
+ end
+
+ def test_invalid_command_line_options
+ rakefile_default
+
+ rake "--bad-options"
+
+ assert_match %r{invalid +option}i, @err
+ end
+
+ def test_inline_verbose_default_should_show_command
+ rakefile_verbose
+
+ rake "inline_verbose_default"
+
+ assert_match(/ruby -e/, @err)
+ end
+
+ def test_inline_verbose_true_should_show_command
+ rakefile_verbose
+
+ rake "inline_verbose_true"
+
+ assert_match(/ruby -e/, @err)
+ end
+
+ def test_inline_verbose_false_should_not_show_command
+ rakefile_verbose
+
+ rake "inline_verbose_false"
+
+ refute_match(/ruby -e/, @err)
+ end
+
+ def test_block_verbose_false_should_not_show_command
+ rakefile_verbose
+
+ rake "block_verbose_false"
+
+ refute_match(/ruby -e/, @err)
+ end
+
+ def test_block_verbose_true_should_show_command
+ rakefile_verbose
+
+ rake "block_verbose_true"
+
+ assert_match(/ruby -e/, @err)
+ end
+
+ def test_standalone_verbose_true_should_show_command
+ rakefile_verbose
+
+ rake "standalone_verbose_true"
+
+ assert_match(/ruby -e/, @err)
+ end
+
+ def test_standalone_verbose_false_should_not_show_command
+ rakefile_verbose
+
+ rake "standalone_verbose_false"
+
+ refute_match(/ruby -e/, @err)
+ end
+
+ def test_dry_run
+ rakefile_default
+
+ rake "-n", "other"
+
+ assert_match %r{Execute \(dry run\) default}, @err
+ assert_match %r{Execute \(dry run\) other}, @err
+ refute_match %r{DEFAULT}, @out
+ refute_match %r{OTHER}, @out
+ end
+
+ # Test for the trace/dry_run bug found by Brian Chandler
+ def test_dry_run_bug
+ rakefile_dryrun
+
+ rake
+
+ FileUtils.rm_f 'temp_one'
+
+ rake "--dry-run"
+
+ refute_match(/No such file/, @out)
+
+ assert_status
+ end
+
+ # Test for the trace/dry_run bug found by Brian Chandler
+ def test_trace_bug
+ rakefile_dryrun
+
+ rake
+
+ FileUtils.rm_f 'temp_one'
+
+ rake "--trace"
+
+ refute_match(/No such file/, @out)
+ assert_status
+ end
+
+ def test_imports
+ rakefile_imports
+
+ rake
+
+ assert File.exist?(File.join(@tempdir, 'dynamic_deps')),
+ "'dynamic_deps' file should exist"
+ assert_match(/^FIRST$\s+^DYNAMIC$\s+^STATIC$\s+^OTHER$/, @out)
+ assert_status
+ end
+
+ def test_rules_chaining_to_file_task
+ rakefile_chains
+
+ rake
+
+ assert File.exist?(File.join(@tempdir, 'play.app')),
+ "'play.app' file should exist"
+ assert_status
+ end
+
+ def test_file_creation_task
+ rakefile_file_creation
+
+ rake "prep"
+ rake "run"
+ rake "run"
+
+ assert(@err !~ /^cp src/, "Should not recopy data")
+ end
+
+ def test_dash_f_with_no_arg_foils_rakefile_lookup
+ rakefile_rakelib
+
+ rake "-I rakelib -rtest1 -f"
+
+ assert_match(/^TEST1$/, @out)
+ end
+
+ def test_dot_rake_files_can_be_loaded_with_dash_r
+ rakefile_rakelib
+
+ rake "-I rakelib -rtest2 -f"
+
+ assert_match(/^TEST2$/, @out)
+ end
+
+ def test_can_invoke_task_in_toplevel_namespace
+ rakefile_namespace
+
+ rake "copy"
+
+ assert_match(/^COPY$/, @out)
+ end
+
+ def test_can_invoke_task_in_nested_namespace
+ rakefile_namespace
+
+ rake "nest:copy"
+
+ assert_match(/^NEST COPY$/, @out)
+ end
+
+ def test_tasks_can_reference_task_in_same_namespace
+ rakefile_namespace
+
+ rake "nest:xx"
+
+ assert_match(/^NEST COPY$/m, @out)
+ end
+
+ def test_tasks_can_reference_task_in_other_namespaces
+ rakefile_namespace
+
+ rake "b:run"
+
+ assert_match(/^IN A\nIN B$/m, @out)
+ end
+
+ def test_anonymous_tasks_can_be_invoked_indirectly
+ rakefile_namespace
+
+ rake "anon"
+
+ assert_match(/^ANON COPY$/m, @out)
+ end
+
+ def test_rake_namespace_refers_to_toplevel
+ rakefile_namespace
+
+ rake "very:nested:run"
+
+ assert_match(/^COPY$/m, @out)
+ end
+
+ def test_file_task_are_not_scoped_by_namespaces
+ rakefile_namespace
+
+ rake "xyz.rb"
+
+ assert_match(/^XYZ1\nXYZ2$/m, @out)
+ end
+
+ def test_file_task_dependencies_scoped_by_namespaces
+ rakefile_namespace
+
+ rake "scopedep.rb"
+
+ assert_match(/^PREPARE\nSCOPEDEP$/m, @out)
+ end
+
+ def test_rake_returns_status_error_values
+ rakefile_statusreturn
+
+ rake "exit5"
+
+ assert_status 5
+ end
+
+ def test_rake_returns_no_status_error_on_normal_exit
+ rakefile_statusreturn
+
+ rake "normal"
+
+ assert_status 0
+ end
+
+ def test_comment_before_task_acts_like_desc
+ rakefile_comments
+
+ rake "-T"
+
+ refute_match(/comment for t1/, @out)
+ end
+
+ def test_comment_separated_from_task_by_blank_line_is_not_picked_up
+ rakefile_comments
+
+ rake "-T"
+
+ assert_not_match("t2", @out)
+ end
+
+ def test_comment_after_desc_is_ignored
+ rakefile_comments
+
+ rake "-T"
+
+ assert_match("override comment for t3", @out)
+ end
+
+ def test_comment_before_desc_is_ignored
+ rakefile_comments
+
+ rake "-T"
+
+ assert_match("override comment for t4", @out)
+ end
+
+ def test_correct_number_of_tasks_reported
+ rakefile_comments
+
+ rake "-T"
+
+ assert_equal(2, @out.split(/\n/).grep(/t\d/).size)
+ end
+
+ def test_file_list_is_requirable_separately
+ ruby "-rrake/file_list", "-e 'puts Rake::FileList[\"a\"].size'"
+ assert_equal "1\n", @out
+ assert_equal 0, @status
+ end
+
+ private
+
+ def assert_not_match(pattern, string, comment="'#{pattern}' was found (incorrectly) in '#{string}.inspect")
+ assert_nil Regexp.new(pattern).match(string), comment
+ end
+
+ # Run a shell Ruby command with command line options (using the
+ # default test options). Output is captured in @out, @err and
+ # @status.
+ def ruby(*option_list)
+ run_ruby(@ruby_options + option_list)
+ end
+
+ # Run a command line rake with the give rake options. Default
+ # command line ruby options are included. Output is captured in
+ # @out, @err and @status.
+ def rake(*rake_options)
+ run_ruby @ruby_options + [@rake_path] + rake_options
+ end
+
+ # Low level ruby command runner ...
+ def run_ruby(option_list)
+ shell = Session::Shell.new
+ command = "#{Gem.ruby} #{option_list.join ' '}"
+ puts "COMMAND: [#{command}]" if @verbose
+ @out, @err = shell.execute command
+ @status = shell.exit_status
+ puts "STATUS: [#{@status}]" if @verbose
+ puts "OUTPUT: [#{@out}]" if @verbose
+ puts "ERROR: [#{@err}]" if @verbose
+ puts "PWD: [#{Dir.pwd}]" if @verbose
+ shell.close
+ end
+
+ def assert_status(expected_status=0)
+ assert_equal expected_status, @status
+ end
+end if defined?(Session)
diff --git a/test/rake/test_rake_invocation_chain.rb b/test/rake/test_rake_invocation_chain.rb
new file mode 100644
index 0000000000..1aab1eac81
--- /dev/null
+++ b/test/rake/test_rake_invocation_chain.rb
@@ -0,0 +1,52 @@
+require File.expand_path('../helper', __FILE__)
+
+class TestRakeInvocationChain < Rake::TestCase
+
+ def setup
+ super
+
+ @empty = Rake::InvocationChain::EMPTY
+
+ @first_member = "A"
+ @second_member = "B"
+ @one = @empty.append(@first_member)
+ @two = @one.append(@second_member)
+ end
+
+ def test_append
+ chain = @empty.append("A")
+
+ assert_equal 'TOP => A', chain.to_s # HACK
+ end
+
+ def test_append_one_circular
+ ex = assert_raises RuntimeError do
+ @one.append(@first_member)
+ end
+ assert_match(/circular +dependency/i, ex.message)
+ assert_match(/A.*=>.*A/, ex.message)
+ end
+
+ def test_append_two_circular
+ ex = assert_raises RuntimeError do
+ @two.append(@first_member)
+ end
+ assert_match(/A.*=>.*B.*=>.*A/, ex.message)
+ end
+
+ def test_member_eh_one
+ assert @one.member?(@first_member)
+ end
+
+ def test_member_eh_two
+ assert @two.member?(@first_member)
+ assert @two.member?(@second_member)
+ end
+
+ def test_to_s_empty
+ assert_equal "TOP", @empty.to_s
+ assert_equal "TOP => A", @one.to_s
+ end
+
+end
+
diff --git a/test/rake/test_makefile_loader.rb b/test/rake/test_rake_makefile_loader.rb
index 15933b1f9b..bd3c99ba71 100644
--- a/test/rake/test_makefile_loader.rb
+++ b/test/rake/test_rake_makefile_loader.rb
@@ -1,14 +1,34 @@
-require 'test/unit'
-require 'rake'
+require File.expand_path('../helper', __FILE__)
require 'rake/loaders/makefile'
-class Rake::TestMakefileLoader < Test::Unit::TestCase
+class TestRakeMakefileLoader < Rake::TestCase
include Rake
def test_parse
+ Dir.chdir @tempdir
+
+ open 'sample.mf', 'w' do |io|
+ io << <<-'SAMPLE_MF'
+# Comments
+a: a1 a2 a3 a4
+b: b1 b2 b3 \
+ b4 b5 b6\
+# Mid: Comment
+b7
+
+ a : a5 a6 a7
+c: c1
+d: d1 d2 \
+
+e f : e1 f1
+
+g\ 0: g1 g\ 2 g\ 3 g4
+ SAMPLE_MF
+ end
+
Task.clear
loader = Rake::MakefileLoader.new
- loader.load("#{File.dirname(__FILE__)}/data/sample.mf")
+ loader.load 'sample.mf'
%w(a b c d).each do |t|
assert Task.task_defined?(t), "#{t} should be a defined task"
end
diff --git a/test/rake/test_multitask.rb b/test/rake/test_rake_multi_task.rb
index 0413d03db3..cac235b9d3 100644
--- a/test/rake/test_multitask.rb
+++ b/test/rake/test_rake_multi_task.rb
@@ -1,18 +1,27 @@
-require 'test/unit'
-require 'rake'
+require File.expand_path('../helper', __FILE__)
+require 'thread'
-######################################################################
-class Rake::TestMultiTask < Test::Unit::TestCase
+class TestRakeMultiTask < Rake::TestCase
include Rake
+ include Rake::DSL
def setup
+ super
+
Task.clear
@runs = Array.new
+ @mutex = Mutex.new
+ end
+
+ def add_run(obj)
+ @mutex.synchronize do
+ @runs << obj
+ end
end
def test_running_multitasks
- task :a do 3.times do |i| @runs << "A#{i}"; sleep 0.01; end end
- task :b do 3.times do |i| @runs << "B#{i}"; sleep 0.01; end end
+ task :a do 3.times do |i| add_run("A#{i}"); sleep 0.01; end end
+ task :b do 3.times do |i| add_run("B#{i}"); sleep 0.01; end end
multitask :both => [:a, :b]
Task[:both].invoke
assert_equal 6, @runs.size
@@ -23,9 +32,9 @@ class Rake::TestMultiTask < Test::Unit::TestCase
end
def test_all_multitasks_wait_on_slow_prerequisites
- task :slow do 3.times do |i| @runs << "S#{i}"; sleep 0.05 end end
- task :a => [:slow] do 3.times do |i| @runs << "A#{i}"; sleep 0.01 end end
- task :b => [:slow] do 3.times do |i| @runs << "B#{i}"; sleep 0.01 end end
+ task :slow do 3.times do |i| add_run("S#{i}"); sleep 0.05 end end
+ task :a => [:slow] do 3.times do |i| add_run("A#{i}"); sleep 0.01 end end
+ task :b => [:slow] do 3.times do |i| add_run("B#{i}"); sleep 0.01 end end
multitask :both => [:a, :b]
Task[:both].invoke
assert_equal 9, @runs.size
@@ -40,4 +49,3 @@ class Rake::TestMultiTask < Test::Unit::TestCase
end
end
-
diff --git a/test/rake/test_namespace.rb b/test/rake/test_rake_name_space.rb
index bd513b6a10..b1f2ed00b2 100644
--- a/test/rake/test_namespace.rb
+++ b/test/rake/test_rake_name_space.rb
@@ -1,7 +1,6 @@
-require 'test/unit'
-require 'rake'
+require File.expand_path('../helper', __FILE__)
-class Rake::TestNameSpace < Test::Unit::TestCase
+class TestRakeNameSpace < Rake::TestCase
class TM
include Rake::TaskManager
@@ -10,7 +9,7 @@ class Rake::TestNameSpace < Test::Unit::TestCase
def test_namespace_creation
mgr = TM.new
ns = Rake::NameSpace.new(mgr, [])
- assert_not_nil ns
+ refute_nil ns
end
def test_namespace_lookup
@@ -19,7 +18,7 @@ class Rake::TestNameSpace < Test::Unit::TestCase
mgr.define_task(Rake::Task, "t")
end
- assert_not_nil ns["t"]
+ refute_nil ns["t"]
assert_equal mgr["n:t"], ns["t"]
end
diff --git a/test/rake/test_rake_package_task.rb b/test/rake/test_rake_package_task.rb
new file mode 100644
index 0000000000..87cb57c105
--- /dev/null
+++ b/test/rake/test_rake_package_task.rb
@@ -0,0 +1,79 @@
+require File.expand_path('../helper', __FILE__)
+require 'rake/packagetask'
+
+class TestRakePackageTask < Rake::TestCase
+
+ def test_initialize
+ touch 'install.rb'
+ touch 'a.c'
+ touch 'b.c'
+ mkdir 'CVS'
+ touch 'a.rb~'
+
+ pkg = Rake::PackageTask.new("pkgr", "1.2.3") { |p|
+ p.package_files << "install.rb"
+ p.package_files.include '*.c'
+ p.package_files.exclude(/\bCVS\b/)
+ p.package_files.exclude(/~$/)
+ p.package_dir = 'pkg'
+ p.need_tar = true
+ p.need_tar_gz = true
+ p.need_tar_bz2 = true
+ p.need_zip = true
+ }
+
+ assert_equal "pkg", pkg.package_dir
+
+ assert_includes pkg.package_files, 'a.c'
+
+ assert_equal 'pkgr', pkg.name
+ assert_equal '1.2.3', pkg.version
+ assert Rake::Task[:package]
+ assert Rake::Task['pkg/pkgr-1.2.3.tgz']
+ assert Rake::Task['pkg/pkgr-1.2.3.tar.gz']
+ assert Rake::Task['pkg/pkgr-1.2.3.tar.bz2']
+ assert Rake::Task['pkg/pkgr-1.2.3.zip']
+ assert Rake::Task['pkg/pkgr-1.2.3']
+ assert Rake::Task[:clobber_package]
+ assert Rake::Task[:repackage]
+ end
+
+ def test_initialize_no_version
+ e = assert_raises RuntimeError do
+ Rake::PackageTask.new 'pkgr'
+ end
+
+ assert_equal 'Version required (or :noversion)', e.message
+ end
+
+ def test_initialize_noversion
+ pkg = Rake::PackageTask.new 'pkgr', :noversion
+
+ assert_equal 'pkg', pkg.package_dir
+ assert_equal 'pkgr', pkg.name
+ assert_equal nil, pkg.version
+ end
+
+ def test_clone
+ pkg = Rake::PackageTask.new("x", :noversion)
+ p2 = pkg.clone
+ pkg.package_files << "y"
+ p2.package_files << "x"
+ assert_equal ["y"], pkg.package_files
+ assert_equal ["x"], p2.package_files
+ end
+
+ def test_package_name
+ pkg = Rake::PackageTask.new 'a', '1'
+
+ assert_equal 'a-1', pkg.package_name
+ end
+
+ def test_package_name_noversion
+ pkg = Rake::PackageTask.new 'a', :noversion
+
+ assert_equal 'a', pkg.package_name
+ end
+
+end
+
diff --git a/test/rake/test_pathmap.rb b/test/rake/test_rake_path_map.rb
index 2775b91039..32ffb854b1 100644
--- a/test/rake/test_pathmap.rb
+++ b/test/rake/test_rake_path_map.rb
@@ -1,8 +1,6 @@
-require 'test/unit'
-require 'rake'
+require File.expand_path('../helper', __FILE__)
-# ====================================================================
-class Rake::TestPathMap < Test::Unit::TestCase
+class TestRakePathMap < Rake::TestCase
def test_returns_self_with_no_args
assert_equal "abc.rb", "abc.rb".pathmap
@@ -84,7 +82,7 @@ class Rake::TestPathMap < Test::Unit::TestCase
end
def test_undefined_percent_causes_error
- ex = assert_raise(ArgumentError) {
+ assert_raises(ArgumentError) {
"dir/abc.rb".pathmap("%z")
}
end
@@ -128,7 +126,7 @@ class Rake::TestPathMap < Test::Unit::TestCase
end
def test_pattern_with_invalid_operator
- ex = assert_raise(ArgumentError) do
+ ex = assert_raises(ArgumentError) do
"abc.xyz".pathmap("%{src,bin}z")
end
assert_match(/unknown.*pathmap.*spec.*z/i, ex.message)
@@ -157,51 +155,3 @@ class Rake::TestPathMap < Test::Unit::TestCase
end
end
-class Rake::TestPathMapExplode < Test::Unit::TestCase
- def setup
- String.class_eval { public :pathmap_explode }
- end
-
- def teardown
- String.class_eval { protected :pathmap_explode }
- end
-
- def test_explode
- assert_equal ['a'], 'a'.pathmap_explode
- assert_equal ['a', 'b'], 'a/b'.pathmap_explode
- assert_equal ['a', 'b', 'c'], 'a/b/c'.pathmap_explode
- assert_equal ['/', 'a'], '/a'.pathmap_explode
- assert_equal ['/', 'a', 'b'], '/a/b'.pathmap_explode
- assert_equal ['/', 'a', 'b', 'c'], '/a/b/c'.pathmap_explode
- if File::ALT_SEPARATOR
- assert_equal ['c:.', 'a'], 'c:a'.pathmap_explode
- assert_equal ['c:.', 'a', 'b'], 'c:a/b'.pathmap_explode
- assert_equal ['c:.', 'a', 'b', 'c'], 'c:a/b/c'.pathmap_explode
- assert_equal ['c:/', 'a'], 'c:/a'.pathmap_explode
- assert_equal ['c:/', 'a', 'b'], 'c:/a/b'.pathmap_explode
- assert_equal ['c:/', 'a', 'b', 'c'], 'c:/a/b/c'.pathmap_explode
- end
- end
-end
-
-class Rake::TestPathMapPartial < Test::Unit::TestCase
- def test_pathmap_partial
- @path = "1/2/file"
- def @path.call(n)
- pathmap_partial(n)
- end
- assert_equal("1", @path.call(1))
- assert_equal("1/2", @path.call(2))
- assert_equal("1/2", @path.call(3))
- assert_equal(".", @path.call(0))
- assert_equal("2", @path.call(-1))
- assert_equal("1/2", @path.call(-2))
- assert_equal("1/2", @path.call(-3))
- end
-end
-
-class Rake::TestFileListPathMap < Test::Unit::TestCase
- def test_file_list_supports_pathmap
- assert_equal ['a', 'b'], FileList['dir/a.rb', 'dir/b.rb'].pathmap("%n")
- end
-end
diff --git a/test/rake/test_rake_path_map_explode.rb b/test/rake/test_rake_path_map_explode.rb
new file mode 100644
index 0000000000..a79235ee74
--- /dev/null
+++ b/test/rake/test_rake_path_map_explode.rb
@@ -0,0 +1,34 @@
+require File.expand_path('../helper', __FILE__)
+
+class TestRakePathMapExplode < Rake::TestCase
+ def setup
+ super
+
+ String.class_eval { public :pathmap_explode }
+ end
+
+ def teardown
+ String.class_eval { protected :pathmap_explode }
+
+ super
+ end
+
+ def test_explode
+ assert_equal ['a'], 'a'.pathmap_explode
+ assert_equal ['a', 'b'], 'a/b'.pathmap_explode
+ assert_equal ['a', 'b', 'c'], 'a/b/c'.pathmap_explode
+ assert_equal ['/', 'a'], '/a'.pathmap_explode
+ assert_equal ['/', 'a', 'b'], '/a/b'.pathmap_explode
+ assert_equal ['/', 'a', 'b', 'c'], '/a/b/c'.pathmap_explode
+
+ if File::ALT_SEPARATOR
+ assert_equal ['c:.', 'a'], 'c:a'.pathmap_explode
+ assert_equal ['c:.', 'a', 'b'], 'c:a/b'.pathmap_explode
+ assert_equal ['c:.', 'a', 'b', 'c'], 'c:a/b/c'.pathmap_explode
+ assert_equal ['c:/', 'a'], 'c:/a'.pathmap_explode
+ assert_equal ['c:/', 'a', 'b'], 'c:/a/b'.pathmap_explode
+ assert_equal ['c:/', 'a', 'b', 'c'], 'c:/a/b/c'.pathmap_explode
+ end
+ end
+end
+
diff --git a/test/rake/test_rake_path_map_partial.rb b/test/rake/test_rake_path_map_partial.rb
new file mode 100644
index 0000000000..566e681bb1
--- /dev/null
+++ b/test/rake/test_rake_path_map_partial.rb
@@ -0,0 +1,18 @@
+require File.expand_path('../helper', __FILE__)
+
+class TestRakePathMapPartial < Rake::TestCase
+ def test_pathmap_partial
+ @path = "1/2/file"
+ def @path.call(n)
+ pathmap_partial(n)
+ end
+ assert_equal("1", @path.call(1))
+ assert_equal("1/2", @path.call(2))
+ assert_equal("1/2", @path.call(3))
+ assert_equal(".", @path.call(0))
+ assert_equal("2", @path.call(-1))
+ assert_equal("1/2", @path.call(-2))
+ assert_equal("1/2", @path.call(-3))
+ end
+end
+
diff --git a/test/rake/test_pseudo_status.rb b/test/rake/test_rake_pseudo_status.rb
index 8bafd5f80a..51b3fef34e 100644
--- a/test/rake/test_pseudo_status.rb
+++ b/test/rake/test_rake_pseudo_status.rb
@@ -1,23 +1,21 @@
-require 'test/unit'
-require 'rake'
+require File.expand_path('../helper', __FILE__)
-require_relative 'capture_stdout'
-
-class Rake::TestPseudoStatus < Test::Unit::TestCase
+class TestRakePseudoStatus < Rake::TestCase
def test_with_zero_exit_status
s = Rake::PseudoStatus.new
assert_equal 0, s.exitstatus
assert_equal 0, s.to_i
assert_equal 0, s >> 8
- assert ! s.stopped?
+ refute s.stopped?
assert s.exited?
end
+
def test_with_99_exit_status
s = Rake::PseudoStatus.new(99)
assert_equal 99, s.exitstatus
assert_equal 25344, s.to_i
assert_equal 99, s >> 8
- assert ! s.stopped?
+ refute s.stopped?
assert s.exited?
end
end
diff --git a/test/rake/test_rake_rdoc_task.rb b/test/rake/test_rake_rdoc_task.rb
new file mode 100644
index 0000000000..0d24ef04a3
--- /dev/null
+++ b/test/rake/test_rake_rdoc_task.rb
@@ -0,0 +1,83 @@
+require File.expand_path('../helper', __FILE__)
+begin
+ old_stderr = $stderr
+ dev_null = File.exist?('/dev/null') ? '/dev/null' : 'NUL'
+ $stderr = open dev_null, 'w'
+ require 'rake/rdoctask'
+ensure
+ $stderr.close
+ $stderr = old_stderr
+end
+
+class TestRakeRDocTask < Rake::TestCase
+ include Rake
+
+ def setup
+ super
+
+ Task.clear
+ end
+
+ def test_tasks_creation
+ Rake::RDocTask.new
+ assert Task[:rdoc]
+ assert Task[:clobber_rdoc]
+ assert Task[:rerdoc]
+ end
+
+ def test_tasks_creation_with_custom_name_symbol
+ rd = Rake::RDocTask.new(:rdoc_dev)
+ assert Task[:rdoc_dev]
+ assert Task[:clobber_rdoc_dev]
+ assert Task[:rerdoc_dev]
+ assert_equal :rdoc_dev, rd.name
+ end
+
+ def test_tasks_creation_with_custom_name_string
+ rd = Rake::RDocTask.new("rdoc_dev")
+ assert Task[:rdoc_dev]
+ assert Task[:clobber_rdoc_dev]
+ assert Task[:rerdoc_dev]
+ assert_equal "rdoc_dev", rd.name
+ end
+
+ def test_tasks_creation_with_custom_name_hash
+ options = { :rdoc => "rdoc", :clobber_rdoc => "rdoc:clean", :rerdoc => "rdoc:force" }
+ rd = Rake::RDocTask.new(options)
+ assert Task[:"rdoc"]
+ assert Task[:"rdoc:clean"]
+ assert Task[:"rdoc:force"]
+ assert_raises(RuntimeError) { Task[:clobber_rdoc] }
+ assert_equal options, rd.name
+ end
+
+ def test_tasks_creation_with_custom_name_hash_will_use_default_if_an_option_isnt_given
+ Rake::RDocTask.new(:clobber_rdoc => "rdoc:clean")
+ assert Task[:rdoc]
+ assert Task[:"rdoc:clean"]
+ assert Task[:rerdoc]
+ end
+
+ def test_tasks_creation_with_custom_name_hash_raises_exception_if_invalid_option_given
+ assert_raises(ArgumentError) do
+ Rake::RDocTask.new(:foo => "bar")
+ end
+
+ begin
+ Rake::RDocTask.new(:foo => "bar")
+ rescue ArgumentError => e
+ assert_match(/foo/, e.message)
+ end
+ end
+
+ def test_inline_source_option_is_only_appended_if_option_not_already_given
+ rd = Rake::RDocTask.new
+ rd.options << '--inline-source'
+ assert_equal 1, rd.option_list.grep('--inline-source').size
+
+ rd = Rake::RDocTask.new
+ rd.options << '-S'
+ assert_equal 1, rd.option_list.grep('-S').size
+ assert_equal 0, rd.option_list.grep('--inline-source').size
+ end
+end
diff --git a/test/rake/test_rake_require.rb b/test/rake/test_rake_require.rb
new file mode 100644
index 0000000000..d229edbc2b
--- /dev/null
+++ b/test/rake/test_rake_require.rb
@@ -0,0 +1,40 @@
+require File.expand_path('../helper', __FILE__)
+
+class TestRakeRequire < Rake::TestCase
+
+ def test_can_load_rake_library
+ rakefile_rakelib
+ app = Rake::Application.new
+
+ assert app.instance_eval {
+ rake_require("test2", ['rakelib'], [])
+ }
+ end
+
+ def test_wont_reload_rake_library
+ rakefile_rakelib
+ app = Rake::Application.new
+
+ paths = ['rakelib']
+ loaded_files = []
+ app.rake_require("test2", paths, loaded_files)
+
+ assert ! app.instance_eval {
+ rake_require("test2", paths, loaded_files)
+ }
+ end
+
+ def test_throws_error_if_library_not_found
+ rakefile_rakelib
+
+ app = Rake::Application.new
+ ex = assert_raises(LoadError) {
+ assert app.instance_eval {
+ rake_require("testx", ['rakelib'], [])
+ }
+ }
+ assert_match(/(can *not|can't)\s+find/i, ex.message)
+ assert_match(/testx/, ex.message)
+ end
+end
+
diff --git a/test/rake/test_rules.rb b/test/rake/test_rake_rules.rb
index 34df180ff4..3f6e352322 100644
--- a/test/rake/test_rules.rb
+++ b/test/rake/test_rake_rules.rb
@@ -1,36 +1,23 @@
-require 'test/unit'
-require 'tmpdir'
+require File.expand_path('../helper', __FILE__)
require 'fileutils'
-require 'rake'
-require_relative 'filecreation'
-######################################################################
-class Rake::TestRules < Test::Unit::TestCase
+class TestRakeRules < Rake::TestCase
include Rake
- include FileCreation
- SRCFILE = "testdata/abc.c"
- SRCFILE2 = "testdata/xyz.c"
- FTNFILE = "testdata/abc.f"
- OBJFILE = "testdata/abc.o"
- FOOFILE = "testdata/foo"
- DOTFOOFILE = "testdata/.foo"
+ SRCFILE = "abc.c"
+ SRCFILE2 = "xyz.c"
+ FTNFILE = "abc.f"
+ OBJFILE = "abc.o"
+ FOOFILE = "foo"
+ DOTFOOFILE = ".foo"
def setup
- @oldpwd = Dir.pwd
- @tmpdir = Dir.mktmpdir("rake")
- Dir.chdir(@tmpdir)
- Dir.mkdir("testdata")
+ super
+
Task.clear
@runs = []
end
- def teardown
- FileList['testdata/{*,.[^.]*,}'].uniq.each do |f| rm_r(f, :verbose=>false) end
- Dir.chdir(@oldpwd)
- Dir.rmdir(@tmpdir)
- end
-
def test_multiple_rules1
create_file(FTNFILE)
delete_file(SRCFILE)
@@ -100,81 +87,70 @@ class Rake::TestRules < Test::Unit::TestCase
assert_equal [OBJFILE], @runs
end
- def test_file_names_beginning_with_dot_can_be_tricked_into_refering_to_file
+ def test_file_names_beginning_with_dot_can_be_tricked_into_referring_to_file
verbose(false) do
- chdir("testdata") do
- create_file('.foo')
- rule '.o' => "./.foo" do |t|
- @runs << t.name
- end
- Task[OBJFILE].invoke
- assert_equal [OBJFILE], @runs
+ create_file('.foo')
+ rule '.o' => "./.foo" do |t|
+ @runs << t.name
end
+ Task[OBJFILE].invoke
+ assert_equal [OBJFILE], @runs
end
end
def test_file_names_beginning_with_dot_can_be_wrapped_in_lambda
verbose(false) do
- chdir("testdata") do
- create_file(".foo")
- rule '.o' => lambda{".foo"} do |t|
- @runs << "#{t.name} - #{t.source}"
- end
- Task[OBJFILE].invoke
- assert_equal ["#{OBJFILE} - .foo"], @runs
+
+ create_file(".foo")
+ rule '.o' => lambda{".foo"} do |t|
+ @runs << "#{t.name} - #{t.source}"
end
+ Task[OBJFILE].invoke
+ assert_equal ["#{OBJFILE} - .foo"], @runs
end
end
def test_file_names_containing_percent_can_be_wrapped_in_lambda
verbose(false) do
- chdir("testdata") do
- create_file("foo%x")
- rule '.o' => lambda{"foo%x"} do |t|
- @runs << "#{t.name} - #{t.source}"
- end
- Task[OBJFILE].invoke
- assert_equal ["#{OBJFILE} - foo%x"], @runs
+ create_file("foo%x")
+ rule '.o' => lambda{"foo%x"} do |t|
+ @runs << "#{t.name} - #{t.source}"
end
+ Task[OBJFILE].invoke
+ assert_equal ["#{OBJFILE} - foo%x"], @runs
end
end
def test_non_extension_rule_name_refers_to_file
verbose(false) do
- chdir("testdata") do
- create_file("abc.c")
- rule "abc" => '.c' do |t|
- @runs << t.name
- end
- Task["abc"].invoke
- assert_equal ["abc"], @runs
+ create_file("abc.c")
+ rule "abc" => '.c' do |t|
+ @runs << t.name
end
+ Task["abc"].invoke
+ assert_equal ["abc"], @runs
end
end
def test_pathmap_automatically_applies_to_name
verbose(false) do
- chdir("testdata") do
- create_file("zzabc.c")
- rule ".o" => 'zz%{x,a}n.c' do |t|
- @runs << "#{t.name} - #{t.source}"
- end
- Task["xbc.o"].invoke
- assert_equal ["xbc.o - zzabc.c"], @runs
+ create_file("zzabc.c")
+ rule ".o" => 'zz%{x,a}n.c' do |t|
+ @runs << "#{t.name} - #{t.source}"
end
+ Task["xbc.o"].invoke
+ assert_equal ["xbc.o - zzabc.c"], @runs
end
end
def test_plain_strings_are_just_filenames
verbose(false) do
- chdir("testdata") do
- create_file("plainname")
- rule ".o" => 'plainname' do |t|
- @runs << "#{t.name} - #{t.source}"
- end
- Task["xbc.o"].invoke
- assert_equal ["xbc.o - plainname"], @runs
+ create_file("plainname")
+ rule ".o" => 'plainname' do |t|
+ @runs << "#{t.name} - #{t.source}"
end
+ Task["xbc.o"].invoke
+ assert_equal ["xbc.o - plainname"], @runs
end
end
@@ -191,12 +167,12 @@ class Rake::TestRules < Test::Unit::TestCase
end
def test_close_matches_on_name_do_not_trigger_rule
- create_file("testdata/x.c")
+ create_file("x.c")
rule '.o' => ['.c'] do |t|
@runs << t.name
end
- assert_raise(RuntimeError) { Task['testdata/x.obj'].invoke }
- assert_raise(RuntimeError) { Task['testdata/x.xyo'].invoke }
+ assert_raises(RuntimeError) { Task['x.obj'].invoke }
+ assert_raises(RuntimeError) { Task['x.xyo'].invoke }
end
def test_rule_rebuilds_obj_when_source_is_newer
@@ -281,27 +257,26 @@ class Rake::TestRules < Test::Unit::TestCase
end
def test_rule_with_proc_dependent_will_trigger
- ran = false
- mkdir_p("testdata/src/jw")
- create_file("testdata/src/jw/X.java")
+ mkdir_p("src/jw")
+ create_file("src/jw/X.java")
rule %r(classes/.*\.class) => [
- proc { |fn| fn.pathmap("%{classes,testdata/src}d/%n.java") }
+ proc { |fn| fn.pathmap("%{classes,src}d/%n.java") }
] do |task|
assert_equal task.name, 'classes/jw/X.class'
- assert_equal task.source, 'testdata/src/jw/X.java'
+ assert_equal task.source, 'src/jw/X.java'
@runs << :RULE
end
Task['classes/jw/X.class'].invoke
assert_equal [:RULE], @runs
ensure
- rm_r("testdata/src", :verbose=>false) rescue nil
+ rm_r("src", :verbose=>false) rescue nil
end
def test_proc_returning_lists_are_flattened_into_prereqs
ran = false
- mkdir_p("testdata/flatten")
- create_file("testdata/flatten/a.txt")
- task 'testdata/flatten/b.data' do |t|
+ mkdir_p("flatten")
+ create_file("flatten/a.txt")
+ task 'flatten/b.data' do |t|
ran = true
touch t.name, :verbose => false
end
@@ -309,43 +284,43 @@ class Rake::TestRules < Test::Unit::TestCase
proc { |fn|
[
fn.ext("txt"),
- "testdata/flatten/b.data"
+ "flatten/b.data"
]
} do |task|
end
- Task['testdata/flatten/a.html'].invoke
+ Task['flatten/a.html'].invoke
assert ran, "Should have triggered flattened dependency"
ensure
- rm_r("testdata/flatten", :verbose=>false) rescue nil
+ rm_r("flatten", :verbose=>false) rescue nil
end
def test_recursive_rules_will_work_as_long_as_they_terminate
actions = []
- create_file("testdata/abc.xml")
+ create_file("abc.xml")
rule '.y' => '.xml' do actions << 'y' end
rule '.c' => '.y' do actions << 'c'end
rule '.o' => '.c' do actions << 'o'end
rule '.exe' => '.o' do actions << 'exe'end
- Task["testdata/abc.exe"].invoke
+ Task["abc.exe"].invoke
assert_equal ['y', 'c', 'o', 'exe'], actions
end
def test_recursive_rules_that_dont_terminate_will_overflow
- create_file("testdata/a.a")
+ create_file("a.a")
prev = 'a'
('b'..'z').each do |letter|
rule ".#{letter}" => ".#{prev}" do |t| puts "#{t.name}" end
prev = letter
end
- ex = assert_raise(Rake::RuleRecursionOverflowError) {
- Task["testdata/a.z"].invoke
+ ex = assert_raises(Rake::RuleRecursionOverflowError) {
+ Task["a.z"].invoke
}
- assert_match(/a\.z => testdata\/a.y/, ex.message)
+ assert_match(/a\.z => a.y/, ex.message)
end
def test_rules_with_bad_dependents_will_fail
rule "a" => [ 1 ] do |t| puts t.name end
- assert_raise(RuntimeError) do Task['a'].invoke end
+ assert_raises(RuntimeError) do Task['a'].invoke end
end
end
diff --git a/test/rake/test_tasks.rb b/test/rake/test_rake_task.rb
index 110ee26a9e..ebbcb2ac2d 100644
--- a/test/rake/test_tasks.rb
+++ b/test/rake/test_rake_task.rb
@@ -1,16 +1,20 @@
-require 'test/unit'
+require File.expand_path('../helper', __FILE__)
require 'fileutils'
-require 'rake'
-require_relative 'filecreation'
-require_relative 'capture_stdout'
-######################################################################
-class Rake::TestTasks < Test::Unit::TestCase
- include CaptureStdout
+class TestRakeTask < Rake::TestCase
include Rake
def setup
+ super
+
Task.clear
+ Rake::TaskManager.record_task_metadata = true
+ end
+
+ def teardown
+ Rake::TaskManager.record_task_metadata = false
+
+ super
end
def test_create
@@ -23,10 +27,13 @@ class Rake::TestTasks < Test::Unit::TestCase
assert_equal t, arg
assert_nil t.source
assert_equal [], t.sources
+ assert_equal 1, t.locations.size
+ assert_match(/#{Regexp.quote(__FILE__)}/, t.locations.first)
end
def test_inspect
- t = task(:foo, :needs => [:bar, :baz])
+# t = task(:foo, :needs => [:bar, :baz])
+ t = task(:foo => [:bar, :baz])
assert_equal "<Rake::Task foo => [bar, baz]>", t.inspect
end
@@ -46,7 +53,7 @@ class Rake::TestTasks < Test::Unit::TestCase
t2 = task(:t2 => [:t1]) { |t| runlist << t.name }
assert_equal ["t2"], t1.prerequisites
assert_equal ["t1"], t2.prerequisites
- ex = assert_raise RuntimeError do
+ ex = assert_raises RuntimeError do
t1.invoke
end
assert_match(/circular dependency/i, ex.message)
@@ -57,10 +64,10 @@ class Rake::TestTasks < Test::Unit::TestCase
Rake.application.options.dryrun = true
runlist = []
t1 = task(:t1) { |t| runlist << t.name; 3321 }
- out = capture_stdout { t1.invoke }
- assert_match(/execute .*t1/i, out)
- assert_match(/dry run/i, out)
- assert_no_match(/invoke/i, out)
+ _, err = capture_io { t1.invoke }
+ assert_match(/execute .*t1/i, err)
+ assert_match(/dry run/i, err)
+ refute_match(/invoke/i, err)
assert_equal [], runlist
ensure
Rake.application.options.dryrun = false
@@ -69,11 +76,11 @@ class Rake::TestTasks < Test::Unit::TestCase
def test_tasks_can_be_traced
Rake.application.options.trace = true
t1 = task(:t1)
- out = capture_stdout {
+ _, err = capture_io {
t1.invoke
}
- assert_match(/invoke t1/i, out)
- assert_match(/execute t1/i, out)
+ assert_match(/invoke t1/i, err)
+ assert_match(/execute t1/i, err)
ensure
Rake.application.options.trace = false
end
@@ -119,7 +126,7 @@ class Rake::TestTasks < Test::Unit::TestCase
def test_find
task :tfind
assert_equal "tfind", Task[:tfind].name
- ex = assert_raise(RuntimeError) { Task[:leaves] }
+ ex = assert_raises(RuntimeError) { Task[:leaves] }
assert_equal "Don't know how to build task 'leaves'", ex.message
end
@@ -170,6 +177,56 @@ class Rake::TestTasks < Test::Unit::TestCase
assert_equal ["b", "c"], Task[:a].prerequisites
end
+ def test_prerequiste_tasks_returns_tasks_not_strings
+ a = task :a => ["b", "c"]
+ b = task :b
+ c = task :c
+ assert_equal [b, c], a.prerequisite_tasks
+ end
+
+ def test_prerequiste_tasks_fails_if_prerequisites_are_undefined
+ a = task :a => ["b", "c"]
+ b = task :b
+ assert_raises(RuntimeError) do
+ a.prerequisite_tasks
+ end
+ end
+
+ def test_prerequiste_tasks_honors_namespaces
+ a = b = nil
+ namespace "X" do
+ a = task :a => ["b", "c"]
+ b = task :b
+ end
+ c = task :c
+
+ assert_equal [b, c], a.prerequisite_tasks
+ end
+
+ def test_timestamp_returns_now_if_all_prereqs_have_no_times
+ a = task :a => ["b", "c"]
+ b = task :b
+ c = task :c
+
+ faux_stamp = 100
+ flexmock(Time, :now => faux_stamp)
+
+ assert_equal faux_stamp, a.timestamp
+ end
+
+ def test_timestamp_returns_latest_prereq_timestamp
+ a = task :a => ["b", "c"]
+ b = task :b
+ c = task :c
+
+ faux_stamp = 100
+ flexmock(Time, :now => faux_stamp-10)
+ flexmock(b, :timestamp => faux_stamp - 1)
+ flexmock(c, :timestamp => faux_stamp)
+
+ assert_equal faux_stamp, a.timestamp
+ end
+
def test_investigation_output
t1 = task(:t1 => [:t2, :t3]) { |t| runlist << t.name; 3321 }
task(:t2)
@@ -212,159 +269,3 @@ class Rake::TestTasks < Test::Unit::TestCase
end
end
-######################################################################
-class Rake::TestTaskWithArguments < Test::Unit::TestCase
- include CaptureStdout
- include Rake
-
- def setup
- Task.clear
- end
-
- def test_no_args_given
- t = task :t
- assert_equal [], t.arg_names
- end
-
- def test_args_given
- t = task :t, :a, :b
- assert_equal [:a, :b], t.arg_names
- end
-
- def test_name_and_needs
- t = task(:t => [:pre])
- assert_equal "t", t.name
- assert_equal [], t.arg_names
- assert_equal ["pre"], t.prerequisites
- end
-
- def test_name_and_explicit_needs
- t = task(:t, :needs => [:pre])
- assert_equal "t", t.name
- assert_equal [], t.arg_names
- assert_equal ["pre"], t.prerequisites
- end
-
- def test_name_args_and_explicit_needs
- t = task(:t, :x, :y, :needs => [:pre])
- assert_equal "t", t.name
- assert_equal [:x, :y], t.arg_names
- assert_equal ["pre"], t.prerequisites
- end
-
- def test_illegal_keys_in_task_name_hash
- assert_raise RuntimeError do
- t = task(:t, :x, :y => 1, :needs => [:pre])
- end
- end
-
- def test_arg_list_is_empty_if_no_args_given
- t = task(:t) { |tt, args| assert_equal({}, args.to_hash) }
- t.invoke(1, 2, 3)
- end
-
- def test_tasks_can_access_arguments_as_hash
- t = task :t, :a, :b, :c do |tt, args|
- assert_equal({:a => 1, :b => 2, :c => 3}, args.to_hash)
- assert_equal 1, args[:a]
- assert_equal 2, args[:b]
- assert_equal 3, args[:c]
- assert_equal 1, args.a
- assert_equal 2, args.b
- assert_equal 3, args.c
- end
- t.invoke(1, 2, 3)
- end
-
- def test_actions_of_various_arity_are_ok_with_args
- notes = []
- t = task(:t, :x) do
- notes << :a
- end
- t.enhance do | |
- notes << :b
- end
- t.enhance do |task|
- notes << :c
- assert_kind_of Task, task
- end
- t.enhance do |t2, args|
- notes << :d
- assert_equal t, t2
- assert_equal({:x => 1}, args.to_hash)
- end
- assert_nothing_raised do t.invoke(1) end
- assert_equal [:a, :b, :c, :d], notes
- end
-
- def test_arguments_are_passed_to_block
- t = task(:t, :a, :b) { |tt, args|
- assert_equal( { :a => 1, :b => 2 }, args.to_hash )
- }
- t.invoke(1, 2)
- end
-
- def test_extra_parameters_are_ignored
- ENV['b'] = nil
- t = task(:t, :a) { |tt, args|
- assert_equal 1, args.a
- assert_nil args.b
- }
- t.invoke(1, 2)
- end
-
- def test_arguments_are_passed_to_all_blocks
- counter = 0
- t = task :t, :a
- task :t do |tt, args|
- assert_equal 1, args.a
- counter += 1
- end
- task :t do |tt, args|
- assert_equal 1, args.a
- counter += 1
- end
- t.invoke(1)
- assert_equal 2, counter
- end
-
- def test_block_with_no_parameters_is_ok
- t = task(:t) { }
- t.invoke(1, 2)
- end
-
- def test_name_with_args
- desc "T"
- t = task(:tt, :a, :b)
- assert_equal "tt", t.name
- assert_equal "T", t.comment
- assert_equal "[a,b]", t.arg_description
- assert_equal "tt[a,b]", t.name_with_args
- assert_equal [:a, :b],t.arg_names
- end
-
- def test_named_args_are_passed_to_prereqs
- value = nil
- pre = task(:pre, :rev) { |t, args| value = args.rev }
- t = task(:t, :name, :rev, :needs => [:pre])
- t.invoke("bill", "1.2")
- assert_equal "1.2", value
- end
-
- def test_args_not_passed_if_no_prereq_names
- pre = task(:pre) { |t, args|
- assert_equal({}, args.to_hash)
- assert_equal "bill", args.name
- }
- t = task(:t, :name, :rev, :needs => [:pre])
- t.invoke("bill", "1.2")
- end
-
- def test_args_not_passed_if_no_arg_names
- pre = task(:pre, :rev) { |t, args|
- assert_equal({}, args.to_hash)
- }
- t = task(:t, :needs => [:pre])
- t.invoke("bill", "1.2")
- end
-end
diff --git a/test/rake/test_rake_task_argument_parsing.rb b/test/rake/test_rake_task_argument_parsing.rb
new file mode 100644
index 0000000000..7a03b2addc
--- /dev/null
+++ b/test/rake/test_rake_task_argument_parsing.rb
@@ -0,0 +1,110 @@
+require File.expand_path('../helper', __FILE__)
+
+class TestRakeTaskArgumentParsing < Rake::TestCase
+ def setup
+ super
+
+ @app = Rake::Application.new
+ end
+
+ def test_name_only
+ name, args = @app.parse_task_string("name")
+ assert_equal "name", name
+ assert_equal [], args
+ end
+
+ def test_empty_args
+ name, args = @app.parse_task_string("name[]")
+ assert_equal "name", name
+ assert_equal [], args
+ end
+
+ def test_one_argument
+ name, args = @app.parse_task_string("name[one]")
+ assert_equal "name", name
+ assert_equal ["one"], args
+ end
+
+ def test_two_arguments
+ name, args = @app.parse_task_string("name[one,two]")
+ assert_equal "name", name
+ assert_equal ["one", "two"], args
+ end
+
+ def test_can_handle_spaces_between_args
+ name, args = @app.parse_task_string("name[one, two,\tthree , \tfour]")
+ assert_equal "name", name
+ assert_equal ["one", "two", "three", "four"], args
+ end
+
+ def test_keeps_embedded_spaces
+ name, args = @app.parse_task_string("name[a one ana, two]")
+ assert_equal "name", name
+ assert_equal ["a one ana", "two"], args
+ end
+
+ def test_terminal_width_using_env
+ app = Rake::Application.new
+ app.terminal_columns = 1234
+
+ assert_equal 1234, app.terminal_width
+ end
+
+ def test_terminal_width_using_stty
+ app = Rake::Application.new
+
+ flexmock(app,
+ :unix? => true,
+ :dynamic_width_stty => 1235,
+ :dynamic_width_tput => 0)
+
+ assert_equal 1235, app.terminal_width
+ end
+
+ def test_terminal_width_using_tput
+ app = Rake::Application.new
+ flexmock(app,
+ :unix? => true,
+ :dynamic_width_stty => 0,
+ :dynamic_width_tput => 1236)
+
+ assert_equal 1236, app.terminal_width
+ end
+
+ def test_terminal_width_using_hardcoded_80
+ app = Rake::Application.new
+ flexmock(app, :unix? => false)
+
+ assert_equal 80, app.terminal_width
+ end
+
+ def test_terminal_width_with_failure
+ app = Rake::Application.new
+ flexmock(app).should_receive(:unix?).and_throw(RuntimeError)
+
+ assert_equal 80, app.terminal_width
+ end
+
+ def test_no_rakeopt
+ ARGV << '--trace'
+ app = Rake::Application.new
+ app.init
+ assert !app.options.silent
+ end
+
+ def test_rakeopt_with_blank_options
+ ARGV << '--trace'
+ app = Rake::Application.new
+ app.init
+ assert !app.options.silent
+ end
+
+ def test_rakeopt_with_silent_options
+ ENV['RAKEOPT'] = '-s'
+ app = Rake::Application.new
+
+ app.init
+
+ assert app.options.silent
+ end
+end
diff --git a/test/rake/test_task_arguments.rb b/test/rake/test_rake_task_arguments.rb
index 9e907aed7d..7001a4aeb2 100644
--- a/test/rake/test_task_arguments.rb
+++ b/test/rake/test_rake_task_arguments.rb
@@ -1,16 +1,12 @@
-require 'test/unit'
-require 'rake'
+require File.expand_path('../helper', __FILE__)
######################################################################
-class Rake::TestTaskArguments < Test::Unit::TestCase
- def setup
- @backup = ENV.to_hash
- ENV.clear
- end
-
+class TestRakeTaskArguments < Rake::TestCase
def teardown
- ENV.clear
- @backup.each {|k, v| ENV[k] = v }
+ ENV.delete('rev')
+ ENV.delete('VER')
+
+ super
end
def test_empty_arg_list_is_empty
@@ -53,12 +49,12 @@ class Rake::TestTaskArguments < Test::Unit::TestCase
assert_nil ta.cc
end
- def test_args_can_reference_env_values
+ def test_args_do_not_reference_env_values
ta = Rake::TaskArguments.new(["aa"], [1])
ENV['rev'] = "1.2"
ENV['VER'] = "2.3"
- assert_equal "1.2", ta.rev
- assert_equal "2.3", ta.ver
+ assert_nil ta.rev
+ assert_nil ta.ver
end
def test_creating_new_argument_scopes
@@ -84,7 +80,7 @@ class Rake::TestTaskArguments < Test::Unit::TestCase
assert_equal 'original_val', ta[:bb]
end
- def test_default_arguements_that_dont_match_names_are_ignored
+ def test_default_arguments_that_dont_match_names_are_ignored
ta = Rake::TaskArguments.new(["aa", "bb"], [nil, "original_val"])
ta.with_defaults({ "cc" => "default_val" })
assert_nil ta[:cc]
diff --git a/test/rake/test_tasklib.rb b/test/rake/test_rake_task_lib.rb
index c8b9cecdb2..9f3f7e9dae 100644
--- a/test/rake/test_tasklib.rb
+++ b/test/rake/test_rake_task_lib.rb
@@ -1,8 +1,7 @@
-require 'test/unit'
+require File.expand_path('../helper', __FILE__)
require 'rake/tasklib'
-
-class Rake::TestTaskLib < Test::Unit::TestCase
+class TestRakeTaskLib < Rake::TestCase
def test_paste
tl = Rake::TaskLib.new
assert_equal :ab, tl.paste(:a, :b)
diff --git a/test/rake/test_task_manager.rb b/test/rake/test_rake_task_manager.rb
index 3ab039ca85..847f784fa8 100644
--- a/test/rake/test_task_manager.rb
+++ b/test/rake/test_rake_task_manager.rb
@@ -1,28 +1,15 @@
-require 'test/unit'
-require 'fileutils'
-require 'tmpdir'
-require 'rake'
-
-class Rake::TestTaskManager < Test::Unit::TestCase
- class TaskManager
- include Rake::TaskManager
- end
+require File.expand_path('../helper', __FILE__)
+
+class TestRakeTaskManager < Rake::TestCase
def setup
- @oldpwd = Dir.pwd
- @tmpdir = Dir.mktmpdir("rake")
- Dir.chdir(@tmpdir)
- @tm = TaskManager.new
- open("README", "wb") {}
- end
+ super
- def teardown
- Dir.chdir(@oldpwd)
- FileUtils.rm_rf(@tmpdir)
+ @tm = Rake::TestCase::TaskManager.new
end
def test_create_task_manager
- assert_not_nil @tm
+ refute_nil @tm
assert_equal [], @tm.tasks
end
@@ -59,6 +46,7 @@ class Rake::TestTaskManager < Test::Unit::TestCase
t = @tm.define_task(Rake::FileTask, "fn")
assert_equal "fn", t.name
end
+
assert_equal ["fn"], @tm.tasks.collect { |t| t.name }
end
@@ -71,14 +59,17 @@ class Rake::TestTaskManager < Test::Unit::TestCase
end
def test_name_lookup_with_implicit_file_tasks
- t = @tm["README"]
- assert_equal "README", t.name
+ FileUtils.touch 'README.rdoc'
+
+ t = @tm["README.rdoc"]
+
+ assert_equal "README.rdoc", t.name
assert Rake::FileTask === t
end
def test_name_lookup_with_nonexistent_task
- assert_raise(RuntimeError) {
- t = @tm["DOES NOT EXIST"]
+ assert_raises(RuntimeError) {
+ @tm["DOES NOT EXIST"]
}
end
@@ -156,26 +147,3 @@ class Rake::TestTaskManager < Test::Unit::TestCase
end
-class Rake::TestTaskManagerArgumentResolution < Test::Unit::TestCase
- TaskManager = Rake::TestTaskManager::TaskManager
-
- def test_good_arg_patterns
- assert_equal [:t, [], []], task(:t)
- assert_equal [:t, [], [:x]], task(:t => :x)
- assert_equal [:t, [], [:x, :y]], task(:t => [:x, :y])
-
- assert_equal [:t, [:a, :b], []], task(:t, :a, :b)
- assert_equal [:t, [], [:x]], task(:t, :needs => :x)
- assert_equal [:t, [:a, :b], [:x]], task(:t, :a, :b, :needs => :x)
- assert_equal [:t, [:a, :b], [:x, :y]], task(:t, :a, :b, :needs => [:x, :y])
-
- assert_equal [:t, [:a, :b], []], task(:t, [:a, :b])
- assert_equal [:t, [:a, :b], [:x]], task(:t, [:a, :b] => :x)
- assert_equal [:t, [:a, :b], [:x, :y]], task(:t, [:a, :b] => [:x, :y])
- end
-
- def task(*args)
- tm = TaskManager.new
- tm.resolve_args(args)
- end
-end
diff --git a/test/rake/test_rake_task_manager_argument_resolution.rb b/test/rake/test_rake_task_manager_argument_resolution.rb
new file mode 100644
index 0000000000..35e0862ef7
--- /dev/null
+++ b/test/rake/test_rake_task_manager_argument_resolution.rb
@@ -0,0 +1,36 @@
+require File.expand_path('../helper', __FILE__)
+
+class TestRakeTaskManagerArgumentResolution < Rake::TestCase
+
+ def setup
+ super
+
+ Rake.application.options.ignore_deprecate = true
+ end
+
+ def teardown
+ Rake.application.options.ignore_deprecate = false
+
+ super
+ end
+
+ def test_good_arg_patterns
+ assert_equal [:t, [], []], task(:t)
+ assert_equal [:t, [], [:x]], task(:t => :x)
+ assert_equal [:t, [], [:x, :y]], task(:t => [:x, :y])
+
+ assert_equal [:t, [:a, :b], []], task(:t, :a, :b)
+ assert_equal [:t, [], [:x]], task(:t, :needs => :x)
+ assert_equal [:t, [:a, :b], [:x]], task(:t, :a, :b, :needs => :x)
+ assert_equal [:t, [:a, :b], [:x, :y]], task(:t, :a, :b, :needs => [:x, :y])
+
+ assert_equal [:t, [:a, :b], []], task(:t, [:a, :b])
+ assert_equal [:t, [:a, :b], [:x]], task(:t, [:a, :b] => :x)
+ assert_equal [:t, [:a, :b], [:x, :y]], task(:t, [:a, :b] => [:x, :y])
+ end
+
+ def task(*args)
+ tm = Rake::TestCase::TaskManager.new
+ tm.resolve_args(args)
+ end
+end
diff --git a/test/rake/test_rake_task_with_arguments.rb b/test/rake/test_rake_task_with_arguments.rb
new file mode 100644
index 0000000000..bbbc82f99f
--- /dev/null
+++ b/test/rake/test_rake_task_with_arguments.rb
@@ -0,0 +1,162 @@
+require File.expand_path('../helper', __FILE__)
+
+class TestRakeTaskWithArguments < Rake::TestCase
+ include Rake
+
+ def setup
+ super
+
+ Task.clear
+ Rake::TaskManager.record_task_metadata = true
+ end
+
+ def teardown
+ Rake::TaskManager.record_task_metadata = false
+
+ super
+ end
+
+ def test_no_args_given
+ t = task :t
+ assert_equal [], t.arg_names
+ end
+
+ def test_args_given
+ t = task :t, :a, :b
+ assert_equal [:a, :b], t.arg_names
+ end
+
+ def test_name_and_needs
+ t = task(:t => [:pre])
+ assert_equal "t", t.name
+ assert_equal [], t.arg_names
+ assert_equal ["pre"], t.prerequisites
+ end
+
+ def test_name_args_and_explicit_needs
+ ignore_deprecations do
+ t = task(:t, :x, :y, :needs => [:pre])
+ assert_equal "t", t.name
+ assert_equal [:x, :y], t.arg_names
+ assert_equal ["pre"], t.prerequisites
+ end
+ end
+
+ def test_illegal_keys_in_task_name_hash
+ ignore_deprecations do
+ assert_raises RuntimeError do
+ t = task(:t, :x, :y => 1, :needs => [:pre])
+ end
+ end
+ end
+
+ def test_arg_list_is_empty_if_no_args_given
+ t = task(:t) { |tt, args| assert_equal({}, args.to_hash) }
+ t.invoke(1, 2, 3)
+ end
+
+ def test_tasks_can_access_arguments_as_hash
+ t = task :t, :a, :b, :c do |tt, args|
+ assert_equal({:a => 1, :b => 2, :c => 3}, args.to_hash)
+ assert_equal 1, args[:a]
+ assert_equal 2, args[:b]
+ assert_equal 3, args[:c]
+ assert_equal 1, args.a
+ assert_equal 2, args.b
+ assert_equal 3, args.c
+ end
+ t.invoke(1, 2, 3)
+ end
+
+ def test_actions_of_various_arity_are_ok_with_args
+ notes = []
+ t = task(:t, :x) do
+ notes << :a
+ end
+ t.enhance do | |
+ notes << :b
+ end
+ t.enhance do |task|
+ notes << :c
+ assert_kind_of Task, task
+ end
+ t.enhance do |t2, args|
+ notes << :d
+ assert_equal t, t2
+ assert_equal({:x => 1}, args.to_hash)
+ end
+ t.invoke(1)
+ assert_equal [:a, :b, :c, :d], notes
+ end
+
+ def test_arguments_are_passed_to_block
+ t = task(:t, :a, :b) { |tt, args|
+ assert_equal( { :a => 1, :b => 2 }, args.to_hash )
+ }
+ t.invoke(1, 2)
+ end
+
+ def test_extra_parameters_are_ignored
+ t = task(:t, :a) { |tt, args|
+ assert_equal 1, args.a
+ assert_nil args.b
+ }
+ t.invoke(1, 2)
+ end
+
+ def test_arguments_are_passed_to_all_blocks
+ counter = 0
+ t = task :t, :a
+ task :t do |tt, args|
+ assert_equal 1, args.a
+ counter += 1
+ end
+ task :t do |tt, args|
+ assert_equal 1, args.a
+ counter += 1
+ end
+ t.invoke(1)
+ assert_equal 2, counter
+ end
+
+ def test_block_with_no_parameters_is_ok
+ t = task(:t) { }
+ t.invoke(1, 2)
+ end
+
+ def test_name_with_args
+ desc "T"
+ t = task(:tt, :a, :b)
+ assert_equal "tt", t.name
+ assert_equal "T", t.comment
+ assert_equal "[a,b]", t.arg_description
+ assert_equal "tt[a,b]", t.name_with_args
+ assert_equal [:a, :b],t.arg_names
+ end
+
+ def test_named_args_are_passed_to_prereqs
+ value = nil
+ pre = task(:pre, :rev) { |t, args| value = args.rev }
+ t = task(:t, [:name, :rev] => [:pre])
+ t.invoke("bill", "1.2")
+ assert_equal "1.2", value
+ end
+
+ def test_args_not_passed_if_no_prereq_names
+ pre = task(:pre) { |t, args|
+ assert_equal({}, args.to_hash)
+ assert_equal "bill", args.name
+ }
+ t = task(:t, [:name, :rev] => [:pre])
+ t.invoke("bill", "1.2")
+ end
+
+ def test_args_not_passed_if_no_arg_names
+ pre = task(:pre, :rev) { |t, args|
+ assert_equal({}, args.to_hash)
+ }
+ t = task(:t => [:pre])
+ t.invoke("bill", "1.2")
+ end
+end
+
diff --git a/test/rake/test_rake_test_task.rb b/test/rake/test_rake_test_task.rb
new file mode 100644
index 0000000000..81b4df3cd5
--- /dev/null
+++ b/test/rake/test_rake_test_task.rb
@@ -0,0 +1,116 @@
+require File.expand_path('../helper', __FILE__)
+require 'rake/testtask'
+
+class TestRakeTestTask < Rake::TestCase
+ include Rake
+
+ def setup
+ super
+
+ Task.clear
+ ENV.delete('TEST')
+ end
+
+ def test_no_task
+ assert ! Task.task_defined?(:test)
+ end
+
+ def test_defaults
+ tt = Rake::TestTask.new do |t| end
+ refute_nil tt
+ assert_equal :test, tt.name
+ assert_equal ['lib'], tt.libs
+ assert_equal 'test/test*.rb', tt.pattern
+ assert_equal false, tt.verbose
+ assert Task.task_defined?(:test)
+ end
+
+ def test_non_defaults
+ tt = Rake::TestTask.new(:example) do |t|
+ t.libs = ['src', 'ext']
+ t.pattern = 'test/tc_*.rb'
+ t.verbose = true
+ end
+ refute_nil tt
+ assert_equal :example, tt.name
+ assert_equal ['src', 'ext'], tt.libs
+ assert_equal 'test/tc_*.rb', tt.pattern
+ assert_equal true, tt.verbose
+ assert Task.task_defined?(:example)
+ end
+
+ def test_pattern
+ tt = Rake::TestTask.new do |t|
+ t.pattern = '*.rb'
+ end
+ assert_equal ['*.rb'], tt.file_list.to_a
+ end
+
+ def test_env_test
+ ENV['TEST'] = 'testfile.rb'
+ tt = Rake::TestTask.new do |t|
+ t.pattern = '*'
+ end
+ assert_equal ["testfile.rb"], tt.file_list.to_a
+ end
+
+ def test_test_files
+ tt = Rake::TestTask.new do |t|
+ t.test_files = FileList['a.rb', 'b.rb']
+ end
+ assert_equal ["a.rb", 'b.rb'], tt.file_list.to_a
+ end
+
+ def test_both_pattern_and_test_files
+ tt = Rake::TestTask.new do |t|
+ t.test_files = FileList['a.rb', 'b.rb']
+ t.pattern = '*.rb'
+ end
+ assert_equal ['a.rb', 'b.rb', '*.rb'], tt.file_list.to_a
+ end
+
+ def test_direct_run_has_quoted_paths
+ test_task = Rake::TestTask.new(:tx) do |t|
+ t.loader = :direct
+ end
+ assert_match(/-e ".*"/, test_task.run_code)
+ end
+
+ def test_testrb_run_has_quoted_paths_on_ruby_182
+ test_task = Rake::TestTask.new(:tx) do |t|
+ t.loader = :testrb
+ end
+ flexmock(test_task).should_receive(:ruby_version).and_return('1.8.2')
+ assert_match(/^-S testrb +".*"$/, test_task.run_code)
+ end
+
+ def test_testrb_run_has_quoted_paths_on_ruby_186
+ test_task = Rake::TestTask.new(:tx) do |t|
+ t.loader = :testrb
+ end
+ flexmock(test_task).should_receive(:ruby_version).and_return('1.8.6')
+ assert_match(/^-S testrb +$/, test_task.run_code)
+ end
+
+ def test_rake_run_has_quoted_paths
+ test_task = Rake::TestTask.new(:tx) do |t|
+ t.loader = :rake
+ end
+ assert_match(/".*"/, test_task.run_code)
+ end
+
+ def test_nested_libs_will_be_flattened
+ test_task = Rake::TestTask.new(:tx) do |t|
+ t.libs << ["A", "B"]
+ end
+ sep = File::PATH_SEPARATOR
+ assert_match(/lib#{sep}A#{sep}B/, test_task.ruby_opts_string)
+ end
+
+ def test_empty_lib_path_implies_no_dash_I_option
+ test_task = Rake::TestTask.new(:tx) do |t|
+ t.libs = []
+ end
+ refute_match(/-I/, test_task.ruby_opts_string)
+ end
+end
diff --git a/test/rake/test_rake_top_level_functions.rb b/test/rake/test_rake_top_level_functions.rb
new file mode 100644
index 0000000000..69ef8691fb
--- /dev/null
+++ b/test/rake/test_rake_top_level_functions.rb
@@ -0,0 +1,76 @@
+require File.expand_path('../helper', __FILE__)
+
+class TestRakeTopLevelFunctions < Rake::TestCase
+
+ def setup
+ super
+
+ @app = Rake.application
+ Rake.application = flexmock("app")
+ Rake.application.should_receive(:deprecate).
+ and_return { |old, new, call| @app.deprecate(old, new, call) }
+ end
+
+ def teardown
+ Rake.application = @app
+
+ super
+ end
+
+ def test_namespace
+ Rake.application.should_receive(:in_namespace).with("xyz", any).once
+ namespace "xyz" do end
+ end
+
+ def test_import
+ Rake.application.should_receive(:add_import).with("x").once.ordered
+ Rake.application.should_receive(:add_import).with("y").once.ordered
+ Rake.application.should_receive(:add_import).with("z").once.ordered
+ import('x', 'y', 'z')
+ end
+
+ def test_when_writing
+ out, = capture_io do
+ when_writing("NOTWRITING") do
+ puts "WRITING"
+ end
+ end
+ assert_equal "WRITING\n", out
+ end
+
+ def test_when_not_writing
+ Rake::FileUtilsExt.nowrite_flag = true
+ _, err = capture_io do
+ when_writing("NOTWRITING") do
+ puts "WRITING"
+ end
+ end
+ assert_equal "DRYRUN: NOTWRITING\n", err
+ ensure
+ Rake::FileUtilsExt.nowrite_flag = false
+ end
+
+ def test_missing_constants_task
+ Rake.application.should_receive(:const_warning).with(:Task).once
+ Object.const_missing(:Task)
+ end
+
+ def test_missing_constants_file_task
+ Rake.application.should_receive(:const_warning).with(:FileTask).once
+ Object.const_missing(:FileTask)
+ end
+
+ def test_missing_constants_file_creation_task
+ Rake.application.should_receive(:const_warning).with(:FileCreationTask).once
+ Object.const_missing(:FileCreationTask)
+ end
+
+ def test_missing_constants_rake_app
+ Rake.application.should_receive(:const_warning).with(:RakeApp).once
+ Object.const_missing(:RakeApp)
+ end
+
+ def test_missing_other_constant
+ assert_raises(NameError) do Object.const_missing(:Xyz) end
+ end
+end
diff --git a/test/rake/test_rake_win32.rb b/test/rake/test_rake_win32.rb
new file mode 100644
index 0000000000..fc2746a0a1
--- /dev/null
+++ b/test/rake/test_rake_win32.rb
@@ -0,0 +1,72 @@
+require File.expand_path('../helper', __FILE__)
+
+class TestRakeWin32 < Rake::TestCase
+
+ Win32 = Rake::Win32
+
+ def test_win32_system_dir_uses_home_if_defined
+ ENV['HOME'] = 'C:\\HP'
+
+ assert_equal "C:/HP/Rake", Win32.win32_system_dir
+ end
+
+ def test_win32_system_dir_uses_homedrive_homepath_when_no_home_defined
+ ENV['HOME'] = nil
+ ENV['HOMEDRIVE'] = 'C:'
+ ENV['HOMEPATH'] = '\\HP'
+
+ assert_equal "C:/HP/Rake", Win32.win32_system_dir
+ end
+
+ def test_win32_system_dir_uses_appdata_when_no_home_or_home_combo
+ ENV['APPDATA'] = "C:\\Documents and Settings\\HP\\Application Data"
+ ENV['HOME'] = nil
+ ENV['HOMEDRIVE'] = nil
+ ENV['HOMEPATH'] = nil
+
+ assert_equal "C:/Documents and Settings/HP/Application Data/Rake",
+ Win32.win32_system_dir
+ end
+
+ def test_win32_system_dir_fallback_to_userprofile_otherwise
+ ENV['HOME'] = nil
+ ENV['HOMEDRIVE'] = nil
+ ENV['HOMEPATH'] = nil
+ ENV['APPDATA'] = nil
+ ENV['USERPROFILE'] = "C:\\Documents and Settings\\HP"
+
+ assert_equal "C:/Documents and Settings/HP/Rake", Win32.win32_system_dir
+ end
+
+ def test_win32_system_dir_nil_of_no_env_vars
+ ENV['APPDATA'] = nil
+ ENV['HOME'] = nil
+ ENV['HOMEDRIVE'] = nil
+ ENV['HOMEPATH'] = nil
+ ENV['RAKE_SYSTEM'] = nil
+ ENV['USERPROFILE'] = nil
+
+ assert_raises(Rake::Win32::Win32HomeError) do
+ Win32.win32_system_dir
+ end
+ end
+
+ def test_win32_backtrace_with_different_case
+ ex = nil
+ begin
+ raise 'test exception'
+ rescue => ex
+ end
+
+ ex.set_backtrace ['abc', 'rakefile']
+
+ rake = Rake::Application.new
+ rake.options.trace = true
+ rake.instance_variable_set(:@rakefile, 'Rakefile')
+
+ _, err = capture_io { rake.display_error_message(ex) }
+
+ assert_match(/rakefile/, err)
+ end
+
+end
diff --git a/test/rake/test_require.rb b/test/rake/test_require.rb
deleted file mode 100644
index 8e6e2e9d5b..0000000000
--- a/test/rake/test_require.rb
+++ /dev/null
@@ -1,32 +0,0 @@
-require 'test/unit'
-require 'rake'
-
-# ====================================================================
-class Rake::TestRequire < Test::Unit::TestCase
- RakeLibDir = File.dirname(__FILE__) + '/data/rakelib'
-
- def test_can_load_rake_library
- app = Rake::Application.new
- assert app.instance_eval {
- rake_require("test1", [RakeLibDir], [])
- }
- end
-
- def test_wont_reload_rake_library
- app = Rake::Application.new
- assert ! app.instance_eval {
- rake_require("test2", [RakeLibDir], ['test2'])
- }
- end
-
- def test_throws_error_if_library_not_found
- app = Rake::Application.new
- ex = assert_raise(LoadError) {
- assert app.instance_eval {
- rake_require("testx", [RakeLibDir], [])
- }
- }
- assert_match(/x/, ex.message)
- end
-end
-
diff --git a/test/rake/test_sys.rb b/test/rake/test_sys.rb
new file mode 100644
index 0000000000..21f7e2c708
--- /dev/null
+++ b/test/rake/test_sys.rb
@@ -0,0 +1,20 @@
+require File.expand_path('../helper', __FILE__)
+begin
+ old_verbose = $VERBOSE
+ $VERBOSE = nil
+ require 'rake/contrib/sys'
+ensure
+ $VERBOSE = old_verbose
+end
+
+class TestSys < Rake::TestCase
+
+ def test_split_all
+ assert_equal ['a'], Sys.split_all('a')
+ assert_equal ['..'], Sys.split_all('..')
+ assert_equal ['/'], Sys.split_all('/')
+ assert_equal ['a', 'b'], Sys.split_all('a/b')
+ assert_equal ['/', 'a', 'b'], Sys.split_all('/a/b')
+ assert_equal ['..', 'a', 'b'], Sys.split_all('../a/b')
+ end
+end
diff --git a/test/rake/test_test_task.rb b/test/rake/test_test_task.rb
deleted file mode 100644
index 0b7dbc625b..0000000000
--- a/test/rake/test_test_task.rb
+++ /dev/null
@@ -1,81 +0,0 @@
-require 'tmpdir'
-require 'test/unit'
-require 'rake/testtask'
-
-class Rake::TestTestTask < Test::Unit::TestCase
- include Rake
-
- def setup
- @oldwd = Dir.pwd
- @tmpwd = Dir.mktmpdir
- Dir.chdir(@tmpwd)
- Task.clear
- ENV.delete('TEST')
- open('install.rb', 'w') {}
- end
-
- def teardown
- FileUtils.rm_rf("testdata")
- Dir.chdir(@oldwd)
- FileUtils.rm_rf(@tmpwd)
- end
-
- def test_no_task
- assert ! Task.task_defined?(:test)
- end
-
- def test_defaults
- tt = Rake::TestTask.new do |t| end
- assert_not_nil tt
- assert_equal :test, tt.name
- assert_equal ['lib'], tt.libs
- assert_equal 'test/test*.rb', tt.pattern
- assert_equal false, tt.verbose
- assert Task.task_defined?(:test)
- end
-
- def test_non_defaults
- tt = Rake::TestTask.new(:example) do |t|
- t.libs = ['src', 'ext']
- t.pattern = 'test/tc_*.rb'
- t.verbose = true
- end
- assert_not_nil tt
- assert_equal :example, tt.name
- assert_equal ['src', 'ext'], tt.libs
- assert_equal 'test/tc_*.rb', tt.pattern
- assert_equal true, tt.verbose
- assert Task.task_defined?(:example)
- end
-
- def test_pattern
- tt = Rake::TestTask.new do |t|
- t.pattern = '*.rb'
- end
- assert_equal ['install.rb'], tt.file_list.to_a
- end
-
- def test_env_test
- ENV['TEST'] = 'testfile.rb'
- tt = Rake::TestTask.new do |t|
- t.pattern = '*'
- end
- assert_equal ["testfile.rb"], tt.file_list.to_a
- end
-
- def test_test_files
- tt = Rake::TestTask.new do |t|
- t.test_files = FileList['a.rb', 'b.rb']
- end
- assert_equal ["a.rb", 'b.rb'], tt.file_list.to_a
- end
-
- def test_both_pattern_and_test_files
- tt = Rake::TestTask.new do |t|
- t.test_files = FileList['a.rb', 'b.rb']
- t.pattern = '*.rb'
- end
- assert_equal ['a.rb', 'b.rb', 'install.rb'], tt.file_list.to_a
- end
-
-end
diff --git a/test/rake/test_top_level_functions.rb b/test/rake/test_top_level_functions.rb
deleted file mode 100644
index 12a8cd1e36..0000000000
--- a/test/rake/test_top_level_functions.rb
+++ /dev/null
@@ -1,91 +0,0 @@
-require 'test/unit'
-require_relative 'capture_stdout'
-require 'rake'
-
-class Rake::TestTopLevelFunctions < Test::Unit::TestCase
- include CaptureStdout
-
- def setup
- super
- @app = Rake.application
- Rake.application = @mock = Object.new
- end
-
- def teardown
- Rake.application = @app
- super
- end
-
- def defmock(sym, &block)
- class << @mock; self; end.class_eval do
- define_method(sym, block)
- end
- end
-
- def test_namespace
- args = []
- defmock(:in_namespace) {|a, *| args << a}
- namespace "xyz" do end
- assert_equal(["xyz"], args)
- end
-
- def test_import
- args = []
- defmock(:add_import) {|a| args << a}
- import('x', 'y', 'z')
- assert_equal(['x', 'y', 'z'], args)
- end
-
- def test_when_writing
- out = capture_stdout do
- when_writing("NOTWRITING") do
- puts "WRITING"
- end
- end
- assert_equal "WRITING\n", out
- end
-
- def test_when_not_writing
- RakeFileUtils.nowrite_flag = true
- out = capture_stdout do
- when_writing("NOTWRITING") do
- puts "WRITING"
- end
- end
- assert_equal "DRYRUN: NOTWRITING\n", out
- ensure
- RakeFileUtils.nowrite_flag = false
- end
-
- def test_missing_constants_task
- args = []
- defmock(:const_warning) {|a| args << a}
- Object.const_missing(:Task)
- assert_equal([:Task], args)
- end
-
- def test_missing_constants_file_task
- args = []
- defmock(:const_warning) {|a| args << a}
- Object.const_missing(:FileTask)
- assert_equal([:FileTask], args)
- end
-
- def test_missing_constants_file_creation_task
- args = []
- defmock(:const_warning) {|a| args << a}
- Object.const_missing(:FileCreationTask)
- assert_equal([:FileCreationTask], args)
- end
-
- def test_missing_constants_rake_app
- args = []
- defmock(:const_warning) {|a| args << a}
- Object.const_missing(:RakeApp)
- assert_equal([:RakeApp], args)
- end
-
- def test_missing_other_constant
- assert_raise(NameError) do Object.const_missing(:Xyz) end
- end
-end
diff --git a/test/rake/test_win32.rb b/test/rake/test_win32.rb
deleted file mode 100644
index dade540629..0000000000
--- a/test/rake/test_win32.rb
+++ /dev/null
@@ -1,45 +0,0 @@
-require 'test/unit'
-require_relative 'in_environment'
-
-require 'rake'
-
-class Rake::TestWin32 < Test::Unit::TestCase
- include InEnvironment
-
- Win32 = Rake::Win32
-
- def test_win32_system_dir_uses_home_if_defined
- in_environment('RAKE_SYSTEM' => nil,
- 'HOME' => "C:\\HP",
- 'APPDATA' => nil
- ) do
- assert_equal "C:/HP/Rake", Win32.win32_system_dir
- end
- end
-
- def test_win32_system_dir_uses_appdata_if_defined
- in_environment(
- 'RAKE_SYSTEM' => nil,
- 'HOME' => "C:\\HP",
- 'APPDATA' => "C:\\Documents and Settings\\HP\\Application Data"
- ) do
- assert_equal "C:/Documents and Settings/HP/Application Data/Rake", Win32.win32_system_dir
- end
- end
-
- def test_win32_system_dir_nil_of_no_env_vars
- in_environment(
- 'RAKE_SYSTEM' => nil,
- 'HOME' => nil,
- 'HOMEDRIVE' => nil,
- "HOMEPATH" => nil,
- 'APPDATA' => nil,
- 'USERPROFILE' => "C:\\Documents and Settings\\HP"
- ) do
- assert_raise(ArgumentError) do
- Win32.win32_system_dir
- end
- end
- end
-
-end if Rake::Win32.windows?