rake 13.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (75) hide show
  1. checksums.yaml +7 -0
  2. data/.github/workflows/macos.yml +22 -0
  3. data/.github/workflows/ubuntu-rvm.yml +28 -0
  4. data/.github/workflows/ubuntu.yml +20 -0
  5. data/.github/workflows/windows.yml +20 -0
  6. data/CONTRIBUTING.rdoc +43 -0
  7. data/Gemfile +10 -0
  8. data/History.rdoc +2359 -0
  9. data/MIT-LICENSE +21 -0
  10. data/README.rdoc +155 -0
  11. data/Rakefile +41 -0
  12. data/bin/bundle +105 -0
  13. data/bin/console +7 -0
  14. data/bin/rake +29 -0
  15. data/bin/rdoc +29 -0
  16. data/bin/rubocop +29 -0
  17. data/bin/setup +6 -0
  18. data/doc/command_line_usage.rdoc +158 -0
  19. data/doc/example/Rakefile1 +38 -0
  20. data/doc/example/Rakefile2 +35 -0
  21. data/doc/example/a.c +6 -0
  22. data/doc/example/b.c +6 -0
  23. data/doc/example/main.c +11 -0
  24. data/doc/glossary.rdoc +42 -0
  25. data/doc/jamis.rb +592 -0
  26. data/doc/proto_rake.rdoc +127 -0
  27. data/doc/rake.1 +156 -0
  28. data/doc/rakefile.rdoc +622 -0
  29. data/doc/rational.rdoc +151 -0
  30. data/exe/rake +27 -0
  31. data/lib/rake.rb +71 -0
  32. data/lib/rake/application.rb +824 -0
  33. data/lib/rake/backtrace.rb +24 -0
  34. data/lib/rake/clean.rb +78 -0
  35. data/lib/rake/cloneable.rb +17 -0
  36. data/lib/rake/cpu_counter.rb +107 -0
  37. data/lib/rake/default_loader.rb +15 -0
  38. data/lib/rake/dsl_definition.rb +195 -0
  39. data/lib/rake/early_time.rb +22 -0
  40. data/lib/rake/ext/core.rb +26 -0
  41. data/lib/rake/ext/string.rb +176 -0
  42. data/lib/rake/file_creation_task.rb +25 -0
  43. data/lib/rake/file_list.rb +435 -0
  44. data/lib/rake/file_task.rb +54 -0
  45. data/lib/rake/file_utils.rb +134 -0
  46. data/lib/rake/file_utils_ext.rb +134 -0
  47. data/lib/rake/invocation_chain.rb +57 -0
  48. data/lib/rake/invocation_exception_mixin.rb +17 -0
  49. data/lib/rake/late_time.rb +18 -0
  50. data/lib/rake/linked_list.rb +112 -0
  51. data/lib/rake/loaders/makefile.rb +54 -0
  52. data/lib/rake/multi_task.rb +14 -0
  53. data/lib/rake/name_space.rb +38 -0
  54. data/lib/rake/packagetask.rb +222 -0
  55. data/lib/rake/phony.rb +16 -0
  56. data/lib/rake/private_reader.rb +21 -0
  57. data/lib/rake/promise.rb +100 -0
  58. data/lib/rake/pseudo_status.rb +30 -0
  59. data/lib/rake/rake_module.rb +67 -0
  60. data/lib/rake/rake_test_loader.rb +27 -0
  61. data/lib/rake/rule_recursion_overflow_error.rb +20 -0
  62. data/lib/rake/scope.rb +43 -0
  63. data/lib/rake/task.rb +433 -0
  64. data/lib/rake/task_argument_error.rb +8 -0
  65. data/lib/rake/task_arguments.rb +109 -0
  66. data/lib/rake/task_manager.rb +328 -0
  67. data/lib/rake/tasklib.rb +12 -0
  68. data/lib/rake/testtask.rb +224 -0
  69. data/lib/rake/thread_history_display.rb +49 -0
  70. data/lib/rake/thread_pool.rb +163 -0
  71. data/lib/rake/trace_output.rb +23 -0
  72. data/lib/rake/version.rb +10 -0
  73. data/lib/rake/win32.rb +51 -0
  74. data/rake.gemspec +36 -0
  75. metadata +132 -0
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+ module Rake
3
+
4
+ # Error indicating an ill-formed task declaration.
5
+ class TaskArgumentError < ArgumentError
6
+ end
7
+
8
+ end
@@ -0,0 +1,109 @@
1
+ # frozen_string_literal: true
2
+ module Rake
3
+
4
+ ##
5
+ # TaskArguments manage the arguments passed to a task.
6
+ #
7
+ class TaskArguments
8
+ include Enumerable
9
+
10
+ # Argument names
11
+ attr_reader :names
12
+
13
+ # Create a TaskArgument object with a list of argument +names+ and a set
14
+ # of associated +values+. +parent+ is the parent argument object.
15
+ def initialize(names, values, parent=nil)
16
+ @names = names
17
+ @parent = parent
18
+ @hash = {}
19
+ @values = values
20
+ names.each_with_index { |name, i|
21
+ next if values[i].nil? || values[i] == ""
22
+ @hash[name.to_sym] = values[i]
23
+ }
24
+ end
25
+
26
+ # Retrieve the complete array of sequential values
27
+ def to_a
28
+ @values.dup
29
+ end
30
+
31
+ # Retrieve the list of values not associated with named arguments
32
+ def extras
33
+ @values[@names.length..-1] || []
34
+ end
35
+
36
+ # Create a new argument scope using the prerequisite argument
37
+ # names.
38
+ def new_scope(names)
39
+ values = names.map { |n| self[n] }
40
+ self.class.new(names, values + extras, self)
41
+ end
42
+
43
+ # Find an argument value by name or index.
44
+ def [](index)
45
+ lookup(index.to_sym)
46
+ end
47
+
48
+ # Specify a hash of default values for task arguments. Use the
49
+ # defaults only if there is no specific value for the given
50
+ # argument.
51
+ def with_defaults(defaults)
52
+ @hash = defaults.merge(@hash)
53
+ end
54
+
55
+ # Enumerates the arguments and their values
56
+ def each(&block)
57
+ @hash.each(&block)
58
+ end
59
+
60
+ # Extracts the argument values at +keys+
61
+ def values_at(*keys)
62
+ keys.map { |k| lookup(k) }
63
+ end
64
+
65
+ # Returns the value of the given argument via method_missing
66
+ def method_missing(sym, *args)
67
+ lookup(sym.to_sym)
68
+ end
69
+
70
+ # Returns a Hash of arguments and their values
71
+ def to_hash
72
+ @hash.dup
73
+ end
74
+
75
+ def to_s # :nodoc:
76
+ inspect
77
+ end
78
+
79
+ def inspect # :nodoc:
80
+ inspection = @hash.map do |k,v|
81
+ "#{k.to_s}: #{v.to_s}"
82
+ end.join(", ")
83
+
84
+ "#<#{self.class} #{inspection}>"
85
+ end
86
+
87
+ # Returns true if +key+ is one of the arguments
88
+ def has_key?(key)
89
+ @hash.has_key?(key)
90
+ end
91
+ alias key? has_key?
92
+
93
+ def fetch(*args, &block)
94
+ @hash.fetch(*args, &block)
95
+ end
96
+
97
+ protected
98
+
99
+ def lookup(name) # :nodoc:
100
+ if @hash.has_key?(name)
101
+ @hash[name]
102
+ elsif @parent
103
+ @parent.lookup(name)
104
+ end
105
+ end
106
+ end
107
+
108
+ EMPTY_TASK_ARGS = TaskArguments.new([], []) # :nodoc:
109
+ end
@@ -0,0 +1,328 @@
1
+ # frozen_string_literal: true
2
+ module Rake
3
+
4
+ # The TaskManager module is a mixin for managing tasks.
5
+ module TaskManager
6
+ # Track the last comment made in the Rakefile.
7
+ attr_accessor :last_description
8
+
9
+ def initialize # :nodoc:
10
+ super
11
+ @tasks = Hash.new
12
+ @rules = Array.new
13
+ @scope = Scope.make
14
+ @last_description = nil
15
+ end
16
+
17
+ def create_rule(*args, &block) # :nodoc:
18
+ pattern, args, deps, order_only = resolve_args(args)
19
+ pattern = Regexp.new(Regexp.quote(pattern) + "$") if String === pattern
20
+ @rules << [pattern, args, deps, order_only, block]
21
+ end
22
+
23
+ def define_task(task_class, *args, &block) # :nodoc:
24
+ task_name, arg_names, deps, order_only = resolve_args(args)
25
+
26
+ original_scope = @scope
27
+ if String === task_name and
28
+ not task_class.ancestors.include? Rake::FileTask
29
+ task_name, *definition_scope = *(task_name.split(":").reverse)
30
+ @scope = Scope.make(*(definition_scope + @scope.to_a))
31
+ end
32
+
33
+ task_name = task_class.scope_name(@scope, task_name)
34
+ task = intern(task_class, task_name)
35
+ task.set_arg_names(arg_names) unless arg_names.empty?
36
+ if Rake::TaskManager.record_task_metadata
37
+ add_location(task)
38
+ task.add_description(get_description(task))
39
+ end
40
+ task.enhance(Task.format_deps(deps), &block)
41
+ task | order_only unless order_only.nil?
42
+ task
43
+ ensure
44
+ @scope = original_scope
45
+ end
46
+
47
+ # Lookup a task. Return an existing task if found, otherwise
48
+ # create a task of the current type.
49
+ def intern(task_class, task_name)
50
+ @tasks[task_name.to_s] ||= task_class.new(task_name, self)
51
+ end
52
+
53
+ # Find a matching task for +task_name+.
54
+ def [](task_name, scopes=nil)
55
+ task_name = task_name.to_s
56
+ self.lookup(task_name, scopes) or
57
+ enhance_with_matching_rule(task_name) or
58
+ synthesize_file_task(task_name) or
59
+ fail generate_message_for_undefined_task(task_name)
60
+ end
61
+
62
+ def generate_message_for_undefined_task(task_name)
63
+ message = "Don't know how to build task '#{task_name}' "\
64
+ "(See the list of available tasks with `#{Rake.application.name} --tasks`)"
65
+ message + generate_did_you_mean_suggestions(task_name)
66
+ end
67
+
68
+ def generate_did_you_mean_suggestions(task_name)
69
+ return "" unless defined?(::DidYouMean::SpellChecker)
70
+
71
+ suggestions = ::DidYouMean::SpellChecker.new(dictionary: @tasks.keys).correct(task_name.to_s)
72
+ if ::DidYouMean.respond_to?(:formatter)# did_you_mean v1.2.0 or later
73
+ ::DidYouMean.formatter.message_for(suggestions)
74
+ elsif defined?(::DidYouMean::Formatter) # before did_you_mean v1.2.0
75
+ ::DidYouMean::Formatter.new(suggestions).to_s
76
+ else
77
+ ""
78
+ end
79
+ end
80
+
81
+ def synthesize_file_task(task_name) # :nodoc:
82
+ return nil unless File.exist?(task_name)
83
+ define_task(Rake::FileTask, task_name)
84
+ end
85
+
86
+ # Resolve the arguments for a task/rule. Returns a triplet of
87
+ # [task_name, arg_name_list, prerequisites].
88
+ def resolve_args(args)
89
+ if args.last.is_a?(Hash)
90
+ deps = args.pop
91
+ resolve_args_with_dependencies(args, deps)
92
+ else
93
+ resolve_args_without_dependencies(args)
94
+ end
95
+ end
96
+
97
+ # Resolve task arguments for a task or rule when there are no
98
+ # dependencies declared.
99
+ #
100
+ # The patterns recognized by this argument resolving function are:
101
+ #
102
+ # task :t
103
+ # task :t, [:a]
104
+ #
105
+ def resolve_args_without_dependencies(args)
106
+ task_name = args.shift
107
+ if args.size == 1 && args.first.respond_to?(:to_ary)
108
+ arg_names = args.first.to_ary
109
+ else
110
+ arg_names = args
111
+ end
112
+ [task_name, arg_names, [], nil]
113
+ end
114
+ private :resolve_args_without_dependencies
115
+
116
+ # Resolve task arguments for a task or rule when there are
117
+ # dependencies declared.
118
+ #
119
+ # The patterns recognized by this argument resolving function are:
120
+ #
121
+ # task :t => [:d]
122
+ # task :t, [a] => [:d]
123
+ #
124
+ def resolve_args_with_dependencies(args, hash) # :nodoc:
125
+ fail "Task Argument Error" if
126
+ hash.size != 1 &&
127
+ (hash.size != 2 || !hash.key?(:order_only))
128
+ order_only = hash.delete(:order_only)
129
+ key, value = hash.map { |k, v| [k, v] }.first
130
+ if args.empty?
131
+ task_name = key
132
+ arg_names = []
133
+ deps = value || []
134
+ else
135
+ task_name = args.shift
136
+ arg_names = key
137
+ deps = value
138
+ end
139
+ deps = [deps] unless deps.respond_to?(:to_ary)
140
+ [task_name, arg_names, deps, order_only]
141
+ end
142
+ private :resolve_args_with_dependencies
143
+
144
+ # If a rule can be found that matches the task name, enhance the
145
+ # task with the prerequisites and actions from the rule. Set the
146
+ # source attribute of the task appropriately for the rule. Return
147
+ # the enhanced task or nil of no rule was found.
148
+ def enhance_with_matching_rule(task_name, level=0)
149
+ fail Rake::RuleRecursionOverflowError,
150
+ "Rule Recursion Too Deep" if level >= 16
151
+ @rules.each do |pattern, args, extensions, order_only, block|
152
+ if pattern && pattern.match(task_name)
153
+ task = attempt_rule(task_name, pattern, args, extensions, block, level)
154
+ task | order_only unless order_only.nil?
155
+ return task if task
156
+ end
157
+ end
158
+ nil
159
+ rescue Rake::RuleRecursionOverflowError => ex
160
+ ex.add_target(task_name)
161
+ fail ex
162
+ end
163
+
164
+ # List of all defined tasks in this application.
165
+ def tasks
166
+ @tasks.values.sort_by { |t| t.name }
167
+ end
168
+
169
+ # List of all the tasks defined in the given scope (and its
170
+ # sub-scopes).
171
+ def tasks_in_scope(scope)
172
+ prefix = scope.path
173
+ tasks.select { |t|
174
+ /^#{prefix}:/ =~ t.name
175
+ }
176
+ end
177
+
178
+ # Clear all tasks in this application.
179
+ def clear
180
+ @tasks.clear
181
+ @rules.clear
182
+ end
183
+
184
+ # Lookup a task, using scope and the scope hints in the task name.
185
+ # This method performs straight lookups without trying to
186
+ # synthesize file tasks or rules. Special scope names (e.g. '^')
187
+ # are recognized. If no scope argument is supplied, use the
188
+ # current scope. Return nil if the task cannot be found.
189
+ def lookup(task_name, initial_scope=nil)
190
+ initial_scope ||= @scope
191
+ task_name = task_name.to_s
192
+ if task_name =~ /^rake:/
193
+ scopes = Scope.make
194
+ task_name = task_name.sub(/^rake:/, "")
195
+ elsif task_name =~ /^(\^+)/
196
+ scopes = initial_scope.trim($1.size)
197
+ task_name = task_name.sub(/^(\^+)/, "")
198
+ else
199
+ scopes = initial_scope
200
+ end
201
+ lookup_in_scope(task_name, scopes)
202
+ end
203
+
204
+ # Lookup the task name
205
+ def lookup_in_scope(name, scope)
206
+ loop do
207
+ tn = scope.path_with_task_name(name)
208
+ task = @tasks[tn]
209
+ return task if task
210
+ break if scope.empty?
211
+ scope = scope.tail
212
+ end
213
+ nil
214
+ end
215
+ private :lookup_in_scope
216
+
217
+ # Return the list of scope names currently active in the task
218
+ # manager.
219
+ def current_scope
220
+ @scope
221
+ end
222
+
223
+ # Evaluate the block in a nested namespace named +name+. Create
224
+ # an anonymous namespace if +name+ is nil.
225
+ def in_namespace(name)
226
+ name ||= generate_name
227
+ @scope = Scope.new(name, @scope)
228
+ ns = NameSpace.new(self, @scope)
229
+ yield(ns)
230
+ ns
231
+ ensure
232
+ @scope = @scope.tail
233
+ end
234
+
235
+ private
236
+
237
+ # Add a location to the locations field of the given task.
238
+ def add_location(task)
239
+ loc = find_location
240
+ task.locations << loc if loc
241
+ task
242
+ end
243
+
244
+ # Find the location that called into the dsl layer.
245
+ def find_location
246
+ locations = caller
247
+ i = 0
248
+ while locations[i]
249
+ return locations[i + 1] if locations[i] =~ /rake\/dsl_definition.rb/
250
+ i += 1
251
+ end
252
+ nil
253
+ end
254
+
255
+ # Generate an anonymous namespace name.
256
+ def generate_name
257
+ @seed ||= 0
258
+ @seed += 1
259
+ "_anon_#{@seed}"
260
+ end
261
+
262
+ def trace_rule(level, message) # :nodoc:
263
+ options.trace_output.puts "#{" " * level}#{message}" if
264
+ Rake.application.options.trace_rules
265
+ end
266
+
267
+ # Attempt to create a rule given the list of prerequisites.
268
+ def attempt_rule(task_name, task_pattern, args, extensions, block, level)
269
+ sources = make_sources(task_name, task_pattern, extensions)
270
+ prereqs = sources.map { |source|
271
+ trace_rule level, "Attempting Rule #{task_name} => #{source}"
272
+ if File.exist?(source) || Rake::Task.task_defined?(source)
273
+ trace_rule level, "(#{task_name} => #{source} ... EXIST)"
274
+ source
275
+ elsif parent = enhance_with_matching_rule(source, level + 1)
276
+ trace_rule level, "(#{task_name} => #{source} ... ENHANCE)"
277
+ parent.name
278
+ else
279
+ trace_rule level, "(#{task_name} => #{source} ... FAIL)"
280
+ return nil
281
+ end
282
+ }
283
+ task = FileTask.define_task(task_name, { args => prereqs }, &block)
284
+ task.sources = prereqs
285
+ task
286
+ end
287
+
288
+ # Make a list of sources from the list of file name extensions /
289
+ # translation procs.
290
+ def make_sources(task_name, task_pattern, extensions)
291
+ result = extensions.map { |ext|
292
+ case ext
293
+ when /%/
294
+ task_name.pathmap(ext)
295
+ when %r{/}
296
+ ext
297
+ when /^\./
298
+ source = task_name.sub(task_pattern, ext)
299
+ source == ext ? task_name.ext(ext) : source
300
+ when String
301
+ ext
302
+ when Proc, Method
303
+ if ext.arity == 1
304
+ ext.call(task_name)
305
+ else
306
+ ext.call
307
+ end
308
+ else
309
+ fail "Don't know how to handle rule dependent: #{ext.inspect}"
310
+ end
311
+ }
312
+ result.flatten
313
+ end
314
+
315
+ # Return the current description, clearing it in the process.
316
+ def get_description(task)
317
+ desc = @last_description
318
+ @last_description = nil
319
+ desc
320
+ end
321
+
322
+ class << self
323
+ attr_accessor :record_task_metadata # :nodoc:
324
+ TaskManager.record_task_metadata = false
325
+ end
326
+ end
327
+
328
+ end
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+ require "rake"
3
+
4
+ module Rake
5
+
6
+ # Base class for Task Libraries.
7
+ class TaskLib
8
+ include Cloneable
9
+ include Rake::DSL
10
+ end
11
+
12
+ end