git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@32217 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
drbrain 2011-06-23 22:11:55 +00:00
Родитель 3fbc9440fe
Коммит d001539a05
119 изменённых файлов: 6777 добавлений и 4774 удалений

Просмотреть файл

@ -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.

6
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

Разница между файлами не показана из-за своего большого размера Загрузить разницу

109
lib/rake/alt_system.rb Normal file
Просмотреть файл

@ -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

594
lib/rake/application.rb Normal file
Просмотреть файл

@ -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

Просмотреть файл

@ -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

25
lib/rake/cloneable.rb Normal file
Просмотреть файл

@ -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

Просмотреть файл

@ -18,3 +18,4 @@ module Rake
end
end

Просмотреть файл

@ -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)

Просмотреть файл

@ -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

Просмотреть файл

@ -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

191
lib/rake/contrib/sys.rb Normal file
Просмотреть файл

@ -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

Просмотреть файл

@ -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

167
lib/rake/dsl_definition.rb Normal file
Просмотреть файл

@ -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

18
lib/rake/early_time.rb Normal file
Просмотреть файл

@ -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

27
lib/rake/ext/core.rb Normal file
Просмотреть файл

@ -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

39
lib/rake/ext/module.rb Normal file
Просмотреть файл

@ -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

167
lib/rake/ext/string.rb Normal file
Просмотреть файл

@ -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

14
lib/rake/ext/time.rb Normal file
Просмотреть файл

@ -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

Просмотреть файл

@ -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

403
lib/rake/file_list.rb Normal file
Просмотреть файл

@ -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

47
lib/rake/file_task.rb Normal file
Просмотреть файл

@ -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

112
lib/rake/file_utils.rb Normal file
Просмотреть файл

@ -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

142
lib/rake/file_utils_ext.rb Normal file
Просмотреть файл

@ -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

Просмотреть файл

@ -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

Просмотреть файл

@ -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

Просмотреть файл

@ -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

21
lib/rake/lib/project.rake Normal file
Просмотреть файл

@ -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

Просмотреть файл

@ -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

16
lib/rake/multi_task.rb Normal file
Просмотреть файл

@ -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

25
lib/rake/name_space.rb Normal file
Просмотреть файл

@ -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

Просмотреть файл

@ -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?

1
lib/rake/pathmap.rb Normal file
Просмотреть файл

@ -0,0 +1 @@
require 'rake/ext/string'

24
lib/rake/pseudo_status.rb Normal file
Просмотреть файл

@ -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

29
lib/rake/rake_module.rb Normal file
Просмотреть файл

@ -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

Просмотреть файл

@ -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

Просмотреть файл

@ -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

Просмотреть файл

@ -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

Просмотреть файл

@ -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

Просмотреть файл

@ -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
}

327
lib/rake/task.rb Normal file
Просмотреть файл

@ -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

Просмотреть файл

@ -0,0 +1,7 @@
module Rake
# Error indicating an ill-formed task declaration.
class TaskArgumentError < ArgumentError
end
end

Просмотреть файл

@ -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

307
lib/rake/task_manager.rb Normal file
Просмотреть файл

@ -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

Просмотреть файл

@ -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.
#

Просмотреть файл

@ -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

10
lib/rake/version.rb Normal file
Просмотреть файл

@ -0,0 +1,10 @@
module Rake
module Version
NUMBERS = [
MAJOR = 0,
MINOR = 9,
BUILD = 2,
]
end
VERSION = Version::NUMBERS.join('.')
end

Просмотреть файл

@ -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
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
end
# 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.
def windows?
AltSystem::WINDOWS
end
# Run a command line on windows.
def rake_system(*cmd)
AltSystem.system(*cmd)
end
# 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

Просмотреть файл

@ -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

Просмотреть файл

@ -1,5 +0,0 @@
if ARGV[0] != ARGV[1]
exit 1
else
exit 0
end

Просмотреть файл

@ -1,5 +0,0 @@
if ARGV[0] != ARGV[1]
exit 0
else
exit 1
end

Просмотреть файл

@ -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

Просмотреть файл

@ -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

Просмотреть файл

@ -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

Просмотреть файл

@ -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

Просмотреть файл

@ -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"

Просмотреть файл

@ -1 +0,0 @@
default: other

Просмотреть файл

@ -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

Просмотреть файл

@ -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

Просмотреть файл

@ -1,3 +0,0 @@
task :default do
puts "TEST1"
end

Просмотреть файл

@ -1,3 +0,0 @@
task :default do
puts "OK"
end

Просмотреть файл

@ -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

Просмотреть файл

@ -1,8 +0,0 @@
#!/usr/bin/env ruby
task :exit5 do
exit(5)
end
task :normal do
end

Просмотреть файл

@ -1 +0,0 @@
# Empty Rakefile for Unit Test

2
test/rake/data/unittest/subdir/.gitignore поставляемый
Просмотреть файл

@ -1,2 +0,0 @@
*
!.gitignore

Просмотреть файл

@ -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

500
test/rake/helper.rb Normal file
Просмотреть файл

@ -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=

Просмотреть файл

@ -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

Просмотреть файл

@ -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

Просмотреть файл

@ -1,3 +0,0 @@
# For --require testing
TESTING_REQUIRE << 1

Просмотреть файл

@ -1,3 +0,0 @@
# For --require testing
TESTING_REQUIRE << 2

Просмотреть файл

@ -1,3 +0,0 @@
# For --require testing
TESTING_REQUIRE << 3

Просмотреть файл

@ -1,3 +0,0 @@
#!/usr/bin/env ruby
exit((ARGV[0] || "0").to_i)

Просмотреть файл

@ -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

Просмотреть файл

@ -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

Просмотреть файл

@ -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

Просмотреть файл

@ -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

Просмотреть файл

@ -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

Просмотреть файл

@ -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

Просмотреть файл

@ -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"),

Просмотреть файл

@ -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

Просмотреть файл

@ -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

Просмотреть файл

@ -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

Просмотреть файл

@ -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

Просмотреть файл

@ -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

Просмотреть файл

@ -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

Просмотреть файл

@ -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
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
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 found, "should have found a matching line"
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_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

Просмотреть файл

@ -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

Просмотреть файл

@ -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

Просмотреть файл

@ -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 redirect_stderr
old_err = $stderr
$stderr = StringIO.new
yield
$stderr.string
ensure
$stderr = old_err
def command name, text
open name, 'w', 0750 do |io|
io << text
end
end
def windows?
! File::ALT_SEPARATOR.nil?
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 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

Просмотреть файл

@ -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

Просмотреть файл

@ -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)

Просмотреть файл

@ -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

Просмотреть файл

@ -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

Просмотреть файл

@ -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

Просмотреть файл

@ -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

Просмотреть файл

@ -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

Просмотреть файл

@ -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

Просмотреть файл

@ -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

Просмотреть файл

@ -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

Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше