rake 0.8.7 → 0.9.0.beta.0

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of rake might be problematic. Click here for more details.

Files changed (122) hide show
  1. data/.gemtest +0 -0
  2. data/CHANGES +77 -9
  3. data/{README → README.rdoc} +14 -10
  4. data/Rakefile +113 -110
  5. data/TODO +1 -1
  6. data/doc/command_line_usage.rdoc +18 -6
  7. data/doc/glossary.rdoc +2 -2
  8. data/doc/jamis.rb +2 -2
  9. data/doc/proto_rake.rdoc +22 -22
  10. data/doc/rake.1.gz +0 -0
  11. data/doc/rakefile.rdoc +60 -28
  12. data/doc/rational.rdoc +6 -6
  13. data/doc/release_notes/rake-0.4.15.rdoc +1 -1
  14. data/doc/release_notes/rake-0.5.0.rdoc +1 -1
  15. data/doc/release_notes/rake-0.7.0.rdoc +1 -1
  16. data/doc/release_notes/rake-0.7.2.rdoc +3 -3
  17. data/doc/release_notes/rake-0.7.3.rdoc +2 -2
  18. data/doc/release_notes/rake-0.8.0.rdoc +1 -1
  19. data/doc/release_notes/rake-0.8.2.rdoc +3 -3
  20. data/doc/release_notes/rake-0.8.3.rdoc +2 -2
  21. data/doc/release_notes/rake-0.8.4.rdoc +1 -1
  22. data/doc/release_notes/rake-0.8.5.rdoc +1 -1
  23. data/doc/release_notes/rake-0.8.6.rdoc +1 -1
  24. data/doc/release_notes/rake-0.8.7.rdoc +1 -1
  25. data/install.rb +14 -12
  26. data/lib/rake.rb +28 -2470
  27. data/lib/rake/alt_system.rb +7 -6
  28. data/lib/rake/application.rb +585 -0
  29. data/lib/rake/classic_namespace.rb +1 -0
  30. data/lib/rake/clean.rb +14 -14
  31. data/lib/rake/cloneable.rb +25 -0
  32. data/lib/rake/contrib/compositepublisher.rb +2 -5
  33. data/lib/rake/contrib/ftptools.rb +5 -8
  34. data/lib/rake/contrib/publisher.rb +2 -8
  35. data/lib/rake/contrib/rubyforgepublisher.rb +2 -4
  36. data/lib/rake/contrib/sshpublisher.rb +4 -6
  37. data/lib/rake/contrib/sys.rb +7 -25
  38. data/lib/rake/default_loader.rb +10 -0
  39. data/lib/rake/dsl.rb +2 -0
  40. data/lib/rake/dsl_definition.rb +146 -0
  41. data/lib/rake/early_time.rb +18 -0
  42. data/lib/rake/environment.rb +40 -0
  43. data/lib/rake/ext/core.rb +27 -0
  44. data/lib/rake/ext/module.rb +39 -0
  45. data/lib/rake/ext/string.rb +167 -0
  46. data/lib/rake/ext/time.rb +14 -0
  47. data/lib/rake/file_creation_task.rb +24 -0
  48. data/lib/rake/file_list.rb +403 -0
  49. data/lib/rake/file_task.rb +47 -0
  50. data/lib/rake/file_utils.rb +112 -0
  51. data/lib/rake/file_utils_ext.rb +132 -0
  52. data/lib/rake/gempackagetask.rb +6 -90
  53. data/lib/rake/invocation_chain.rb +51 -0
  54. data/lib/rake/invocation_exception_mixin.rb +16 -0
  55. data/lib/rake/loaders/makefile.rb +13 -15
  56. data/lib/rake/multi_task.rb +16 -0
  57. data/lib/rake/name_space.rb +25 -0
  58. data/lib/rake/packagetask.rb +13 -12
  59. data/lib/rake/pathmap.rb +1 -0
  60. data/lib/rake/pseudo_status.rb +24 -0
  61. data/lib/rake/rake_module.rb +25 -0
  62. data/lib/rake/rake_test_loader.rb +10 -2
  63. data/lib/rake/rdoctask.rb +211 -190
  64. data/lib/rake/ruby182_test_unit_fix.rb +9 -7
  65. data/lib/rake/rule_recursion_overflow_error.rb +20 -0
  66. data/lib/rake/runtest.rb +4 -6
  67. data/lib/rake/task.rb +327 -0
  68. data/lib/rake/task_argument_error.rb +7 -0
  69. data/lib/rake/task_arguments.rb +74 -0
  70. data/lib/rake/task_manager.rb +329 -0
  71. data/lib/rake/tasklib.rb +1 -2
  72. data/lib/rake/testtask.rb +51 -26
  73. data/lib/rake/version.rb +12 -0
  74. data/lib/rake/win32.rb +4 -4
  75. data/test/contrib/test_sys.rb +7 -30
  76. data/test/data/comments/Rakefile +18 -0
  77. data/test/data/default/Rakefile +1 -1
  78. data/test/data/dryrun/Rakefile +1 -1
  79. data/test/data/file_creation_task/Rakefile +1 -1
  80. data/test/data/namespace/Rakefile +9 -0
  81. data/test/data/rakelib/test1.rb +4 -2
  82. data/test/data/verbose/Rakefile +34 -0
  83. data/test/functional/functional_test.rb +25 -0
  84. data/test/{session_functional.rb → functional/session_based_tests.rb} +134 -23
  85. data/test/in_environment.rb +6 -4
  86. data/test/{test_application.rb → lib/application_test.rb} +277 -136
  87. data/test/{test_clean.rb → lib/clean_test.rb} +1 -0
  88. data/test/{test_definitions.rb → lib/definitions_test.rb} +2 -2
  89. data/test/lib/dsl_test.rb +52 -0
  90. data/test/{test_earlytime.rb → lib/earlytime_test.rb} +1 -2
  91. data/test/lib/environment_test.rb +18 -0
  92. data/test/{test_extension.rb → lib/extension_test.rb} +2 -2
  93. data/test/{test_file_creation_task.rb → lib/file_creation_task_test.rb} +0 -0
  94. data/test/{test_file_task.rb → lib/file_task_test.rb} +3 -3
  95. data/test/{test_filelist.rb → lib/filelist_test.rb} +28 -24
  96. data/test/{test_fileutils.rb → lib/fileutils_test.rb} +26 -21
  97. data/test/{test_ftp.rb → lib/ftp_test.rb} +0 -0
  98. data/test/{test_invocation_chain.rb → lib/invocation_chain_test.rb} +0 -0
  99. data/test/{test_makefile_loader.rb → lib/makefile_loader_test.rb} +0 -0
  100. data/test/{test_multitask.rb → lib/multitask_test.rb} +14 -6
  101. data/test/{test_namespace.rb → lib/namespace_test.rb} +0 -0
  102. data/test/lib/package_task_test.rb +82 -0
  103. data/test/{test_pathmap.rb → lib/pathmap_test.rb} +3 -2
  104. data/test/{test_pseudo_status.rb → lib/pseudo_status_test.rb} +0 -0
  105. data/test/{test_rake.rb → lib/rake_test.rb} +1 -1
  106. data/test/{test_rdoc_task.rb → lib/rdoc_task_test.rb} +19 -23
  107. data/test/{test_require.rb → lib/require_test.rb} +8 -2
  108. data/test/{test_rules.rb → lib/rules_test.rb} +1 -2
  109. data/test/{test_task_arguments.rb → lib/task_arguments_test.rb} +5 -5
  110. data/test/{test_task_manager.rb → lib/task_manager_test.rb} +5 -5
  111. data/test/{test_tasks.rb → lib/task_test.rb} +69 -4
  112. data/test/{test_tasklib.rb → lib/tasklib_test.rb} +0 -0
  113. data/test/{test_test_task.rb → lib/test_task_test.rb} +3 -3
  114. data/test/lib/testtask_test.rb +49 -0
  115. data/test/{test_top_level_functions.rb → lib/top_level_functions_test.rb} +3 -3
  116. data/test/{test_win32.rb → lib/win32_test.rb} +19 -0
  117. data/test/rake_test_setup.rb +4 -9
  118. data/test/ruby_version_test.rb +3 -0
  119. data/test/test_helper.rb +12 -0
  120. metadata +100 -44
  121. data/test/functional.rb +0 -15
  122. data/test/test_package_task.rb +0 -118
@@ -1,10 +1,13 @@
1
- module Test
2
- module Unit
3
- module Collector
4
- class Dir
1
+ # Local Rake override to fix bug in Ruby 0.8.2
2
+ module Test # :nodoc:
3
+ # Local Rake override to fix bug in Ruby 0.8.2
4
+ module Unit # :nodoc:
5
+ # Local Rake override to fix bug in Ruby 0.8.2
6
+ module Collector # :nodoc:
7
+ # Local Rake override to fix bug in Ruby 0.8.2
8
+ class Dir # :nodoc:
5
9
  undef collect_file
6
- def collect_file(name, suites, already_gathered)
7
- # loadpath = $:.dup
10
+ def collect_file(name, suites, already_gathered) # :nodoc:
8
11
  dir = File.dirname(File.expand_path(name))
9
12
  $:.unshift(dir) unless $:.first == dir
10
13
  if(@req)
@@ -14,7 +17,6 @@ module Test
14
17
  end
15
18
  find_test_cases(already_gathered).each{|t| add_suite(suites, t.suite)}
16
19
  ensure
17
- # $:.replace(loadpath)
18
20
  $:.delete_at $:.rindex(dir)
19
21
  end
20
22
  end
@@ -0,0 +1,20 @@
1
+
2
+ module Rake
3
+
4
+ # Error indicating a recursion overflow error in task selection.
5
+ class RuleRecursionOverflowError < StandardError
6
+ def initialize(*args)
7
+ super
8
+ @targets = []
9
+ end
10
+
11
+ def add_target(target)
12
+ @targets << target
13
+ end
14
+
15
+ def message
16
+ super + ": [" + @targets.reverse.join(' => ') + "]"
17
+ end
18
+ end
19
+
20
+ end
@@ -1,5 +1,3 @@
1
- #!/usr/bin/env ruby
2
-
3
1
  require 'test/unit'
4
2
  require 'test/unit/assertions'
5
3
 
@@ -8,12 +6,12 @@ module Rake
8
6
 
9
7
  def run_tests(pattern='test/test*.rb', log_enabled=false)
10
8
  Dir["#{pattern}"].each { |fn|
11
- puts fn if log_enabled
9
+ $stderr.puts fn if log_enabled
12
10
  begin
13
- load fn
11
+ require fn
14
12
  rescue Exception => ex
15
- puts "Error in #{fn}: #{ex.message}"
16
- puts ex.backtrace
13
+ $stderr.puts "Error in #{fn}: #{ex.message}"
14
+ $stderr.puts ex.backtrace
17
15
  assert false
18
16
  end
19
17
  }
@@ -0,0 +1,327 @@
1
+ require 'rake/invocation_exception_mixin'
2
+
3
+ module Rake
4
+
5
+ # #########################################################################
6
+ # A Task is the basic unit of work in a Rakefile. Tasks have associated
7
+ # actions (possibly more than one) and a list of prerequisites. When
8
+ # invoked, a task will first ensure that all of its prerequisites have an
9
+ # opportunity to run and then it will execute its own actions.
10
+ #
11
+ # Tasks are not usually created directly using the new method, but rather
12
+ # use the +file+ and +task+ convenience methods.
13
+ #
14
+ class Task
15
+ # List of prerequisites for a task.
16
+ attr_reader :prerequisites
17
+
18
+ # List of actions attached to a task.
19
+ attr_reader :actions
20
+
21
+ # Application owning this task.
22
+ attr_accessor :application
23
+
24
+ # Comment for this task. Restricted to a single line of no more than 50
25
+ # characters.
26
+ attr_reader :comment
27
+
28
+ # Full text of the (possibly multi-line) comment.
29
+ attr_reader :full_comment
30
+
31
+ # Array of nested namespaces names used for task lookup by this task.
32
+ attr_reader :scope
33
+
34
+ # File/Line locations of each of the task definitions for this
35
+ # task (only valid if the task was defined with the detect
36
+ # location option set).
37
+ attr_reader :locations
38
+
39
+ # Return task name
40
+ def to_s
41
+ name
42
+ end
43
+
44
+ def inspect
45
+ "<#{self.class} #{name} => [#{prerequisites.join(', ')}]>"
46
+ end
47
+
48
+ # List of sources for task.
49
+ attr_writer :sources
50
+ def sources
51
+ @sources ||= []
52
+ end
53
+
54
+ # List of prerequisite tasks
55
+ def prerequisite_tasks
56
+ prerequisites.collect { |pre| lookup_prerequisite(pre) }
57
+ end
58
+
59
+ def lookup_prerequisite(prerequisite_name)
60
+ application[prerequisite_name, @scope]
61
+ end
62
+ private :lookup_prerequisite
63
+
64
+ # First source from a rule (nil if no sources)
65
+ def source
66
+ @sources.first if defined?(@sources)
67
+ end
68
+
69
+ # Create a task named +task_name+ with no actions or prerequisites. Use
70
+ # +enhance+ to add actions and prerequisites.
71
+ def initialize(task_name, app)
72
+ @name = task_name.to_s
73
+ @prerequisites = []
74
+ @actions = []
75
+ @already_invoked = false
76
+ @full_comment = nil
77
+ @comment = nil
78
+ @lock = Monitor.new
79
+ @application = app
80
+ @scope = app.current_scope
81
+ @arg_names = nil
82
+ @locations = []
83
+ end
84
+
85
+ # Enhance a task with prerequisites or actions. Returns self.
86
+ def enhance(deps=nil, &block)
87
+ @prerequisites |= deps if deps
88
+ @actions << block if block_given?
89
+ self
90
+ end
91
+
92
+ # Name of the task, including any namespace qualifiers.
93
+ def name
94
+ @name.to_s
95
+ end
96
+
97
+ # Name of task with argument list description.
98
+ def name_with_args # :nodoc:
99
+ if arg_description
100
+ "#{name}#{arg_description}"
101
+ else
102
+ name
103
+ end
104
+ end
105
+
106
+ # Argument description (nil if none).
107
+ def arg_description # :nodoc:
108
+ @arg_names ? "[#{(arg_names || []).join(',')}]" : nil
109
+ end
110
+
111
+ # Name of arguments for this task.
112
+ def arg_names
113
+ @arg_names || []
114
+ end
115
+
116
+ # Reenable the task, allowing its tasks to be executed if the task
117
+ # is invoked again.
118
+ def reenable
119
+ @already_invoked = false
120
+ end
121
+
122
+ # Clear the existing prerequisites and actions of a rake task.
123
+ def clear
124
+ clear_prerequisites
125
+ clear_actions
126
+ self
127
+ end
128
+
129
+ # Clear the existing prerequisites of a rake task.
130
+ def clear_prerequisites
131
+ prerequisites.clear
132
+ self
133
+ end
134
+
135
+ # Clear the existing actions on a rake task.
136
+ def clear_actions
137
+ actions.clear
138
+ self
139
+ end
140
+
141
+ # Invoke the task if it is needed. Prerequisites are invoked first.
142
+ def invoke(*args)
143
+ task_args = TaskArguments.new(arg_names, args)
144
+ invoke_with_call_chain(task_args, InvocationChain::EMPTY)
145
+ end
146
+
147
+ # Same as invoke, but explicitly pass a call chain to detect
148
+ # circular dependencies.
149
+ def invoke_with_call_chain(task_args, invocation_chain) # :nodoc:
150
+ new_chain = InvocationChain.append(self, invocation_chain)
151
+ @lock.synchronize do
152
+ if application.options.trace
153
+ $stderr.puts "** Invoke #{name} #{format_trace_flags}"
154
+ end
155
+ return if @already_invoked
156
+ @already_invoked = true
157
+ invoke_prerequisites(task_args, new_chain)
158
+ execute(task_args) if needed?
159
+ end
160
+ rescue Exception => ex
161
+ add_chain_to(ex, new_chain)
162
+ raise ex
163
+ end
164
+ protected :invoke_with_call_chain
165
+
166
+ def add_chain_to(exception, new_chain)
167
+ exception.extend(InvocationExceptionMixin) unless exception.respond_to?(:chain)
168
+ exception.chain = new_chain if exception.chain.nil?
169
+ end
170
+ private :add_chain_to
171
+
172
+ # Invoke all the prerequisites of a task.
173
+ def invoke_prerequisites(task_args, invocation_chain) # :nodoc:
174
+ prerequisite_tasks.each { |prereq|
175
+ prereq_args = task_args.new_scope(prereq.arg_names)
176
+ prereq.invoke_with_call_chain(prereq_args, invocation_chain)
177
+ }
178
+ end
179
+
180
+ # Format the trace flags for display.
181
+ def format_trace_flags
182
+ flags = []
183
+ flags << "first_time" unless @already_invoked
184
+ flags << "not_needed" unless needed?
185
+ flags.empty? ? "" : "(" + flags.join(", ") + ")"
186
+ end
187
+ private :format_trace_flags
188
+
189
+ # Execute the actions associated with this task.
190
+ def execute(args=nil)
191
+ args ||= EMPTY_TASK_ARGS
192
+ if application.options.dryrun
193
+ $stderr.puts "** Execute (dry run) #{name}"
194
+ return
195
+ end
196
+ if application.options.trace
197
+ $stderr.puts "** Execute #{name}"
198
+ end
199
+ application.enhance_with_matching_rule(name) if @actions.empty?
200
+ @actions.each do |act|
201
+ case act.arity
202
+ when 1
203
+ act.call(self)
204
+ else
205
+ act.call(self, args)
206
+ end
207
+ end
208
+ end
209
+
210
+ # Is this task needed?
211
+ def needed?
212
+ true
213
+ end
214
+
215
+ # Timestamp for this task. Basic tasks return the current time for their
216
+ # time stamp. Other tasks can be more sophisticated.
217
+ def timestamp
218
+ prerequisite_tasks.collect { |pre| pre.timestamp }.max || Time.now
219
+ end
220
+
221
+ # Add a description to the task. The description can consist of an option
222
+ # argument list (enclosed brackets) and an optional comment.
223
+ def add_description(description)
224
+ return if ! description
225
+ comment = description.strip
226
+ add_comment(comment) if comment && ! comment.empty?
227
+ end
228
+
229
+ # Writing to the comment attribute is the same as adding a description.
230
+ def comment=(description)
231
+ add_description(description)
232
+ end
233
+
234
+ # Add a comment to the task. If a comment already exists, separate
235
+ # the new comment with " / ".
236
+ def add_comment(comment)
237
+ if @full_comment
238
+ @full_comment << " / "
239
+ else
240
+ @full_comment = ''
241
+ end
242
+ @full_comment << comment
243
+ if @full_comment =~ /\A([^.]+?\.)( |$)/
244
+ @comment = $1
245
+ else
246
+ @comment = @full_comment
247
+ end
248
+ end
249
+ private :add_comment
250
+
251
+ # Set the names of the arguments for this task. +args+ should be
252
+ # an array of symbols, one for each argument name.
253
+ def set_arg_names(args)
254
+ @arg_names = args.map { |a| a.to_sym }
255
+ end
256
+
257
+ # Return a string describing the internal state of a task. Useful for
258
+ # debugging.
259
+ def investigation
260
+ result = "------------------------------\n"
261
+ result << "Investigating #{name}\n"
262
+ result << "class: #{self.class}\n"
263
+ result << "task needed: #{needed?}\n"
264
+ result << "timestamp: #{timestamp}\n"
265
+ result << "pre-requisites: \n"
266
+ prereqs = prerequisite_tasks
267
+ prereqs.sort! {|a,b| a.timestamp <=> b.timestamp}
268
+ prereqs.each do |p|
269
+ result << "--#{p.name} (#{p.timestamp})\n"
270
+ end
271
+ latest_prereq = prerequisite_tasks.collect { |pre| pre.timestamp }.max
272
+ result << "latest-prerequisite time: #{latest_prereq}\n"
273
+ result << "................................\n\n"
274
+ return result
275
+ end
276
+
277
+ # ----------------------------------------------------------------
278
+ # Rake Module Methods
279
+ #
280
+ class << self
281
+
282
+ # Clear the task list. This cause rake to immediately forget all the
283
+ # tasks that have been assigned. (Normally used in the unit tests.)
284
+ def clear
285
+ Rake.application.clear
286
+ end
287
+
288
+ # List of all defined tasks.
289
+ def tasks
290
+ Rake.application.tasks
291
+ end
292
+
293
+ # Return a task with the given name. If the task is not currently
294
+ # known, try to synthesize one from the defined rules. If no rules are
295
+ # found, but an existing file matches the task name, assume it is a file
296
+ # task with no dependencies or actions.
297
+ def [](task_name)
298
+ Rake.application[task_name]
299
+ end
300
+
301
+ # TRUE if the task name is already defined.
302
+ def task_defined?(task_name)
303
+ Rake.application.lookup(task_name) != nil
304
+ end
305
+
306
+ # Define a task given +args+ and an option block. If a rule with the
307
+ # given name already exists, the prerequisites and actions are added to
308
+ # the existing task. Returns the defined task.
309
+ def define_task(*args, &block)
310
+ Rake.application.define_task(self, *args, &block)
311
+ end
312
+
313
+ # Define a rule for synthesizing tasks.
314
+ def create_rule(*args, &block)
315
+ Rake.application.create_rule(*args, &block)
316
+ end
317
+
318
+ # Apply the scope to the task name according to the rules for
319
+ # this kind of task. Generic tasks will accept the scope as
320
+ # part of the name.
321
+ def scope_name(scope, task_name)
322
+ (scope + [task_name]).join(':')
323
+ end
324
+
325
+ end # class << Rake::Task
326
+ end # class Rake::Task
327
+ end
@@ -0,0 +1,7 @@
1
+ module Rake
2
+
3
+ # Error indicating an ill-formed task declaration.
4
+ class TaskArgumentError < ArgumentError
5
+ end
6
+
7
+ end
@@ -0,0 +1,74 @@
1
+ module Rake
2
+
3
+ ####################################################################
4
+ # TaskArguments manage the arguments passed to a task.
5
+ #
6
+ class TaskArguments
7
+ include Enumerable
8
+
9
+ attr_reader :names
10
+
11
+ # Create a TaskArgument object with a list of named arguments
12
+ # (given by :names) and a set of associated values (given by
13
+ # :values). :parent is the parent argument object.
14
+ def initialize(names, values, parent=nil)
15
+ @names = names
16
+ @parent = parent
17
+ @hash = {}
18
+ names.each_with_index { |name, i|
19
+ @hash[name.to_sym] = values[i] unless values[i].nil?
20
+ }
21
+ end
22
+
23
+ # Create a new argument scope using the prerequisite argument
24
+ # names.
25
+ def new_scope(names)
26
+ values = names.collect { |n| self[n] }
27
+ self.class.new(names, values, self)
28
+ end
29
+
30
+ # Find an argument value by name or index.
31
+ def [](index)
32
+ lookup(index.to_sym)
33
+ end
34
+
35
+ # Specify a hash of default values for task arguments. Use the
36
+ # defaults only if there is no specific value for the given
37
+ # argument.
38
+ def with_defaults(defaults)
39
+ @hash = defaults.merge(@hash)
40
+ end
41
+
42
+ def each(&block)
43
+ @hash.each(&block)
44
+ end
45
+
46
+ def method_missing(sym, *args, &block)
47
+ lookup(sym.to_sym)
48
+ end
49
+
50
+ def to_hash
51
+ @hash
52
+ end
53
+
54
+ def to_s
55
+ @hash.inspect
56
+ end
57
+
58
+ def inspect
59
+ to_s
60
+ end
61
+
62
+ protected
63
+
64
+ def lookup(name)
65
+ if @hash.has_key?(name)
66
+ @hash[name]
67
+ elsif @parent
68
+ @parent.lookup(name)
69
+ end
70
+ end
71
+ end
72
+
73
+ EMPTY_TASK_ARGS = TaskArguments.new([], [])
74
+ end