* NEWS (with all sufficient information):

* lib/rake:  Update to rake 10.1.0
* bin/rake:  ditto.
* test/rake:  ditto.

* NEWS:  Update NEWS to include rake 10.1.0 and links to release notes.


git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@43264 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
drbrain 2013-10-11 21:35:01 +00:00
Родитель 52c1331763
Коммит 9cadc95b28
83 изменённых файлов: 1724 добавлений и 2954 удалений

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

@ -1,3 +1,11 @@
2013-10-11 Eric Hodel <drbrain@segment7.net>
* lib/rake: Update to rake 10.1.0
* bin/rake: ditto.
* test/rake: ditto.
* NEWS: Update NEWS to include rake 10.1.0 and links to release notes.
Sat Oct 12 03:26:04 2013 Koichi Sasada <ko1@atdot.net>
* class.c, variable.c, gc.c (rb_class_tbl): removed.

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

@ -174,6 +174,17 @@ with all sufficient information, see the ChangeLog file.
* open-uri
* Support multiple fields with same field name (like Set-Cookie).
* rake
* Updated to 10.1.0. Major changes include removal of the class namespace,
Rake::DSL to hold the rake DSL methods and removal of support for legacy
rake features.
For a complete list of changes since rake 0.9.6 see:
http://rake.rubyforge.org/doc/release_notes/rake-10_1_0_rdoc.html
http://rake.rubyforge.org/doc/release_notes/rake-10_0_3_rdoc.html
* RDoc
* Updated to 4.1.0.preview.1. Major enhancements include a modified default
template and accessibility enhancements.

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

@ -28,10 +28,6 @@ begin
rescue LoadError
end
module Rake
REDUCE_COMPAT = true if ARGV.include?("--reduce-compat")
end
require 'rake'
Rake.application.run

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

@ -40,6 +40,8 @@ require 'rake/ext/time'
require 'rake/win32'
require 'rake/linked_list'
require 'rake/scope'
require 'rake/task_argument_error'
require 'rake/rule_recursion_overflow_error'
require 'rake/rake_module'

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

@ -39,7 +39,7 @@ module Rake::AltSystem
end
end
if WINDOWS and RUBY_VERSION < "1.9.0"
if WINDOWS && RUBY_VERSION < "1.9.0"
RUNNABLE_EXTS = %w[com exe bat cmd]
RUNNABLE_PATTERN = %r!\.(#{RUNNABLE_EXTS.join('|')})\Z!i
@ -73,9 +73,8 @@ module Rake::AltSystem
file
else
RUNNABLE_EXTS.each { |ext|
if File.exist?(test = "#{file}.#{ext}")
return test
end
test = "#{file}.#{ext}"
return test if File.exist?(test)
}
nil
end

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

@ -35,7 +35,12 @@ module Rake
# List of the top level task names (task names from the command line).
attr_reader :top_level_tasks
DEFAULT_RAKEFILES = ['rakefile', 'Rakefile', 'rakefile.rb', 'Rakefile.rb'].freeze
DEFAULT_RAKEFILES = [
'rakefile',
'Rakefile',
'rakefile.rb',
'Rakefile.rb'
].freeze
# Initialize a Rake::Application object.
def initialize
@ -115,7 +120,8 @@ module Rake
puts "Maximum active threads: #{stats[:max_active_threads]}"
puts "Total threads in play: #{stats[:total_threads_in_play]}"
end
ThreadHistoryDisplay.new(thread_pool.history).show if options.job_stats == :history
ThreadHistoryDisplay.new(thread_pool.history).show if
options.job_stats == :history
end
# Add a loader to handle imported files ending in the extension
@ -132,7 +138,7 @@ module Rake
# Return the thread pool used for multithreaded processing.
def thread_pool # :nodoc:
@thread_pool ||= ThreadPool.new(options.thread_pool_size||FIXNUM_MAX)
@thread_pool ||= ThreadPool.new(options.thread_pool_size || FIXNUM_MAX)
end
# private ----------------------------------------------------------------
@ -156,19 +162,23 @@ module Rake
# Provide standard exception handling for the given block.
def standard_exception_handling
begin
yield
rescue SystemExit => ex
# Exit silently with current status
raise
rescue OptionParser::InvalidOption => ex
$stderr.puts ex.message
exit(false)
rescue Exception => ex
# Exit with error message
display_error_message(ex)
exit(false)
end
yield
rescue SystemExit
# Exit silently with current status
raise
rescue OptionParser::InvalidOption => ex
$stderr.puts ex.message
exit(false)
rescue Exception => ex
# Exit with error message
display_error_message(ex)
exit_because_of_exception(ex)
end
# Exit the program because of an unhandle exception.
# (may be overridden by subclasses)
def exit_because_of_exception(ex)
exit(false)
end
# Display the error message that caused the exception.
@ -181,7 +191,8 @@ module Rake
trace Backtrace.collapse(ex.backtrace).join("\n")
end
trace "Tasks: #{ex.chain}" if has_chain?(ex)
trace "(See full trace by running task with --trace)" unless options.backtrace
trace "(See full trace by running task with --trace)" unless
options.backtrace
end
# Warn about deprecated usage.
@ -190,10 +201,11 @@ module Rake
# Rake.application.deprecate("import", "Rake.import", caller.first)
#
def deprecate(old_usage, new_usage, call_site)
return if options.ignore_deprecate
$stderr.puts "WARNING: '#{old_usage}' is deprecated. " +
"Please use '#{new_usage}' instead.\n" +
" at #{call_site}"
unless options.ignore_deprecate
$stderr.puts "WARNING: '#{old_usage}' is deprecated. " +
"Please use '#{new_usage}' instead.\n" +
" at #{call_site}"
end
end
# Does the exception have a task invocation chain?
@ -222,7 +234,7 @@ module Rake
end
# Override the detected TTY output state (mostly for testing)
def tty_output=( tty_output_state )
def tty_output=(tty_output_state)
@tty_output = tty_output_state
end
@ -235,16 +247,22 @@ module Rake
# Display the tasks and comments.
def display_tasks_and_comments
displayable_tasks = tasks.select { |t|
(options.show_all_tasks || t.comment) && t.name =~ options.show_task_pattern
(options.show_all_tasks || t.comment) &&
t.name =~ options.show_task_pattern
}
case options.show_tasks
when :tasks
width = displayable_tasks.collect { |t| t.name_with_args.length }.max || 10
max_column = truncate_output? ? terminal_width - name.size - width - 7 : nil
width = displayable_tasks.map { |t| t.name_with_args.length }.max || 10
if truncate_output?
max_column = terminal_width - name.size - width - 7
else
max_column = nil
end
displayable_tasks.each do |t|
printf "#{name} %-#{width}s # %s\n",
t.name_with_args, max_column ? truncate(t.comment, max_column) : t.comment
printf("#{name} %-#{width}s # %s\n",
t.name_with_args,
max_column ? truncate(t.comment, max_column) : t.comment)
end
when :describe
displayable_tasks.each do |t|
@ -258,7 +276,7 @@ module Rake
when :lines
displayable_tasks.each do |t|
t.locations.each do |loc|
printf "#{name} %-30s %s\n",t.name_with_args, loc
printf "#{name} %-30s %s\n", t.name_with_args, loc
end
end
else
@ -291,7 +309,8 @@ module Rake
end
def unix?
RbConfig::CONFIG['host_os'] =~ /(aix|darwin|linux|(net|free|open)bsd|cygwin|solaris|irix|hpux)/i
RbConfig::CONFIG['host_os'] =~
/(aix|darwin|linux|(net|free|open)bsd|cygwin|solaris|irix|hpux)/i
end
def windows?
@ -304,7 +323,7 @@ module Rake
elsif string.length <= width
string
else
( string[0, width-3] || "" ) + "..."
(string[0, width - 3] || "") + "..."
end
end
@ -333,34 +352,33 @@ module Rake
def standard_rake_options
sort_options(
[
['--all', '-A', "Show all tasks, even uncommented ones",
['--all', '-A',
"Show all tasks, even uncommented ones",
lambda { |value|
options.show_all_tasks = value
}
],
['--backtrace=[OUT]', "Enable full backtrace. OUT can be stderr (default) or stdout.",
['--backtrace=[OUT]',
"Enable full backtrace. OUT can be stderr (default) or stdout.",
lambda { |value|
options.backtrace = true
select_trace_output(options, 'backtrace', value)
}
],
['--classic-namespace', '-C', "Put Task and FileTask in the top level namespace",
lambda { |value|
require 'rake/classic_namespace'
options.classic_namespace = true
}
],
['--comments', "Show commented tasks only",
['--comments',
"Show commented tasks only",
lambda { |value|
options.show_all_tasks = !value
}
],
['--describe', '-D [PATTERN]', "Describe the tasks (matching optional PATTERN), then exit.",
['--describe', '-D [PATTERN]',
"Describe the tasks (matching optional PATTERN), then exit.",
lambda { |value|
select_tasks_to_show(options, :describe, value)
}
],
['--dry-run', '-n', "Do a dry run without executing actions.",
['--dry-run', '-n',
"Do a dry run without executing actions.",
lambda { |value|
Rake.verbose(true)
Rake.nowrite(true)
@ -368,28 +386,35 @@ module Rake
options.trace = true
}
],
['--execute', '-e CODE', "Execute some Ruby code and exit.",
['--execute', '-e CODE',
"Execute some Ruby code and exit.",
lambda { |value|
eval(value)
exit
}
],
['--execute-print', '-p CODE', "Execute some Ruby code, print the result, then exit.",
['--execute-print', '-p CODE',
"Execute some Ruby code, print the result, then exit.",
lambda { |value|
puts eval(value)
exit
}
],
['--execute-continue', '-E CODE',
"Execute some Ruby code, then continue with normal task processing.",
"Execute some Ruby code, " +
"then continue with normal task processing.",
lambda { |value| eval(value) }
],
['--jobs', '-j [NUMBER]',
"Specifies the maximum number of tasks to execute in parallel. (default:2)",
lambda { |value| options.thread_pool_size = [(value || 2).to_i,2].max }
"Specifies the maximum number of tasks to execute in parallel. " +
"(default is 2)",
lambda { |value|
options.thread_pool_size = [(value || 2).to_i, 2].max
}
],
['--job-stats [LEVEL]',
"Display job statistics. LEVEL=history displays a complete job list",
"Display job statistics. " +
"LEVEL=history displays a complete job list",
lambda { |value|
if value =~ /^history/i
options.job_stats = :history
@ -398,22 +423,28 @@ module Rake
end
}
],
['--libdir', '-I LIBDIR', "Include LIBDIR in the search path for required modules.",
['--libdir', '-I LIBDIR',
"Include LIBDIR in the search path for required modules.",
lambda { |value| $:.push(value) }
],
['--multitask', '-m', "Treat all tasks as multitasks.",
['--multitask', '-m',
"Treat all tasks as multitasks.",
lambda { |value| options.always_multitask = true }
],
['--no-search', '--nosearch', '-N', "Do not search parent directories for the Rakefile.",
['--no-search', '--nosearch',
'-N', "Do not search parent directories for the Rakefile.",
lambda { |value| options.nosearch = true }
],
['--prereqs', '-P', "Display the tasks and dependencies, then exit.",
['--prereqs', '-P',
"Display the tasks and dependencies, then exit.",
lambda { |value| options.show_prereqs = true }
],
['--quiet', '-q', "Do not log messages to standard output.",
['--quiet', '-q',
"Do not log messages to standard output.",
lambda { |value| Rake.verbose(false) }
],
['--rakefile', '-f [FILE]', "Use FILE as the rakefile.",
['--rakefile', '-f [FILE]',
"Use FILE as the rakefile.",
lambda { |value|
value ||= ''
@rakefiles.clear
@ -421,15 +452,14 @@ module Rake
}
],
['--rakelibdir', '--rakelib', '-R RAKELIBDIR',
"Auto-import any .rake files in RAKELIBDIR. (default is 'rakelib')",
lambda { |value| options.rakelib = value.split(File::PATH_SEPARATOR) }
"Auto-import any .rake files in RAKELIBDIR. " +
"(default is 'rakelib')",
lambda { |value|
options.rakelib = value.split(File::PATH_SEPARATOR)
}
],
['--reduce-compat', "Remove DSL in Object; remove Module#const_missing which defines ::Task etc.",
# Load-time option.
# Handled in bin/rake where Rake::REDUCE_COMPAT is defined (or not).
lambda { |_| }
],
['--require', '-r MODULE', "Require MODULE before executing rakefile.",
['--require', '-r MODULE',
"Require MODULE before executing rakefile.",
lambda { |value|
begin
require value
@ -442,34 +472,45 @@ module Rake
end
}
],
['--rules', "Trace the rules resolution.",
['--rules',
"Trace the rules resolution.",
lambda { |value| options.trace_rules = true }
],
['--silent', '-s', "Like --quiet, but also suppresses the 'in directory' announcement.",
['--silent', '-s',
"Like --quiet, but also suppresses the " +
"'in directory' announcement.",
lambda { |value|
Rake.verbose(false)
options.silent = true
}
],
['--suppress-backtrace PATTERN', "Suppress backtrace lines matching regexp PATTERN. Ignored if --trace is on.",
['--suppress-backtrace PATTERN',
"Suppress backtrace lines matching regexp PATTERN. " +
"Ignored if --trace is on.",
lambda { |value|
options.suppress_backtrace_pattern = Regexp.new(value)
}
],
['--system', '-g',
"Using system wide (global) rakefiles (usually '~/.rake/*.rake').",
"Using system wide (global) rakefiles " +
"(usually '~/.rake/*.rake').",
lambda { |value| options.load_system = true }
],
['--no-system', '--nosystem', '-G',
"Use standard project Rakefile search paths, ignore system wide rakefiles.",
"Use standard project Rakefile search paths, " +
"ignore system wide rakefiles.",
lambda { |value| options.ignore_system = true }
],
['--tasks', '-T [PATTERN]', "Display the tasks (matching optional PATTERN) with descriptions, then exit.",
['--tasks', '-T [PATTERN]',
"Display the tasks (matching optional PATTERN) " +
"with descriptions, then exit.",
lambda { |value|
select_tasks_to_show(options, :tasks, value)
}
],
['--trace=[OUT]', '-t', "Turn on invoke/execute tracing, enable full backtrace. OUT can be stderr (default) or stdout.",
['--trace=[OUT]', '-t',
"Turn on invoke/execute tracing, enable full backtrace. " +
"OUT can be stderr (default) or stdout.",
lambda { |value|
options.trace = true
options.backtrace = true
@ -477,22 +518,26 @@ module Rake
Rake.verbose(true)
}
],
['--verbose', '-v', "Log message to standard output.",
['--verbose', '-v',
"Log message to standard output.",
lambda { |value| Rake.verbose(true) }
],
['--version', '-V', "Display the program version.",
['--version', '-V',
"Display the program version.",
lambda { |value|
puts "rake, version #{RAKEVERSION}"
exit
}
],
['--where', '-W [PATTERN]', "Describe the tasks (matching optional PATTERN), then exit.",
['--where', '-W [PATTERN]',
"Describe the tasks (matching optional PATTERN), then exit.",
lambda { |value|
select_tasks_to_show(options, :lines, value)
options.show_all_tasks = true
}
],
['--no-deprecation-warnings', '-X', "Disable the deprecation warnings.",
['--no-deprecation-warnings', '-X',
"Disable the deprecation warnings.",
lambda { |value|
options.ignore_deprecate = true
}
@ -515,7 +560,8 @@ module Rake
when 'stderr', nil
options.trace_output = $stderr
else
fail CommandLineOptionError, "Unrecognized --#{trace_option} option '#{value}'"
fail CommandLineOptionError,
"Unrecognized --#{trace_option} option '#{value}'"
end
end
private :select_trace_output
@ -526,7 +572,7 @@ module Rake
options.trace_output = $stderr
OptionParser.new do |opts|
opts.banner = "rake [-f rakefile] {options} targets..."
opts.banner = "#{Rake.application.name} [-f rakefile] {options} targets..."
opts.separator ""
opts.separator "Options are ..."
@ -538,16 +584,6 @@ module Rake
standard_rake_options.each { |args| opts.on(*args) }
opts.environment('RAKEOPT')
end.parse!
# If class namespaces are requested, set the global options
# according to the values in the options structure.
if options.classic_namespace
$show_tasks = options.show_tasks
$show_prereqs = options.show_prereqs
$trace = options.trace
$dryrun = options.dryrun
$silent = options.silent
end
end
# Similar to the regular Ruby +require+ command, but will check
@ -568,11 +604,9 @@ module Rake
def find_rakefile_location
here = Dir.pwd
while ! (fn = have_rakefile)
until (fn = have_rakefile)
Dir.chdir("..")
if Dir.pwd == here || options.nosearch
return nil
end
return nil if Dir.pwd == here || options.nosearch
here = Dir.pwd
end
[fn, here]
@ -600,8 +634,8 @@ module Rake
@rakefile = rakefile
Dir.chdir(location)
print_rakefile_directory(location)
$rakefile = @rakefile if options.classic_namespace
Rake.load_rakefile(File.expand_path(@rakefile)) if @rakefile && @rakefile != ''
Rake.load_rakefile(File.expand_path(@rakefile)) if
@rakefile && @rakefile != ''
options.rakelib.each do |rlib|
glob("#{rlib}/*.rake") do |name|
add_import name
@ -646,13 +680,19 @@ module Rake
def collect_tasks
@top_level_tasks = []
ARGV.each do |arg|
if arg =~ /^(\w+)=(.*)$/
if arg =~ /^(\w+)=(.*)$/m
ENV[$1] = $2
else
@top_level_tasks << arg unless arg =~ /^-/
end
end
@top_level_tasks.push("default") if @top_level_tasks.size == 0
@top_level_tasks.push(default_task_name) if @top_level_tasks.empty?
end
# Default task name ("default").
# (May be overridden by subclasses)
def default_task_name
"default"
end
# Add a file to the list of files to be imported.
@ -664,9 +704,7 @@ module Rake
def load_imports
while fn = @pending_imports.shift
next if @imported.member?(fn)
if fn_task = lookup(fn)
fn_task.invoke
end
fn_task = lookup(fn) and fn_task.invoke
ext = File.extname(fn)
loader = @loaders[ext] || @default_loader
loader.load(fn)
@ -674,20 +712,8 @@ module Rake
end
end
# Warn about deprecated use of top level constant names.
def const_warning(const_name)
@const_warning ||= false
if ! @const_warning
$stderr.puts %{WARNING: Deprecated reference to top-level constant '#{const_name}' } +
%{found at: #{rakefile_location}} # '
$stderr.puts %{ Use --classic-namespace on rake command}
$stderr.puts %{ or 'require "rake/classic_namespace"' in Rakefile}
end
@const_warning = true
end
def rakefile_location(backtrace=caller)
backtrace.map { |t| t[/([^:]+):/,1] }
backtrace.map { |t| t[/([^:]+):/, 1] }
re = /^#{@rakefile}$/
re = /#{re.source}/i if windows?

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

@ -1,13 +1,15 @@
module Rake
module Backtrace
SUPPRESSED_PATHS =
RbConfig::CONFIG.values_at(*RbConfig::CONFIG.
keys.grep(/(prefix|libdir)/)).uniq + [
File.join(File.dirname(__FILE__), ".."),
].map { |f| Regexp.quote(File.expand_path(f)) }
SUPPRESSED_PATHS.reject! { |s| s.nil? || s =~ /^ *$/ }
SYS_KEYS = RbConfig::CONFIG.keys.grep(/(prefix|libdir)/)
SYS_PATHS = RbConfig::CONFIG.values_at(*SYS_KEYS).uniq +
[ File.join(File.dirname(__FILE__), "..") ]
SUPPRESS_PATTERN = %r!(\A#{SUPPRESSED_PATHS.join('|')}|bin/rake:\d+)!i
SUPPRESSED_PATHS = SYS_PATHS.
map { |s| s.gsub("\\", "/") }.
map { |f| File.expand_path(f) }.
reject { |s| s.nil? || s =~ /^ *$/ }
SUPPRESSED_PATHS_RE = SUPPRESSED_PATHS.map { |f| Regexp.quote(f) }.join("|")
SUPPRESS_PATTERN = %r!(\A(#{SUPPRESSED_PATHS_RE})|bin/rake:\d+)!i
def self.collapse(backtrace)
pattern = Rake.application.options.suppress_backtrace_pattern ||

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

@ -1,11 +0,0 @@
# The following classes used to be in the top level namespace.
# Loading this file enables compatibility with older Rakefile that
# referenced Task from the top level.
warn "WARNING: Classic namespaces are deprecated and will be removed from future versions of Rake."
# :stopdoc:
Task = Rake::Task
FileTask = Rake::FileTask
FileCreationTask = Rake::FileCreationTask
RakeApp = Rake::Application
# :startdoc:

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

@ -14,19 +14,42 @@
require 'rake'
# :stopdoc:
CLEAN = Rake::FileList["**/*~", "**/*.bak", "**/core"]
module Rake
module Cleaner
extend FileUtils
module_function
def cleanup_files(file_names)
file_names.each do |file_name|
cleanup(file_name)
end
end
def cleanup(file_name, opts={})
begin
rm_r file_name, opts
rescue StandardError => ex
puts "Failed to remove #{file_name}: #{ex}"
end
end
end
end
CLEAN = ::Rake::FileList["**/*~", "**/*.bak", "**/core"]
CLEAN.clear_exclude.exclude { |fn|
fn.pathmap("%f").downcase == 'core' && File.directory?(fn)
}
desc "Remove any temporary products."
task :clean do
CLEAN.each { |fn| rm_r fn rescue nil }
Rake::Cleaner.cleanup_files(CLEAN)
end
CLOBBER = Rake::FileList.new
CLOBBER = ::Rake::FileList.new
desc "Remove any generated file."
task :clobber => [:clean] do
CLOBBER.each { |fn| rm_r fn rescue nil }
Rake::Cleaner.cleanup_files(CLOBBER)
end

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

@ -50,33 +50,21 @@ module Rake # :nodoc:
def parse_mode(m)
result = 0
(1..9).each do |i|
result = 2*result + ((m[i]==?-) ? 0 : 1)
result = 2 * result + ((m[i] == ?-) ? 0 : 1)
end
result
end
def determine_time(d1, d2, d3)
now = self.class.time.now
if /:/ =~ d3
result = Time.parse("#{d1} #{d2} #{now.year} #{d3}")
if result > now
result = Time.parse("#{d1} #{d2} #{now.year-1} #{d3}")
end
else
if /:/ !~ d3
result = Time.parse("#{d1} #{d2} #{d3}")
else
result = Time.parse("#{d1} #{d2} #{now.year} #{d3}")
result = Time.parse("#{d1} #{d2} #{now.year - 1} #{d3}") if
result > now
end
result
# elements = ParseDate.parsedate("#{d1} #{d2} #{d3}")
# if elements[0].nil?
# today = self.class.date.today
# if elements[1] > today.month
# elements[0] = today.year - 1
# else
# elements[0] = today.year
# end
# end
# elements = elements.collect { |el| el.nil? ? 0 : el }
# Time.mktime(*elements[0,7])
end
end

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

@ -1,192 +1,2 @@
warn 'Sys has been deprecated in favor of FileUtils'
#--
# Copyright 2003-2010 by Jim Weirich (jim.weirich@gmail.com)
# All rights reserved.
#++
#
begin
require 'ftools'
rescue LoadError
end
require 'rbconfig'
require 'rake/file_list'
######################################################################
# Sys provides a number of file manipulation tools for the convenience
# of writing Rakefiles. All commands in this module will announce
# their activity on standard output if the $verbose flag is set
# ($verbose = true is the default). You can control this by globally
# setting $verbose or by using the +verbose+ and +quiet+ methods.
#
# Sys has been deprecated in favor of the FileUtils module available
# in Ruby 1.8.
#
module Sys
RUBY = RbConfig::CONFIG['ruby_install_name']
# Install all the files matching +wildcard+ into the +dest_dir+
# directory. The permission mode is set to +mode+.
def install(wildcard, dest_dir, mode)
FileList.glob(wildcard).each do |fn|
File.install(fn, dest_dir, mode, $verbose)
end
end
# Run the system command +cmd+.
def run(cmd)
log cmd
system(cmd) or fail "Command Failed: [#{cmd}]"
end
# Run a Ruby interpreter with the given arguments.
def ruby(*args)
run "#{RUBY} #{args.join(' ')}"
end
# Copy a single file from +file_name+ to +dest_file+.
def copy(file_name, dest_file)
log "Copying file #{file_name} to #{dest_file}"
File.copy(file_name, dest_file)
end
# Copy all files matching +wildcard+ into the directory +dest_dir+.
def copy_files(wildcard, dest_dir)
for_matching_files(wildcard, dest_dir) { |from, to| copy(from, to) }
end
# Link +file_name+ to +dest_file+.
def link(file_name, dest_file)
log "Linking file #{file_name} to #{dest_file}"
File.link(file_name, dest_file)
end
# Link all files matching +wildcard+ into the directory +dest_dir+.
def link_files(wildcard, dest_dir)
for_matching_files(wildcard, dest_dir) { |from, to| link(from, to) }
end
# Symlink +file_name+ to +dest_file+.
def symlink(file_name, dest_file)
log "Symlinking file #{file_name} to #{dest_file}"
File.symlink(file_name, dest_file)
end
# Symlink all files matching +wildcard+ into the directory +dest_dir+.
def symlink_files(wildcard, dest_dir)
for_matching_files(wildcard, dest_dir) { |from, to| link(from, to) }
end
# Remove all files matching +wildcard+. If a matching file is a
# directory, it must be empty to be removed. used +delete_all+ to
# recursively delete directories.
def delete(*wildcards)
wildcards.each do |wildcard|
FileList.glob(wildcard).each do |fn|
if File.directory?(fn)
log "Deleting directory #{fn}"
Dir.delete(fn)
else
log "Deleting file #{fn}"
File.delete(fn)
end
end
end
end
# Recursively delete all files and directories matching +wildcard+.
def delete_all(*wildcards)
wildcards.each do |wildcard|
FileList.glob(wildcard).each do |fn|
next if ! File.exist?(fn)
if File.directory?(fn)
FileList.glob("#{fn}/*").each do |subfn|
next if subfn=='.' || subfn=='..'
delete_all(subfn)
end
log "Deleting directory #{fn}"
Dir.delete(fn)
else
log "Deleting file #{fn}"
File.delete(fn)
end
end
end
end
# Make the directories given in +dirs+.
def makedirs(*dirs)
dirs.each do |fn|
log "Making directory #{fn}"
File.makedirs(fn)
end
end
# Make +dir+ the current working directory for the duration of
# executing the given block.
def indir(dir)
olddir = Dir.pwd
Dir.chdir(dir)
yield
ensure
Dir.chdir(olddir)
end
# Split a file path into individual directory names.
#
# For example:
# split_all("a/b/c") => ['a', 'b', 'c']
def split_all(path)
head, tail = File.split(path)
return [tail] if head == '.' || tail == '/'
return [head, tail] if head == '/'
return split_all(head) + [tail]
end
# Write a message to standard error if $verbose is enabled.
def log(msg)
print " " if $trace && $verbose
$stderr.puts msg if $verbose
end
# Perform a block with $verbose disabled.
def quiet(&block)
with_verbose(false, &block)
end
# Perform a block with $verbose enabled.
def verbose(&block)
with_verbose(true, &block)
end
# Perform a block with each file matching a set of wildcards.
def for_files(*wildcards)
wildcards.each do |wildcard|
FileList.glob(wildcard).each do |fn|
yield(fn)
end
end
end
extend(self)
private # ----------------------------------------------------------
def for_matching_files(wildcard, dest_dir)
FileList.glob(wildcard).each do |fn|
dest_file = File.join(dest_dir, fn)
parent = File.dirname(dest_file)
makedirs(parent) if ! File.directory?(parent)
yield(fn, dest_file)
end
end
def with_verbose(v)
oldverbose = $verbose
$verbose = v
yield
ensure
$verbose = oldverbose
end
end
fail "ERROR: 'rake/contrib/sys' is obsolete and no longer supported. " +
"Use 'FileUtils' instead."

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

@ -1,21 +0,0 @@
Copyright (c) 2003, 2004 Jim Weirich
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

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

@ -1,187 +0,0 @@
= RAKE -- Ruby Make
This package contains Rake, a simple ruby build program with capabilities
similar to make.
Rake has the following features:
* Rakefiles (rake's version of Makefiles) are completely defined in
standard Ruby syntax. No XML files to edit. No quirky Makefile
syntax to worry about (is that a tab or a space?)
* Users can specify tasks with prerequisites.
* Rake supports rule patterns to synthesize implicit tasks.
* Flexible FileLists that act like arrays but know about manipulating
file names and paths.
* A library of prepackaged tasks to make building rakefiles easier. For example,
tasks for building tarballs and publishing to FTP or SSH sites. (Formerly
tasks for building RDoc and Gems were included in rake but they're now
available in RDoc and RubyGems respectively.)
* Supports parallel execution of tasks.
== Installation
=== Gem Installation
Download and install rake with the following.
gem install rake
== Usage
=== Simple Example
First, you must write a "Rakefile" file which contains the build rules. Here's
a simple example:
task :default => [:test]
task :test do
ruby "test/unittest.rb"
end
This Rakefile has two tasks:
* A task named "test", which - upon invocation - will run a unit test file in
Ruby.
* A task named "default". This task does nothing by itself, but it has exactly
one dependency, namely the "test" task. Invoking the "default" task will
cause Rake to invoke the "test" task as well.
Running the "rake" command without any options will cause it to run the
"default" task in the Rakefile:
% ls
Rakefile test/
% rake
(in /home/some_user/Projects/rake)
ruby test/unittest.rb
....unit test output here...
Type "rake --help" for all available options.
=== More Information
* For details on Rake's command-line invocation, read
doc/command_line_usage.rdoc[https://github.com/jimweirich/rake/blob/master/doc/command_line_usage.rdoc]
* For details on writing Rakefiles, see
doc/rakefile.rdoc[https://github.com/jimweirich/rake/blob/master/doc/rakefile.rdoc].
* For the original announcement of Rake, see
doc/rational.rdoc[https://github.com/jimweirich/rake/blob/master/doc/rational.rdoc].
* For a glossary of terms, see
doc/glossary.rdoc[https://github.com/jimweirich/rake/blob/master/doc/glossary.rdoc].
== Development
=== Source Repository
Rake is currently hosted at github. The github web page is
http://github.com/jimweirich/rake. The public git clone URL is
* git://github.com/jimweirich/rake.git
=== Running the Rake Test Suite
If you wish to run the unit and functional tests that come with Rake:
* Install the 'flexmock' gem
* Install the 'session' gem in order to run the functional tests.
* CD into the top project directory of rake.
* Type one of the following:
rake # If you have a version of rake installed
ruby -Ilib bin/rake # If you do not have a version of rake installed.
=== Issues and Bug Reports
Feature requests and bug reports can be made here
* https://github.com/jimweirich/rake/issues
Issues and bug reports can also be tracked here:
* http://www.pivotaltracker.com/projects/28469
== Online Resources
=== Rake References
* Rake Documentation Home: http://docs.rubyrake.org
* Rake Project Page: http://rubyforge.org/projects/rake
* Rake API Documents: http://rake.rubyforge.org
* Rake Source Code Repo: http://github.com/jimweirich/rake
* Rake Git Repo Clone URL: git://github.com/jimweirich/rake.git
* Rake Bug Reports: https://github.com/jimweirich/rake/issues
* Rake Continuous Build Server: https://travis-ci.org/#!/jimweirich/rake
=== Presentations and Articles about Rake
* Jim Weirich's 2003 RubyConf presentation:
http://onestepback.org/articles/buildingwithrake/
* Martin Fowler's article on Rake: http://martinfowler.com/articles/rake.html
== Other Make Reinvisionings ...
Rake is a late entry in the make replacement field. Here are links to
other projects with similar (and not so similar) goals.
* http://directory.fsf.org/bras.html -- Bras, one of earliest
implementations of "make in a scripting language".
* http://www.a-a-p.org -- Make in Python
* http://www.aromatic.com/tools/jam.txt -- JAM, Java Automated Make
* http://ant.apache.org -- The Ant project
* http://ppt.perl.org/commands/make/index.html -- Make from the Perl
Power Tools implementation.
* http://search.cpan.org/search?query=PerlBuildSystem -- The Perl Build System
* http://make.rubyforge.org -- Rant, another Ruby make tool.
== Credits
[<b>Ryan Dlugosz</b>] For the initial conversation that sparked Rake.
[<b>nobu.nokada@softhome.net</b>] For the initial patch for rule support.
[<b>Tilman Sauerbeck <tilman@code-monkey.de></b>] For the recursive rule patch.
[<b>Eric Hodel</b>] For aid in maintaining rake.
== License
Rake is available under an MIT-style license.
See {MIT-LICENSE}[rdoc-ref:lib/rake/doc/MIT-LICENSE] for permissions.
== Support
The Rake homepage is http://rake.rubyforge.org. You can find the Rake
RubyForge page at http://rubyforge.org/projects/rake.
Feel free to submit commits or feature requests. If you send a patch,
remember to update the corresponding unit tests. In fact, I prefer
new feature to be submitted in the form of new unit tests.
For other information, feel free to ask on the ruby-talk mailing list
(which is mirrored to comp.lang.ruby) or contact
jim dot weirich at gmail.com.
---
= Other stuff
Author:: Jim Weirich <jim.weirich@gmail.com>
Requires:: Ruby 1.8.6 or later
License:: Copyright 2003-2011 by Jim Weirich.
Released under an MIT-style license. See the MIT-LICENSE
file included in the distribution.
== Warranty
This software is provided "as is" and without any express or
implied warranties, including, without limitation, the implied
warranties of merchantibility and fitness for a particular
purpose.

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

@ -1,152 +0,0 @@
= Rake Command Line Usage
Rake is invoked from the command line using:
% rake [options ...] [VAR=VALUE ...] [targets ...]
Options are:
[<tt><em>name</em>=<em>value</em></tt>]
Set the environment variable <em>name</em> to <em>value</em>
during the execution of the <b>rake</b> command. You can access
the value by using ENV['<em>name</em>'].
[<tt>--all</tt> (-A)]
Used in combination with the -T and -D options, will force
those options to show all the tasks, even the ones without comments.
[<tt>--backtrace</tt>{=_output_} (-n)]
Enable a full backtrace (i.e. like --trace, but without the task
tracing details). The _output_ parameter is optional, but if
specified it controls where the backtrace output is sent. If
_output_ is <tt>stdout</tt>, then backtrace output is directed to
stardard output. If _output_ is <tt>stderr</tt>, or if it is
missing, then the backtrace output is sent to standard error.
[<tt>--comments</tt>]
Used in combination with the -W options to force the output to
contain commented options only. This is the reverse of
<tt>--all</tt>.
[<tt>--describe</tt> _pattern_ (-D)]
Describe the tasks (matching optional PATTERN), then exit.
[<tt>--dry-run</tt> (-n)]
Do a dry run. Print the tasks invoked and executed, but do not
actually execute any of the actions.
[<tt>--execute</tt> _code_ (-e)]
Execute some Ruby code and exit.
[<tt>--execute-print</tt> _code_ (-p)]
Execute some Ruby code, print the result, and exit.
[<tt>--execute-continue</tt> _code_ (-E)]
Execute some Ruby code, then continue with normal task processing.
[<tt>--help</tt> (-H)]
Display some help text and exit.
[<tt>--jobs</tt> _number_ (-j)]
Specifies the number of active concurrent tasks used. The
suggested value is equal to the number of CPUs. The concurrent
tasks are used to execute the <tt>multitask</tt> prerequisites.
Also see the <tt>-m</tt> option which turns all tasks into
multitasks.
Sample values:
(no -j) : unlimited concurrent tasks (standard rake behavior)
-j : 2 concurrent tasks (exact number may change)
-j 16 : 16 concurrent tasks
[<tt>--job-stats</tt> _level_]
Display job statistics at the completion of the run. By default,
this will display the requested number of active tasks (from the
-j options) and the maximum number of tasks in play at any given
time.
If the optional _level_ is <tt>history</tt>, then a complete trace
of task history will be displayed on standard output.
[<tt>--libdir</tt> _directory_ (-I)]
Add _directory_ to the list of directories searched for require.
[<tt>--multitask</tt> (-m)]
Treat all tasks as multitasks. ('make/drake' semantics)
[<tt>--nosearch</tt> (-N)]
Do not search for a Rakefile in parent directories.
[<tt>--prereqs</tt> (-P)]
Display a list of all tasks and their immediate prerequisites.
[<tt>--quiet</tt> (-q)]
Do not echo commands from FileUtils.
[<tt>--rakefile</tt> _filename_ (-f)]
Use _filename_ as the name of the rakefile. The default rakefile
names are +rakefile+ and +Rakefile+ (with +rakefile+ taking
precedence). If the rakefile is not found in the current
directory, +rake+ will search parent directories for a match. The
directory where the Rakefile is found will become the current
directory for the actions executed in the Rakefile.
[<tt>--rakelibdir</tt> _rakelibdir_ (-R)]
Auto-import any .rake files in RAKELIBDIR. (default is 'rakelib')
[<tt>--require</tt> _name_ (-r)]
Require _name_ before executing the Rakefile.
[<tt>--rules</tt>]
Trace the rules resolution.
[<tt>--silent (-s)</tt>]
Like --quiet, but also suppresses the 'in directory' announcement.
[<tt>--suppress-backtrace _pattern_ </tt>]
Line matching the regular expression _pattern_ will be removed
from the backtrace output. Note that the --backtrace option is the
full backtrace without these lines suppressed.
[<tt>--system</tt> (-g)]
Use the system wide (global) rakefiles. The project Rakefile is
ignored. By default, the system wide rakefiles are used only if no
project Rakefile is found. On Unix-like system, the system wide
rake files are located in $HOME/.rake. On a windows system they
are stored in $APPDATA/Rake.
[<tt>--no-system</tt> (-G)]
Use the project level Rakefile, ignoring the system-wide (global)
rakefiles.
[<tt>--tasks</tt> <em>pattern</em> (-T)]
Display a list of the major tasks and their comments. Comments
are defined using the "desc" command. If a pattern is given, then
only tasks matching the pattern are displayed.
[<tt>--trace</tt>{=_output_} (-t)]
Turn on invoke/execute tracing. Also enable full backtrace on
errors. The _output_ parameter is optional, but if specified it
controls where the trace output is sent. If _output_ is
<tt>stdout</tt>, then trace output is directed to stardard output.
If _output_ is <tt>stderr</tt>, or if it is missing, then trace
output is sent to standard error.
[<tt>--verbose</tt> (-v)]
Echo the Sys commands to standard output.
[<tt>--version</tt> (-V)]
Display the program version and exit.
[<tt>--where</tt> <em>pattern</em> (-W)]
Display tasks that match <em>pattern</em> and the file and line
number where the task is defined. By default this option will
display all tasks, not just the tasks that have descriptions.
[<tt>--no-deprecation-warnings</tt> (-W)]
Do not display the deprecation warnings.
In addition, any command line option of the form
<em>VAR</em>=<em>VALUE</em> will be added to the environment hash
<tt>ENV</tt> and may be tested in the Rakefile.

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

@ -1,51 +0,0 @@
= Glossary
[<b>action</b>]
Code to be executed in order to perform a task. Actions in a
rakefile are specified in a code block (usually delimited by
+do+/+end+ pairs.
[<b>execute</b>]
When a task is executed, all of its actions are performed, in
the order they were defined. Note that unlike
<tt>invoke</tt>, <tt>execute</tt> always executes the actions
(without invoking or executing the prerequisites).
[<b>file task</b> (FileTask)]
A file task is a task whose purpose is to create a file
(which has the same name as the task). When invoked, a file
task will only execute if one or more of the following
conditions are true.
1. The associated file does not exist.
2. A prerequisite has a later time stamp than the existing file.
Because normal Tasks always have the current time as
timestamp, a FileTask that has a normal Task prerequisite
will always execute.
[<b>invoke</b>]
When a task is invoked, first we check to see if it has been
invoked before. if it has been, then nothing else is done.
If this is the first time its been invoked, then we invoke
each of its prerequisites. Finally, we check to see if we
need to execute the actions of this task by calling
<tt>needed?</tt>. Finally, if the task is needed, we execute
its actions.
NOTE: Currently prerequisites are invoked even if the task is
not needed. This may change in the future.
[<b>prerequisites</b>]
Every task has a set (possibly empty) of prerequisites. A
prerequisite P to Task T is itself a task that must be invoked
before Task T.
[<b>rule</b>]
A rule is a recipe for synthesizing a task when no task is
explicitly defined. Rules generally synthesize file tasks.
[<b>task</b> (Task)]
Basic unit of work in a rakefile. A task has a name, a set of
prerequisites and a list of actions to be performed.

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

@ -1,557 +0,0 @@
= Rakefile Format (as of version 0.8.7)
First of all, there is no special format for a Rakefile. A Rakefile
contains executable Ruby code. Anything legal in a ruby script is
allowed in a Rakefile.
Now that we understand there is no special syntax in a Rakefile, there
are some conventions that are used in a Rakefile that are a little
unusual in a typical Ruby program. Since a Rakefile is tailored to
specifying tasks and actions, the idioms used in a Rakefile are
designed to support that.
So, what goes into a Rakefile?
== Tasks
Tasks are the main unit of work in a Rakefile. Tasks have a name
(usually given as a symbol or a string), a list of prerequisites (more
symbols or strings) and a list of actions (given as a block).
=== Simple Tasks
A task is declared by using the +task+ method. +task+ takes a single
parameter that is the name of the task.
task :name
=== Tasks with Prerequisites
Any prerequisites are given as a list (enclosed in square brackets)
following the name and an arrow (=>).
task :name => [:prereq1, :prereq2]
<b>NOTE:</b> Although this syntax looks a little funky, it is legal
Ruby. We are constructing a hash where the key is :name and the value
for that key is the list of prerequisites. It is equivalent to the
following ...
hash = Hash.new
hash[:name] = [:prereq1, :prereq2]
task(hash)
=== Tasks with Actions
Actions are defined by passing a block to the +task+ method. Any Ruby
code can be placed in the block. The block may reference the task
object via the block parameter.
task :name => [:prereq1, :prereq2] do |t|
# actions (may reference t)
end
=== Multiple Definitions
A task may be specified more than once. Each specification adds its
prerequisites and actions to the existing definition. This allows one
part of a rakefile to specify the actions and a different rakefile
(perhaps separately generated) to specify the dependencies.
For example, the following is equivalent to the single task
specification given above.
task :name
task :name => [:prereq1]
task :name => [:prereq2]
task :name do |t|
# actions
end
== File Tasks
Some tasks are designed to create a file from one or more other files.
Tasks that generate these files may be skipped if the file already
exists. File tasks are used to specify file creation tasks.
File tasks are declared using the +file+ method (instead of the +task+
method). In addition, file tasks are usually named with a string
rather than a symbol.
The following file task creates a executable program (named +prog+)
given two object files name <tt>a.o</tt> and <tt>b.o</tt>. The tasks
for creating <tt>a.o</tt> and <tt>b.o</tt> are not shown.
file "prog" => ["a.o", "b.o"] do |t|
sh "cc -o #{t.name} #{t.prerequisites.join(' ')}"
end
== Directory Tasks
It is common to need to create directories upon demand. The
+directory+ convenience method is a short-hand for creating a FileTask
that creates the directory. For example, the following declaration
...
directory "testdata/examples/doc"
is equivalent to ...
file "testdata" do |t| mkdir t.name end
file "testdata/examples" do |t| mkdir t.name end
file "testdata/examples/doc" do |t| mkdir t.name end
The +directory+ method does not accept prerequisites or actions, but
both prerequisites and actions can be added later. For example ...
directory "testdata"
file "testdata" => ["otherdata"]
file "testdata" do
cp Dir["standard_data/*.data"], "testdata"
end
== Tasks with Parallel Prerequisites
Rake allows parallel execution of prerequisites using the following syntax:
multitask :copy_files => [:copy_src, :copy_doc, :copy_bin] do
puts "All Copies Complete"
end
In this example, +copy_files+ is a normal rake task. Its actions are
executed whenever all of its prerequisites are done. The big
difference is that the prerequisites (+copy_src+, +copy_bin+ and
+copy_doc+) are executed in parallel. Each of the prerequisites are
run in their own Ruby thread, possibly allowing faster overall runtime.
=== Secondary Prerequisites
If any of the primary prerequisites of a multitask have common secondary
prerequisites, all of the primary/parallel prerequisites will wait
until the common prerequisites have been run.
For example, if the <tt>copy_<em>xxx</em></tt> tasks have the
following prerequisites:
task :copy_src => [:prep_for_copy]
task :copy_bin => [:prep_for_copy]
task :copy_doc => [:prep_for_copy]
Then the +prep_for_copy+ task is run before starting all the copies in
parallel. Once +prep_for_copy+ is complete, +copy_src+, +copy_bin+,
and +copy_doc+ are all run in parallel. Note that +prep_for_copy+ is
run only once, even though it is referenced in multiple threads.
=== Thread Safety
The Rake internal data structures are thread-safe with respect
to the multitask parallel execution, so there is no need for the user
to do extra synchronization for Rake's benefit. However, if there are
user data structures shared between the parallel prerequisites, the
user must do whatever is necessary to prevent race conditions.
== Tasks with Arguments
Prior to version 0.8.0, rake was only able to handle command line
arguments of the form NAME=VALUE that were passed into Rake via the
ENV hash. Many folks had asked for some kind of simple command line
arguments, perhaps using "--" to separate regular task names from
argument values on the command line. The problem is that there was no
easy way to associate positional arguments on the command line with
different tasks. Suppose both tasks :a and :b expect a command line
argument: does the first value go with :a? What if :b is run first?
Should it then get the first command line argument.
Rake 0.8.0 solves this problem by explicitly passing values directly
to the tasks that need them. For example, if I had a release task
that required a version number, I could say:
rake release[0.8.2]
And the string "0.8.2" will be passed to the :release task. Multiple
arguments can be passed by separating them with a comma, for example:
rake name[john,doe]
Just a few words of caution. The rake task name and its arguments
need to be a single command line argument to rake. This generally
means no spaces. If spaces are needed, then the entire rake +
argument string should be quoted. Something like this:
rake "name[billy bob, smith]"
(Quoting rules vary between operating systems and shells, so make sure
you consult the proper docs for your OS/shell).
=== Tasks Arguments and the Environment
Task argument values can also be picked up from the environment. For
example, if the "release" task expected a parameter named
"release_version", then either
rake release[0.8.2]
or
RELEASE_VERSION=0.8.2 rake release
will work. Environment variable names must either match the task
parameter exactly, or match an all-uppercase version of the task
parameter.
=== Tasks that Expect Parameters
Parameters are only given to tasks that are setup to expect them. In
order to handle named parameters, the task declaration syntax for
tasks has been extended slightly.
For example, a task that needs a first name and last name might be
declared as:
task :name, [:first_name, :last_name]
The first argument is still the name of the task (:name in this case).
The next two arguments are the names of the parameters expected by
:name in an array (:first_name and :last_name in the example).
To access the values of the parameters, the block defining the task
behaviour can now accept a second parameter:
task :name, [:first_name, :last_name] do |t, args|
puts "First name is #{args.first_name}"
puts "Last name is #{args.last_name}"
end
The first argument of the block "t" is always bound to the current
task object. The second argument "args" is an open-struct like object
that allows access to the task arguments. Extra command line
arguments to a task are ignored. Missing command line arguments are
picked up from matching environment variables. If there are no
matching environment variables, they are given the nil value.
If you wish to specify default values for the arguments, you can use
the with_defaults method in the task body. Here is the above example
where we specify default values for the first and last names:
task :name, [:first_name, :last_name] do |t, args|
args.with_defaults(:first_name => "John", :last_name => "Dough")
puts "First name is #{args.first_name}"
puts "Last name is #{args.last_name}"
end
=== Tasks that Expect Parameters and Have Prerequisites
Tasks that use parameters have a slightly different format for
prerequisites. Use the arrow notation to indicate the prerequisites
for tasks with arguments. For example:
task :name, [:first_name, :last_name] => [:pre_name] do |t, args|
args.with_defaults(:first_name => "John", :last_name => "Dough")
puts "First name is #{args.first_name}"
puts "Last name is #{args.last_name}"
end
=== Deprecated Task Parameters Format
There is an older format for declaring task parameters that omitted
the task argument array and used the :needs keyword to introduce the
dependencies. That format is still supported for compatibility, but
is not recommended for use. The older format may be dropped in future
versions of rake.
== Accessing Task Programmatically
Sometimes it is useful to manipulate tasks programmatically in a
Rakefile. To find a task object, use the <tt>:[]</tt> operator on the
<tt>Rake::Task</tt>.
=== Programmatic Task Example
For example, the following Rakefile defines two tasks. The :doit task
simply prints a simple "DONE" message. The :dont class will lookup
the doit class and remove (clear) all of its prerequisites and
actions.
task :doit do
puts "DONE"
end
task :dont do
Rake::Task[:doit].clear
end
Running this example:
$ rake doit
(in /Users/jim/working/git/rake/x)
DONE
$ rake dont doit
(in /Users/jim/working/git/rake/x)
$
The ability to programmatically manipulate tasks gives rake very
powerful meta-programming capabilities w.r.t. task execution, but
should be used with caution.
== Rules
When a file is named as a prerequisite, but does not have a file task
defined for it, Rake will attempt to synthesize a task by looking at a
list of rules supplied in the Rakefile.
Suppose we were trying to invoke task "mycode.o", but no task is
defined for it. But the rakefile has a rule that look like this ...
rule '.o' => ['.c'] do |t|
sh "cc #{t.source} -c -o #{t.name}"
end
This rule will synthesize any task that ends in ".o". It has a
prerequisite a source file with an extension of ".c" must exist. If
Rake is able to find a file named "mycode.c", it will automatically
create a task that builds "mycode.o" from "mycode.c".
If the file "mycode.c" does not exist, rake will attempt
to recursively synthesize a rule for it.
When a task is synthesized from a rule, the +source+ attribute of the
task is set to the matching source file. This allows us to write
rules with actions that reference the source file.
=== Advanced Rules
Any regular expression may be used as the rule pattern. Additionally,
a proc may be used to calculate the name of the source file. This
allows for complex patterns and sources.
The following rule is equivalent to the example above.
rule( /\.o$/ => [
proc {|task_name| task_name.sub(/\.[^.]+$/, '.c') }
]) do |t|
sh "cc #{t.source} -c -o #{t.name}"
end
<b>NOTE:</b> Because of a _quirk_ in Ruby syntax, parenthesis are
required on *rule* when the first argument is a regular expression.
The following rule might be used for Java files ...
rule '.class' => [
proc { |tn| tn.sub(/\.class$/, '.java').sub(/^classes\//, 'src/') }
] do |t|
java_compile(t.source, t.name)
end
<b>NOTE:</b> +java_compile+ is a hypothetical method that invokes the
java compiler.
== Importing Dependencies
Any ruby file (including other rakefiles) can be included with a
standard Ruby +require+ command. The rules and declarations in the
required file are just added to the definitions already accumulated.
Because the files are loaded _before_ the rake targets are evaluated,
the loaded files must be "ready to go" when the rake command is
invoked. This make generated dependency files difficult to use. By
the time rake gets around to updating the dependencies file, it is too
late to load it.
The +Rake.import+ command addresses this by specifying a file to be
loaded _after_ the main rakefile is loaded, but _before_ any targets
on the command line are invoked. In addition, if the file name
matches an explicit task, that task is invoked before loading the
file. This allows dependency files to be generated and used in a
single rake command invocation.
<b>NOTE:</b> Starting in Rake version 0.9.0, the top level +import+
command is deprecated and we recommend using the scoped
"+Rake.import+" command mentioned above. Future versions of Rake will
drop support for the top level +import+ command.
=== Example:
require 'rake/loaders/makefile'
file ".depends.mf" => [SRC_LIST] do |t|
sh "makedepend -f- -- #{CFLAGS} -- #{t.prerequisites} > #{t.name}"
end
Rake.import ".depends.mf"
If ".depends" does not exist, or is out of date w.r.t. the source
files, a new ".depends" file is generated using +makedepend+ before
loading.
== Comments
Standard Ruby comments (beginning with "#") can be used anywhere it is
legal in Ruby source code, including comments for tasks and rules.
However, if you wish a task to be described using the "-T" switch,
then you need to use the +desc+ command to describe the task.
=== Example:
desc "Create a distribution package"
task :package => [ ... ] do ... end
The "-T" switch (or "--tasks" if you like to spell things out) will
display a list of tasks that have a description. If you use +desc+ to
describe your major tasks, you have a semi-automatic way of generating
a summary of your Rake file.
traken$ rake -T
(in /home/.../rake)
rake clean # Remove any temporary products.
rake clobber # Remove any generated file.
rake clobber_rdoc # Remove rdoc products
rake contrib_test # Run tests for contrib_test
rake default # Default Task
rake install # Install the application
rake lines # Count lines in the main rake file
rake rdoc # Build the rdoc HTML Files
rake rerdoc # Force a rebuild of the RDOC files
rake test # Run tests
rake testall # Run all test targets
Only tasks with descriptions will be displayed with the "-T" switch.
Use "-P" (or "--prereqs") to get a list of all tasks and their
prerequisites.
== Namespaces
As projects grow (and along with it, the number of tasks), it is
common for task names to begin to clash. For example, if you might
have a main program and a set of sample programs built by a single
Rakefile. By placing the tasks related to the main program in one
namespace, and the tasks for building the sample programs in a
different namespace, the task names will not will not interfere with
each other.
For example:
namespace "main" do
task :build do
# Build the main program
end
end
namespace "samples" do
task :build do
# Build the sample programs
end
end
task :build => ["main:build", "samples:build"]
Referencing a task in a separate namespace can be achieved by
prefixing the task name with the namespace and a colon
(e.g. "main:build" refers to the :build task in the +main+ namespace).
Nested namespaces are supported, so
Note that the name given in the +task+ command is always the unadorned
task name without any namespace prefixes. The +task+ command always
defines a task in the current namespace.
=== FileTasks
File task names are not scoped by the namespace command. Since the
name of a file task is the name of an actual file in the file system,
it makes little sense to include file task names in name space.
Directory tasks (created by the +directory+ command) are a type of
file task and are also not affected by namespaces.
=== Name Resolution
When looking up a task name, rake will start with the current
namespace and attempt to find the name there. If it fails to find a
name in the current namespace, it will search the parent namespaces
until a match is found (or an error occurs if there is no match).
The "rake" namespace is a special implicit namespace that refers to
the toplevel names.
If a task name begins with a "^" character, the name resolution will
start in the parent namespace. Multiple "^" characters are allowed.
Here is an example file with multiple :run tasks and how various names
resolve in different locations.
task :run
namespace "one" do
task :run
namespace "two" do
task :run
# :run => "one:two:run"
# "two:run" => "one:two:run"
# "one:two:run" => "one:two:run"
# "one:run" => "one:run"
# "^run" => "one:run"
# "^^run" => "rake:run" (the top level task)
# "rake:run" => "rake:run" (the top level task)
end
# :run => "one:run"
# "two:run" => "one:two:run"
# "^run" => "rake:run"
end
# :run => "rake:run"
# "one:run" => "one:run"
# "one:two:run" => "one:two:run"
== FileLists
FileLists are the way Rake manages lists of files. You can treat a
FileList as an array of strings for the most part, but FileLists
support some additional operations.
=== Creating a FileList
Creating a file list is easy. Just give it the list of file names:
fl = FileList['file1.rb', file2.rb']
Or give it a glob pattern:
fl = FileList['*.rb']
== Odds and Ends
=== do/end versus { }
Blocks may be specified with either a +do+/+end+ pair, or with curly
braces in Ruby. We _strongly_ recommend using +do+/+end+ to specify the
actions for tasks and rules. Because the rakefile idiom tends to
leave off parentheses on the task/file/rule methods, unusual
ambiguities can arise when using curly braces.
For example, suppose that the method +object_files+ returns a list of
object files in a project. Now we use +object_files+ as the
prerequisites in a rule specified with actions in curly braces.
# DON'T DO THIS!
file "prog" => object_files {
# Actions are expected here (but it doesn't work)!
}
Because curly braces have a higher precedence than +do+/+end+, the
block is associated with the +object_files+ method rather than the
+file+ method.
This is the proper way to specify the task ...
# THIS IS FINE
file "prog" => object_files do
# Actions go here
end
----
== See
* README.rdoc -- Main documentation for Rake.

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

@ -1,151 +0,0 @@
= Why rake?
Ok, let me state from the beginning that I never intended to write this
code. I'm not convinced it is useful, and I'm not convinced anyone
would even be interested in it. All I can say is that Why's onion truck
must by been passing through the Ohio valley.
What am I talking about? ... A Ruby version of Make.
See, I can sense you cringing already, and I agree. The world certainly
doesn't need yet another reworking of the "make" program. I mean, we
already have "ant". Isn't that enough?
It started yesterday. I was helping a coworker fix a problem in one of
the Makefiles we use in our project. Not a particularly tough problem,
but during the course of the conversation I began lamenting some of the
shortcomings of make. In particular, in one of my makefiles I wanted to
determine the name of a file dynamically and had to resort to some
simple scripting (in Ruby) to make it work. "Wouldn't it be nice if you
could just use Ruby inside a Makefile" I said.
My coworker (a recent convert to Ruby) agreed, but wondered what it
would look like. So I sketched the following on the whiteboard...
"What if you could specify the make tasks in Ruby, like this ..."
task "build" do
java_compile(...args, etc ...)
end
"The task function would register "build" as a target to be made,
and the block would be the action executed whenever the build
system determined that it was time to do the build target."
We agreed that would be cool, but writing make from scratch would be WAY
too much work. And that was the end of that!
... Except I couldn't get the thought out of my head. What exactly
would be needed to make the about syntax work as a make file? Hmmm, you
would need to register the tasks, you need some way of specifying
dependencies between tasks, and some way of kicking off the process.
Hey! What if we did ... and fifteen minutes later I had a working
prototype of Ruby make, complete with dependencies and actions.
I showed the code to my coworker and we had a good laugh. It was just
about a page worth of code that reproduced an amazing amount of the
functionality of make. We were both truly stunned with the power of
Ruby.
But it didn't do everything make did. In particular, it didn't have
timestamp based file dependencies (where a file is rebuilt if any of its
prerequisite files have a later timestamp). Obviously THAT would be a
pain to add and so Ruby Make would remain an interesting experiment.
... Except as I walked back to my desk, I started thinking about what
file based dependencies would really need. Rats! I was hooked again,
and by adding a new class and two new methods, file/timestamp
dependencies were implemented.
Ok, now I was really hooked. Last night (during CSI!) I massaged the
code and cleaned it up a bit. The result is a bare-bones replacement
for make in exactly 100 lines of code.
For the curious, you can see it at ...
* doc/proto_rake.rdoc
Oh, about the name. When I wrote the example Ruby Make task on my
whiteboard, my coworker exclaimed "Oh! I have the perfect name: Rake ...
Get it? Ruby-Make. Rake!" He said he envisioned the tasks as leaves
and Rake would clean them up ... or something like that. Anyways, the
name stuck.
Some quick examples ...
A simple task to delete backup files ...
task :clean do
Dir['*~'].each {|fn| rm fn rescue nil}
end
Note that task names are symbols (they are slightly easier to type
than quoted strings ... but you may use quoted string if you would
rather). Rake makes the methods of the FileUtils module directly
available, so we take advantage of the <tt>rm</tt> command. Also note
the use of "rescue nil" to trap and ignore errors in the <tt>rm</tt>
command.
To run it, just type "rake clean". Rake will automatically find a
Rakefile in the current directory (or above!) and will invoke the
targets named on the command line. If there are no targets explicitly
named, rake will invoke the task "default".
Here's another task with dependencies ...
task :clobber => [:clean] do
rm_r "tempdir"
end
Task :clobber depends upon task :clean, so :clean will be run before
:clobber is executed.
Files are specified by using the "file" command. It is similar to the
task command, except that the task name represents a file, and the task
will be run only if the file doesn't exist, or if its modification time
is earlier than any of its prerequisites.
Here is a file based dependency that will compile "hello.cc" to
"hello.o".
file "hello.cc"
file "hello.o" => ["hello.cc"] do |t|
srcfile = t.name.sub(/\.o$/, ".cc")
sh %{g++ #{srcfile} -c -o #{t.name}}
end
I normally specify file tasks with string (rather than symbols). Some
file names can't be represented by symbols. Plus it makes the
distinction between them more clear to the casual reader.
Currently writing a task for each and every file in the project would be
tedious at best. I envision a set of libraries to make this job
easier. For instance, perhaps something like this ...
require 'rake/ctools'
Dir['*.c'].each do |fn|
c_source_file(fn)
end
where "c_source_file" will create all the tasks need to compile all the
C source files in a directory. Any number of useful libraries could be
created for rake.
That's it. There's no documentation (other than whats in this
message). Does this sound interesting to anyone? If so, I'll continue
to clean it up and write it up and publish it on RAA. Otherwise, I'll
leave it as an interesting exercise and a tribute to the power of Ruby.
Why /might/ rake be interesting to Ruby programmers. I don't know,
perhaps ...
* No weird make syntax (only weird Ruby syntax :-)
* No need to edit or read XML (a la ant)
* Platform independent build scripts.
* Will run anywhere Ruby exists, so no need to have "make" installed.
If you stay away from the "sys" command and use things like
'ftools', you can have a perfectly platform independent
build script. Also rake is only 100 lines of code, so it can
easily be packaged along with the rest of your code.
So ... Sorry for the long rambling message. Like I said, I never
intended to write this code at all.

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

@ -32,7 +32,6 @@ module Rake
Rake::Task.define_task(*args, &block)
end
# Declare a file task.
#
# Example:
@ -67,7 +66,7 @@ module Rake
dir, _ = *Rake.application.resolve_args(args)
Rake.each_dir_parent(dir) do |d|
file_create d do |t|
mkdir_p t.name if ! File.exist?(t.name)
mkdir_p t.name unless File.exist?(t.name)
end
end
result
@ -117,6 +116,7 @@ module Rake
end
# Describe the next rake task.
# Duplicate descriptions are discarded.
#
# Example:
# desc "Run the Unit Tests"
@ -147,31 +147,7 @@ module Rake
Rake.application.add_import(fn)
end
end
end
DeprecatedCommands = Object.new.extend(DSL)
module DeprecatedObjectDSL # :nodoc:
DSL.private_instance_methods(false).each do |name|
line = __LINE__+1
class_eval %{
def #{name}(*args, &block)
unless Rake.application.options.ignore_deprecate
unless @rake_dsl_warning
$stderr.puts "WARNING: Global access to Rake DSL methods is deprecated. Please include"
$stderr.puts " ... Rake::DSL into classes and modules which use the Rake DSL methods."
@rake_dsl_warning = true
end
$stderr.puts "WARNING: DSL method \#{self.class}##{name} called at \#{caller.first}"
end
Rake::DeprecatedCommands.send(:#{name}, *args, &block)
end
private :#{name}
}, __FILE__, line
end
end unless defined? Rake::REDUCE_COMPAT
extend FileUtilsExt
end
@ -179,4 +155,3 @@ end
# calls to task, etc. to work from a Rakefile without polluting the
# object inheritance tree.
self.extend Rake::DSL
include Rake::DeprecatedObjectDSL unless defined? Rake::REDUCE_COMPAT

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

@ -19,7 +19,8 @@ class Module
#
def rake_extension(method)
if method_defined?(method)
$stderr.puts "WARNING: Possible conflict with Rake extension: #{self}##{method} already exists"
$stderr.puts "WARNING: Possible conflict with Rake extension: " +
"#{self}##{method} already exists"
else
yield
end

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

@ -1,39 +0,0 @@
require 'rake/ext/core'
require 'rake/task'
require 'rake/file_task'
require 'rake/file_creation_task'
require 'rake/application'
require 'rake/task_manager'
######################################################################
# Rake extensions to Module.
#
class Module
# Rename the original handler to make it available.
alias :rake_original_const_missing :const_missing
# Check for deprecated uses of top level (i.e. in Object) uses of
# Rake class names. If someone tries to reference the constant
# name, display a warning and return the proper object. Using the
# --classic-namespace command line option will define these
# constants in Object and avoid this handler.
def const_missing(const_name)
case const_name
when :Task
Rake.application.const_warning(const_name)
Rake::Task
when :FileTask
Rake.application.const_warning(const_name)
Rake::FileTask
when :FileCreationTask
Rake.application.const_warning(const_name)
Rake::FileCreationTask
when :RakeApp
Rake.application.const_warning(const_name)
Rake::Application
else
rake_original_const_missing(const_name)
end
end
end unless defined? Rake::REDUCE_COMPAT

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

@ -13,9 +13,7 @@ class String
# +ext+ is a user added method for the String class.
def ext(newext='')
return self.dup if ['.', '..'].include? self
if newext != ''
newext = (newext =~ /^\./) ? newext : ("." + newext)
end
newext = (newext =~ /^\./) ? newext : ("." + newext) if newext != ''
self.chomp(File.extname(self)) << newext
end
end

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

@ -41,10 +41,11 @@ module Rake
# List of array methods (that are not in +Object+) that need to be
# delegated.
ARRAY_METHODS = (Array.instance_methods - Object.instance_methods).map { |n| n.to_s }
ARRAY_METHODS = (Array.instance_methods - Object.instance_methods).
map { |n| n.to_s }
# List of additional methods that must be delegated.
MUST_DEFINE = %w[to_a inspect <=>]
MUST_DEFINE = %w[inspect <=>]
# List of methods that should not be delegated here (we define special
# versions of them explicitly below).
@ -58,12 +59,13 @@ module Rake
+ - & |
]
DELEGATING_METHODS = (ARRAY_METHODS + MUST_DEFINE - MUST_NOT_DEFINE).collect{ |s| s.to_s }.sort.uniq
DELEGATING_METHODS = (ARRAY_METHODS + MUST_DEFINE - MUST_NOT_DEFINE).
map { |s| s.to_s }.sort.uniq
# Now do the delegation.
DELEGATING_METHODS.each_with_index do |sym, i|
DELEGATING_METHODS.each do |sym|
if SPECIAL_RETURN.include?(sym)
ln = __LINE__+1
ln = __LINE__ + 1
class_eval %{
def #{sym}(*args, &block)
resolve
@ -72,7 +74,7 @@ module Rake
end
}, __FILE__, ln
else
ln = __LINE__+1
ln = __LINE__ + 1
class_eval %{
def #{sym}(*args, &block)
resolve
@ -149,10 +151,8 @@ module Rake
patterns.each do |pat|
@exclude_patterns << pat
end
if block_given?
@exclude_procs << block
end
resolve_exclude if ! @pending
@exclude_procs << block if block_given?
resolve_exclude unless @pending
self
end
@ -219,7 +219,7 @@ module Rake
private :resolve_add
def resolve_exclude
reject! { |fn| exclude?(fn) }
reject! { |fn| excluded_from_list?(fn) }
self
end
private :resolve_exclude
@ -231,7 +231,7 @@ module Rake
# FileList['a.c', 'b.c'].sub(/\.c$/, '.o') => ['a.o', 'b.o']
#
def sub(pat, rep)
inject(FileList.new) { |res, fn| res << fn.sub(pat,rep) }
inject(FileList.new) { |res, fn| res << fn.sub(pat, rep) }
end
# Return a new FileList with the results of running +gsub+ against each
@ -242,18 +242,18 @@ module Rake
# => ['lib\\test\\file', 'x\\y']
#
def gsub(pat, rep)
inject(FileList.new) { |res, fn| res << fn.gsub(pat,rep) }
inject(FileList.new) { |res, fn| res << fn.gsub(pat, rep) }
end
# Same as +sub+ except that the original file list is modified.
def sub!(pat, rep)
each_with_index { |fn, i| self[i] = fn.sub(pat,rep) }
each_with_index { |fn, i| self[i] = fn.sub(pat, rep) }
self
end
# Same as +gsub+ except that the original file list is modified.
def gsub!(pat, rep)
each_with_index { |fn, i| self[i] = fn.gsub(pat,rep) }
each_with_index { |fn, i| self[i] = fn.gsub(pat, rep) }
self
end
@ -341,13 +341,19 @@ module Rake
# Add matching glob patterns.
def add_matching(pattern)
FileList.glob(pattern).each do |fn|
self << fn unless exclude?(fn)
self << fn unless excluded_from_list?(fn)
end
end
private :add_matching
# Should the given file name be excluded?
def exclude?(fn)
# Should the given file name be excluded from the list?
#
# NOTE: This method was formally named "exclude?", but Rails
# introduced an exclude? method as an array method and setup a
# conflict with file list. We renamed the method to avoid
# confusion. If you were using "FileList#exclude?" in your user
# code, you will need to update.
def excluded_from_list?(fn)
return true if @exclude_patterns.any? do |pat|
case pat
when Regexp

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

@ -29,7 +29,7 @@ module Rake
# Are there any prerequisites with a later time than the given time stamp?
def out_of_date?(stamp)
@prerequisites.any? { |n| application[n, @scope].timestamp > stamp}
@prerequisites.any? { |n| application[n, @scope].timestamp > stamp }
end
# ----------------------------------------------------------------
@ -44,4 +44,3 @@ module Rake
end
end
end

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

@ -41,24 +41,26 @@ module FileUtils
unless options[:noop]
res = rake_system(*cmd)
status = $?
status = PseudoStatus.new(1) if !res && status.nil?
status = Rake::PseudoStatus.new(1) if !res && status.nil?
shell_runner.call(res, status)
end
end
def create_shell_runner(cmd) # :nodoc:
show_command = cmd.join(" ")
show_command = show_command[0,42] + "..." unless $trace
lambda { |ok, status|
ok or fail "Command failed with status (#{status.exitstatus}): [#{show_command}]"
}
show_command = show_command[0, 42] + "..." unless $trace
lambda do |ok, status|
ok or
fail "Command failed with status (#{status.exitstatus}): " +
"[#{show_command}]"
end
end
private :create_shell_runner
def set_verbose_option(options) # :nodoc:
unless options.key? :verbose
options[:verbose] =
Rake::FileUtilsExt.verbose_flag == Rake::FileUtilsExt::DEFAULT ||
(Rake::FileUtilsExt.verbose_flag == Rake::FileUtilsExt::DEFAULT) ||
Rake::FileUtilsExt.verbose_flag
end
end
@ -74,9 +76,9 @@ module FileUtils
# Example:
# ruby %{-pe '$_.upcase!' <README}
#
def ruby(*args,&block)
def ruby(*args, &block)
options = (Hash === args.last) ? args.pop : {}
if args.length > 1 then
if args.length > 1
sh(*([RUBY] + args + [options]), &block)
else
sh("#{RUBY} #{args.first}", options, &block)
@ -88,7 +90,7 @@ module FileUtils
# Attempt to do a normal file link, but fall back to a copy if the link
# fails.
def safe_ln(*args)
unless LN_SUPPORTED[0]
if ! LN_SUPPORTED[0]
cp(*args)
else
begin

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

@ -18,9 +18,6 @@ module Rake
FileUtilsExt.verbose_flag = DEFAULT
FileUtilsExt.nowrite_flag = false
$fileutils_verbose = true
$fileutils_nowrite = false
FileUtils.commands.each do |name|
opts = FileUtils.options_of name
default_options = []
@ -90,7 +87,7 @@ module Rake
oldvalue
end
# Use this function to prevent potentially destructive Ruby code
# Use this function to prevent potentially destructive ruby code
# from running when the :nowrite flag is set.
#
# Example:
@ -138,7 +135,8 @@ module Rake
optdecl.each do |name|
h.delete name
end
raise ArgumentError, "no such option: #{h.keys.join(' ')}" unless h.empty?
raise ArgumentError, "no such option: #{h.keys.join(' ')}" unless
h.empty?
end
extend self

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

@ -1,15 +1,2 @@
# rake/gempackagetask is deprecated in favor of rubygems/package_task
warn 'rake/gempackagetask is deprecated. Use rubygems/package_task instead'
require 'rubygems'
require 'rubygems/package_task'
require 'rake'
# :stopdoc:
module Rake
GemPackageTask = Gem::PackageTask
end
fail "ERROR: 'rake/gempackagetask' is obsolete and no longer supported. " +
"Use 'rubygems/packagetask' instead."

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

@ -3,44 +3,50 @@ module Rake
####################################################################
# InvocationChain tracks the chain of task invocations to detect
# circular dependencies.
class InvocationChain
def initialize(value, tail)
@value = value
@tail = tail
class InvocationChain < LinkedList
# Is the invocation already in the chain?
def member?(invocation)
head == invocation || tail.member?(invocation)
end
def member?(obj)
@value == obj || @tail.member?(obj)
end
def append(value)
if member?(value)
fail RuntimeError, "Circular dependency detected: #{to_s} => #{value}"
# Append an invocation to the chain of invocations. It is an error
# if the invocation already listed.
def append(invocation)
if member?(invocation)
fail RuntimeError, "Circular dependency detected: #{to_s} => #{invocation}"
end
self.class.new(value, self)
conj(invocation)
end
# Convert to string, ie: TOP => invocation => invocation
def to_s
"#{prefix}#{@value}"
"#{prefix}#{head}"
end
def self.append(value, chain)
chain.append(value)
# Class level append.
def self.append(invocation, chain)
chain.append(invocation)
end
private
def prefix
"#{@tail.to_s} => "
"#{tail.to_s} => "
end
class EmptyInvocationChain
# Null object for an empty chain.
class EmptyInvocationChain < LinkedList::EmptyLinkedList
@parent = InvocationChain
def member?(obj)
false
end
def append(value)
InvocationChain.new(value, self)
def append(invocation)
conj(invocation)
end
def to_s
"TOP"
end

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

@ -0,0 +1,103 @@
module Rake
# Polylithic linked list structure used to implement several data
# structures in Rake.
class LinkedList
include Enumerable
attr_reader :head, :tail
def initialize(head, tail=EMPTY)
@head = head
@tail = tail
end
# Polymorphically add a new element to the head of a list. The
# type of head node will be the same list type has the tail.
def conj(item)
self.class.cons(item, self)
end
# Is the list empty?
def empty?
false
end
# Lists are structurally equivalent.
def ==(other)
current = self
while ! current.empty? && ! other.empty?
return false if current.head != other.head
current = current.tail
other = other.tail
end
current.empty? && other.empty?
end
# Convert to string: LL(item, item...)
def to_s
items = map { |item| item.to_s }.join(", ")
"LL(#{items})"
end
# Same as +to_s+, but with inspected items.
def inspect
items = map { |item| item.inspect }.join(", ")
"LL(#{items})"
end
# For each item in the list.
def each
current = self
while ! current.empty?
yield(current.head)
current = current.tail
end
self
end
# Make a list out of the given arguments. This method is
# polymorphic
def self.make(*args)
result = empty
args.reverse_each do |item|
result = cons(item, result)
end
result
end
# Cons a new head onto the tail list.
def self.cons(head, tail)
new(head, tail)
end
# The standard empty list class for the given LinkedList class.
def self.empty
self::EMPTY
end
# Represent an empty list, using the Null Object Pattern.
#
# When inheriting from the LinkedList class, you should implement
# a type specific Empty class as well. Make sure you set the class
# instance variable @parent to the assocated list class (this
# allows conj, cons and make to work polymorphically).
class EmptyLinkedList < LinkedList
@parent = LinkedList
def initialize
end
def empty?
true
end
def self.cons(head, tail)
@parent.cons(head, tail)
end
end
EMPTY = EmptyLinkedList.new
end
end

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

@ -1,6 +1,6 @@
module Rake
# The NameSpace class will lookup task names in the scope
# The NameSpace class will lookup task names in the the scope
# defined by a +namespace+ command.
#
class NameSpace

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

@ -51,13 +51,16 @@ module Rake
# Directory used to store the package files (default is 'pkg').
attr_accessor :package_dir
# True if a gzipped tar file (tgz) should be produced (default is false).
# True if a gzipped tar file (tgz) should be produced (default is
# false).
attr_accessor :need_tar
# True if a gzipped tar file (tar.gz) should be produced (default is false).
# True if a gzipped tar file (tar.gz) should be produced (default
# is false).
attr_accessor :need_tar_gz
# True if a bzip2'd tar file (tar.bz2) should be produced (default is false).
# True if a bzip2'd tar file (tar.bz2) should be produced (default
# is false).
attr_accessor :need_tar_bz2
# True if a zip file should be produced (default is false)
@ -121,7 +124,8 @@ module Rake
].each do |(need, file, flag)|
if need
task :package => ["#{package_dir}/#{file}"]
file "#{package_dir}/#{file}" => [package_dir_path] + package_files do
file "#{package_dir}/#{file}" =>
[package_dir_path] + package_files do
chdir(package_dir) do
sh %{#{@tar_command} #{flag}cvf #{file} #{package_name}}
end
@ -131,7 +135,8 @@ module Rake
if need_zip
task :package => ["#{package_dir}/#{zip_file}"]
file "#{package_dir}/#{zip_file}" => [package_dir_path] + package_files do
file "#{package_dir}/#{zip_file}" =>
[package_dir_path] + package_files do
chdir(package_dir) do
sh %{#{@zip_command} -r #{zip_file} #{package_name}}
end
@ -145,7 +150,7 @@ module Rake
@package_files.each do |fn|
f = File.join(package_dir_path, fn)
fdir = File.dirname(f)
mkdir_p(fdir) if !File.exist?(fdir)
mkdir_p(fdir) unless File.exist?(fdir)
if File.directory?(fn)
mkdir_p(f)
else

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

@ -17,7 +17,7 @@ module Rake
@mutex = Mutex.new
@result = NOT_SET
@error = NOT_SET
@args = args.collect { |a| begin; a.dup; rescue; a; end }
@args = args
@block = block
end

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

@ -4,18 +4,23 @@ module Rake
# Exit status class for times the system just gives us a nil.
class PseudoStatus
attr_reader :exitstatus
def initialize(code=0)
@exitstatus = code
end
def to_i
@exitstatus << 8
end
def >>(n)
to_i >> n
end
def stopped?
false
end
def exited?
true
end

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

@ -1,234 +1,2 @@
# rake/rdoctask is deprecated in favor of rdoc/task
if Rake.application
Rake.application.deprecate('require \'rake/rdoctask\'', 'require \'rdoc/task\' (in RDoc 2.4.2+)', caller.first)
end
require 'rubygems'
begin
gem 'rdoc'
require 'rdoc'
require 'rdoc/task'
rescue LoadError, Gem::LoadError
end
# :stopdoc:
if defined?(RDoc::Task) then
module Rake
RDocTask = RDoc::Task unless const_defined? :RDocTask
end
else
require 'rake'
require 'rake/tasklib'
module Rake
# NOTE: Rake::RDocTask is deprecated in favor of RDoc:Task which is included
# in RDoc 2.4.2+. Use require 'rdoc/task' to require it.
#
# Create a documentation task that will generate the RDoc files for
# a project.
#
# The RDocTask will create the following targets:
#
# [<b><em>rdoc</em></b>]
# Main task for this RDOC task.
#
# [<b>:clobber_<em>rdoc</em></b>]
# Delete all the rdoc files. This target is automatically
# added to the main clobber target.
#
# [<b>:re<em>rdoc</em></b>]
# Rebuild the rdoc files from scratch, even if they are not out
# of date.
#
# Simple Example:
#
# Rake::RDocTask.new do |rd|
# rd.main = "README.rdoc"
# rd.rdoc_files.include("README.rdoc", "lib/**/*.rb")
# end
#
# The +rd+ object passed to the block is an RDocTask object. See the
# attributes list for the RDocTask class for available customization options.
#
# == Specifying different task names
#
# You may wish to give the task a different name, such as if you are
# generating two sets of documentation. For instance, if you want to have a
# development set of documentation including private methods:
#
# Rake::RDocTask.new(:rdoc_dev) do |rd|
# rd.main = "README.doc"
# rd.rdoc_files.include("README.rdoc", "lib/**/*.rb")
# rd.options << "--all"
# end
#
# The tasks would then be named :<em>rdoc_dev</em>, :clobber_<em>rdoc_dev</em>, and
# :re<em>rdoc_dev</em>.
#
# If you wish to have completely different task names, then pass a Hash as
# first argument. With the <tt>:rdoc</tt>, <tt>:clobber_rdoc</tt> and
# <tt>:rerdoc</tt> options, you can customize the task names to your liking.
# For example:
#
# Rake::RDocTask.new(:rdoc => "rdoc", :clobber_rdoc => "rdoc:clean", :rerdoc => "rdoc:force")
#
# This will create the tasks <tt>:rdoc</tt>, <tt>:rdoc_clean</tt> and
# <tt>:rdoc:force</tt>.
#
class RDocTask < TaskLib
# Name of the main, top level task. (default is :rdoc)
attr_accessor :name
# Name of directory to receive the html output files. (default is "html")
attr_accessor :rdoc_dir
# Title of RDoc documentation. (defaults to rdoc's default)
attr_accessor :title
# Name of file to be used as the main, top level file of the
# RDoc. (default is none)
attr_accessor :main
# Name of template to be used by rdoc. (defaults to rdoc's default)
attr_accessor :template
# List of files to be included in the rdoc generation. (default is [])
attr_accessor :rdoc_files
# Additional list of options to be passed rdoc. (default is [])
attr_accessor :options
# Whether to run the rdoc process as an external shell (default is false)
attr_accessor :external
attr_accessor :inline_source
# Create an RDoc task with the given name. See the RDocTask class overview
# for documentation.
def initialize(name = :rdoc) # :yield: self
if name.is_a?(Hash)
invalid_options = name.keys.map { |k| k.to_sym } - [:rdoc, :clobber_rdoc, :rerdoc]
if !invalid_options.empty?
raise ArgumentError, "Invalid option(s) passed to RDocTask.new: #{invalid_options.join(", ")}"
end
end
@name = name
@rdoc_files = Rake::FileList.new
@rdoc_dir = 'html'
@main = nil
@title = nil
@template = nil
@external = false
@inline_source = true
@options = []
yield self if block_given?
define
end
# Create the tasks defined by this task lib.
def define
if rdoc_task_name != "rdoc"
desc "Build the RDOC HTML Files"
else
desc "Build the #{rdoc_task_name} HTML Files"
end
task rdoc_task_name
desc "Force a rebuild of the RDOC files"
task rerdoc_task_name => [clobber_task_name, rdoc_task_name]
desc "Remove rdoc products"
task clobber_task_name do
rm_r rdoc_dir rescue nil
end
task :clobber => [clobber_task_name]
directory @rdoc_dir
task rdoc_task_name => [rdoc_target]
file rdoc_target => @rdoc_files + [Rake.application.rakefile] do
rm_r @rdoc_dir rescue nil
@before_running_rdoc.call if @before_running_rdoc
args = option_list + @rdoc_files
if @external
argstring = args.join(' ')
sh %{ruby -Ivendor vendor/rd #{argstring}}
else
require 'rdoc/rdoc'
RDoc::RDoc.new.document(args)
end
end
self
end
def option_list
result = @options.dup
result << "-o" << @rdoc_dir
result << "--main" << quote(main) if main
result << "--title" << quote(title) if title
result << "-T" << quote(template) if template
result << "--inline-source" if inline_source && !@options.include?("--inline-source") && !@options.include?("-S")
result
end
def quote(str)
if @external
"'#{str}'"
else
str
end
end
def option_string
option_list.join(' ')
end
# The block passed to this method will be called just before running the
# RDoc generator. It is allowed to modify RDocTask attributes inside the
# block.
def before_running_rdoc(&block)
@before_running_rdoc = block
end
private
def rdoc_target
"#{rdoc_dir}/index.html"
end
def rdoc_task_name
case name
when Hash
(name[:rdoc] || "rdoc").to_s
else
name.to_s
end
end
def clobber_task_name
case name
when Hash
(name[:clobber_rdoc] || "clobber_rdoc").to_s
else
"clobber_#{name}"
end
end
def rerdoc_task_name
case name
when Hash
(name[:rerdoc] || "rerdoc").to_s
else
"re#{name}"
end
end
end
end
end
fail "ERROR: 'rake/rdoctask' is obsolete and no longer supported. " +
"Use 'rdoc/task' (available in RDoc 2.4.2+) instead."

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

@ -10,12 +10,14 @@ module Test # :nodoc:
def collect_file(name, suites, already_gathered) # :nodoc:
dir = File.dirname(File.expand_path(name))
$:.unshift(dir) unless $:.first == dir
if(@req)
if @req
@req.require(name)
else
require(name)
end
find_test_cases(already_gathered).each{|t| add_suite(suites, t.suite)}
find_test_cases(already_gathered).each do |t|
add_suite(suites, t.suite)
end
ensure
$:.delete_at $:.rindex(dir)
end

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

@ -6,7 +6,7 @@ module Rake
include Test::Unit::Assertions
def run_tests(pattern='test/test*.rb', log_enabled=false)
FileList.glob(pattern).each { |fn|
FileList.glob(pattern).each do |fn|
$stderr.puts fn if log_enabled
begin
require fn
@ -15,7 +15,7 @@ module Rake
$stderr.puts ex.backtrace
assert false
end
}
end
end
extend self

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

@ -0,0 +1,42 @@
module Rake
class Scope < LinkedList
# Path for the scope.
def path
map { |item| item.to_s }.reverse.join(":")
end
# Path for the scope + the named path.
def path_with_task_name(task_name)
"#{path}:#{task_name}"
end
# Trim +n+ innermost scope levels from the scope. In no case will
# this trim beyond the toplevel scope.
def trim(n)
result = self
while n > 0 && ! result.empty?
result = result.tail
n -= 1
end
result
end
# Scope lists always end with an EmptyScope object. See Null
# Object Pattern)
class EmptyScope < EmptyLinkedList
@parent = Scope
def path
""
end
def path_with_task_name(task_name)
task_name
end
end
# Singleton null object for an empty scope.
EMPTY = EmptyScope.new
end
end

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

@ -21,13 +21,6 @@ module Rake
# Application owning this task.
attr_accessor :application
# Comment for this task. Restricted to a single line of no more than 50
# characters.
attr_reader :comment
# Full text of the (possibly multi-line) comment.
attr_reader :full_comment
# Array of nested namespaces names used for task lookup by this task.
attr_reader :scope
@ -53,7 +46,7 @@ module Rake
# List of prerequisite tasks
def prerequisite_tasks
prerequisites.collect { |pre| lookup_prerequisite(pre) }
prerequisites.map { |pre| lookup_prerequisite(pre) }
end
def lookup_prerequisite(prerequisite_name)
@ -61,6 +54,24 @@ module Rake
end
private :lookup_prerequisite
# List of all unique prerequisite tasks including prerequisite tasks'
# prerequisites.
# Includes self when cyclic dependencies are found.
def all_prerequisite_tasks
seen = {}
collect_prerequisites(seen)
seen.values
end
def collect_prerequisites(seen)
prerequisite_tasks.each do |pre|
next if seen[pre.name]
seen[pre.name] = pre
pre.collect_prerequisites(seen)
end
end
protected :collect_prerequisites
# First source from a rule (nil if no sources)
def source
@sources.first if defined?(@sources)
@ -69,17 +80,16 @@ module Rake
# Create a task named +task_name+ with no actions or prerequisites. Use
# +enhance+ to add actions and prerequisites.
def initialize(task_name, app)
@name = task_name.to_s
@prerequisites = []
@actions = []
@name = task_name.to_s
@prerequisites = []
@actions = []
@already_invoked = false
@full_comment = nil
@comment = nil
@lock = Monitor.new
@application = app
@scope = app.current_scope
@arg_names = nil
@locations = []
@comments = []
@lock = Monitor.new
@application = app
@scope = app.current_scope
@arg_names = nil
@locations = []
end
# Enhance a task with prerequisites or actions. Returns self.
@ -141,8 +151,7 @@ module Rake
# Clear the existing comments on a rake task.
def clear_comments
@full_comment = nil
@comment = nil
@comments = []
self
end
@ -172,7 +181,8 @@ module Rake
protected :invoke_with_call_chain
def add_chain_to(exception, new_chain)
exception.extend(InvocationExceptionMixin) unless exception.respond_to?(:chain)
exception.extend(InvocationExceptionMixin) unless
exception.respond_to?(:chain)
exception.chain = new_chain if exception.chain.nil?
end
private :add_chain_to
@ -190,8 +200,8 @@ module Rake
end
# Invoke all the prerequisites of a task in parallel.
def invoke_prerequisites_concurrently(task_args, invocation_chain) # :nodoc:
futures = prerequisite_tasks.collect do |p|
def invoke_prerequisites_concurrently(task_args, invocation_chain)# :nodoc:
futures = prerequisite_tasks.map do |p|
prereq_args = task_args.new_scope(p.arg_names)
application.thread_pool.future(p) do |r|
r.invoke_with_call_chain(prereq_args, invocation_chain)
@ -216,9 +226,7 @@ module Rake
application.trace "** Execute (dry run) #{name}"
return
end
if application.options.trace
application.trace "** Execute #{name}"
end
application.trace "** Execute #{name}" if application.options.trace
application.enhance_with_matching_rule(name) if @actions.empty?
@actions.each do |act|
case act.arity
@ -238,39 +246,58 @@ module Rake
# Timestamp for this task. Basic tasks return the current time for their
# time stamp. Other tasks can be more sophisticated.
def timestamp
prerequisite_tasks.collect { |pre| pre.timestamp }.max || Time.now
Time.now
end
# Add a description to the task. The description can consist of an option
# argument list (enclosed brackets) and an optional comment.
def add_description(description)
return if ! description
return unless description
comment = description.strip
add_comment(comment) if comment && ! comment.empty?
end
# Writing to the comment attribute is the same as adding a description.
def comment=(description)
add_description(description)
def comment=(comment)
add_comment(comment)
end
# Add a comment to the task. If a comment already exists, separate
# the new comment with " / ".
def add_comment(comment)
if @full_comment
@full_comment << " / "
else
@full_comment = ''
end
@full_comment << comment
if @full_comment =~ /\A([^.]+?\.)( |$)/
@comment = $1
else
@comment = @full_comment
end
@comments << comment unless @comments.include?(comment)
end
private :add_comment
# Full collection of comments. Multiple comments are separated by
# newlines.
def full_comment
transform_comments("\n")
end
# First line (or sentence) of all comments. Multiple comments are
# separated by a "/".
def comment
transform_comments(" / ") { |c| first_sentence(c) }
end
# Transform the list of comments as specified by the block and
# join with the separator.
def transform_comments(separator, &block)
if @comments.empty?
nil
else
block ||= lambda { |c| c }
@comments.map(&block).join(separator)
end
end
private :transform_comments
# Get the first sentence in a string. The sentence is terminated
# by the first period or the end of the line. Decimal points do
# not count as periods.
def first_sentence(string)
string.split(/\.[ \t]|\.$|\n/).first
end
private :first_sentence
# Set the names of the arguments for this task. +args+ should be
# an array of symbols, one for each argument name.
def set_arg_names(args)
@ -287,11 +314,11 @@ module Rake
result << "timestamp: #{timestamp}\n"
result << "pre-requisites: \n"
prereqs = prerequisite_tasks
prereqs.sort! {|a,b| a.timestamp <=> b.timestamp}
prereqs.sort! { |a, b| a.timestamp <=> b.timestamp }
prereqs.each do |p|
result << "--#{p.name} (#{p.timestamp})\n"
end
latest_prereq = prerequisite_tasks.collect { |pre| pre.timestamp }.max
latest_prereq = prerequisite_tasks.map { |pre| pre.timestamp }.max
result << "latest-prerequisite time: #{latest_prereq}\n"
result << "................................\n\n"
return result
@ -342,7 +369,8 @@ module Rake
# this kind of task. Generic tasks will accept the scope as
# part of the name.
def scope_name(scope, task_name)
(scope + [task_name]).join(':')
# (scope + [task_name]).join(':')
scope.path_with_task_name(task_name)
end
end # class << Rake::Task

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

@ -15,16 +15,27 @@ module Rake
@names = names
@parent = parent
@hash = {}
@values = values
names.each_with_index { |name, i|
@hash[name.to_sym] = values[i] unless values[i].nil?
}
end
# Retrive the complete array of sequential values
def to_a
@values.dup
end
# Retrive the list of values not associated with named arguments
def extras
@values[@names.length..-1] || []
end
# Create a new argument scope using the prerequisite argument
# names.
def new_scope(names)
values = names.collect { |n| self[n] }
self.class.new(names, values, self)
values = names.map { |n| self[n] }
self.class.new(names, values + extras, self)
end
# Find an argument value by name or index.

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

@ -10,21 +10,21 @@ module Rake
super
@tasks = Hash.new
@rules = Array.new
@scope = Array.new
@scope = Scope.make
@last_description = nil
end
def create_rule(*args, &block)
pattern, _, deps = resolve_args(args)
pattern, args, deps = resolve_args(args)
pattern = Regexp.new(Regexp.quote(pattern) + '$') if String === pattern
@rules << [pattern, deps, block]
@rules << [pattern, args, deps, block]
end
def define_task(task_class, *args, &block)
task_name, arg_names, deps = resolve_args(args)
task_name = task_class.scope_name(@scope, task_name)
deps = [deps] unless deps.respond_to?(:to_ary)
deps = deps.collect {|d| d.to_s }
deps = deps.map { |d| d.to_s }
task = intern(task_class, task_name)
task.set_arg_names(arg_names) unless arg_names.empty?
if Rake::TaskManager.record_task_metadata
@ -72,7 +72,6 @@ module Rake
#
# task :t
# task :t, [:a]
# task :t, :a (deprecated)
#
def resolve_args_without_dependencies(args)
task_name = args.shift
@ -92,24 +91,14 @@ module Rake
#
# task :t => [:d]
# task :t, [a] => [:d]
# task :t, :needs => [:d] (deprecated)
# task :t, :a, :needs => [:d] (deprecated)
#
def resolve_args_with_dependencies(args, hash) # :nodoc:
fail "Task Argument Error" if hash.size != 1
key, value = hash.map { |k, v| [k,v] }.first
key, value = hash.map { |k, v| [k, v] }.first
if args.empty?
task_name = key
arg_names = []
deps = value
elsif key == :needs
Rake.application.deprecate(
"task :t, arg, :needs => [deps]",
"task :t, [args] => [deps]",
caller.detect { |c| c !~ /\blib\/rake\b/ })
task_name = args.shift
arg_names = args
deps = value
else
task_name = args.shift
arg_names = key
@ -127,9 +116,9 @@ module Rake
def enhance_with_matching_rule(task_name, level=0)
fail Rake::RuleRecursionOverflowError,
"Rule Recursion Too Deep" if level >= 16
@rules.each do |pattern, extensions, block|
@rules.each do |pattern, args, extensions, block|
if pattern.match(task_name)
task = attempt_rule(task_name, extensions, block, level)
task = attempt_rule(task_name, args, extensions, block, level)
return task if task
end
end
@ -147,7 +136,7 @@ module Rake
# List of all the tasks defined in the given scope (and its
# sub-scopes).
def tasks_in_scope(scope)
prefix = scope.join(":")
prefix = scope.path
tasks.select { |t|
/^#{prefix}:/ =~ t.name
}
@ -168,10 +157,10 @@ module Rake
initial_scope ||= @scope
task_name = task_name.to_s
if task_name =~ /^rake:/
scopes = []
scopes = Scope.make
task_name = task_name.sub(/^rake:/, '')
elsif task_name =~ /^(\^+)/
scopes = initial_scope[0, initial_scope.size - $1.size]
scopes = initial_scope.trim($1.size)
task_name = task_name.sub(/^(\^+)/, '')
else
scopes = initial_scope
@ -181,12 +170,12 @@ module Rake
# Lookup the task name
def lookup_in_scope(name, scope)
n = scope.size
while n >= 0
tn = (scope[0,n] + [name]).join(':')
loop do
tn = scope.path_with_task_name(name)
task = @tasks[tn]
return task if task
n -= 1
break if scope.empty?
scope = scope.tail
end
nil
end
@ -195,19 +184,19 @@ module Rake
# Return the list of scope names currently active in the task
# manager.
def current_scope
@scope.dup
@scope
end
# Evaluate the block in a nested namespace named +name+. Create
# an anonymous namespace if +name+ is nil.
def in_namespace(name)
name ||= generate_name
@scope.push(name)
@scope = Scope.new(name, @scope)
ns = NameSpace.new(self, @scope)
yield(ns)
ns
ensure
@scope.pop
@scope = @scope.tail
end
private
@ -224,7 +213,7 @@ module Rake
locations = caller
i = 0
while locations[i]
return locations[i+1] if locations[i] =~ /rake\/dsl_definition.rb/
return locations[i + 1] if locations[i] =~ /rake\/dsl_definition.rb/
i += 1
end
nil
@ -238,18 +227,19 @@ module Rake
end
def trace_rule(level, message)
options.trace_output.puts "#{" "*level}#{message}" if Rake.application.options.trace_rules
options.trace_output.puts "#{" " * level}#{message}" if
Rake.application.options.trace_rules
end
# Attempt to create a rule given the list of prerequisites.
def attempt_rule(task_name, extensions, block, level)
def attempt_rule(task_name, args, extensions, block, level)
sources = make_sources(task_name, extensions)
prereqs = sources.collect { |source|
prereqs = sources.map { |source|
trace_rule level, "Attempting Rule #{task_name} => #{source}"
if File.exist?(source) || Rake::Task.task_defined?(source)
trace_rule level, "(#{task_name} => #{source} ... EXIST)"
source
elsif parent = enhance_with_matching_rule(source, level+1)
elsif parent = enhance_with_matching_rule(source, level + 1)
trace_rule level, "(#{task_name} => #{source} ... ENHANCE)"
parent.name
else
@ -257,7 +247,7 @@ module Rake
return nil
end
}
task = FileTask.define_task({task_name => prereqs}, &block)
task = FileTask.define_task(task_name, {args => prereqs}, &block)
task.sources = prereqs
task
end
@ -265,7 +255,7 @@ module Rake
# Make a list of sources from the list of file name extensions /
# translation procs.
def make_sources(task_name, extensions)
result = extensions.collect { |ext|
result = extensions.map { |ext|
case ext
when /%/
task_name.pathmap(ext)

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

@ -14,7 +14,7 @@ module Rake
# libraries depend on this so I can't remove it without breaking
# other people's code. So for now it stays for backwards
# compatibility. BUT DON'T USE IT.
def paste(a,b) # :nodoc:
def paste(a, b) # :nodoc:
(a.to_s + b.to_s).intern
end
end

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

@ -64,7 +64,7 @@ module Rake
#
attr_accessor :loader
# Array of commandline options to pass to Ruby when running test loader.
# Array of commandline options to pass to ruby when running test loader.
attr_accessor :ruby_opts
# Explicitly define the list of test files to be included in a
@ -93,15 +93,18 @@ module Rake
# Create the tasks defined by this task lib.
def define
desc "Run tests" + (@name==:test ? "" : " for #{@name}")
desc "Run tests" + (@name == :test ? "" : " for #{@name}")
task @name do
FileUtilsExt.verbose(@verbose) do
args = "#{ruby_opts_string} #{run_code} #{file_list_string} #{option_list}"
args =
"#{ruby_opts_string} #{run_code} " +
"#{file_list_string} #{option_list}"
ruby args do |ok, status|
if !ok && status.respond_to?(:signaled?) && status.signaled?
raise SignalException.new(status.termsig)
elsif !ok
fail "Command failed with status (#{status.exitstatus}): [ruby #{args}]"
fail "Command failed with status (#{status.exitstatus}): " +
"[ruby #{args}]"
end
end
end
@ -120,8 +123,8 @@ module Rake
def ruby_opts_string
opts = @ruby_opts.dup
opts.unshift( "-I\"#{lib_path}\"" ) unless @libs.empty?
opts.unshift( "-w" ) if @warning
opts.unshift("-I\"#{lib_path}\"") unless @libs.empty?
opts.unshift("-w") if @warning
opts.join(" ")
end
@ -130,12 +133,12 @@ module Rake
end
def file_list_string
file_list.collect { |fn| "\"#{fn}\"" }.join(' ')
file_list.map { |fn| "\"#{fn}\"" }.join(' ')
end
def file_list # :nodoc:
if ENV['TEST']
FileList[ ENV['TEST'] ]
FileList[ENV['TEST']]
else
result = []
result += @test_files.to_a if @test_files

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

@ -25,7 +25,7 @@ module Rake
(stat[:time] * 1_000_000).round,
stat[:thread],
stat[:event],
stat[:data].map { |k,v| "#{k}:#{v}" }.join(" "))
stat[:data].map do |k, v| "#{k}:#{v}" end.join(" "))
end
end

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

@ -50,8 +50,10 @@ module Rake
rescue Exception => e
stat :joined
$stderr.puts e
$stderr.print "Queue contains #{@queue.size} items. Thread pool contains #{@threads.count} threads\n"
$stderr.print "Current Thread #{Thread.current} status = #{Thread.current.status}\n"
$stderr.print "Queue contains #{@queue.size} items. " +
"Thread pool contains #{@threads.count} threads\n"
$stderr.print "Current Thread #{Thread.current} status = " +
"#{Thread.current.status}\n"
$stderr.puts e.backtrace.join("\n")
@threads.each do |t|
$stderr.print "Thread #{t} status = #{t.status}\n"
@ -125,8 +127,12 @@ module Rake
end
end
@threads << t
stat :spawned, :new_thread => t.object_id, :thread_count => @threads.count
@total_threads_in_play = @threads.count if @threads.count > @total_threads_in_play
stat(
:spawned,
:new_thread => t.object_id,
:thread_count => @threads.count)
@total_threads_in_play = @threads.count if
@threads.count > @total_threads_in_play
end
end

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

@ -11,7 +11,10 @@ module Rake
if strings.empty?
output = sep
else
output = strings.map { |s| s.end_with?(sep) ? s : s + sep }.join
output = strings.map { |s|
next if s.nil?
s =~ /#{sep}$/ ? s : s + sep
}.join
end
out.print(output)
end

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

@ -1,14 +1,9 @@
# :include: doc/README.rdoc
module Rake
VERSION = '0.9.6'
VERSION = '10.1.0'
module Version # :nodoc: all
MAJOR, MINOR, BUILD, = Rake::VERSION.split '.'
MAJOR, MINOR, BUILD, *OTHER = Rake::VERSION.split '.'
NUMBERS = [
MAJOR,
MINOR,
BUILD,
]
NUMBERS = [MAJOR, MINOR, BUILD, *OTHER]
end
end

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

@ -40,8 +40,9 @@ module Rake
win32_shared_path ||= ENV['APPDATA']
win32_shared_path ||= ENV['USERPROFILE']
raise Win32HomeError, "Unable to determine home path environment variable." if
win32_shared_path.nil? or win32_shared_path.empty?
raise Win32HomeError,
"Unable to determine home path environment variable." if
win32_shared_path.nil? or win32_shared_path.empty?
normalize(File.join(win32_shared_path, 'Rake'))
end

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

@ -11,6 +11,9 @@ require 'rake'
require 'tmpdir'
require File.expand_path('../file_creation', __FILE__)
require_relative 'support/ruby_runner'
require_relative 'support/rakefile_definitions'
begin
require_relative '../ruby/envutil'
rescue NoMethodError, LoadError
@ -33,26 +36,30 @@ class Rake::TestCase < MiniTest::Unit::TestCase
test_dir = File.basename File.dirname File.expand_path __FILE__
@rake_root = if test_dir == 'test' then
# rake repository
File.expand_path '../../', __FILE__
else
# ruby repository
File.expand_path '../../../', __FILE__
end
@rake_root =
if test_dir == 'test'
# rake repository
File.expand_path '../../', __FILE__
else
# ruby repository
File.expand_path '../../../', __FILE__
end
@verbose = ENV['VERBOSE']
@rake_exec = File.join @rake_root, 'bin', 'rake'
@rake_lib = File.join @rake_root, 'lib'
@ruby_options = ["-I#{@rake_lib}", "-I."]
@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']
@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'
@ -70,22 +77,22 @@ class Rake::TestCase < MiniTest::Unit::TestCase
end
def teardown
Dir.chdir @orig_PWD
Dir.chdir @orig_pwd
FileUtils.rm_rf @tempdir
if @orig_APPDATA then
ENV['APPDATA'] = @orig_APPDATA
if @orig_appdata
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
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
@ -111,452 +118,11 @@ end
ENV['RAKE_SYSTEM'] = @system_dir
end
def rakefile contents
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|
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_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
def rakefile_test_signal
rakefile <<-TEST_SIGNAL
require 'rake/testtask'
Rake::TestTask.new(:a) do |t|
t.test_files = ['a_test.rb']
end
Rake::TestTask.new(:b) do |t|
t.test_files = ['b_test.rb']
end
task :test do
Rake::Task[:a].invoke
Rake::Task[:b].invoke
end
task :default => :test
TEST_SIGNAL
open 'a_test.rb', 'w' do |io|
io << 'puts "ATEST"' << "\n"
io << '$stdout.flush' << "\n"
io << 'Process.kill("TERM", $$)' << "\n"
end
open 'b_test.rb', 'w' do |io|
io << 'puts "BTEST"' << "\n"
io << '$stdout.flush' << "\n"
end
end
def rakefile_failing_test_task
rakefile <<-TEST_TASK
require 'rake/testtask'
task :default => :test
Rake::TestTask.new(:test) do |t|
t.test_files = ['a_test.rb']
end
TEST_TASK
open 'a_test.rb', 'w' do |io|
io << "require 'minitest/autorun'\n"
io << "class ExitTaskTest < MiniTest::Unit::TestCase\n"
io << " def test_exit\n"
io << " assert false, 'this should fail'\n"
io << " end\n"
io << "end\n"
end
end
def rakefile_stand_alone_filelist
open 'stand_alone_filelist.rb', 'w' do |io|
io << "require 'rake/file_list'\n"
io << "FL = Rake::FileList['*.rb']\n"
io << "puts FL\n"
end
end
include RakefileDefinitions
end

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

@ -0,0 +1,444 @@
module RakefileDefinitions
include FileUtils
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
end
task :run => target
end
task :prep => :clean do
mkdir_p 'src'
N.times do |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_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
def rakefile_test_signal
rakefile <<-TEST_SIGNAL
require 'rake/testtask'
Rake::TestTask.new(:a) do |t|
t.test_files = ['a_test.rb']
end
Rake::TestTask.new(:b) do |t|
t.test_files = ['b_test.rb']
end
task :test do
Rake::Task[:a].invoke
Rake::Task[:b].invoke
end
task :default => :test
TEST_SIGNAL
open 'a_test.rb', 'w' do |io|
io << 'puts "ATEST"' << "\n"
io << '$stdout.flush' << "\n"
io << 'Process.kill("TERM", $$)' << "\n"
end
open 'b_test.rb', 'w' do |io|
io << 'puts "BTEST"' << "\n"
io << '$stdout.flush' << "\n"
end
end
def rakefile_failing_test_task
rakefile <<-TEST_TASK
require 'rake/testtask'
task :default => :test
Rake::TestTask.new(:test) do |t|
t.test_files = ['a_test.rb']
end
TEST_TASK
open 'a_test.rb', 'w' do |io|
io << "require 'minitest/autorun'\n"
io << "class ExitTaskTest < MiniTest::Unit::TestCase\n"
io << " def test_exit\n"
io << " assert false, 'this should fail'\n"
io << " end\n"
io << "end\n"
end
end
def rakefile_stand_alone_filelist
open 'stand_alone_filelist.rb', 'w' do |io|
io << "require 'rake/file_list'\n"
io << "FL = Rake::FileList['*.rb']\n"
io << "puts FL\n"
end
end
end

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

@ -0,0 +1,33 @@
module RubyRunner
include FileUtils
# Run a shell Ruby command with command line options (using the
# default test options). Output is captured in @out and @err
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 and @err
def rake(*rake_options)
run_ruby @ruby_options + [@rake_exec] + rake_options
end
# Low level ruby command runner ...
def run_ruby(option_list)
puts "COMMAND: [#{RUBY} #{option_list.join ' '}]" if @verbose
inn, out, err, wait = Open3.popen3(RUBY, *option_list)
inn.close
@exit = wait ? wait.value : $?
@out = out.read
@err = err.read
puts "OUTPUT: [#{@out}]" if @verbose
puts "ERROR: [#{@err}]" if @verbose
puts "EXIT: [#{@exit.inspect}]" if @verbose
puts "PWD: [#{Dir.pwd}]" if @verbose
end
end

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

@ -9,13 +9,6 @@ class TestRakeApplication < Rake::TestCase
@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 = //
@ -30,13 +23,14 @@ class TestRakeApplication < Rake::TestCase
@app.terminal_columns = 80
@app.options.show_tasks = :tasks
@app.options.show_task_pattern = //
@app.last_description = "1234567890" * 8
numbers = "1234567890" * 8
@app.last_description = numbers
@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)
assert_match(/# #{numbers[0, 65]}\.\.\./, out)
end
def test_display_tasks_with_task_name_wider_than_tty_display
@ -45,7 +39,7 @@ class TestRakeApplication < Rake::TestCase
@app.options.show_task_pattern = //
task_name = "task name" * 80
@app.last_description = "something short"
@app.define_task(Rake::Task, task_name )
@app.define_task(Rake::Task, task_name)
out, = capture_io do @app.instance_eval { display_tasks_and_comments } end
@ -60,7 +54,7 @@ class TestRakeApplication < Rake::TestCase
description = "something short"
task_name = "task name" * 80
@app.last_description = "something short"
@app.define_task(Rake::Task, task_name )
@app.define_task(Rake::Task, task_name)
out, = capture_io do @app.instance_eval { display_tasks_and_comments } end
@ -79,18 +73,19 @@ class TestRakeApplication < Rake::TestCase
assert_match(/# #{@app.last_description}/, out)
end
def test_display_tasks_with_long_comments_to_a_non_tty_with_columns_set_truncates_comments
def test_truncating_comments_to_a_non_tty
@app.terminal_columns = 80
@app.options.show_tasks = :tasks
@app.options.show_task_pattern = //
@app.tty_output = false
@app.last_description = "1234567890" * 8
numbers = "1234567890" * 8
@app.last_description = numbers
@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)
assert_match(/# #{numbers[0, 65]}\.\.\./, out)
end
def test_describe_tasks
@ -121,7 +116,7 @@ class TestRakeApplication < Rake::TestCase
def test_not_finding_rakefile
@app.instance_eval { @rakefiles = ['NEVER_FOUND'] }
assert( ! @app.instance_eval do have_rakefile end )
assert(! @app.instance_eval do have_rakefile end)
assert_nil @app.rakefile
end
@ -252,7 +247,7 @@ class TestRakeApplication < Rake::TestCase
end
def test_terminal_columns
old_RAKE_COLUMNS = ENV['RAKE_COLUMNS']
old_rake_columns = ENV['RAKE_COLUMNS']
ENV['RAKE_COLUMNS'] = '42'
@ -260,10 +255,10 @@ class TestRakeApplication < Rake::TestCase
assert_equal 42, app.terminal_columns
ensure
if old_RAKE_COLUMNS then
if old_rake_columns
ENV['RAKE_COLUMNS'].delete
else
ENV['RAKE_COLUMNS'] = old_RAKE_COLUMNS
ENV['RAKE_COLUMNS'] = old_rake_columns
end
end
@ -296,7 +291,7 @@ class TestRakeApplication < Rake::TestCase
# HACK no assertions
end
def test_handle_options_should_strip_options_from_ARGV
def test_handle_options_should_strip_options_from_argv
assert !@app.options.trace
valid_option = '--trace'
@ -439,15 +434,6 @@ class TestRakeApplication < Rake::TestCase
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
def test_standard_exception_handling_invalid_option
out, err = capture_io do
e = assert_raises SystemExit do

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

@ -1,6 +1,6 @@
require File.expand_path('../helper', __FILE__)
TESTING_REQUIRE = [ ]
TESTING_REQUIRE = []
class TestRakeApplicationOptions < Rake::TestCase
@ -22,15 +22,12 @@ class TestRakeApplicationOptions < Rake::TestCase
end
def clear_argv
while ! ARGV.empty?
ARGV.pop
end
ARGV.pop until ARGV.empty?
end
def test_default_options
opts = command_line
assert_nil opts.backtrace
assert_nil opts.classic_namespace
assert_nil opts.dryrun
assert_nil opts.ignore_system
assert_nil opts.load_system
@ -147,7 +144,11 @@ class TestRakeApplicationOptions < Rake::TestCase
def test_rakelib
dirs = %w(A B C).join(File::PATH_SEPARATOR)
flags(['--rakelibdir', dirs], ["--rakelibdir=#{dirs}"], ['-R', dirs], ["-R#{dirs}"]) do |opts|
flags(
['--rakelibdir', dirs],
["--rakelibdir=#{dirs}"],
['-R', dirs],
["-R#{dirs}"]) do |opts|
assert_equal ['A', 'B', 'C'], opts.rakelib
end
end
@ -186,9 +187,10 @@ class TestRakeApplicationOptions < Rake::TestCase
end
def test_quiet
Rake::FileUtilsExt.verbose_flag = true
flags('--quiet', '-q') do |opts|
assert ! Rake::FileUtilsExt.verbose_flag
assert ! opts.silent
assert ! Rake::FileUtilsExt.verbose_flag, "verbose flag shoud be false"
assert ! opts.silent, "should not be silent"
end
end
@ -199,9 +201,10 @@ class TestRakeApplicationOptions < Rake::TestCase
end
def test_silent
Rake::FileUtilsExt.verbose_flag = true
flags('--silent', '-s') do |opts|
assert ! Rake::FileUtilsExt.verbose_flag
assert opts.silent
assert ! Rake::FileUtilsExt.verbose_flag, "verbose flag should be false"
assert opts.silent, "should be silent"
end
end
@ -353,18 +356,16 @@ class TestRakeApplicationOptions < Rake::TestCase
end
def test_verbose
out, = capture_io do
flags('--verbose', '-V') do |opts|
assert Rake::FileUtilsExt.verbose_flag
assert ! opts.silent
capture_io do
flags('--verbose', '-v') do |opts|
assert Rake::FileUtilsExt.verbose_flag, "verbose should be true"
assert ! opts.silent, "opts should not be silent"
end
end
assert_equal "rake, version #{Rake::VERSION}\n", out
end
def test_version
out, = capture_io do
out, _ = capture_io do
flags '--version', '-V'
end
@ -373,22 +374,6 @@ class TestRakeApplicationOptions < Rake::TestCase
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
@ -418,9 +403,21 @@ class TestRakeApplicationOptions < Rake::TestCase
def test_environment_definition
ENV.delete('TESTKEY')
command_line("a", "TESTKEY=12")
assert_equal ["a"], @tasks.sort
assert '12', ENV['TESTKEY']
command_line("TESTKEY=12")
assert_equal '12', ENV['TESTKEY']
end
def test_multiline_environment_definition
ENV.delete('TESTKEY')
command_line("TESTKEY=a\nb\n")
assert_equal "a\nb\n", ENV['TESTKEY']
end
def test_environment_and_tasks_together
ENV.delete('TESTKEY')
command_line("a", "b", "TESTKEY=12")
assert_equal ["a", "b"], @tasks.sort
assert_equal '12', ENV['TESTKEY']
end
def test_rake_explicit_task_library

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

@ -1,7 +1,36 @@
require File.expand_path('../helper', __FILE__)
require 'open3'
class TestBacktraceSuppression < Rake::TestCase
def test_bin_rake_suppressed
paths = ["something/bin/rake:12"]
actual = Rake::Backtrace.collapse(paths)
assert_equal [], actual
end
def test_system_dir_suppressed
path = RbConfig::CONFIG['rubylibprefix']
paths = [path + ":12"]
actual = Rake::Backtrace.collapse(paths)
assert_equal [], actual
end
def test_near_system_dir_isnt_suppressed
path = RbConfig::CONFIG['rubylibprefix']
paths = [" " + path + ":12"]
actual = Rake::Backtrace.collapse(paths)
assert_equal paths, actual
end
end
class TestRakeBacktrace < Rake::TestCase
include RubyRunner
def setup
super
@ -10,15 +39,9 @@ class TestRakeBacktrace < Rake::TestCase
Dir.pwd =~ Rake::Backtrace::SUPPRESS_PATTERN
end
# TODO: factor out similar code in test_rake_functional.rb
def rake(*args)
Open3.popen3(RUBY, "-I", @rake_lib, @rake_exec, *args) { |_, _, err, _|
err.read
}
end
def invoke(task_name)
rake task_name.to_s
def invoke(*args)
rake(*args)
@err
end
def test_single_collapse
@ -28,7 +51,7 @@ class TestRakeBacktrace < Rake::TestCase
end
}
lines = invoke(:foo).split("\n")
lines = invoke("foo").split("\n")
assert_equal "rake aborted!", lines[0]
assert_equal "foooo!", lines[1]
@ -46,7 +69,7 @@ class TestRakeBacktrace < Rake::TestCase
end
}
lines = invoke(:foo).split("\n")
lines = invoke("foo").split("\n")
assert_equal "rake aborted!", lines[0]
assert_equal "barrr!", lines[1]
@ -62,12 +85,12 @@ class TestRakeBacktrace < Rake::TestCase
end
}
lines = rake("baz").split("\n")
lines = invoke("baz").split("\n")
assert_equal "rake aborted!", lines[0]
assert_equal "bazzz!", lines[1]
assert_something_matches %r!Rakefile!i, lines
lines = rake("--suppress-backtrace", ".ak.file", "baz").split("\n")
lines = invoke("--suppress-backtrace", ".ak.file", "baz").split("\n")
assert_equal "rake aborted!", lines[0]
assert_equal "bazzz!", lines[1]
refute_match %r!Rakefile!i, lines[2]
@ -83,7 +106,8 @@ class TestRakeBacktrace < Rake::TestCase
return
end
end
flunk "expected #{pattern.inspect} to match something in:\n #{lines.join("\n ")}"
flunk "expected #{pattern.inspect} to match something in:\n" +
"#{lines.join("\n ")}"
end
end

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

@ -2,13 +2,45 @@ require File.expand_path('../helper', __FILE__)
require 'rake/clean'
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"),
assert Rake::Task['clean'], "Should define clean"
assert Rake::Task['clobber'], "Should define clobber"
assert Rake::Task['clobber'].prerequisites.include?("clean"),
"Clobber should require clean"
end
def test_cleanup
file_name = create_undeletable_file
out, _ = capture_io do
Rake::Cleaner.cleanup(file_name, verbose: false)
end
assert_match(/failed to remove/i, out)
ensure
remove_undeletable_file
end
private
def create_undeletable_file
dir_name = File.join(@tempdir, "deletedir")
file_name = File.join(dir_name, "deleteme")
FileUtils.mkdir(dir_name)
FileUtils.touch(file_name)
FileUtils.chmod(0, file_name)
FileUtils.chmod(0, dir_name)
file_name
end
def remove_undeletable_file
dir_name = File.join(@tempdir, "deletedir")
file_name = File.join(dir_name, "deleteme")
FileUtils.chmod(0777, dir_name)
FileUtils.chmod(0777, file_name)
Rake::Cleaner.cleanup(file_name, verbose: false)
Rake::Cleaner.cleanup(dir_name, verbose: false)
end
end

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

@ -34,12 +34,12 @@ class TestRakeDefinitions < Rake::TestCase
t = Task[n1]
assert Task === t, "Should be a Task"
assert_equal n1.to_s, t.name
assert_equal [n2.to_s], t.prerequisites.collect{|n| n.to_s}
assert_equal [n2.to_s], t.prerequisites.map { |n| n.to_s }
t.invoke
t2 = Task[n2]
assert_equal FileList[], t2.prerequisites
t3 = Task[n3]
assert_equal [n1.to_s, n2.to_s], t3.prerequisites.collect{|n|n.to_s}
assert_equal [n1.to_s, n2.to_s], t3.prerequisites.map { |n| n.to_s }
end
def test_incremental_definitions
@ -77,4 +77,3 @@ class TestRakeDefinitions < Rake::TestCase
end
end

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

@ -33,45 +33,8 @@ class TestRakeDsl < Rake::TestCase
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_no_commands_constant
assert ! defined?(Commands), "should not define Commands"
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

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

@ -21,7 +21,7 @@ class TestRakeFileCreationTask < Rake::TestCase
FileUtils.rm_rf fc_task.name
assert fc_task.needed?, "file should be needed"
FileUtils.mkdir fc_task.name
assert_equal nil, fc_task.prerequisites.collect{|n| Task[n].timestamp}.max
assert_equal nil, fc_task.prerequisites.map { |n| Task[n].timestamp }.max
assert ! fc_task.needed?, "file should not be needed"
end
@ -51,6 +51,6 @@ class TestRakeFileCreationTask < Rake::TestCase
def test_very_early_timestamp
t1 = Rake.application.intern(FileCreationTask, OLDFILE)
assert t1.timestamp < Time.now
assert t1.timestamp < Time.now - 1000000
assert t1.timestamp < Time.now - 1_000_000
end
end

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

@ -166,7 +166,7 @@ class TestRakeFileList < Rake::TestCase
def test_excluding_via_block
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 fl.excluded_from_list?("xyz.c"), "Should exclude xyz.c"
assert_equal ['a.c', 'b.c'], fl
end
@ -404,24 +404,24 @@ class TestRakeFileList < Rake::TestCase
def test_exclude_with_alternate_file_seps
fl = FileList.new
assert fl.exclude?("x/CVS/y")
assert fl.exclude?("x\\CVS\\y")
assert fl.exclude?("x/.svn/y")
assert fl.exclude?("x\\.svn\\y")
assert fl.exclude?("x/core")
assert fl.exclude?("x\\core")
assert fl.excluded_from_list?("x/CVS/y")
assert fl.excluded_from_list?("x\\CVS\\y")
assert fl.excluded_from_list?("x/.svn/y")
assert fl.excluded_from_list?("x\\.svn\\y")
assert fl.excluded_from_list?("x/core")
assert fl.excluded_from_list?("x\\core")
end
def test_add_default_exclude_list
fl = FileList.new
fl.exclude(/~\d+$/)
assert fl.exclude?("x/CVS/y")
assert fl.exclude?("x\\CVS\\y")
assert fl.exclude?("x/.svn/y")
assert fl.exclude?("x\\.svn\\y")
assert fl.exclude?("x/core")
assert fl.exclude?("x\\core")
assert fl.exclude?("x/abc~1")
assert fl.excluded_from_list?("x/CVS/y")
assert fl.excluded_from_list?("x\\CVS\\y")
assert fl.excluded_from_list?("x/.svn/y")
assert fl.excluded_from_list?("x\\.svn\\y")
assert fl.excluded_from_list?("x/core")
assert fl.excluded_from_list?("x\\core")
assert fl.excluded_from_list?("x/abc~1")
end
def test_basic_array_functions
@ -482,12 +482,12 @@ class TestRakeFileList < Rake::TestCase
a = ['b', 'a']
b = ['b', 'b']
c = ['b', 'c']
assert_equal( 1, fl <=> a )
assert_equal( 0, fl <=> b )
assert_equal( -1, fl <=> c )
assert_equal( -1, a <=> fl )
assert_equal( 0, b <=> fl )
assert_equal( 1, c <=> fl )
assert_equal(1, fl <=> a)
assert_equal(0, fl <=> b)
assert_equal(-1, fl <=> c)
assert_equal(-1, a <=> fl)
assert_equal(0, b <=> fl)
assert_equal(1, c <=> fl)
end
def test_array_equality
@ -503,7 +503,7 @@ class TestRakeFileList < Rake::TestCase
def test_enumeration_methods
a = FileList['a', 'b']
b = a.collect { |it| it.upcase }
b = a.map { |it| it.upcase }
assert_equal ['A', 'B'], b
assert_equal FileList, b.class
@ -519,7 +519,7 @@ class TestRakeFileList < Rake::TestCase
assert_equal ['a', 'b'], b
assert_equal FileList, b.class
b = a.find_all { |it| it == 'b'}
b = a.select { |it| it == 'b' }
assert_equal ['b'], b
assert_equal FileList, b.class
@ -609,7 +609,7 @@ class TestRakeFileList < Rake::TestCase
assert_equal FileList, r.class
f = FileList['a', 'b', 'c', 'd']
r = f.values_at(1,3)
r = f.values_at(1, 3)
assert_equal ['b', 'd'], r
assert_equal FileList, r.class
end
@ -625,4 +625,3 @@ class TestRakeFileList < Rake::TestCase
end
end

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

@ -26,7 +26,7 @@ class TestRakeFileTask < Rake::TestCase
open(ftask.name, "w") { |f| f.puts "HI" }
assert_equal nil, ftask.prerequisites.collect{|n| Task[n].timestamp}.max
assert_equal nil, ftask.prerequisites.map { |n| Task[n].timestamp }.max
assert ! ftask.needed?, "file should not be needed"
ensure
File.delete(ftask.name) rescue nil
@ -55,16 +55,16 @@ class TestRakeFileTask < Rake::TestCase
task(name => :phony)
assert ! t1.needed?, "unless the non-file task has a timestamp"
assert t1.needed?, "unless the non-file task has a timestamp"
end
def test_file_times_old_depends_on_new
create_timed_files(OLDFILE, NEWFILE)
t1 = Rake.application.intern(FileTask,OLDFILE).enhance([NEWFILE])
t1 = Rake.application.intern(FileTask, OLDFILE).enhance([NEWFILE])
t2 = Rake.application.intern(FileTask, NEWFILE)
assert ! t2.needed?, "Should not need to build new file"
preq_stamp = t1.prerequisites.collect{|t| Task[t].timestamp}.max
preq_stamp = t1.prerequisites.map { |t| Task[t].timestamp }.max
assert_equal t2.timestamp, preq_stamp
assert t1.timestamp < preq_stamp, "T1 should be older"
assert t1.needed?, "Should need to rebuild old file because of new"
@ -79,7 +79,7 @@ class TestRakeFileTask < Rake::TestCase
Task[:obj].invoke
Task[NEWFILE].invoke
assert ! @runs.include?(NEWFILE)
assert @runs.include?(NEWFILE)
end
def test_existing_file_depends_on_non_existing_file
@ -112,7 +112,7 @@ class TestRakeFileTask < Rake::TestCase
Task[NEWFILE].invoke
rescue Exception
end
assert( ! File.exist?(NEWFILE), "NEWFILE should be deleted")
assert(! File.exist?(NEWFILE), "NEWFILE should be deleted")
end
def load_phony

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

@ -44,15 +44,19 @@ class TestRakeFileUtils < Rake::TestCase
class BadLink
include Rake::FileUtilsExt
attr_reader :cp_args
def initialize(klass)
@failure_class = klass
end
def cp(*args)
@cp_args = args
end
def ln(*args)
fail @failure_class, "ln not supported"
end
public :safe_ln
end
@ -94,7 +98,7 @@ class TestRakeFileUtils < Rake::TestCase
assert_equal true, nowrite
nowrite false
assert_equal false, nowrite
nowrite(true){
nowrite(true) {
assert_equal true, nowrite
}
assert_equal false, nowrite
@ -250,7 +254,7 @@ class TestRakeFileUtils < Rake::TestCase
assert_equal ['..', 'a', 'b'], Rake::FileUtilsExt.split_all('../a/b')
end
def command name, text
def command(name, text)
open name, 'w', 0750 do |io|
io << text
end

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

@ -5,10 +5,11 @@ require 'rake/contrib/ftptools'
class FakeDate
def self.today
Date.new(2003,10,3)
Date.new(2003, 10, 3)
end
def self.now
Time.local(2003,10,3,12,00,00)
Time.local(2003, 10, 3, 12, 00, 00)
end
end
@ -17,43 +18,57 @@ class TestRakeFtpFile < Rake::TestCase
def setup
super
Rake::FtpFile.class_eval { @date_class = FakeDate; @time_class = FakeDate }
Rake::FtpFile.class_eval {
@date_class = FakeDate
@time_class = FakeDate
}
end
def test_general
file = Rake::FtpFile.new("here", "-rw-r--r-- 1 a279376 develop 121770 Mar 6 14:50 wiki.pl")
file = Rake::FtpFile.new(
"here",
"-rw-r--r-- 1 a279376 develop 121770 Mar 6 14:50 wiki.pl")
assert_equal "wiki.pl", file.name
assert_equal "here/wiki.pl", file.path
assert_equal "a279376", file.owner
assert_equal "develop", file.group
assert_equal 0644, file.mode
assert_equal 121770, file.size
assert_equal Time.mktime(2003,3,6,14,50,0,0), file.time
assert_equal 121_770, file.size
assert_equal Time.mktime(2003, 3, 6, 14, 50, 0, 0), file.time
assert ! file.directory?
assert ! file.symlink?
end
def test_far_date
file = Rake::FtpFile.new(".", "drwxr-xr-x 3 a279376 develop 4096 Nov 26 2001 vss")
assert_equal Time.mktime(2001,11,26,0,0,0,0), file.time
file = Rake::FtpFile.new(
".",
"drwxr-xr-x 3 a279376 develop 4096 Nov 26 2001 vss")
assert_equal Time.mktime(2001, 11, 26, 0, 0, 0, 0), file.time
end
def test_close_date
file = Rake::FtpFile.new(".", "drwxr-xr-x 3 a279376 develop 4096 Nov 26 15:35 vss")
assert_equal Time.mktime(2002,11,26,15,35,0,0), file.time
file = Rake::FtpFile.new(
".",
"drwxr-xr-x 3 a279376 develop 4096 Nov 26 15:35 vss")
assert_equal Time.mktime(2002, 11, 26, 15, 35, 0, 0), file.time
end
def test_directory
file = Rake::FtpFile.new(".", "drwxrwxr-x 9 a279376 develop 4096 Mar 13 14:32 working")
file = Rake::FtpFile.new(
".",
"drwxrwxr-x 9 a279376 develop 4096 Mar 13 14:32 working")
assert file.directory?
assert !file.symlink?
end
def test_symlink
file = Rake::FtpFile.new(".", "lrwxrwxrwx 1 a279376 develop 64 Mar 26 2002 xtrac -> /home/a279376/working/ics/development/java/com/fmr/fwp/ics/xtrac")
file = Rake::FtpFile.new(
".",
"lrwxrwxrwx 1 a279376 develop 64 Mar 26 2002 " +
"xtrac -> /home/a279376/working/ics/development/java/" +
"com/fmr/fwp/ics/xtrac")
assert_equal 'xtrac', file.name
assert file.symlink?
assert !file.directory?
end
end

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

@ -3,13 +3,11 @@ require 'fileutils'
require 'open3'
class TestRakeFunctional < Rake::TestCase
include RubyRunner
def setup
super
@ruby_options = ["-I#{@rake_lib}", "-I."]
@verbose = ENV['VERBOSE']
if @verbose
puts
puts
@ -68,7 +66,7 @@ class TestRakeFunctional < Rake::TestCase
rake "--describe"
assert_match %r{^rake a\n *A / A2 *$}m, @out
assert_match %r{^rake a\n *A\n *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
@ -420,8 +418,10 @@ class TestRakeFunctional < Rake::TestCase
status = $?
if @verbose
puts " SIG status = #{$?.inspect}"
puts " SIG status.respond_to?(:signaled?) = #{$?.respond_to?(:signaled?).inspect}"
puts " SIG status.signaled? = #{status.signaled?}" if status.respond_to?(:signaled?)
puts " SIG status.respond_to?(:signaled?) = " +
"#{$?.respond_to?(:signaled?).inspect}"
puts " SIG status.signaled? = #{status.signaled?}" if
status.respond_to?(:signaled?)
end
status.respond_to?(:signaled?) && status.signaled?
end
@ -463,34 +463,4 @@ class TestRakeFunctional < Rake::TestCase
RUBY_VERSION < "1.9" || defined?(JRUBY_VERSION)
end
# Run a shell Ruby command with command line options (using the
# default test options). Output is captured in @out and @err
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 and @err
def rake(*rake_options)
run_ruby @ruby_options + [@rake_exec] + rake_options
end
# Low level ruby command runner ...
def run_ruby(option_list)
puts "COMMAND: [#{RUBY} #{option_list.join ' '}]" if @verbose
inn, out, err, wait = Open3.popen3(RUBY, *option_list)
inn.close
@exit = wait ? wait.value : $?
@out = out.read
@err = err.read
puts "OUTPUT: [#{@out}]" if @verbose
puts "ERROR: [#{@err}]" if @verbose
puts "EXIT: [#{@exit.inspect}]" if @verbose
puts "PWD: [#{Dir.pwd}]" if @verbose
end
end

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

@ -1,11 +1,12 @@
require File.expand_path('../helper', __FILE__)
class TestRakeInvocationChain < Rake::TestCase
include Rake
def setup
super
@empty = Rake::InvocationChain::EMPTY
@empty = InvocationChain.empty
@first_member = "A"
@second_member = "B"
@ -13,7 +14,19 @@ class TestRakeInvocationChain < Rake::TestCase
@two = @one.append(@second_member)
end
def test_append
def test_conj_on_invocation_chains
list = InvocationChain.empty.conj("B").conj("A")
assert_equal InvocationChain.make("A", "B"), list
assert_equal InvocationChain, list.class
end
def test_make_on_invocation_chains
assert_equal @empty, InvocationChain.make()
assert_equal @one, InvocationChain.make(@first_member)
assert_equal @two, InvocationChain.make(@second_member, @first_member)
end
def test_append_with_one_argument
chain = @empty.append("A")
assert_equal 'TOP => A', chain.to_s # HACK
@ -49,4 +62,3 @@ class TestRakeInvocationChain < Rake::TestCase
end
end

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

@ -0,0 +1,84 @@
require File.expand_path('../helper', __FILE__)
class TestLinkedList < Rake::TestCase
include Rake
def test_empty_list
empty = LinkedList::EMPTY
assert empty.empty?, "should be empty"
end
def test_list_with_one_item
list = LinkedList.make(:one)
assert ! list.empty?, "should not be empty"
assert_equal :one, list.head
assert_equal LinkedList::EMPTY, list.tail
end
def test_make_with_no_arguments
empty = LinkedList.make()
assert_equal LinkedList::EMPTY, empty
end
def test_make_with_one_argument
list = LinkedList.make(:one)
assert ! list.empty?
assert_equal :one, list.head
assert_equal LinkedList::EMPTY, list.tail
end
def test_make_with_two_arguments
list = LinkedList.make(:one, :two)
assert ! list.empty?
assert_equal :one, list.head
assert_equal :two, list.tail.head
assert_equal LinkedList::EMPTY, list.tail.tail
end
def test_list_with_several_items
list = LinkedList.make(:one, :two, :three)
assert ! list.empty?, "should not be empty"
assert_equal :one, list.head
assert_equal :two, list.tail.head
assert_equal :three, list.tail.tail.head
assert_equal LinkedList::EMPTY, list.tail.tail.tail
end
def test_lists_are_structurally_equivalent
list = LinkedList.make(1, 2, 3)
same = LinkedList.make(1, 2, 3)
diff = LinkedList.make(1, 2, 4)
short = LinkedList.make(1, 2)
assert_equal list, same
refute_equal list, diff
refute_equal list, short
refute_equal short, list
end
def test_converstion_to_string
list = LinkedList.make(:one, :two, :three)
assert_equal "LL(one, two, three)", list.to_s
assert_equal "LL()", LinkedList.make().to_s
end
def test_converstion_with_inspect
list = LinkedList.make(:one, :two, :three)
assert_equal "LL(:one, :two, :three)", list.inspect
assert_equal "LL()", LinkedList.make().inspect
end
def test_lists_are_enumerable
list = LinkedList.make(1, 2, 3)
new_list = list.map { |item| item + 10 }
expected = [11, 12, 13]
assert_equal expected, new_list
end
def test_conjunction
list = LinkedList.make.conj("C").conj("B").conj("A")
assert_equal LinkedList.make("A", "B", "C"), list
end
end

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

@ -38,7 +38,9 @@ g\ 0: g1 g\ 2 g\ 3 g4
assert_equal %w(d1 d2).sort, Task['d'].prerequisites.sort
assert_equal %w(e1 f1).sort, Task['e'].prerequisites.sort
assert_equal %w(e1 f1).sort, Task['f'].prerequisites.sort
assert_equal ["g1", "g 2", "g 3", "g4"].sort, Task['g 0'].prerequisites.sort
assert_equal(
["g1", "g 2", "g 3", "g4"].sort,
Task['g 0'].prerequisites.sort)
assert_equal 7, Task.tasks.size
end
end

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

@ -49,11 +49,10 @@ class TestRakeMultiTask < Rake::TestCase
end
def test_multitasks_with_parameters
task :a, [:arg] do |t,args| add_run(args[:arg]) end
multitask :b, [:arg] => [:a] do |t,args| add_run(args[:arg]+'mt') end
task :a, [:arg] do |t, args| add_run(args[:arg]) end
multitask :b, [:arg] => [:a] do |t, args| add_run(args[:arg] + 'mt') end
Task[:b].invoke "b"
assert @runs[0] == "b"
assert @runs[1] == "bmt"
end
end

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

@ -38,6 +38,6 @@ class TestRakeNameSpace < Rake::TestCase
assert_equal ["n:nn:z", "n:x", "n:y"],
ns.tasks.map { |tsk| tsk.name }
assert_equal ["n:nn:z"], nns.tasks.map {|t| t.name}
assert_equal ["n:nn:z"], nns.tasks.map { |t| t.name }
end
end

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

@ -52,7 +52,7 @@ class TestRakePathMap < Rake::TestCase
assert_equal "", "dir/.depends".pathmap("%x")
end
def test_X_returns_everything_but_extension
def test_x_returns_everything_but_extension
assert_equal "abc", "abc".pathmap("%X")
assert_equal "abc", "abc.rb".pathmap("%X")
assert_equal "abc.xyz", "abc.xyz.rb".pathmap("%X")
@ -142,16 +142,27 @@ class TestRakePathMap < Rake::TestCase
def test_complex_patterns
sep = "".pathmap("%s")
assert_equal "dir/abc.rb", "dir/abc.rb".pathmap("%d/%n%x")
assert_equal "./abc.rb", "abc.rb".pathmap("%d/%n%x")
assert_equal "Your file extension is '.rb'",
"dir/abc.rb".pathmap("Your file extension is '%x'")
assert_equal "bin/org/onstepback/proj/A.class",
"src/org/onstepback/proj/A.java".pathmap("%{src,bin}d/%n.class")
assert_equal "src_work/bin/org/onstepback/proj/A.class",
"src_work/src/org/onstepback/proj/A.java".pathmap('%{\bsrc\b,bin}X.class')
assert_equal ".depends.bak", ".depends".pathmap("%X.bak")
assert_equal "d#{sep}a/b/c#{sep}file.txt", "a/b/c/d/file.txt".pathmap("%-1d%s%3d%s%f")
assert_equal(
"dir/abc.rb",
"dir/abc.rb".pathmap("%d/%n%x"))
assert_equal(
"./abc.rb",
"abc.rb".pathmap("%d/%n%x"))
assert_equal(
"Your file extension is '.rb'",
"dir/abc.rb".pathmap("Your file extension is '%x'"))
assert_equal(
"bin/org/onstepback/proj/A.class",
"src/org/onstepback/proj/A.java".pathmap("%{src,bin}d/%n.class"))
assert_equal(
"src_work/bin/org/onstepback/proj/A.class",
"src_work/src/org/onstepback/proj/A.java"
.pathmap('%{\bsrc\b,bin}X.class'))
assert_equal(
".depends.bak",
".depends".pathmap("%X.bak"))
assert_equal(
"d#{sep}a/b/c#{sep}file.txt",
"a/b/c/d/file.txt".pathmap("%-1d%s%3d%s%f"))
end
end

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

@ -3,7 +3,7 @@ require File.expand_path('../helper', __FILE__)
class TestRakeRakeTestLoader < Rake::TestCase
def test_pattern
orig_LOADED_FEATURES = $:.dup
orig_loaded_features = $:.dup
FileUtils.touch 'foo.rb'
FileUtils.touch 'test_a.rb'
FileUtils.touch 'test_b.rb'
@ -14,8 +14,7 @@ class TestRakeRakeTestLoader < Rake::TestCase
assert_equal %w[-v], ARGV
ensure
$:.replace orig_LOADED_FEATURES
$:.replace orig_loaded_features
end
end

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

@ -1,83 +0,0 @@
require File.expand_path('../helper', __FILE__)
begin
old_stderr = $stderr
dev_null = File.exist?('/dev/null') ? '/dev/null' : 'NUL'
$stderr = open dev_null, 'w'
require 'rake/rdoctask'
ensure
$stderr.close
$stderr = old_stderr
end
class TestRakeRDocTask < Rake::TestCase
include Rake
def setup
super
Task.clear
end
def test_tasks_creation
Rake::RDocTask.new
assert Task[:rdoc]
assert Task[:clobber_rdoc]
assert Task[:rerdoc]
end
def test_tasks_creation_with_custom_name_symbol
rd = Rake::RDocTask.new(:rdoc_dev)
assert Task[:rdoc_dev]
assert Task[:clobber_rdoc_dev]
assert Task[:rerdoc_dev]
assert_equal :rdoc_dev, rd.name
end
def test_tasks_creation_with_custom_name_string
rd = Rake::RDocTask.new("rdoc_dev")
assert Task[:rdoc_dev]
assert Task[:clobber_rdoc_dev]
assert Task[:rerdoc_dev]
assert_equal "rdoc_dev", rd.name
end
def test_tasks_creation_with_custom_name_hash
options = { :rdoc => "rdoc", :clobber_rdoc => "rdoc:clean", :rerdoc => "rdoc:force" }
rd = Rake::RDocTask.new(options)
assert Task[:"rdoc"]
assert Task[:"rdoc:clean"]
assert Task[:"rdoc:force"]
assert_raises(RuntimeError) { Task[:clobber_rdoc] }
assert_equal options, rd.name
end
def test_tasks_creation_with_custom_name_hash_will_use_default_if_an_option_isnt_given
Rake::RDocTask.new(:clobber_rdoc => "rdoc:clean")
assert Task[:rdoc]
assert Task[:"rdoc:clean"]
assert Task[:rerdoc]
end
def test_tasks_creation_with_custom_name_hash_raises_exception_if_invalid_option_given
assert_raises(ArgumentError) do
Rake::RDocTask.new(:foo => "bar")
end
begin
Rake::RDocTask.new(:foo => "bar")
rescue ArgumentError => e
assert_match(/foo/, e.message)
end
end
def test_inline_source_option_is_only_appended_if_option_not_already_given
rd = Rake::RDocTask.new
rd.options << '--inline-source'
assert_equal 1, rd.option_list.grep('--inline-source').size
rd = Rake::RDocTask.new
rd.options << '-S'
assert_equal 1, rd.option_list.grep('-S').size
assert_equal 0, rd.option_list.grep('--inline-source').size
end
end

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

@ -2,19 +2,11 @@ require File.expand_path('../helper', __FILE__)
require 'open3'
class TestRakeReduceCompat < Rake::TestCase
# TODO: factor out similar code in test_rake_functional.rb
def rake(*args)
Open3.popen3(RUBY, "-I", @rake_lib, @rake_exec, *args) { |_, out, _, _|
out.read
}
end
include RubyRunner
def invoke_normal(task_name)
rake task_name.to_s
end
def invoke_reduce_compat(task_name)
rake "--reduce-compat", task_name.to_s
@out
end
def test_no_deprecated_dsl
@ -28,38 +20,7 @@ class TestRakeReduceCompat < Rake::TestCase
end
}
assert_equal %{"method"}, invoke_normal(:check_task).chomp
assert_equal %{"method"}, invoke_normal(:check_file).chomp
assert_equal "nil", invoke_reduce_compat(:check_task).chomp
assert_equal "nil", invoke_reduce_compat(:check_file).chomp
end
def test_no_classic_namespace
rakefile %q{
task :check_task do
begin
Task
print "present"
rescue NameError
print "absent"
end
end
task :check_file_task do
begin
FileTask
print "present"
rescue NameError
print "absent"
end
end
}
assert_equal "present", invoke_normal(:check_task)
assert_equal "present", invoke_normal(:check_file_task)
assert_equal "absent", invoke_reduce_compat(:check_task)
assert_equal "absent", invoke_reduce_compat(:check_file_task)
assert_equal "nil", invoke_normal(:check_task).chomp
assert_equal "nil", invoke_normal(:check_file).chomp
end
end

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

@ -102,7 +102,7 @@ class TestRakeRules < Rake::TestCase
verbose(false) do
create_file(".foo")
rule '.o' => lambda{".foo"} do |t|
rule '.o' => lambda { ".foo" } do |t|
@runs << "#{t.name} - #{t.source}"
end
Task[OBJFILE].invoke
@ -113,7 +113,7 @@ class TestRakeRules < Rake::TestCase
def test_file_names_containing_percent_can_be_wrapped_in_lambda
verbose(false) do
create_file("foo%x")
rule '.o' => lambda{"foo%x"} do |t|
rule '.o' => lambda { "foo%x" } do |t|
@runs << "#{t.name} - #{t.source}"
end
Task[OBJFILE].invoke
@ -186,7 +186,7 @@ class TestRakeRules < Rake::TestCase
def test_rule_with_two_sources_runs_if_both_sources_are_present
create_timed_files(OBJFILE, SRCFILE, SRCFILE2)
rule OBJFILE => [lambda{SRCFILE}, lambda{SRCFILE2}] do
rule OBJFILE => [lambda { SRCFILE }, lambda { SRCFILE2 }] do
@runs << :RULE
end
Task[OBJFILE].invoke
@ -196,7 +196,7 @@ class TestRakeRules < Rake::TestCase
def test_rule_with_two_sources_but_one_missing_does_not_run
create_timed_files(OBJFILE, SRCFILE)
delete_file(SRCFILE2)
rule OBJFILE => [lambda{SRCFILE}, lambda{SRCFILE2}] do
rule OBJFILE => [lambda { SRCFILE }, lambda { SRCFILE2 }] do
@runs << :RULE
end
Task[OBJFILE].invoke
@ -222,10 +222,10 @@ class TestRakeRules < Rake::TestCase
def test_second_rule_runs_when_first_rule_doesnt
create_timed_files(OBJFILE, SRCFILE)
delete_file(SRCFILE2)
rule OBJFILE => [lambda{SRCFILE}, lambda{SRCFILE2}] do
rule OBJFILE => [lambda { SRCFILE }, lambda { SRCFILE2 }] do
@runs << :RULE1
end
rule OBJFILE => [lambda{SRCFILE}] do
rule OBJFILE => [lambda { SRCFILE }] do
@runs << :RULE2
end
Task[OBJFILE].invoke
@ -234,10 +234,10 @@ class TestRakeRules < Rake::TestCase
def test_second_rule_doest_run_if_first_triggers
create_timed_files(OBJFILE, SRCFILE, SRCFILE2)
rule OBJFILE => [lambda{SRCFILE}, lambda{SRCFILE2}] do
rule OBJFILE => [lambda { SRCFILE }, lambda { SRCFILE2 }] do
@runs << :RULE1
end
rule OBJFILE => [lambda{SRCFILE}] do
rule OBJFILE => [lambda { SRCFILE }] do
@runs << :RULE2
end
Task[OBJFILE].invoke
@ -246,10 +246,10 @@ class TestRakeRules < Rake::TestCase
def test_second_rule_doest_run_if_first_triggers_with_reversed_rules
create_timed_files(OBJFILE, SRCFILE, SRCFILE2)
rule OBJFILE => [lambda{SRCFILE}] do
rule OBJFILE => [lambda { SRCFILE }] do
@runs << :RULE1
end
rule OBJFILE => [lambda{SRCFILE}, lambda{SRCFILE2}] do
rule OBJFILE => [lambda { SRCFILE }, lambda { SRCFILE2 }] do
@runs << :RULE2
end
Task[OBJFILE].invoke
@ -298,9 +298,9 @@ class TestRakeRules < Rake::TestCase
actions = []
create_file("abc.xml")
rule '.y' => '.xml' do actions << 'y' end
rule '.c' => '.y' do actions << 'c' end
rule '.o' => '.c' do actions << 'o' end
rule '.exe' => '.o' do actions << 'exe' end
rule '.c' => '.y' do actions << 'c'end
rule '.o' => '.c' do actions << 'o'end
rule '.exe' => '.o' do actions << 'exe'end
Task["abc.exe"].invoke
assert_equal ['y', 'c', 'o', 'exe'], actions
end
@ -319,9 +319,44 @@ class TestRakeRules < Rake::TestCase
end
def test_rules_with_bad_dependents_will_fail
rule "a" => [ 1 ] do |t| puts t.name end
rule "a" => [1] do |t| puts t.name end
assert_raises(RuntimeError) do Task['a'].invoke end
end
end
def test_string_rule_with_args
delete_file(OBJFILE)
create_file(SRCFILE)
rule '.o', [:a] => SRCFILE do |t, args|
assert_equal 'arg', args.a
end
Task[OBJFILE].invoke('arg')
end
def test_regex_rule_with_args
delete_file(OBJFILE)
create_file(SRCFILE)
rule(/.o$/, [:a] => SRCFILE) do |t, args|
assert_equal 'arg', args.a
end
Task[OBJFILE].invoke('arg')
end
def test_string_rule_with_args_and_lambda_prereq
delete_file(OBJFILE)
create_file(SRCFILE)
rule '.o', [:a] => [lambda{SRCFILE}]do |t, args|
assert_equal 'arg', args.a
end
Task[OBJFILE].invoke('arg')
end
def test_regex_rule_with_args_and_lambda_prereq
delete_file(OBJFILE)
create_file(SRCFILE)
rule(/.o$/, [:a] => [lambda{SRCFILE}]) do |t, args|
assert_equal 'arg', args.a
end
Task[OBJFILE].invoke('arg')
end
end

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

@ -0,0 +1,44 @@
require File.expand_path('../helper', __FILE__)
class TestRakeScope < Rake::TestCase
include Rake
def test_path_against_empty_scope
scope = Scope.make
assert_equal scope, Scope::EMPTY
assert_equal scope.path, ""
end
def test_path_against_one_element
scope = Scope.make(:one)
assert_equal "one", scope.path
end
def test_path_against_two_elements
scope = Scope.make(:inner, :outer)
assert_equal "outer:inner", scope.path
end
def test_path_with_task_name
scope = Scope.make(:inner, :outer)
assert_equal "outer:inner:task", scope.path_with_task_name("task")
end
def test_path_with_task_name_against_empty_scope
scope = Scope.make
assert_equal "task", scope.path_with_task_name("task")
end
def test_conj_against_two_elements
scope = Scope.make.conj("B").conj("A")
assert_equal Scope.make("A", "B"), scope
end
def test_trim
scope = Scope.make("A", "B")
assert_equal scope, scope.trim(0)
assert_equal scope.tail, scope.trim(1)
assert_equal scope.tail.tail, scope.trim(2)
assert_equal scope.tail.tail, scope.trim(3)
end
end

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

@ -32,7 +32,6 @@ class TestRakeTask < Rake::TestCase
end
def test_inspect
# t = task(:foo, :needs => [:bar, :baz])
t = task(:foo => [:bar, :baz])
assert_equal "<Rake::Task foo => [bar, baz]>", t.inspect
end
@ -157,8 +156,8 @@ class TestRakeTask < Rake::TestCase
def test_multi_invocations
runs = []
p = proc do |t| runs << t.name end
task({:t1=>[:t2,:t3]}, &p)
task({:t2=>[:t3]}, &p)
task({ :t1 => [:t2, :t3] }, &p)
task({ :t2 => [:t3] }, &p)
task(:t3, &p)
Task[:t1].invoke
assert_equal ["t1", "t2", "t3"], runs.sort
@ -167,7 +166,7 @@ class TestRakeTask < Rake::TestCase
def test_task_list
task :t2
task :t1 => [:t2]
assert_equal ["t1", "t2"], Task.tasks.collect {|t| t.name}
assert_equal ["t1", "t2"], Task.tasks.map { |t| t.name }
end
def test_task_gives_name_on_to_s
@ -221,6 +220,31 @@ class TestRakeTask < Rake::TestCase
assert_equal [b, c], a.prerequisite_tasks
end
def test_all_prerequisite_tasks_includes_all_prerequisites
a = task :a => "b"
b = task :b => ["c", "d"]
c = task :c => "e"
d = task :d
e = task :e
assert_equal [b, c, d, e], a.all_prerequisite_tasks.sort_by { |t| t.name }
end
def test_all_prerequisite_tasks_does_not_include_duplicates
a = task :a => ["b", "c"]
b = task :b => "c"
c = task :c
assert_equal [b, c], a.all_prerequisite_tasks.sort_by { |t| t.name }
end
def test_all_prerequisite_tasks_includes_self_on_cyclic_dependencies
a = task :a => "b"
b = task :b => "a"
assert_equal [a, b], a.all_prerequisite_tasks.sort_by { |t| t.name }
end
def test_timestamp_returns_now_if_all_prereqs_have_no_times
a = task :a => ["b", "c"]
task :b
@ -238,7 +262,7 @@ class TestRakeTask < Rake::TestCase
def b.timestamp() Time.now + 10 end
def c.timestamp() Time.now + 5 end
assert_in_delta now + 10, a.timestamp, 0.1, 'computer too slow?'
assert_in_delta now, a.timestamp, 0.1, 'computer too slow?'
end
def test_always_multitask
@ -247,15 +271,15 @@ class TestRakeTask < Rake::TestCase
t_a = task(:a) do |t|
sleep 0.02
mx.synchronize{ result << t.name }
mx.synchronize { result << t.name }
end
t_b = task(:b) do |t|
mx.synchronize{ result << t.name }
mx.synchronize { result << t.name }
end
t_c = task(:c => [:a,:b]) do |t|
mx.synchronize{ result << t.name }
t_c = task(:c => [:a, :b]) do |t|
mx.synchronize { result << t.name }
end
t_c.invoke
@ -283,6 +307,30 @@ class TestRakeTask < Rake::TestCase
assert_match(/pre-requisites:\s*--t[23]/, out)
end
# NOTE: Rail-ties uses comment=.
def test_comment_setting
t = task(:t, :name, :rev)
t.comment = "A Comment"
assert_equal "A Comment", t.comment
end
def test_comments_with_sentences
desc "Comment 1. Comment 2."
t = task(:t, :name, :rev)
assert_equal "Comment 1", t.comment
end
def test_comments_with_tabbed_sentences
desc "Comment 1.\tComment 2."
t = task(:t, :name, :rev)
assert_equal "Comment 1", t.comment
end
def test_comments_with_decimal_points
desc "Revision 1.2.3."
t = task(:t, :name, :rev)
assert_equal "Revision 1.2.3", t.comment
end
def test_extended_comments
desc %{
@ -294,7 +342,7 @@ class TestRakeTask < Rake::TestCase
}
t = task(:t, :name, :rev)
assert_equal "[name,rev]", t.arg_description
assert_equal "This is a comment.", t.comment
assert_equal "This is a comment", t.comment
assert_match(/^\s*name -- Name/, t.full_comment)
assert_match(/^\s*rev -- Software/, t.full_comment)
assert_match(/\A\s*This is a comment\.$/, t.full_comment)
@ -308,9 +356,21 @@ class TestRakeTask < Rake::TestCase
assert_equal "line one / line two", t.comment
end
def test_settable_comments
def test_duplicate_comments
desc "line one"
t = task(:t)
t.comment = "HI"
assert_equal "HI", t.comment
desc "line one"
task(:t)
assert_equal "line one", t.comment
end
def test_interspersed_duplicate_comments
desc "line one"
t = task(:t)
desc "line two"
task(:t)
desc "line one"
task(:t)
assert_equal "line one / line two", t.comment
end
end

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

@ -26,8 +26,8 @@ class TestRakeTaskArguments < Rake::TestCase
end
def test_enumerable_behavior
ta = Rake::TaskArguments.new([:a, :b, :c], [1, 2 ,3])
assert_equal [10, 20, 30], ta.collect { |k,v| v * 10 }.sort
ta = Rake::TaskArguments.new([:a, :b, :c], [1, 2, 3])
assert_equal [10, 20, 30], ta.map { |k, v| v * 10 }.sort
end
def test_named_args
@ -85,4 +85,37 @@ class TestRakeTaskArguments < Rake::TestCase
ta.with_defaults({ "cc" => "default_val" })
assert_nil ta[:cc]
end
def test_all_and_extra_arguments_without_named_arguments
app = Rake::Application.new
_, args = app.parse_task_string("task[1,two,more]")
ta = Rake::TaskArguments.new([], args)
assert_equal [], ta.names
assert_equal ['1', 'two', 'more'], ta.to_a
assert_equal ['1', 'two', 'more'], ta.extras
end
def test_all_and_extra_arguments_with_named_arguments
app = Rake::Application.new
_, args = app.parse_task_string("task[1,two,more,still more]")
ta = Rake::TaskArguments.new([:first, :second], args)
assert_equal [:first, :second], ta.names
assert_equal "1", ta[:first]
assert_equal "two", ta[:second]
assert_equal ['1', 'two', 'more', 'still more'], ta.to_a
assert_equal ['more', 'still more'], ta.extras
end
def test_extra_args_with_less_than_named_arguments
app = Rake::Application.new
_, args = app.parse_task_string("task[1,two]")
ta = Rake::TaskArguments.new([:first, :second, :third], args)
assert_equal [:first, :second, :third], ta.names
assert_equal "1", ta[:first]
assert_equal "two", ta[:second]
assert_equal nil, ta[:third]
assert_equal ['1', 'two'], ta.to_a
assert_equal [], ta.extras
end
end

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

@ -37,7 +37,7 @@ class TestRakeTaskManager < Rake::TestCase
t = @tm.define_task(Rake::Task, :t)
assert_equal "x:t", t.name
end
assert_equal ["x:t"], @tm.tasks.collect { |t| t.name }
assert_equal ["x:t"], @tm.tasks.map { |t| t.name }
end
def test_anonymous_namespace
@ -55,7 +55,7 @@ class TestRakeTaskManager < Rake::TestCase
assert_equal "fn", t.name
end
assert_equal ["fn"], @tm.tasks.collect { |t| t.name }
assert_equal ["fn"], @tm.tasks.map { |t| t.name }
end
def test_namespace_yields_same_namespace_as_returned
@ -93,7 +93,7 @@ class TestRakeTaskManager < Rake::TestCase
bb = @tm.define_task(Rake::Task, :bb)
bot_z = @tm.define_task(Rake::Task, :z)
assert_equal ["a", "b"], @tm.current_scope
assert_equal Rake::Scope.make("b", "a"), @tm.current_scope
assert_equal bb, @tm["a:b:bb"]
assert_equal aa, @tm["a:aa"]
@ -101,10 +101,11 @@ class TestRakeTaskManager < Rake::TestCase
assert_equal bot_z, @tm["z"]
assert_equal mid_z, @tm["^z"]
assert_equal top_z, @tm["^^z"]
assert_equal top_z, @tm["^^^z"] # Over the top
assert_equal top_z, @tm["rake:z"]
end
assert_equal ["a"], @tm.current_scope
assert_equal Rake::Scope.make("a"), @tm.current_scope
assert_equal bb, @tm["a:b:bb"]
assert_equal aa, @tm["a:aa"]
@ -113,18 +114,19 @@ class TestRakeTaskManager < Rake::TestCase
assert_equal aa, @tm["aa"]
assert_equal mid_z, @tm["z"]
assert_equal top_z, @tm["^z"]
assert_equal top_z, @tm["^^z"] # Over the top
assert_equal top_z, @tm["rake:z"]
end
assert_equal [], @tm.current_scope
assert_equal Rake::Scope.make, @tm.current_scope
assert_equal [], xx.scope
assert_equal ['a'], aa.scope
assert_equal ['a', 'b'], bb.scope
assert_equal Rake::Scope.make, xx.scope
assert_equal Rake::Scope.make('a'), aa.scope
assert_equal Rake::Scope.make('b', 'a'), bb.scope
end
def test_lookup_with_explicit_scopes
t1, t2, t3, s = (0...4).collect { nil }
t1, t2, t3, s = (0...4).map { nil }
t1 = @tm.define_task(Rake::Task, :t)
@tm.in_namespace("a") do
t2 = @tm.define_task(Rake::Task, :t)
@ -133,11 +135,11 @@ class TestRakeTaskManager < Rake::TestCase
t3 = @tm.define_task(Rake::Task, :t)
end
end
assert_equal t1, @tm[:t, []]
assert_equal t2, @tm[:t, ["a"]]
assert_equal t3, @tm[:t, ["a", "b"]]
assert_equal s, @tm[:s, ["a", "b"]]
assert_equal s, @tm[:s, ["a"]]
assert_equal t1, @tm[:t, Rake::Scope.make]
assert_equal t2, @tm[:t, Rake::Scope.make("a")]
assert_equal t3, @tm[:t, Rake::Scope.make("b", "a")]
assert_equal s, @tm[:s, Rake::Scope.make("b", "a")]
assert_equal s, @tm[:s, Rake::Scope.make("a")]
end
def test_correctly_scoped_prerequisites_are_invoked
@ -154,4 +156,3 @@ class TestRakeTaskManager < Rake::TestCase
end
end

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

@ -2,28 +2,11 @@ require File.expand_path('../helper', __FILE__)
class TestRakeTaskManagerArgumentResolution < Rake::TestCase
def setup
super
Rake.application.options.ignore_deprecate = true
end
def teardown
Rake.application.options.ignore_deprecate = false
super
end
def test_good_arg_patterns
assert_equal [:t, [], []], task(:t)
assert_equal [:t, [], [:x]], task(:t => :x)
assert_equal [:t, [], [:x, :y]], task(:t => [:x, :y])
assert_equal [:t, [:a, :b], []], task(:t, :a, :b)
assert_equal [:t, [], [:x]], task(:t, :needs => :x)
assert_equal [:t, [:a, :b], [:x]], task(:t, :a, :b, :needs => :x)
assert_equal [:t, [:a, :b], [:x, :y]], task(:t, :a, :b, :needs => [:x, :y])
assert_equal [:t, [:a, :b], []], task(:t, [:a, :b])
assert_equal [:t, [:a, :b], [:x]], task(:t, [:a, :b] => :x)
assert_equal [:t, [:a, :b], [:x, :y]], task(:t, [:a, :b] => [:x, :y])

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

@ -33,21 +33,11 @@ class TestRakeTaskWithArguments < Rake::TestCase
assert_equal ["pre"], t.prerequisites
end
def test_name_args_and_explicit_needs
ignore_deprecations do
t = task(:t, :x, :y, :needs => [:pre])
assert_equal "t", t.name
assert_equal [:x, :y], t.arg_names
assert_equal ["pre"], t.prerequisites
end
end
def test_illegal_keys_in_task_name_hash
ignore_deprecations do
assert_raises RuntimeError do
task(:t, :x, :y => 1, :needs => [:pre])
end
end
def test_name_args_and_prereqs
t = task(:t, [:x, :y] => [:pre])
assert_equal "t", t.name
assert_equal [:x, :y], t.arg_names
assert_equal ["pre"], t.prerequisites
end
def test_arg_list_is_empty_if_no_args_given
@ -91,7 +81,7 @@ class TestRakeTaskWithArguments < Rake::TestCase
def test_arguments_are_passed_to_block
t = task(:t, :a, :b) { |tt, args|
assert_equal( { :a => 1, :b => 2 }, args.to_hash )
assert_equal({ :a => 1, :b => 2 }, args.to_hash)
}
t.invoke(1, 2)
end
@ -131,7 +121,7 @@ class TestRakeTaskWithArguments < Rake::TestCase
assert_equal "T", t.comment
assert_equal "[a,b]", t.arg_description
assert_equal "tt[a,b]", t.name_with_args
assert_equal [:a, :b],t.arg_names
assert_equal [:a, :b], t.arg_names
end
def test_named_args_are_passed_to_prereqs

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

@ -28,7 +28,7 @@ class TestRakeTestTask < Rake::TestCase
assert Task.task_defined?(:example)
end
def test_file_list_ENV_TEST
def test_file_list_env_test
ENV['TEST'] = 'testfile.rb'
tt = Rake::TestTask.new do |t|
t.pattern = '*'
@ -117,4 +117,3 @@ class TestRakeTestTask < Rake::TestCase
end
end

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

@ -7,21 +7,28 @@ class TestRakeTestThreadPool < Rake::TestCase
def test_pool_executes_in_current_thread_for_zero_threads
pool = ThreadPool.new(0)
f = pool.future{Thread.current}
f = pool.future { Thread.current }
pool.join
assert_equal Thread.current, f.value
end
def test_pool_executes_in_other_thread_for_pool_of_size_one
pool = ThreadPool.new(1)
f = pool.future{Thread.current}
f = pool.future { Thread.current }
pool.join
refute_equal Thread.current, f.value
end
def test_pool_executes_in_two_other_threads_for_pool_of_size_two
pool = ThreadPool.new(2)
threads = 2.times.collect{ pool.future{ sleep 0.1; Thread.current } }.each{|f|f.value}
threads = 2.times.map {
pool.future {
sleep 0.1
Thread.current
}
}.each { |f|
f.value
}
refute_equal threads[0], threads[1]
refute_equal Thread.current, threads[0]
@ -35,22 +42,20 @@ class TestRakeTestThreadPool < Rake::TestCase
10.times.each do
pool.future do
sleep 0.02
t_mutex.synchronize{ threads << Thread.current }
t_mutex.synchronize { threads << Thread.current }
end
end
pool.join
assert_equal 2, threads.count
end
def test_pool_future_captures_arguments
def test_pool_future_does_not_duplicate_arguments
pool = ThreadPool.new(2)
a = 'a'
b = 'b'
c = 5 # 5 throws an exception with 5.dup. It should be ignored
pool.future(a,c){ |a_var,ignore| a_var.capitalize!; b.capitalize! }
obj = Object.new
captured = nil
pool.future(obj) { |var| captured = var }
pool.join
assert_equal 'a', a
assert_equal 'b'.capitalize, b
assert_equal obj, captured
end
def test_pool_join_empties_queue
@ -69,35 +74,49 @@ class TestRakeTestThreadPool < Rake::TestCase
}
pool.join
assert_equal true, pool.__send__(:__queue__).empty?, "queue should be empty"
assert_equal(
true,
pool.__send__(:__queue__).empty?,
"queue should be empty")
end
CustomError = Class.new(StandardError)
# test that throwing an exception way down in the blocks propagates
# to the top
def test_exceptions
pool = ThreadPool.new(10)
deep_exception_block = lambda do |count|
next raise Exception.new if ( count < 1 )
pool.future(count-1, &deep_exception_block).value
raise CustomError if count < 1
pool.future(count - 1, &deep_exception_block).value
end
assert_raises(Exception) do
assert_raises(CustomError) do
pool.future(2, &deep_exception_block).value
end
end
def test_pool_prevents_deadlock
pool = ThreadPool.new(5)
common_dependency_a = pool.future { sleep 0.2 }
futures_a = 10.times.collect { pool.future{ common_dependency_a.value; sleep(rand() * 0.01) } }
futures_a = 10.times.map {
pool.future {
common_dependency_a.value
sleep(rand() * 0.01)
}
}
common_dependency_b = pool.future { futures_a.each { |f| f.value } }
futures_b = 10.times.collect { pool.future{ common_dependency_b.value; sleep(rand() * 0.01) } }
futures_b = 10.times.map {
pool.future {
common_dependency_b.value
sleep(rand() * 0.01)
}
}
futures_b.each{|f|f.value}
futures_b.each { |f| f.value }
pool.join
end
@ -108,15 +127,15 @@ class TestRakeTestThreadPool < Rake::TestCase
b = 5
c = 3
result = a.times.collect do
result = a.times.map do
pool.future do
b.times.collect do
b.times.map do
pool.future { sleep rand * 0.001; c }
end.inject(0) { |m,f| m+f.value }
end.reduce(0) { |m, f| m + f.value }
end
end.inject(0) { |m,f| m+f.value }
end.reduce(0) { |m, f| m + f.value }
assert_equal( (a*b*c), result )
assert_equal a * b * c, result
pool.join
end

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

@ -65,46 +65,6 @@ class TestRakeTopLevelFunctions < Rake::TestCase
Rake::FileUtilsExt.nowrite_flag = false
end
def test_missing_constants_task
Object.const_missing(:Task)
expected = [
[[:const_warning, :Task], nil]
]
assert_equal expected, @app.called
end
def test_missing_constants_file_task
Object.const_missing(:FileTask)
expected = [
[[:const_warning, :FileTask], nil]
]
assert_equal expected, @app.called
end
def test_missing_constants_file_creation_task
Object.const_missing(:FileCreationTask)
expected = [
[[:const_warning, :FileCreationTask], nil]
]
assert_equal expected, @app.called
end
def test_missing_constants_rake_app
Object.const_missing(:RakeApp)
expected = [
[[:const_warning, :RakeApp], nil]
]
assert_equal expected, @app.called
end
def test_missing_other_constant
assert_raises(NameError) do Object.const_missing(:Xyz) end
end

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

@ -1,20 +0,0 @@
require File.expand_path('../helper', __FILE__)
begin
old_verbose = $VERBOSE
$VERBOSE = nil
require 'rake/contrib/sys'
ensure
$VERBOSE = old_verbose
end
class TestSys < Rake::TestCase
def test_split_all
assert_equal ['a'], Sys.split_all('a')
assert_equal ['..'], Sys.split_all('..')
assert_equal ['/'], Sys.split_all('/')
assert_equal ['a', 'b'], Sys.split_all('a/b')
assert_equal ['/', 'a', 'b'], Sys.split_all('/a/b')
assert_equal ['..', 'a', 'b'], Sys.split_all('../a/b')
end
end

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

@ -5,7 +5,7 @@ require 'rake/thread_history_display'
class TestThreadHistoryDisplay < Rake::TestCase
def setup
super
@time = 1000000
@time = 1_000_000
@stats = []
@display = Rake::ThreadHistoryDisplay.new(@stats)
end
@ -60,24 +60,34 @@ class TestThreadHistoryDisplay < Rake::TestCase
end
def test_thread_deleted
@stats << event(:thread_deleted, :deleted_thread => 123456, :thread_count => 12)
@stats << event(
:thread_deleted,
:deleted_thread => 123_456,
:thread_count => 12)
out, _ = capture_io do
@display.show
end
assert_match(/^ *1000000 +A +thread_deleted( +deleted_thread:B| +thread_count:12){2}$/, out)
assert_match(
/^ *1000000 +A +thread_deleted( +deleted_thread:B| +thread_count:12){2}$/,
out)
end
def test_thread_created
@stats << event(:thread_created, :new_thread => 123456, :thread_count => 13)
@stats << event(
:thread_created,
:new_thread => 123_456,
:thread_count => 13)
out, _ = capture_io do
@display.show
end
assert_match(/^ *1000000 +A +thread_created( +new_thread:B| +thread_count:13){2}$/, out)
assert_match(
/^ *1000000 +A +thread_created( +new_thread:B| +thread_count:13){2}$/,
out)
end
private
def event(type, data={})
def event(type, data = {})
result = {
:event => type,
:time => @time / 1_000_000.0,

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

@ -6,10 +6,12 @@ class TestTraceOutput < Rake::TestCase
class PrintSpy
attr_reader :result, :calls
def initialize
@result = ""
@calls = 0
end
def print(string)
@result << string
@calls += 1
@ -30,6 +32,13 @@ class TestTraceOutput < Rake::TestCase
assert_equal 1, spy.calls
end
def test_trace_handles_nil_objects
spy = PrintSpy.new
trace_on(spy, "HI\n", nil, "LO")
assert_equal "HI\nLO\n", spy.result
assert_equal 1, spy.calls
end
def test_trace_issues_single_io_for_args_multiple_strings_and_alternate_sep
old_sep = $\
$\ = "\r"