rake 0.4.11 → 13.4.2

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 (85) hide show
  1. checksums.yaml +7 -0
  2. data/History.rdoc +2454 -0
  3. data/MIT-LICENSE +1 -1
  4. data/README.rdoc +155 -0
  5. data/doc/command_line_usage.rdoc +171 -0
  6. data/doc/glossary.rdoc +40 -49
  7. data/doc/jamis.rb +135 -107
  8. data/doc/proto_rake.rdoc +22 -22
  9. data/doc/rake.1 +156 -0
  10. data/doc/rakefile.rdoc +428 -27
  11. data/doc/rational.rdoc +6 -6
  12. data/exe/rake +27 -0
  13. data/lib/rake/application.rb +847 -0
  14. data/lib/rake/backtrace.rb +25 -0
  15. data/lib/rake/clean.rb +57 -10
  16. data/lib/rake/cloneable.rb +17 -0
  17. data/lib/rake/cpu_counter.rb +122 -0
  18. data/lib/rake/default_loader.rb +15 -0
  19. data/lib/rake/dsl_definition.rb +196 -0
  20. data/lib/rake/early_time.rb +22 -0
  21. data/lib/rake/ext/core.rb +26 -0
  22. data/lib/rake/ext/string.rb +176 -0
  23. data/lib/rake/file_creation_task.rb +25 -0
  24. data/lib/rake/file_list.rb +435 -0
  25. data/lib/rake/file_task.rb +58 -0
  26. data/lib/rake/file_utils.rb +137 -0
  27. data/lib/rake/file_utils_ext.rb +135 -0
  28. data/lib/rake/invocation_chain.rb +57 -0
  29. data/lib/rake/invocation_exception_mixin.rb +17 -0
  30. data/lib/rake/late_time.rb +18 -0
  31. data/lib/rake/linked_list.rb +112 -0
  32. data/lib/rake/loaders/makefile.rb +54 -0
  33. data/lib/rake/multi_task.rb +14 -0
  34. data/lib/rake/name_space.rb +38 -0
  35. data/lib/rake/options.rb +31 -0
  36. data/lib/rake/packagetask.rb +124 -54
  37. data/lib/rake/phony.rb +16 -0
  38. data/lib/rake/private_reader.rb +21 -0
  39. data/lib/rake/promise.rb +100 -0
  40. data/lib/rake/pseudo_status.rb +30 -0
  41. data/lib/rake/rake_module.rb +67 -0
  42. data/lib/rake/rake_test_loader.rb +27 -0
  43. data/lib/rake/rule_recursion_overflow_error.rb +20 -0
  44. data/lib/rake/scope.rb +43 -0
  45. data/lib/rake/task.rb +434 -0
  46. data/lib/rake/task_argument_error.rb +8 -0
  47. data/lib/rake/task_arguments.rb +113 -0
  48. data/lib/rake/task_manager.rb +333 -0
  49. data/lib/rake/tasklib.rb +4 -16
  50. data/lib/rake/testtask.rb +110 -36
  51. data/lib/rake/thread_history_display.rb +49 -0
  52. data/lib/rake/thread_pool.rb +157 -0
  53. data/lib/rake/trace_output.rb +23 -0
  54. data/lib/rake/version.rb +10 -0
  55. data/lib/rake/win32.rb +17 -0
  56. data/lib/rake.rb +64 -992
  57. data/rake.gemspec +102 -0
  58. metadata +117 -89
  59. data/CHANGES +0 -153
  60. data/README +0 -209
  61. data/Rakefile +0 -215
  62. data/TODO +0 -19
  63. data/bin/rake +0 -8
  64. data/install.rb +0 -88
  65. data/lib/rake/contrib/compositepublisher.rb +0 -24
  66. data/lib/rake/contrib/ftptools.rb +0 -139
  67. data/lib/rake/contrib/publisher.rb +0 -75
  68. data/lib/rake/contrib/rubyforgepublisher.rb +0 -18
  69. data/lib/rake/contrib/sshpublisher.rb +0 -47
  70. data/lib/rake/contrib/sys.rb +0 -207
  71. data/lib/rake/gempackagetask.rb +0 -98
  72. data/lib/rake/rdoctask.rb +0 -128
  73. data/lib/rake/runtest.rb +0 -23
  74. data/test/contrib/testsys.rb +0 -47
  75. data/test/data/rbext/rakefile.rb +0 -3
  76. data/test/filecreation.rb +0 -26
  77. data/test/functional.rb +0 -82
  78. data/test/shellcommand.rb +0 -3
  79. data/test/testclean.rb +0 -13
  80. data/test/testfilelist.rb +0 -255
  81. data/test/testfileutils.rb +0 -83
  82. data/test/testftp.rb +0 -55
  83. data/test/testpackagetask.rb +0 -81
  84. data/test/testtasks.rb +0 -371
  85. data/test/testtesttask.rb +0 -71
@@ -0,0 +1,333 @@
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)
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 tuple of
87
+ # [task_name, arg_name_list, prerequisites, order_only_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, order_only: [:e]
122
+ # task :t => [:d]
123
+ # task :t => [:d], order_only: [:e]
124
+ # task :t, [a] => [:d]
125
+ # task :t, [a] => [:d], order_only: [:e]
126
+ #
127
+ def resolve_args_with_dependencies(args, hash) # :nodoc:
128
+ fail "Task Argument Error" if
129
+ hash.size != 1 &&
130
+ (hash.size != 2 || !hash.key?(:order_only))
131
+ order_only = hash.delete(:order_only)
132
+ key, value = hash.map { |k, v| [k, v] }.first
133
+ if args.empty?
134
+ task_name = key
135
+ arg_names = []
136
+ deps = value || []
137
+ else
138
+ task_name = args.shift
139
+ arg_names = key || args.shift|| []
140
+ deps = value || []
141
+ end
142
+ deps = [deps] unless deps.respond_to?(:to_ary)
143
+ [task_name, arg_names, deps, order_only]
144
+ end
145
+ private :resolve_args_with_dependencies
146
+
147
+ # If a rule can be found that matches the task name, enhance the
148
+ # task with the prerequisites and actions from the rule. Set the
149
+ # source attribute of the task appropriately for the rule. Return
150
+ # the enhanced task or nil of no rule was found.
151
+ def enhance_with_matching_rule(task_name, level=0)
152
+ fail Rake::RuleRecursionOverflowError,
153
+ "Rule Recursion Too Deep" if level >= 16
154
+ @rules.each do |pattern, args, extensions, order_only, block|
155
+ if pattern && pattern.match(task_name)
156
+ task = attempt_rule(task_name, pattern, args, extensions, block, level)
157
+ task | order_only unless order_only.nil?
158
+ return task if task
159
+ end
160
+ end
161
+ nil
162
+ rescue Rake::RuleRecursionOverflowError => ex
163
+ ex.add_target(task_name)
164
+ fail ex
165
+ end
166
+
167
+ # List of all defined tasks in this application.
168
+ def tasks
169
+ @tasks.values.sort_by { |t| t.name }
170
+ end
171
+
172
+ # List of all the tasks defined in the given scope (and its
173
+ # sub-scopes).
174
+ def tasks_in_scope(scope)
175
+ prefix = scope.path
176
+ tasks.select { |t|
177
+ /^#{prefix}:/ =~ t.name
178
+ }
179
+ end
180
+
181
+ # Clear all tasks in this application.
182
+ def clear
183
+ @tasks.clear
184
+ @rules.clear
185
+ end
186
+
187
+ # Lookup a task, using scope and the scope hints in the task name.
188
+ # This method performs straight lookups without trying to
189
+ # synthesize file tasks or rules. Special scope names (e.g. '^')
190
+ # are recognized. If no scope argument is supplied, use the
191
+ # current scope. Return nil if the task cannot be found.
192
+ def lookup(task_name, initial_scope=nil)
193
+ initial_scope ||= @scope
194
+ task_name = task_name.to_s
195
+ if task_name =~ /^rake:/
196
+ scopes = Scope.make
197
+ task_name = task_name.sub(/^rake:/, "")
198
+ elsif task_name =~ /^(\^+)/
199
+ scopes = initial_scope.trim($1.size)
200
+ task_name = task_name.sub(/^(\^+)/, "")
201
+ else
202
+ scopes = initial_scope
203
+ end
204
+ lookup_in_scope(task_name, scopes)
205
+ end
206
+
207
+ # Lookup the task name
208
+ def lookup_in_scope(name, scope)
209
+ loop do
210
+ tn = scope.path_with_task_name(name)
211
+ task = @tasks[tn]
212
+ return task if task
213
+ break if scope.empty?
214
+ scope = scope.tail
215
+ end
216
+ nil
217
+ end
218
+ private :lookup_in_scope
219
+
220
+ # Return the list of scope names currently active in the task
221
+ # manager.
222
+ def current_scope
223
+ @scope
224
+ end
225
+
226
+ # Evaluate the block in a nested namespace named +name+. Create
227
+ # an anonymous namespace if +name+ is nil.
228
+ def in_namespace(name)
229
+ name ||= generate_name
230
+ @scope = Scope.new(name, @scope)
231
+ ns = NameSpace.new(self, @scope)
232
+ yield(ns)
233
+ ns
234
+ ensure
235
+ @scope = @scope.tail
236
+ end
237
+
238
+ private
239
+
240
+ # Add a location to the locations field of the given task.
241
+ def add_location(task)
242
+ loc = find_location
243
+ task.locations << loc if loc
244
+ task
245
+ end
246
+
247
+ # Find the location that called into the dsl layer.
248
+ def find_location
249
+ locations = caller
250
+ i = 0
251
+ while locations[i]
252
+ return locations[i + 1] if locations[i] =~ /rake\/dsl_definition.rb/
253
+ i += 1
254
+ end
255
+ nil
256
+ end
257
+
258
+ # Generate an anonymous namespace name.
259
+ def generate_name
260
+ @seed ||= 0
261
+ @seed += 1
262
+ "_anon_#{@seed}"
263
+ end
264
+
265
+ def trace_rule(level, message) # :nodoc:
266
+ options.trace_output.puts "#{" " * level}#{message}" if
267
+ Rake.application.options.trace_rules
268
+ end
269
+
270
+ # Attempt to create a rule given the list of prerequisites.
271
+ def attempt_rule(task_name, task_pattern, args, extensions, block, level)
272
+ sources = make_sources(task_name, task_pattern, extensions)
273
+ prereqs = sources.map { |source|
274
+ trace_rule level, "Attempting Rule #{task_name} => #{source}"
275
+ if File.exist?(source) || Rake::Task.task_defined?(source)
276
+ trace_rule level, "(#{task_name} => #{source} ... EXIST)"
277
+ source
278
+ elsif parent = enhance_with_matching_rule(source, level + 1)
279
+ trace_rule level, "(#{task_name} => #{source} ... ENHANCE)"
280
+ parent.name
281
+ else
282
+ trace_rule level, "(#{task_name} => #{source} ... FAIL)"
283
+ return nil
284
+ end
285
+ }
286
+ task = FileTask.define_task(task_name, { args => prereqs }, &block)
287
+ task.sources = prereqs
288
+ task
289
+ end
290
+
291
+ # Make a list of sources from the list of file name extensions /
292
+ # translation procs.
293
+ def make_sources(task_name, task_pattern, extensions)
294
+ result = extensions.map { |ext|
295
+ case ext
296
+ when /%/
297
+ task_name.pathmap(ext)
298
+ when %r{/}
299
+ ext
300
+ when /^\./
301
+ source = task_name.sub(task_pattern, ext)
302
+ source == ext ? task_name.ext(ext) : source
303
+ when String, Symbol
304
+ ext.to_s
305
+ when Pathname
306
+ Rake.from_pathname(ext)
307
+ when Proc, Method
308
+ if ext.arity == 1
309
+ ext.call(task_name)
310
+ else
311
+ ext.call
312
+ end
313
+ else
314
+ fail "Don't know how to handle rule dependent: #{ext.inspect}"
315
+ end
316
+ }
317
+ result.flatten
318
+ end
319
+
320
+ # Return the current description, clearing it in the process.
321
+ def get_description
322
+ desc = @last_description
323
+ @last_description = nil
324
+ desc
325
+ end
326
+
327
+ class << self
328
+ attr_accessor :record_task_metadata # :nodoc:
329
+ TaskManager.record_task_metadata = false
330
+ end
331
+ end
332
+
333
+ end
data/lib/rake/tasklib.rb CHANGED
@@ -1,24 +1,12 @@
1
- #!/usr/bin/env ruby
1
+ # frozen_string_literal: true
2
+ require_relative "../rake"
2
3
 
3
4
  module Rake
4
5
 
5
6
  # Base class for Task Libraries.
6
7
  class TaskLib
7
-
8
- # Make a copy of a task.
9
- def clone
10
- sibling = self.class.new
11
- instance_variables.each do |ivar|
12
- value = self.instance_variable_get(ivar)
13
- sibling.instance_variable_set(ivar, value.dup) if value
14
- end
15
- sibling
16
- end
17
-
18
- # Make a symbol by pasting two strings together.
19
- def paste(a,b)
20
- (a.to_s + b.to_s).intern
21
- end
8
+ include Cloneable
9
+ include Rake::DSL
22
10
  end
23
11
 
24
12
  end
data/lib/rake/testtask.rb CHANGED
@@ -1,16 +1,14 @@
1
- #!/usr/bin/env ruby
2
-
3
- # Define a task library for running unit tests.
4
-
5
- require 'rake'
6
- require 'rake/tasklib'
1
+ # frozen_string_literal: true
2
+ require_relative "../rake"
3
+ require_relative "tasklib"
7
4
 
8
5
  module Rake
9
6
 
10
7
  # Create a task that runs a set of tests.
11
8
  #
12
9
  # Example:
13
- #
10
+ # require "rake/testtask"
11
+ #
14
12
  # Rake::TestTask.new do |t|
15
13
  # t.libs << "test"
16
14
  # t.test_files = FileList['test/test*.rb']
@@ -36,24 +34,46 @@ module Rake
36
34
  #
37
35
  class TestTask < TaskLib
38
36
 
39
- SEP = ''
40
-
41
37
  # Name of test task. (default is :test)
42
38
  attr_accessor :name
43
39
 
44
- # List of directories to added to $LOAD_PATH before running the
40
+ # List of directories added to $LOAD_PATH before running the
45
41
  # tests. (default is 'lib')
46
42
  attr_accessor :libs
47
43
 
48
44
  # True if verbose test output desired. (default is false)
49
45
  attr_accessor :verbose
50
46
 
51
- # Test options passed to the test suite. (default is NONE)
47
+ # Test options passed to the test suite. An explicit
48
+ # TESTOPTS=opts on the command line will override this. (default
49
+ # is NONE)
52
50
  attr_accessor :options
53
51
 
52
+ # Request that the tests be run with the warning flag set.
53
+ # E.g. warning=true implies "ruby -w" used to run the tests.
54
+ # (default is true)
55
+ attr_accessor :warning
56
+
54
57
  # Glob pattern to match test files. (default is 'test/test*.rb')
55
58
  attr_accessor :pattern
56
59
 
60
+ # Style of test loader to use. Options are:
61
+ #
62
+ # * :rake -- Rake provided test loading script (default).
63
+ # * :testrb -- Ruby provided test loading script.
64
+ # * :direct -- Load tests using command line loader.
65
+ #
66
+ attr_accessor :loader
67
+
68
+ # Array of command line options to pass to ruby when running test loader.
69
+ attr_accessor :ruby_opts
70
+
71
+ # Description of the test task. (default is 'Run tests')
72
+ attr_accessor :description
73
+
74
+ # Task prerequisites.
75
+ attr_accessor :deps
76
+
57
77
  # Explicitly define the list of test files to be included in a
58
78
  # test. +list+ is expected to be an array of file names (a
59
79
  # FileList is acceptable). If both +pattern+ and +test_files+ are
@@ -67,52 +87,106 @@ module Rake
67
87
  @name = name
68
88
  @libs = ["lib"]
69
89
  @pattern = nil
90
+ @options = nil
70
91
  @test_files = nil
71
92
  @verbose = false
93
+ @warning = true
94
+ @loader = :rake
95
+ @ruby_opts = []
96
+ @description = "Run tests" + (@name == :test ? "" : " for #{@name}")
97
+ @deps = []
98
+ if @name.is_a?(Hash)
99
+ @deps = @name.values.first
100
+ @name = @name.keys.first
101
+ end
72
102
  yield self if block_given?
73
- @pattern = 'test/test*.rb' if @pattern.nil? && @test_files.nil?
103
+ @pattern = "test/test*.rb" if @pattern.nil? && @test_files.nil?
74
104
  define
75
105
  end
76
106
 
77
107
  # Create the tasks defined by this task lib.
78
108
  def define
79
- lib_path = @libs.join(File::PATH_SEPARATOR)
80
- desc "Run tests" + (@name==:test ? "" : " for #{@name}")
81
- task @name do
82
- RakeFileUtils.verbose(@verbose) do
83
- ruby %{-I#{lib_path} -e0 #{SEP}#{required_files}#{option_list}}
84
- end
109
+ desc @description
110
+ task @name => Array(deps) do
111
+ effective_verbose = @verbose || FileUtilsExt.verbose_flag == true
112
+ FileUtilsExt.verbose(effective_verbose) do
113
+ args =
114
+ "#{ruby_opts_string} #{run_code} " +
115
+ "#{file_list_string} #{option_list(verbose: effective_verbose)}"
116
+ ruby args do |ok, status|
117
+ if !ok && status.respond_to?(:signaled?) && status.signaled?
118
+ raise SignalException.new(status.termsig)
119
+ elsif !ok
120
+ status = "Command failed with status (#{status.exitstatus})"
121
+ details = ": [ruby #{args}]"
122
+ message =
123
+ if Rake.application.options.trace or @verbose
124
+ status + details
125
+ else
126
+ status
127
+ end
128
+
129
+ fail message
130
+ end
131
+ end
132
+ end
85
133
  end
86
134
  self
87
135
  end
88
136
 
89
- def required_files # :nodoc:
90
- file_list.gsub(/^(.*)\.rb$/, ' -r\1').join(" #{SEP}")
91
- end
92
-
93
- def option_list # :nodoc:
94
- if get_options
95
- testoptions = " #{SEP} -- #{get_options}"
96
- else
97
- testoptions = ''
137
+ def option_list(verbose: @verbose) # :nodoc:
138
+ opts = ENV["TESTOPTS"] ||
139
+ ENV["TESTOPT"] ||
140
+ ENV["TEST_OPTS"] ||
141
+ ENV["TEST_OPT"] ||
142
+ @options ||
143
+ ""
144
+ if verbose && !opts.split.include?("-v")
145
+ opts = opts.empty? ? "-v" : "#{opts} -v"
98
146
  end
147
+ opts
148
+ end
149
+
150
+ def ruby_opts_string # :nodoc:
151
+ opts = @ruby_opts.dup
152
+ opts.unshift("-I\"#{lib_path}\"") unless @libs.empty?
153
+ opts.unshift("-w") if @warning
154
+ opts.join(" ")
99
155
  end
100
156
 
101
- def get_options # :nodoc:
102
- ENV['TESTOPTS'] || @options
157
+ def lib_path # :nodoc:
158
+ @libs.join(File::PATH_SEPARATOR)
159
+ end
160
+
161
+ def file_list_string # :nodoc:
162
+ file_list.map { |fn| "\"#{fn}\"" }.join(" ")
103
163
  end
104
164
 
105
165
  def file_list # :nodoc:
106
- if ENV['TEST']
107
- FileList[ ENV['TEST'] ]
166
+ if ENV["TEST"]
167
+ FileList[ENV["TEST"].split(",")]
108
168
  else
109
- result = []
110
- result += @test_files.to_a if @test_files
111
- result += FileList[ @pattern ].to_a if @pattern
112
- FileList[result]
169
+ result = []
170
+ result += @test_files.to_a if @test_files
171
+ result += FileList[@pattern].to_a if @pattern
172
+ result
173
+ end
174
+ end
175
+
176
+ def ruby_version # :nodoc:
177
+ RUBY_VERSION
178
+ end
179
+
180
+ def run_code # :nodoc:
181
+ case @loader
182
+ when :direct
183
+ "-e \"ARGV.each{|f| require f}\""
184
+ when :testrb
185
+ "-S testrb"
186
+ when :rake
187
+ "#{__dir__}/rake_test_loader.rb"
113
188
  end
114
189
  end
115
190
 
116
191
  end
117
192
  end
118
-
@@ -0,0 +1,49 @@
1
+ # frozen_string_literal: true
2
+ require_relative "private_reader"
3
+
4
+ module Rake
5
+
6
+ class ThreadHistoryDisplay # :nodoc: all
7
+ include Rake::PrivateReader
8
+
9
+ private_reader :stats, :items, :threads
10
+
11
+ def initialize(stats)
12
+ @stats = stats
13
+ @items = { _seq_: 1 }
14
+ @threads = { _seq_: "A" }
15
+ end
16
+
17
+ def show
18
+ puts "Job History:"
19
+ stats.each do |stat|
20
+ stat[:data] ||= {}
21
+ rename(stat, :thread, threads)
22
+ rename(stat[:data], :item_id, items)
23
+ rename(stat[:data], :new_thread, threads)
24
+ rename(stat[:data], :deleted_thread, threads)
25
+ printf("%8d %2s %-20s %s\n",
26
+ (stat[:time] * 1_000_000).round,
27
+ stat[:thread],
28
+ stat[:event],
29
+ stat[:data].map do |k, v| "#{k}:#{v}" end.join(" "))
30
+ end
31
+ end
32
+
33
+ private
34
+
35
+ def rename(hash, key, renames)
36
+ if hash && hash[key]
37
+ original = hash[key]
38
+ value = renames[original]
39
+ unless value
40
+ value = renames[:_seq_]
41
+ renames[:_seq_] = renames[:_seq_].succ
42
+ renames[original] = value
43
+ end
44
+ hash[key] = value
45
+ end
46
+ end
47
+ end
48
+
49
+ end