source: EcnlProtoTool/trunk/mruby-1.3.0/minirake@ 331

Last change on this file since 331 was 331, checked in by coas-nagasima, 6 years ago

prototoolに関連するプロジェクトをnewlibからmuslを使うよう変更・更新
ntshellをnewlibの下位の実装から、muslのsyscallの実装に変更・更新
以下のOSSをアップデート
・mruby-1.3.0
・musl-1.1.18
・onigmo-6.1.3
・tcc-0.9.27
以下のOSSを追加
・openssl-1.1.0e
・curl-7.57.0
・zlib-1.2.11
以下のmrbgemsを追加
・iij/mruby-digest
・iij/mruby-env
・iij/mruby-errno
・iij/mruby-iijson
・iij/mruby-ipaddr
・iij/mruby-mock
・iij/mruby-require
・iij/mruby-tls-openssl

File size: 13.2 KB
Line 
1#!/usr/bin/env ruby
2
3# Original is https://github.com/jimweirich/rake/
4# Copyright (c) 2003 Jim Weirich
5# License: MIT-LICENSE
6
7require 'getoptlong'
8require 'fileutils'
9
10class String
11 def ext(newext='')
12 return self.dup if ['.', '..'].include? self
13 if newext != ''
14 newext = (newext =~ /^\./) ? newext : ("." + newext)
15 end
16 self.chomp(File.extname(self)) << newext
17 end
18
19 def pathmap(spec=nil, &block)
20 return self if spec.nil?
21 result = ''
22 spec.scan(/%\{[^}]*\}-?\d*[sdpfnxX%]|%-?\d+d|%.|[^%]+/) do |frag|
23 case frag
24 when '%f'
25 result << File.basename(self)
26 when '%n'
27 result << File.basename(self).ext
28 when '%d'
29 result << File.dirname(self)
30 when '%x'
31 result << File.extname(self)
32 when '%X'
33 result << self.ext
34 when '%p'
35 result << self
36 when '%s'
37 result << (File::ALT_SEPARATOR || File::SEPARATOR)
38 when '%-'
39 # do nothing
40 when '%%'
41 result << "%"
42 when /%(-?\d+)d/
43 result << pathmap_partial($1.to_i)
44 when /^%\{([^}]*)\}(\d*[dpfnxX])/
45 patterns, operator = $1, $2
46 result << pathmap('%' + operator).pathmap_replace(patterns, &block)
47 when /^%/
48 fail ArgumentError, "Unknown pathmap specifier #{frag} in '#{spec}'"
49 else
50 result << frag
51 end
52 end
53 result
54 end
55end
56
57module MiniRake
58 class Task
59 TASKS = Hash.new
60 RULES = Array.new
61
62 # List of prerequisites for a task.
63 attr_reader :prerequisites
64
65 # Source dependency for rule synthesized tasks. Nil if task was not
66 # sythesized from a rule.
67 attr_accessor :source
68
69 # Create a task named +task_name+ with no actions or prerequisites..
70 # use +enhance+ to add actions and prerequisites.
71 def initialize(task_name)
72 @name = task_name
73 @prerequisites = []
74 @actions = []
75 end
76
77 # Enhance a task with prerequisites or actions. Returns self.
78 def enhance(deps=nil, &block)
79 @prerequisites |= deps if deps
80 @actions << block if block_given?
81 self
82 end
83
84 # Name of the task.
85 def name
86 @name.to_s
87 end
88
89 # Invoke the task if it is needed. Prerequites are invoked first.
90 def invoke
91 puts "Invoke #{name} (already=[#{@already_invoked}], needed=[#{needed?}])" if $trace
92 return if @already_invoked
93 @already_invoked = true
94 prerequisites = @prerequisites.collect{ |n| n.is_a?(Proc) ? n.call(name) : n }.flatten
95 prerequisites.each { |n| Task[n].invoke }
96 execute if needed?
97 end
98
99 # Execute the actions associated with this task.
100 def execute
101 puts "Execute #{name}" if $trace
102 self.class.enhance_with_matching_rule(name) if @actions.empty?
103 unless $dryrun
104 @actions.each { |act| act.call(self) }
105 end
106 end
107
108 # Is this task needed?
109 def needed?
110 true
111 end
112
113 # Timestamp for this task. Basic tasks return the current time for
114 # their time stamp. Other tasks can be more sophisticated.
115 def timestamp
116 Time.now
117 end
118
119 # Class Methods ----------------------------------------------------
120
121 class << self
122
123 # Clear the task list. This cause rake to immediately forget all
124 # the tasks that have been assigned. (Normally used in the unit
125 # tests.)
126 def clear
127 TASKS.clear
128 RULES.clear
129 end
130
131 # List of all defined tasks.
132 def tasks
133 TASKS.keys.sort.collect { |tn| Task[tn] }
134 end
135
136 # Return a task with the given name. If the task is not currently
137 # known, try to synthesize one from the defined rules. If no
138 # rules are found, but an existing file matches the task name,
139 # assume it is a file task with no dependencies or actions.
140 def [](task_name)
141 task_name = task_name.to_s
142 if task_name.end_with?(":")
143 task_name = task_name.slice(0, task_name.length - 1)
144 end
145 if task = TASKS[task_name]
146 return task
147 end
148 if task = enhance_with_matching_rule(task_name)
149 return task
150 end
151 if File.exist?(task_name)
152 return FileTask.define_task(task_name)
153 end
154 fail "Don't know how to rake #{task_name}"
155 end
156
157 # Define a task given +args+ and an option block. If a rule with
158 # the given name already exists, the prerequisites and actions are
159 # added to the existing task.
160 def define_task(args, &block)
161 task_name, deps = resolve_args(args)
162 lookup(task_name).enhance([deps].flatten, &block)
163 end
164
165 # Define a rule for synthesizing tasks.
166 def create_rule(args, &block)
167 pattern, deps = resolve_args(args)
168 pattern = Regexp.new(Regexp.quote(pattern) + '$') if String === pattern
169 RULES << [pattern, deps, block]
170 end
171
172
173 # Lookup a task. Return an existing task if found, otherwise
174 # create a task of the current type.
175 def lookup(task_name)
176 name = task_name.to_s
177 TASKS[name] ||= self.new(name)
178 end
179
180 # If a rule can be found that matches the task name, enhance the
181 # task with the prerequisites and actions from the rule. Set the
182 # source attribute of the task appropriately for the rule. Return
183 # the enhanced task or nil of no rule was found.
184 def enhance_with_matching_rule(task_name)
185 RULES.each do |pattern, extensions, block|
186 if pattern.match(task_name)
187 ext = extensions.first
188 deps = extensions[1..-1]
189 case ext
190 when String
191 source = task_name.sub(/\.[^.]*$/, ext)
192 when Proc
193 source = ext.call(task_name)
194 else
195 fail "Don't know how to handle rule dependent: #{ext.inspect}"
196 end
197 if File.exist?(source)
198 task = FileTask.define_task({task_name => [source]+deps}, &block)
199 task.source = source
200 return task
201 end
202 end
203 end
204 nil
205 end
206
207 private
208
209 # Resolve the arguments for a task/rule.
210 def resolve_args(args)
211 case args
212 when Hash
213 fail "Too Many Task Names: #{args.keys.join(' ')}" if args.size > 1
214 fail "No Task Name Given" if args.size < 1
215 task_name = args.keys[0]
216 deps = args[task_name]
217 deps = [deps] if (String===deps) || (Regexp===deps) || (Proc===deps)
218 else
219 task_name = args
220 deps = []
221 end
222 [task_name, deps]
223 end
224 end
225 end
226
227
228 ######################################################################
229 class FileTask < Task
230 # Is this file task needed? Yes if it doesn't exist, or if its time
231 # stamp is out of date.
232 def needed?
233 return true unless File.exist?(name)
234 prerequisites = @prerequisites.collect{ |n| n.is_a?(Proc) ? n.call(name) : n }.flatten
235 latest_prereq = prerequisites.collect{|n| Task[n].timestamp}.max
236 return false if latest_prereq.nil?
237 timestamp < latest_prereq
238 end
239
240 # Time stamp for file task.
241 def timestamp
242 return Time.at(0) unless File.exist?(name)
243 stat = File::stat(name.to_s)
244 stat.directory? ? Time.at(0) : stat.mtime
245 end
246 end
247
248 module DSL
249 # Declare a basic task.
250 def task(args, &block)
251 MiniRake::Task.define_task(args, &block)
252 end
253
254 # Declare a file task.
255 def file(args, &block)
256 MiniRake::FileTask.define_task(args, &block)
257 end
258
259 # Declare a set of files tasks to create the given directories on
260 # demand.
261 def directory(args, &block)
262 MiniRake::FileTask.define_task(args) do |t|
263 block.call(t) unless block.nil?
264 dir = args.is_a?(Hash) ? args.keys.first : args
265 (dir.split(File::SEPARATOR) + ['']).inject do |acc, part|
266 (acc + File::SEPARATOR).tap do |d|
267 Dir.mkdir(d) unless File.exists? d
268 end + part
269 end
270 end
271 end
272
273 # Declare a rule for auto-tasks.
274 def rule(args, &block)
275 MiniRake::Task.create_rule(args, &block)
276 end
277
278 # Write a message to standard out if $verbose is enabled.
279 def log(msg)
280 print " " if $trace && $verbose
281 puts msg if $verbose
282 end
283
284 # Run the system command +cmd+.
285 def sh(cmd)
286 puts cmd if $verbose
287 system(cmd) or fail "Command Failed: [#{cmd}]"
288 end
289
290 def desc(text)
291 end
292 end
293end
294
295Rake = MiniRake
296extend MiniRake::DSL
297
298
299######################################################################
300# Task Definition Functions ...
301
302######################################################################
303# Rake main application object. When invoking +rake+ from the command
304# line, a RakeApp object is created and run.
305#
306class RakeApp
307 RAKEFILES = ['rakefile', 'Rakefile']
308
309 OPTIONS = [
310 ['--dry-run', '-n', GetoptLong::NO_ARGUMENT,
311 "Do a dry run without executing actions."],
312 ['--help', '-H', GetoptLong::NO_ARGUMENT,
313 "Display this help message."],
314 ['--libdir', '-I', GetoptLong::REQUIRED_ARGUMENT,
315 "Include LIBDIR in the search path for required modules."],
316 ['--nosearch', '-N', GetoptLong::NO_ARGUMENT,
317 "Do not search parent directories for the Rakefile."],
318 ['--quiet', '-q', GetoptLong::NO_ARGUMENT,
319 "Do not log messages to standard output (default)."],
320 ['--rakefile', '-f', GetoptLong::REQUIRED_ARGUMENT,
321 "Use FILE as the rakefile."],
322 ['--require', '-r', GetoptLong::REQUIRED_ARGUMENT,
323 "Require MODULE before executing rakefile."],
324 ['--tasks', '-T', GetoptLong::NO_ARGUMENT,
325 "Display the tasks and dependencies, then exit."],
326 ['--pull-gems','-p', GetoptLong::NO_ARGUMENT,
327 "Pull all git mrbgems."],
328 ['--trace', '-t', GetoptLong::NO_ARGUMENT,
329 "Turn on invoke/execute tracing."],
330 ['--usage', '-h', GetoptLong::NO_ARGUMENT,
331 "Display usage."],
332 ['--verbose', '-v', GetoptLong::NO_ARGUMENT,
333 "Log message to standard output."],
334 ['--directory', '-C', GetoptLong::REQUIRED_ARGUMENT,
335 "Change executing directory of rakefiles."]
336 ]
337
338 # Create a RakeApp object.
339 def initialize
340 @rakefile = nil
341 @nosearch = false
342 end
343
344 # True if one of the files in RAKEFILES is in the current directory.
345 # If a match is found, it is copied into @rakefile.
346 def have_rakefile
347 RAKEFILES.each do |fn|
348 if File.exist?(fn)
349 @rakefile = fn
350 return true
351 end
352 end
353 return false
354 end
355
356 # Display the program usage line.
357 def usage
358 puts "rake [-f rakefile] {options} targets..."
359 end
360
361 # Display the rake command line help.
362 def help
363 usage
364 puts
365 puts "Options are ..."
366 puts
367 OPTIONS.sort.each do |long, short, mode, desc|
368 if mode == GetoptLong::REQUIRED_ARGUMENT
369 if desc =~ /\b([A-Z]{2,})\b/
370 long = long + "=#{$1}"
371 end
372 end
373 printf " %-20s (%s)\n", long, short
374 printf " %s\n", desc
375 end
376 end
377
378 # Display the tasks and dependencies.
379 def display_tasks
380 MiniRake::Task.tasks.each do |t|
381 puts "#{t.class} #{t.name}"
382 t.prerequisites.each { |pre| puts " #{pre}" }
383 end
384 end
385
386 # Return a list of the command line options supported by the
387 # program.
388 def command_line_options
389 OPTIONS.collect { |lst| lst[0..-2] }
390 end
391
392 # Do the option defined by +opt+ and +value+.
393 def do_option(opt, value)
394 case opt
395 when '--dry-run'
396 $dryrun = true
397 $trace = true
398 when '--help'
399 help
400 exit
401 when '--libdir'
402 $:.push(value)
403 when '--nosearch'
404 @nosearch = true
405 when '--quiet'
406 $verbose = false
407 when '--rakefile'
408 RAKEFILES.clear
409 RAKEFILES << value
410 when '--require'
411 require value
412 when '--tasks'
413 $show_tasks = true
414 when '--pull-gems'
415 $pull_gems = true
416 when '--trace'
417 $trace = true
418 when '--usage'
419 usage
420 exit
421 when '--verbose'
422 $verbose = true
423 when '--version'
424 puts "rake, version #{RAKEVERSION}"
425 exit
426 when '--directory'
427 Dir.chdir value
428 else
429 fail "Unknown option: #{opt}"
430 end
431 end
432
433 # Read and handle the command line options.
434 def handle_options
435 $verbose = false
436 $pull_gems = false
437 opts = GetoptLong.new(*command_line_options)
438 opts.each { |opt, value| do_option(opt, value) }
439 end
440
441 # Run the +rake+ application.
442 def run
443 handle_options
444 begin
445 here = Dir.pwd
446 while ! have_rakefile
447 Dir.chdir("..")
448 if Dir.pwd == here || @nosearch
449 fail "No Rakefile found (looking for: #{RAKEFILES.join(', ')})"
450 end
451 here = Dir.pwd
452 end
453 tasks = []
454 ARGV.each do |task_name|
455 if /^(\w+)=(.*)/.match(task_name)
456 ENV[$1] = $2
457 else
458 tasks << task_name
459 end
460 end
461 puts "(in #{Dir.pwd})"
462 $rakefile = @rakefile
463 load @rakefile
464 if $show_tasks
465 display_tasks
466 else
467 tasks.push("default") if tasks.size == 0
468 tasks.each do |task_name|
469 MiniRake::Task[task_name].invoke
470 end
471 end
472 rescue Exception => ex
473 puts "rake aborted!"
474 puts ex.message
475 if $trace
476 puts ex.backtrace.join("\n")
477 else
478 puts ex.backtrace.find {|str| str =~ /#{@rakefile}/ } || ""
479 end
480 exit 1
481 end
482 end
483end
484
485if __FILE__ == $0 then
486 RakeApp.new.run
487end
Note: See TracBrowser for help on using the repository browser.