Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

added task parameters, named parameter via desc, column limited output

git-svn-id: svn+ssh://rubyforge.org/var/svn/rake/trunk@591 5af023f1-ac1a-0410-98d6-829a145c37ef
  • Loading branch information...
commit d1f89d7c62365633731850c8ec1ba76808d21cf8 1 parent 0b08813
jimweirich authored
View
6 CHANGES
@@ -2,7 +2,11 @@
== Pre-Version 0.7.4
-* Added task parameters (e.g. "rake build[version7]svn ")
+* Added task parameters (e.g. "rake build[version7]")
+* Made task parameters passable to prerequisites.
+* The 'desc' command will now document task argument names.
+* Comments are limited to 80 columns or so (suggested by Jamis Buck).
+* Added -D to display full comments (suggested by Jamis Buck).
== Version 0.7.3
View
3  Rakefile
@@ -357,7 +357,7 @@ task :update_version => [:prerelease] do
end
end
-desc "Tag all the CVS files with the latest release number (REL=x.y.z)"
+desc "[rel] Tag all the CVS files with the latest release number (REL=x.y.z)"
task :tag => [:prerelease] do
reltag = "REL_#{PKG_VERSION.gsub(/\./, '_')}"
reltag << ENV['REUSE'].gsub(/\./, '_') if ENV['REUSE']
@@ -381,6 +381,7 @@ end
load 'xforge.rf' if File.exist?('xforge.rf')
+desc "Where is the current directory. This task displays\nthe current rake directory"
task :where_am_i do
puts Rake.original_dir
end
View
161 lib/rake.rb
@@ -2,7 +2,7 @@
#--
-# Copyright (c) 2003, 2004, 2005, 2006 Jim Weirich
+# Copyright (c) 2003, 2004, 2005, 2006, 2007 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
@@ -303,15 +303,19 @@ class Task
# Application owning this task.
attr_accessor :application
- # Comment for this task.
- attr_accessor :comment
+ # 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
# List of arguments to the task
attr_accessor :args
-
+
# Return task name
def to_s
name
@@ -335,11 +339,13 @@ def initialize(task_name, app)
@prerequisites = FileList[]
@actions = []
@already_invoked = false
+ @full_comment = nil
@comment = nil
@lock = Mutex.new
@application = app
@scope = app.current_scope
@args = []
+ @arg_names = nil
end
# Enhance a task with prerequisites or actions. Returns self.
@@ -353,6 +359,35 @@ def enhance(deps=nil, &block)
def name
@name.to_s
end
+
+ # Name of task with argument list description.
+ def name_with_args # :nodoc:
+ if arg_description
+ "#{name}#{arg_description}"
+ else
+ name
+ end
+ end
+
+ # Argument description (nil if none).
+ def arg_description # :nodoc:
+ @arg_names ? "[#{(arg_names || []).join(',')}]" : nil
+ end
+
+ # Hash of argument names to argument positions (0 based). (empty if no
+ # named arguments).
+ def arg_map
+ result = {}
+ arg_names.each_with_index do |n, i|
+ result[n] = i
+ end
+ result
+ end
+
+ # Name of arguments for this task.
+ def arg_names
+ @arg_names || []
+ end
# Invoke the task if it is needed. Prerequites are invoked first.
def invoke
@@ -370,10 +405,22 @@ def invoke
# Invoke all the prerequisites of a task.
def invoke_prerequisites
@prerequisites.each { |n|
- application[n, @scope].invoke
+ prereq = application[n, @scope]
+ setup_arguments(prereq)
+ prereq.invoke
}
end
+ # Setup the arguments to be passed to prerequesites.
+ def setup_arguments(prereq) # :nodoc:
+ if ! arg_names.empty? && ! prereq.arg_names.empty?
+ prereq.args = prereq.arg_names.collect do |name|
+ arg_map[name] ? args[arg_map[name]] : nil
+ end
+ end
+ end
+ private :setup_arguments
+
# Format the trace flags for display.
def format_trace_flags
flags = []
@@ -416,17 +463,45 @@ def timestamp
@prerequisites.collect { |p| application[p].timestamp }.max || Time.now
end
+ # Add a description to the task. The description can consist of an option
+ # argument list (enclosed brackets) and an optional comment.
+ def add_description(description)
+ return if ! description
+ if description =~ %r{\A\s*(\[([^\]]*)\])\s*(.*)\Z}m
+ arg_string = $2
+ comment = $3.strip
+ else
+ comment = description.strip
+ end
+ set_arg_names(arg_string) if arg_string
+ add_comment(comment) if comment && ! comment.empty?
+ end
+
# Add a comment to the task. If a comment alread exists, separate
# the new comment with " / ".
def add_comment(comment)
- return if ! comment
- if @comment
- @comment << " / "
+ if @full_comment
+ @full_comment << " / "
+ else
+ @full_comment = ''
+ end
+ @full_comment << comment
+ if @full_comment =~ /\A([^.]+?\.)/
+ @comment = $1
else
- @comment = ''
+ @comment = @full_comment
+ end
+ if @comment.length > 50
+ @comment = @comment[0, 47] + "..."
end
- @comment << comment
end
+ private :add_comment
+
+ # Set the names of the arguments for this task.
+ def set_arg_names(arg_string)
+ @arg_names = arg_string.split(',').collect { |n| n.strip }
+ end
+ private :set_arg_names
# Return a string describing the internal state of a task. Useful for
# debugging.
@@ -673,8 +748,8 @@ def rule(args, &block)
# runtests
# end
#
-def desc(comment)
- Rake.application.last_comment = comment
+def desc(description)
+ Rake.application.last_description = description
end
# Import the partial Rakefiles +fn+. Imported files are loaded _after_ the
@@ -1442,14 +1517,15 @@ def tasks
# The TaskManager module is a mixin for managing tasks.
module TaskManager
# Track the last comment made in the Rakefile.
- attr_accessor :last_comment
+ attr_accessor :last_description
+ alias :last_comment :last_description # Backwards compatibility
def initialize
super
@tasks = Hash.new
@rules = Array.new
@scope = Array.new
- @last_comment = nil
+ @last_description = nil
end
def create_rule(args, &block)
@@ -1464,8 +1540,8 @@ def define_task(task_class, args, &block)
deps = [deps] unless deps.respond_to?(:to_ary)
deps = deps.collect {|d| d.to_s }
task = intern(task_class, task_name)
- task.add_comment(@last_comment)
- @last_comment = nil
+ task.add_description(@last_description)
+ @last_description = nil
task.enhance(deps, &block)
task
end
@@ -1658,38 +1734,40 @@ class Application
DEFAULT_RAKEFILES = ['rakefile', 'Rakefile', 'rakefile.rb', 'Rakefile.rb'].freeze
OPTIONS = [ # :nodoc:
- ['--dry-run', '-n', GetoptLong::NO_ARGUMENT,
- "Do a dry run without executing actions."],
+ ['--classic-namespace', '-C', GetoptLong::NO_ARGUMENT,
+ "Put Task and FileTask in the top level namespace"],
+ ['--describe', '-D', GetoptLong::OPTIONAL_ARGUMENT,
+ "Describe the tasks (matching optional PATTERN), then exit."],
+ ['--rakefile', '-f', GetoptLong::OPTIONAL_ARGUMENT,
+ "Use FILE as the rakefile."],
+ ['--usage', '-h', GetoptLong::NO_ARGUMENT,
+ "Display usage."],
['--help', '-H', GetoptLong::NO_ARGUMENT,
"Display this help message."],
['--libdir', '-I', GetoptLong::REQUIRED_ARGUMENT,
"Include LIBDIR in the search path for required modules."],
- ['--rakelibdir', '-R', GetoptLong::REQUIRED_ARGUMENT,
- "Auto-import any .rake files in RAKELIBDIR. (default is 'rakelib')"],
+ ['--dry-run', '-n', GetoptLong::NO_ARGUMENT,
+ "Do a dry run without executing actions."],
['--nosearch', '-N', GetoptLong::NO_ARGUMENT,
"Do not search parent directories for the Rakefile."],
['--prereqs', '-P', GetoptLong::NO_ARGUMENT,
"Display the tasks and dependencies, then exit."],
['--quiet', '-q', GetoptLong::NO_ARGUMENT,
"Do not log messages to standard output."],
- ['--rakefile', '-f', GetoptLong::OPTIONAL_ARGUMENT,
- "Use FILE as the rakefile."],
['--require', '-r', GetoptLong::REQUIRED_ARGUMENT,
"Require MODULE before executing rakefile."],
+ ['--rakelibdir', '-R', GetoptLong::REQUIRED_ARGUMENT,
+ "Auto-import any .rake files in RAKELIBDIR. (default is 'rakelib')"],
['--silent', '-s', GetoptLong::NO_ARGUMENT,
"Like --quiet, but also suppresses the 'in directory' announcement."],
['--tasks', '-T', GetoptLong::OPTIONAL_ARGUMENT,
"Display the tasks (matching optional PATTERN) with descriptions, then exit."],
['--trace', '-t', GetoptLong::NO_ARGUMENT,
"Turn on invoke/execute tracing, enable full backtrace."],
- ['--usage', '-h', GetoptLong::NO_ARGUMENT,
- "Display usage."],
['--verbose', '-v', GetoptLong::NO_ARGUMENT,
"Log message to standard output (default)."],
['--version', '-V', GetoptLong::NO_ARGUMENT,
"Display the program version."],
- ['--classic-namespace', '-C', GetoptLong::NO_ARGUMENT,
- "Put Task and FileTask in the top level namespace"],
]
# Initialize a Rake::Application object.
@@ -1851,9 +1929,29 @@ def display_tasks_and_comments
displayable_tasks = tasks.select { |t|
t.comment && t.name =~ options.show_task_pattern
}
- width = displayable_tasks.collect { |t| t.name.length }.max
- displayable_tasks.each do |t|
- printf "#{name} %-#{width}s # %s\n", t.name, t.comment
+ if options.full_description
+ displayable_tasks.each do |t|
+ puts "task #{t.name_with_args}"
+ t.full_comment.each do |line|
+ puts " #{line}"
+ end
+ puts
+ end
+ else
+ width = displayable_tasks.collect { |t| t.name_with_args.length }.max
+ max_column = 80 - name.size - width - 7
+ displayable_tasks.each do |t|
+ printf "#{name} %-#{width}s # %s\n",
+ t.name_with_args, truncate(t.comment, max_column)
+ end
+ end
+ end
+
+ def truncate(string, width)
+ if string.length <= width
+ string
+ else
+ string[0, width-3] + "..."
end
end
@@ -1874,6 +1972,10 @@ def command_line_options
# Do the option defined by +opt+ and +value+.
def do_option(opt, value)
case opt
+ when '--describe'
+ options.show_tasks = true
+ options.show_task_pattern = Regexp.new(value || '.')
+ options.full_description = true
when '--dry-run'
verbose(true)
nowrite(true)
@@ -1911,6 +2013,7 @@ def do_option(opt, value)
when '--tasks'
options.show_tasks = true
options.show_task_pattern = Regexp.new(value || '.')
+ options.full_description = false
when '--trace'
options.trace = true
verbose(true)
View
6 test/test_application.rb
@@ -31,7 +31,7 @@ def test_constant_warning
def test_display_tasks
@app.options.show_task_pattern = //
- @app.last_comment = "COMMENT"
+ @app.last_description = "COMMENT"
@app.define_task(Rake::Task, "t")
out = capture_stdout do @app.instance_eval { display_tasks_and_comments } end
assert_match(/^rake t/, out)
@@ -134,7 +134,7 @@ def test_display_task_run
ran = false
ARGV.clear
ARGV << '-f' << '-s' << '--tasks'
- @app.last_comment = "COMMENT"
+ @app.last_description = "COMMENT"
@app.define_task(Rake::Task, "default")
out = capture_stdout { @app.run }
assert @app.options.show_tasks
@@ -147,7 +147,7 @@ def test_display_prereqs
ran = false
ARGV.clear
ARGV << '-f' << '-s' << '--prereqs'
- @app.last_comment = "COMMENT"
+ @app.last_description = "COMMENT"
t = @app.define_task(Rake::Task, "default")
t.enhance([:a, :b])
@app.define_task(Rake::Task, "a")
View
96 test/test_tasks.rb
@@ -204,6 +204,102 @@ def test_block_with_no_parameters_is_ok
t.invoke
end
+ def test_descriptions_with_no_args
+ desc "T"
+ t = intern(:tt).enhance { }
+ assert_equal "tt", t.name
+ assert_nil t.arg_description
+ assert_equal "T", t.comment
+ end
+
+ def test_name_with_args
+ desc "[a, b] T"
+ t = intern(:tt)
+ assert_equal "tt", t.name
+ assert_equal "T", t.comment
+ assert_equal "[a,b]", t.arg_description
+ assert_equal "tt[a,b]", t.name_with_args
+ assert_equal ["a", "b"],t.arg_names
+ end
+
+ def test_named_args_are_passed_to_prereqs
+ value = nil
+ desc "[rev] pre"
+ pre = intern(:pre).enhance { |t, rev| value = rev }
+ desc "[name,rev] t"
+ t = intern(:t).enhance([:pre])
+ t.args = ["bill", "1.2"]
+ t.invoke
+ assert_equal "1.2", value
+ end
+
+ def test_args_not_passed_if_no_prereq_names
+ value = nil
+ desc "pre"
+ pre = intern(:pre).enhance { |t, rev| value = rev }
+ desc "[name,rev] t"
+ t = intern(:t).enhance([:pre])
+ t.args = ["bill", "1.2"]
+ t.invoke
+ assert_nil value
+ end
+
+ def test_args_not_passed_if_no_arg_names
+ value = nil
+ desc "[rev] pre"
+ pre = intern(:pre).enhance { |t, rev| value = rev }
+ desc "t"
+ t = intern(:t).enhance([:pre])
+ t.args = ["bill", "1.2"]
+ t.invoke
+ assert_nil value
+ end
+
+ def test_task_can_have_arg_names_but_no_comment
+ desc "[a,b]"
+ t = intern(:t)
+ assert_equal "[a,b]", t.arg_description
+ assert_nil t.comment
+ assert_nil t.full_comment
+ end
+
+ def test_extended_comments
+ desc %{
+ [name, rev]
+ This is a comment.
+
+ And this is the extended comment.
+ name -- Name of task to execute.
+ rev -- Software revision to use.
+ }
+ t = intern(:t)
+ assert_equal "[name,rev]", t.arg_description
+ 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)
+ end
+
+ def test_comments_below_limit_are_unchanged
+ desc %{12345678901234567890123456789012345678901234567890}
+ t = intern(:t)
+ assert_equal "12345678901234567890123456789012345678901234567890", t.comment
+ end
+
+ def test_comments_above_limit_are_truncated
+ desc %{123456789012345678901234567890123456789012345678901}
+ t = intern(:t)
+ assert_equal "12345678901234567890123456789012345678901234567...", t.comment
+ end
+
+ def test_multiple_comments
+ desc "line one"
+ t = intern(:t)
+ desc "line two"
+ intern(:t)
+ assert_equal "line one / line two", t.comment
+ end
+
private
def intern(name)
Please sign in to comment.
Something went wrong with that request. Please try again.