drake 0.8.7.0.2.4 → 0.9.0.0.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (132) hide show
  1. data/.gemtest +0 -0
  2. data/CHANGES +77 -9
  3. data/{CHANGES.drake → CHANGES-drake} +6 -2
  4. data/MIT-LICENSE +2 -0
  5. data/{README → README.rdoc} +30 -18
  6. data/Rakefile +144 -130
  7. data/Rakefile-drake +67 -0
  8. data/TODO +1 -1
  9. data/bin/drake +2 -0
  10. data/doc/command_line_usage.rdoc +25 -11
  11. data/doc/glossary.rdoc +2 -2
  12. data/doc/jamis.rb +2 -2
  13. data/doc/parallel.rdoc +37 -29
  14. data/doc/proto_rake.rdoc +22 -22
  15. data/doc/rake.1.gz +0 -0
  16. data/doc/rakefile.rdoc +56 -33
  17. data/doc/rational.rdoc +6 -6
  18. data/doc/release_notes/rake-0.4.15.rdoc +1 -1
  19. data/doc/release_notes/rake-0.5.0.rdoc +1 -1
  20. data/doc/release_notes/rake-0.7.0.rdoc +1 -1
  21. data/doc/release_notes/rake-0.7.2.rdoc +3 -3
  22. data/doc/release_notes/rake-0.7.3.rdoc +2 -2
  23. data/doc/release_notes/rake-0.8.0.rdoc +1 -1
  24. data/doc/release_notes/rake-0.8.2.rdoc +3 -3
  25. data/doc/release_notes/rake-0.8.3.rdoc +2 -2
  26. data/doc/release_notes/rake-0.8.4.rdoc +1 -1
  27. data/doc/release_notes/rake-0.8.5.rdoc +1 -1
  28. data/doc/release_notes/rake-0.8.6.rdoc +1 -1
  29. data/doc/release_notes/rake-0.8.7.rdoc +1 -1
  30. data/doc/release_notes/rake-0.9.0.rdoc +112 -0
  31. data/install.rb +14 -12
  32. data/lib/rake.rb +31 -2527
  33. data/lib/rake/alt_system.rb +7 -6
  34. data/lib/rake/application.rb +626 -0
  35. data/lib/rake/classic_namespace.rb +1 -0
  36. data/lib/rake/clean.rb +2 -4
  37. data/lib/rake/cloneable.rb +25 -0
  38. data/lib/rake/contrib/compositepublisher.rb +2 -5
  39. data/lib/rake/contrib/ftptools.rb +5 -8
  40. data/lib/rake/contrib/publisher.rb +2 -8
  41. data/lib/rake/contrib/rubyforgepublisher.rb +2 -4
  42. data/lib/rake/contrib/sshpublisher.rb +4 -6
  43. data/lib/rake/contrib/sys.rb +7 -25
  44. data/lib/rake/default_loader.rb +10 -0
  45. data/lib/rake/dsl.rb +2 -0
  46. data/lib/rake/dsl_definition.rb +143 -0
  47. data/lib/rake/early_time.rb +18 -0
  48. data/lib/rake/ext/core.rb +27 -0
  49. data/lib/rake/ext/module.rb +39 -0
  50. data/lib/rake/ext/string.rb +167 -0
  51. data/lib/rake/ext/time.rb +14 -0
  52. data/lib/rake/file_creation_task.rb +24 -0
  53. data/lib/rake/file_list.rb +403 -0
  54. data/lib/rake/file_task.rb +47 -0
  55. data/lib/rake/file_utils.rb +112 -0
  56. data/lib/rake/file_utils_ext.rb +142 -0
  57. data/lib/rake/gempackagetask.rb +6 -90
  58. data/lib/rake/invocation_chain.rb +51 -0
  59. data/lib/rake/invocation_exception_mixin.rb +16 -0
  60. data/lib/rake/loaders/makefile.rb +13 -15
  61. data/lib/rake/multi_task.rb +16 -0
  62. data/lib/rake/name_space.rb +25 -0
  63. data/lib/rake/packagetask.rb +13 -12
  64. data/lib/rake/parallel.rb +17 -28
  65. data/lib/rake/pathmap.rb +1 -0
  66. data/lib/rake/pseudo_status.rb +24 -0
  67. data/lib/rake/rake_module.rb +29 -0
  68. data/lib/rake/rake_test_loader.rb +10 -2
  69. data/lib/rake/rdoctask.rb +211 -190
  70. data/lib/rake/ruby182_test_unit_fix.rb +9 -7
  71. data/lib/rake/rule_recursion_overflow_error.rb +20 -0
  72. data/lib/rake/runtest.rb +4 -6
  73. data/lib/rake/task.rb +351 -0
  74. data/lib/rake/task_argument_error.rb +7 -0
  75. data/lib/rake/task_arguments.rb +74 -0
  76. data/lib/rake/task_manager.rb +307 -0
  77. data/lib/rake/tasklib.rb +1 -2
  78. data/lib/rake/testtask.rb +57 -27
  79. data/lib/rake/version.rb +13 -0
  80. data/lib/rake/win32.rb +4 -4
  81. data/test/contrib/test_sys.rb +8 -31
  82. data/test/data/access/Rakefile +33 -0
  83. data/test/data/comments/Rakefile +18 -0
  84. data/test/data/default/Rakefile +1 -1
  85. data/test/data/deprecated_import/Rakefile +1 -0
  86. data/test/data/dryrun/Rakefile +1 -1
  87. data/test/data/file_creation_task/Rakefile +1 -1
  88. data/test/data/namespace/Rakefile +9 -0
  89. data/test/data/rakelib/test1.rb +1 -0
  90. data/test/data/verbose/Rakefile +34 -0
  91. data/test/{filecreation.rb → file_creation.rb} +11 -7
  92. data/test/functional/functional_test.rb +25 -0
  93. data/test/{session_functional.rb → functional/session_based_tests.rb} +141 -23
  94. data/test/in_environment.rb +7 -5
  95. data/test/{test_application.rb → lib/application_test.rb} +331 -143
  96. data/test/{test_clean.rb → lib/clean_test.rb} +1 -0
  97. data/test/{test_definitions.rb → lib/definitions_test.rb} +4 -4
  98. data/test/lib/dsl_test.rb +52 -0
  99. data/test/{test_earlytime.rb → lib/earlytime_test.rb} +1 -2
  100. data/test/{test_extension.rb → lib/extension_test.rb} +2 -2
  101. data/test/{test_file_creation_task.rb → lib/file_creation_task_test.rb} +1 -1
  102. data/test/{test_file_task.rb → lib/file_task_test.rb} +9 -5
  103. data/test/{test_filelist.rb → lib/filelist_test.rb} +38 -24
  104. data/test/{test_fileutils.rb → lib/fileutils_test.rb} +27 -22
  105. data/test/{test_ftp.rb → lib/ftp_test.rb} +0 -0
  106. data/test/{test_invocation_chain.rb → lib/invocation_chain_test.rb} +0 -0
  107. data/test/{test_makefile_loader.rb → lib/makefile_loader_test.rb} +0 -0
  108. data/test/{test_multitask.rb → lib/multitask_test.rb} +3 -2
  109. data/test/{test_namespace.rb → lib/namespace_test.rb} +0 -0
  110. data/test/lib/package_task_test.rb +82 -0
  111. data/test/{test_parallel.rb → lib/parallel_test.rb} +5 -5
  112. data/test/{test_pathmap.rb → lib/pathmap_test.rb} +3 -2
  113. data/test/{test_pseudo_status.rb → lib/pseudo_status_test.rb} +0 -0
  114. data/test/{test_rake.rb → lib/rake_test.rb} +1 -1
  115. data/test/{test_rdoc_task.rb → lib/rdoc_task_test.rb} +19 -23
  116. data/test/{test_require.rb → lib/require_test.rb} +8 -2
  117. data/test/{test_rules.rb → lib/rules_test.rb} +4 -5
  118. data/test/{test_task_arguments.rb → lib/task_arguments_test.rb} +5 -5
  119. data/test/{test_task_manager.rb → lib/task_manager_test.rb} +15 -5
  120. data/test/{test_tasks.rb → lib/task_test.rb} +91 -28
  121. data/test/{test_tasklib.rb → lib/tasklib_test.rb} +0 -0
  122. data/test/{test_test_task.rb → lib/test_task_test.rb} +3 -3
  123. data/test/lib/testtask_test.rb +49 -0
  124. data/test/{test_top_level_functions.rb → lib/top_level_functions_test.rb} +5 -3
  125. data/test/{test_win32.rb → lib/win32_test.rb} +19 -0
  126. data/test/rake_test_setup.rb +6 -10
  127. data/test/ruby_version_test.rb +3 -0
  128. data/test/test_helper.rb +19 -0
  129. metadata +108 -66
  130. data/Rakefile.drake +0 -73
  131. data/test/functional.rb +0 -15
  132. data/test/test_package_task.rb +0 -118
@@ -1,6 +1,6 @@
1
1
  #
2
2
  # Copyright (c) 2008 James M. Lawrence
3
- #
3
+ #
4
4
  # Permission is hereby granted, free of charge, to any person
5
5
  # obtaining a copy of this software and associated documentation files
6
6
  # (the "Software"), to deal in the Software without restriction,
@@ -8,10 +8,10 @@
8
8
  # publish, distribute, sublicense, and/or sell copies of the Software,
9
9
  # and to permit persons to whom the Software is furnished to do so,
10
10
  # subject to the following conditions:
11
- #
11
+ #
12
12
  # The above copyright notice and this permission notice shall be
13
13
  # included in all copies or substantial portions of the Software.
14
- #
14
+ #
15
15
  # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16
16
  # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17
17
  # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
@@ -27,9 +27,10 @@ require 'rbconfig'
27
27
  #
28
28
  # Alternate implementations of system() and backticks `` on Windows
29
29
  # for ruby-1.8 and earlier.
30
- #
30
+ #
31
31
  module Rake::AltSystem
32
- WINDOWS = Config::CONFIG["host_os"] =~ %r!(msdos|mswin|djgpp|mingw)!
32
+ WINDOWS = RbConfig::CONFIG["host_os"] =~
33
+ %r!(msdos|mswin|djgpp|mingw|[Ww]indows)!
33
34
 
34
35
  class << self
35
36
  def define_module_function(name, &block)
@@ -37,7 +38,7 @@ module Rake::AltSystem
37
38
  module_function(name)
38
39
  end
39
40
  end
40
-
41
+
41
42
  if WINDOWS and RUBY_VERSION < "1.9.0"
42
43
  RUNNABLE_EXTS = %w[com exe bat cmd]
43
44
  RUNNABLE_PATTERN = %r!\.(#{RUNNABLE_EXTS.join('|')})\Z!i
@@ -0,0 +1,626 @@
1
+ require 'shellwords'
2
+ require 'optparse'
3
+
4
+ require 'rake/task_manager'
5
+ require 'rake/win32'
6
+
7
+ module Rake
8
+
9
+ ######################################################################
10
+ # Rake main application object. When invoking +rake+ from the
11
+ # command line, a Rake::Application object is created and run.
12
+ #
13
+ class Application
14
+ include TaskManager
15
+
16
+ # The name of the application (typically 'rake')
17
+ attr_reader :name
18
+
19
+ # The original directory where rake was invoked.
20
+ attr_reader :original_dir
21
+
22
+ # Name of the actual rakefile used.
23
+ attr_reader :rakefile
24
+
25
+ # List of the top level task names (task names from the command line).
26
+ attr_reader :top_level_tasks
27
+
28
+ DEFAULT_RAKEFILES = ['rakefile', 'Rakefile', 'rakefile.rb', 'Rakefile.rb'].freeze
29
+
30
+ # Initialize a Rake::Application object.
31
+ def initialize
32
+ super
33
+ @name = 'rake'
34
+ @rakefiles = DEFAULT_RAKEFILES.dup
35
+ @rakefile = nil
36
+ @pending_imports = []
37
+ @imported = []
38
+ @loaders = {}
39
+ @default_loader = Rake::DefaultLoader.new
40
+ @original_dir = Dir.pwd
41
+ @top_level_tasks = []
42
+ add_loader('rb', DefaultLoader.new)
43
+ add_loader('rf', DefaultLoader.new)
44
+ add_loader('rake', DefaultLoader.new)
45
+ @tty_output = STDOUT.tty?
46
+ end
47
+
48
+ # Run the Rake application. The run method performs the following
49
+ # three steps:
50
+ #
51
+ # * Initialize the command line options (+init+).
52
+ # * Define the tasks (+load_rakefile+).
53
+ # * Run the top level tasks (+run_tasks+).
54
+ #
55
+ # If you wish to build a custom rake command, you should call
56
+ # +init+ on your application. Then define any tasks. Finally,
57
+ # call +top_level+ to run your top level tasks.
58
+ def run
59
+ standard_exception_handling do
60
+ init
61
+ load_rakefile
62
+ top_level
63
+ end
64
+ end
65
+
66
+ # Initialize the command line parameters and app name.
67
+ def init(app_name='rake')
68
+ standard_exception_handling do
69
+ @name = app_name
70
+ handle_options
71
+ collect_tasks
72
+ end
73
+ end
74
+
75
+ # Find the rakefile and then load it and any pending imports.
76
+ def load_rakefile
77
+ standard_exception_handling do
78
+ raw_load_rakefile
79
+ end
80
+ end
81
+
82
+ # Run the top level tasks of a Rake application.
83
+ def top_level
84
+ standard_exception_handling do
85
+ if options.show_tasks
86
+ display_tasks_and_comments
87
+ elsif options.show_prereqs
88
+ display_prerequisites
89
+ else
90
+ top_level_tasks.each { |task_name| invoke_task(task_name) }
91
+ end
92
+ end
93
+ end
94
+
95
+ # Add a loader to handle imported files ending in the extension
96
+ # +ext+.
97
+ def add_loader(ext, loader)
98
+ ext = ".#{ext}" unless ext =~ /^\./
99
+ @loaders[ext] = loader
100
+ end
101
+
102
+ # Application options from the command line
103
+ def options
104
+ @options ||= Options.new
105
+ end
106
+
107
+ # private ----------------------------------------------------------------
108
+
109
+ def invoke_task(task_string)
110
+ name, args = parse_task_string(task_string)
111
+ t = self[name]
112
+ t.invoke(*args)
113
+ end
114
+
115
+ def parse_task_string(string)
116
+ if string =~ /^([^\[]+)(\[(.*)\])$/
117
+ name = $1
118
+ args = $3.split(/\s*,\s*/)
119
+ else
120
+ name = string
121
+ args = []
122
+ end
123
+ [name, args]
124
+ end
125
+
126
+ # Provide standard exception handling for the given block.
127
+ def standard_exception_handling
128
+ begin
129
+ yield
130
+ rescue SystemExit => ex
131
+ # Exit silently with current status
132
+ raise
133
+ rescue OptionParser::InvalidOption => ex
134
+ $stderr.puts ex.message
135
+ exit(false)
136
+ rescue Exception => ex
137
+ # Exit with error message
138
+ display_error_message(ex)
139
+ exit(false)
140
+ end
141
+ end
142
+
143
+ # Display the error message that caused the exception.
144
+ def display_error_message(ex)
145
+ $stderr.puts "#{name} aborted!"
146
+ $stderr.puts ex.message
147
+ if options.trace
148
+ $stderr.puts ex.backtrace.join("\n")
149
+ else
150
+ $stderr.puts rakefile_location(ex.backtrace)
151
+ end
152
+ $stderr.puts "Tasks: #{ex.chain}" if has_chain?(ex)
153
+ $stderr.puts "(See full trace by running task with --trace)" unless options.trace
154
+ end
155
+
156
+ # Warn about deprecated usage.
157
+ #
158
+ # Example:
159
+ # Rake.application.deprecate("import", "Rake.import", caller.first)
160
+ #
161
+ def deprecate(old_usage, new_usage, call_site)
162
+ return if options.ignore_deprecate
163
+ $stderr.puts "WARNING: '#{old_usage}' is deprecated. " +
164
+ "Please use '#{new_usage}' instead.\n" +
165
+ " at #{call_site}"
166
+ end
167
+
168
+ # Does the exception have a task invocation chain?
169
+ def has_chain?(exception)
170
+ exception.respond_to?(:chain) && exception.chain
171
+ end
172
+ private :has_chain?
173
+
174
+ # True if one of the files in RAKEFILES is in the current directory.
175
+ # If a match is found, it is copied into @rakefile.
176
+ def have_rakefile
177
+ @rakefiles.each do |fn|
178
+ if File.exist?(fn)
179
+ others = Dir.glob(fn, File::FNM_CASEFOLD)
180
+ return others.size == 1 ? others.first : fn
181
+ elsif fn == ''
182
+ return fn
183
+ end
184
+ end
185
+ return nil
186
+ end
187
+
188
+ # True if we are outputting to TTY, false otherwise
189
+ def tty_output?
190
+ @tty_output
191
+ end
192
+
193
+ # Override the detected TTY output state (mostly for testing)
194
+ def tty_output=( tty_output_state )
195
+ @tty_output = tty_output_state
196
+ end
197
+
198
+ # We will truncate output if we are outputting to a TTY or if we've been
199
+ # given an explicit column width to honor
200
+ def truncate_output?
201
+ tty_output? || ENV['RAKE_COLUMNS']
202
+ end
203
+
204
+ # Display the tasks and comments.
205
+ def display_tasks_and_comments
206
+ displayable_tasks = tasks.select { |t|
207
+ t.comment && t.name =~ options.show_task_pattern
208
+ }
209
+ case options.show_tasks
210
+ when :tasks
211
+ width = displayable_tasks.collect { |t| t.name_with_args.length }.max || 10
212
+ max_column = truncate_output? ? terminal_width - name.size - width - 7 : nil
213
+ displayable_tasks.each do |t|
214
+ printf "#{name} %-#{width}s # %s\n",
215
+ t.name_with_args, max_column ? truncate(t.comment, max_column) : t.comment
216
+ end
217
+ when :describe
218
+ displayable_tasks.each do |t|
219
+ puts "#{name} #{t.name_with_args}"
220
+ t.full_comment.split("\n").each do |line|
221
+ puts " #{line}"
222
+ end
223
+ puts
224
+ end
225
+ when :lines
226
+ displayable_tasks.each do |t|
227
+ t.locations.each do |loc|
228
+ printf "#{name} %-30s %s\n",t.name_with_args, loc
229
+ end
230
+ end
231
+ else
232
+ fail "Unknown show task mode: '#{options.show_tasks}'"
233
+ end
234
+ end
235
+
236
+ def terminal_width
237
+ if ENV['RAKE_COLUMNS']
238
+ result = ENV['RAKE_COLUMNS'].to_i
239
+ else
240
+ result = unix? ? dynamic_width : 80
241
+ end
242
+ (result < 10) ? 80 : result
243
+ rescue
244
+ 80
245
+ end
246
+
247
+ # Calculate the dynamic width of the
248
+ def dynamic_width
249
+ @dynamic_width ||= (dynamic_width_stty.nonzero? || dynamic_width_tput)
250
+ end
251
+
252
+ def dynamic_width_stty
253
+ %x{stty size 2>/dev/null}.split[1].to_i
254
+ end
255
+
256
+ def dynamic_width_tput
257
+ %x{tput cols 2>/dev/null}.to_i
258
+ end
259
+
260
+ def unix?
261
+ RbConfig::CONFIG['host_os'] =~ /(aix|darwin|linux|(net|free|open)bsd|cygwin|solaris|irix|hpux)/i
262
+ end
263
+
264
+ def windows?
265
+ Win32.windows?
266
+ end
267
+
268
+ def truncate(string, width)
269
+ if string.length <= width
270
+ string
271
+ else
272
+ ( string[0, width-3] || "" ) + "..."
273
+ end
274
+ end
275
+
276
+ # Display the tasks and prerequisites
277
+ def display_prerequisites
278
+ tasks.each do |t|
279
+ puts "#{name} #{t.name}"
280
+ t.prerequisites.each { |pre| puts " #{pre}" }
281
+ end
282
+ end
283
+
284
+ # A list of all the standard options used in rake, suitable for
285
+ # passing to OptionParser.
286
+ def standard_rake_options
287
+ [
288
+ ['--classic-namespace', '-C', "Put Task and FileTask in the top level namespace",
289
+ lambda { |value|
290
+ require 'rake/classic_namespace'
291
+ options.classic_namespace = true
292
+ }
293
+ ],
294
+ ['--describe', '-D [PATTERN]', "Describe the tasks (matching optional PATTERN), then exit.",
295
+ lambda { |value|
296
+ options.show_tasks = :describe
297
+ options.show_task_pattern = Regexp.new(value || '')
298
+ TaskManager.record_task_metadata = true
299
+ }
300
+ ],
301
+ ['--dry-run', '-n', "Do a dry run without executing actions.",
302
+ lambda { |value|
303
+ Rake.verbose(true)
304
+ Rake.nowrite(true)
305
+ options.dryrun = true
306
+ options.trace = true
307
+ }
308
+ ],
309
+ ['--execute', '-e CODE', "Execute some Ruby code and exit.",
310
+ lambda { |value|
311
+ eval(value)
312
+ exit
313
+ }
314
+ ],
315
+ ['--execute-print', '-p CODE', "Execute some Ruby code, print the result, then exit.",
316
+ lambda { |value|
317
+ puts eval(value)
318
+ exit
319
+ }
320
+ ],
321
+ ['--execute-continue', '-E CODE',
322
+ "Execute some Ruby code, then continue with normal task processing.",
323
+ lambda { |value| eval(value) }
324
+ ],
325
+ ['--threads', '-j [N]', Integer, "Run up to N tasks simultaneously; without N (or N=0), no limit.",
326
+ lambda { |value|
327
+ # nil.to_i == 0, which means unlimited threads
328
+ options.threads = value.to_i
329
+ }
330
+ ],
331
+ ['--libdir', '-I LIBDIR', "Include LIBDIR in the search path for required modules.",
332
+ lambda { |value| $:.push(value) }
333
+ ],
334
+ ['--no-search', '--nosearch', '-N', "Do not search parent directories for the Rakefile.",
335
+ lambda { |value| options.nosearch = true }
336
+ ],
337
+ ['--prereqs', '-P', "Display the tasks and dependencies, then exit.",
338
+ lambda { |value| options.show_prereqs = true }
339
+ ],
340
+ ['--quiet', '-q', "Do not log messages to standard output.",
341
+ lambda { |value| Rake.verbose(false) }
342
+ ],
343
+ ['--rakefile', '-f [FILE]', "Use FILE as the rakefile.",
344
+ lambda { |value|
345
+ value ||= ''
346
+ @rakefiles.clear
347
+ @rakefiles << value
348
+ }
349
+ ],
350
+ ['--rakelibdir', '--rakelib', '-R RAKELIBDIR',
351
+ "Auto-import any .rake files in RAKELIBDIR. (default is 'rakelib')",
352
+ lambda { |value| options.rakelib = value.split(':') }
353
+ ],
354
+ ['--randomize[=SEED]', Integer, "Randomize the order of sibling prerequisites.",
355
+ lambda { |value|
356
+ MultiTask.class_eval { remove_method(:invoke_prerequisites) }
357
+ options.randomize = value || (srand ; srand % 10_000)
358
+ srand options.randomize
359
+ at_exit do
360
+ $stderr.puts "Run options: --randomize=#{options.randomize}"
361
+ end
362
+ }
363
+ ],
364
+ ['--require', '-r MODULE', "Require MODULE before executing rakefile.",
365
+ lambda { |value|
366
+ begin
367
+ require value
368
+ rescue LoadError => ex
369
+ begin
370
+ rake_require value
371
+ rescue LoadError
372
+ raise ex
373
+ end
374
+ end
375
+ }
376
+ ],
377
+ ['--rules', "Trace the rules resolution.",
378
+ lambda { |value| options.trace_rules = true }
379
+ ],
380
+ ['--silent', '-s', "Like --quiet, but also suppresses the 'in directory' announcement.",
381
+ lambda { |value|
382
+ Rake.verbose(false)
383
+ options.silent = true
384
+ }
385
+ ],
386
+ ['--system', '-g',
387
+ "Using system wide (global) rakefiles (usually '~/.rake/*.rake').",
388
+ lambda { |value| options.load_system = true }
389
+ ],
390
+ ['--no-system', '--nosystem', '-G',
391
+ "Use standard project Rakefile search paths, ignore system wide rakefiles.",
392
+ lambda { |value| options.ignore_system = true }
393
+ ],
394
+ ['--tasks', '-T [PATTERN]', "Display the tasks (matching optional PATTERN) with descriptions, then exit.",
395
+ lambda { |value|
396
+ options.show_tasks = :tasks
397
+ options.show_task_pattern = Regexp.new(value || '')
398
+ Rake::TaskManager.record_task_metadata = true
399
+ }
400
+ ],
401
+ ['--trace', '-t', "Turn on invoke/execute tracing, enable full backtrace.",
402
+ lambda { |value|
403
+ options.trace = true
404
+ Rake.verbose(true)
405
+ }
406
+ ],
407
+ ['--verbose', '-v', "Log message to standard output.",
408
+ lambda { |value| Rake.verbose(true) }
409
+ ],
410
+ ['--version', '-V', "Display the program version.",
411
+ lambda { |value|
412
+ puts "drake, version #{RAKEVERSION}"
413
+ exit
414
+ }
415
+ ],
416
+ ['--where', '-W [PATTERN]', "Describe the tasks (matching optional PATTERN), then exit.",
417
+ lambda { |value|
418
+ options.show_tasks = :lines
419
+ options.show_task_pattern = Regexp.new(value || '')
420
+ Rake::TaskManager.record_task_metadata = true
421
+ }
422
+ ],
423
+ ['--no-deprecation-warnings', '-X', "Disable the deprecation warnings.",
424
+ lambda { |value|
425
+ options.ignore_deprecate = true
426
+ }
427
+ ],
428
+ ]
429
+ end
430
+
431
+ # Read and handle the command line options.
432
+ def handle_options
433
+ options.rakelib = ['rakelib']
434
+
435
+ OptionParser.new do |opts|
436
+ opts.banner = "drake [-f rakefile] {options} targets..."
437
+ opts.separator ""
438
+ opts.separator "Options are ..."
439
+
440
+ opts.on_tail("-h", "--help", "-H", "Display this help message.") do
441
+ puts opts
442
+ exit
443
+ end
444
+
445
+ standard_rake_options.each { |args| opts.on(*args) }
446
+ opts.environment('RAKEOPT')
447
+ end.parse!
448
+
449
+ # If class namespaces are requested, set the global options
450
+ # according to the values in the options structure.
451
+ if options.classic_namespace
452
+ $show_tasks = options.show_tasks
453
+ $show_prereqs = options.show_prereqs
454
+ $trace = options.trace
455
+ $dryrun = options.dryrun
456
+ $silent = options.silent
457
+ end
458
+ end
459
+
460
+ # Similar to the regular Ruby +require+ command, but will check
461
+ # for *.rake files in addition to *.rb files.
462
+ def rake_require(file_name, paths=$LOAD_PATH, loaded=$")
463
+ fn = file_name + ".rake"
464
+ return false if loaded.include?(fn)
465
+ paths.each do |path|
466
+ full_path = File.join(path, fn)
467
+ if File.exist?(full_path)
468
+ Rake.load_rakefile(full_path)
469
+ loaded << fn
470
+ return true
471
+ end
472
+ end
473
+ fail LoadError, "Can't find #{file_name}"
474
+ end
475
+
476
+ def find_rakefile_location
477
+ here = Dir.pwd
478
+ while ! (fn = have_rakefile)
479
+ Dir.chdir("..")
480
+ if Dir.pwd == here || options.nosearch
481
+ return nil
482
+ end
483
+ here = Dir.pwd
484
+ end
485
+ [fn, here]
486
+ ensure
487
+ Dir.chdir(Rake.original_dir)
488
+ end
489
+
490
+ def print_rakefile_directory(location)
491
+ $stderr.puts "(in #{Dir.pwd})" unless
492
+ options.silent or original_dir == location
493
+ end
494
+
495
+ def raw_load_rakefile # :nodoc:
496
+ rakefile, location = find_rakefile_location
497
+ if (! options.ignore_system) &&
498
+ (options.load_system || rakefile.nil?) &&
499
+ system_dir && File.directory?(system_dir)
500
+ print_rakefile_directory(location)
501
+ glob("#{system_dir}/*.rake") do |name|
502
+ add_import name
503
+ end
504
+ else
505
+ fail "No Rakefile found (looking for: #{@rakefiles.join(', ')})" if
506
+ rakefile.nil?
507
+ @rakefile = rakefile
508
+ Dir.chdir(location)
509
+ print_rakefile_directory(location)
510
+ $rakefile = @rakefile if options.classic_namespace
511
+ Rake.load_rakefile(File.expand_path(@rakefile)) if @rakefile && @rakefile != ''
512
+ options.rakelib.each do |rlib|
513
+ glob("#{rlib}/*.rake") do |name|
514
+ add_import name
515
+ end
516
+ end
517
+ end
518
+ load_imports
519
+ end
520
+
521
+ def glob(path, &block)
522
+ Dir[path.gsub("\\", '/')].each(&block)
523
+ end
524
+ private :glob
525
+
526
+ # The directory path containing the system wide rakefiles.
527
+ def system_dir
528
+ @system_dir ||=
529
+ begin
530
+ if ENV['RAKE_SYSTEM']
531
+ ENV['RAKE_SYSTEM']
532
+ else
533
+ standard_system_dir
534
+ end
535
+ end
536
+ end
537
+
538
+ # The standard directory containing system wide rake files.
539
+ if Win32.windows?
540
+ def standard_system_dir #:nodoc:
541
+ Win32.win32_system_dir
542
+ end
543
+ else
544
+ def standard_system_dir #:nodoc:
545
+ File.join(File.expand_path('~'), '.rake')
546
+ end
547
+ end
548
+ private :standard_system_dir
549
+
550
+ # Collect the list of tasks on the command line. If no tasks are
551
+ # given, return a list containing only the default task.
552
+ # Environmental assignments are processed at this time as well.
553
+ def collect_tasks
554
+ @top_level_tasks = []
555
+ ARGV.each do |arg|
556
+ if arg =~ /^(\w+)=(.*)$/
557
+ ENV[$1] = $2
558
+ else
559
+ @top_level_tasks << arg unless arg =~ /^-/
560
+ end
561
+ end
562
+ @top_level_tasks.push("default") if @top_level_tasks.size == 0
563
+ end
564
+
565
+ # Add a file to the list of files to be imported.
566
+ def add_import(fn)
567
+ @pending_imports << fn
568
+ end
569
+
570
+ # Load the pending list of imported files.
571
+ def load_imports
572
+ while fn = @pending_imports.shift
573
+ next if @imported.member?(fn)
574
+ if fn_task = lookup(fn)
575
+ fn_task.invoke
576
+ end
577
+ ext = File.extname(fn)
578
+ loader = @loaders[ext] || @default_loader
579
+ loader.load(fn)
580
+ @imported << fn
581
+ end
582
+ end
583
+
584
+ # Warn about deprecated use of top level constant names.
585
+ def const_warning(const_name)
586
+ @const_warning ||= false
587
+ if ! @const_warning
588
+ $stderr.puts %{WARNING: Deprecated reference to top-level constant '#{const_name}' } +
589
+ %{found at: #{rakefile_location}} # '
590
+ $stderr.puts %{ Use --classic-namespace on rake command}
591
+ $stderr.puts %{ or 'require "rake/classic_namespace"' in Rakefile}
592
+ end
593
+ @const_warning = true
594
+ end
595
+
596
+ def rakefile_location backtrace = caller
597
+ backtrace.map { |t| t[/([^:]+):/,1] }
598
+
599
+ re = /^#{@rakefile}$/
600
+ re = /#{re.source}/i if windows?
601
+
602
+ backtrace.find { |str| str =~ re } || ''
603
+ end
604
+
605
+ #
606
+ # Lazily pull in the parallelizing code
607
+ #
608
+ class Options < OpenStruct # :nodoc:
609
+ attr_reader :threads
610
+
611
+ def initialize
612
+ super
613
+ @threads = 1
614
+ end
615
+
616
+ def threads=(n)
617
+ raise ArgumentError, "threads must be nonnegative" if n < 0
618
+ if require('rake/parallel')
619
+ Task.module_eval { include Parallel::TaskMixin }
620
+ Application.module_eval { include Parallel::ApplicationMixin }
621
+ end
622
+ @threads = n
623
+ end
624
+ end
625
+ end
626
+ end