Module: Rscons::Util
- Defined in:
- lib/rscons/util.rb
Overview
A collection of stand-alone utility methods.
Class Method Summary collapse
-
.absolute_path(path) ⇒ String, ...
Return the absolute path for a given target if not a phony target.
-
.absolute_path?(path) ⇒ Boolean
Return whether the given path is an absolute filesystem path.
-
.clean_d_precompile_path(pc_path, import_path) ⇒ void
Remove any stale .di files from the precompile path.
-
.colorize_markup(message) ⇒ Array
Colorize a builder run message.
-
.command_to_execute_me ⇒ Object
Command that can be run to execute this instance of rscons from the current working directory.
-
.command_to_s(command) ⇒ String
Return a string representation of a command.
-
.determine_n_threads ⇒ Integer
Determine the number of threads to use by default.
-
.find_executable(name) ⇒ String?
Look for an executable.
-
.find_import_path_for_d_source(import_paths, source, module_name) ⇒ String?
Find the D import path that will be used to import the given module.
-
.format_elapsed_time(elapsed) ⇒ String
Format an elapsed time in human-readable format.
-
.get_module_name(source_path) ⇒ String?
Get the module name for a D source file.
-
.glob(*patterns) ⇒ Array<String>
Return a list of paths matching the specified pattern(s).
-
.make_relative_path(path) ⇒ String
Make a relative path corresponding to a possibly absolute one.
-
.parse_dependency_file(mf_fname) ⇒ Array<String>
Parse dependencies from a Makefile or ldc2 dependency file.
-
.short_format_paths(paths) ⇒ String
Return a string showing the path specified, or if more than one, then the first path with a “(+D)” afterward, where D is the number of remaining paths.
-
.task(name, options = {}, &block) ⇒ Task
private
Create or modify a task.
-
.wait_for_thread(*threads) ⇒ Thread
Wait for any of a number of threads to complete.
Class Method Details
.absolute_path(path) ⇒ String, ...
Return the absolute path for a given target if not a phony target.
26 27 28 29 30 31 32 |
# File 'lib/rscons/util.rb', line 26 def absolute_path(path) if path.is_a?(String) File.(path) else path end end |
.absolute_path?(path) ⇒ Boolean
Return whether the given path is an absolute filesystem path.
11 12 13 14 15 16 17 |
# File 'lib/rscons/util.rb', line 11 def absolute_path?(path) if RUBY_PLATFORM =~ /mingw|msys/ path =~ %r{^(?:\w:)?[\\/]} else path.start_with?("/") end end |
.clean_d_precompile_path(pc_path, import_path) ⇒ void
This method returns an undefined value.
Remove any stale .di files from the precompile path.
43 44 45 46 47 48 49 50 51 |
# File 'lib/rscons/util.rb', line 43 def clean_d_precompile_path(pc_path, import_path) glob("#{pc_path}/**/*.di").each do |di_path| end_path = di_path[(pc_path.size+1)..] path = "#{import_path}/#{end_path}".sub(/\.di$/, ".d") unless File.exist?(path) FileUtils.rm_f(di_path) end end end |
.colorize_markup(message) ⇒ Array
Colorize a builder run message.
60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 |
# File 'lib/rscons/util.rb', line 60 def colorize_markup() if =~ /^(.*?)(<[^>]+>)(.*)$/ prefix, code, suffix = $1, $2, $3 case code when "<target>" code = :magenta when "<source>" code = :cyan when "<reset>" code = :reset end [prefix, code, *colorize_markup(suffix)].delete_if {|v| v == ""} else [] end end |
.command_to_execute_me ⇒ Object
Command that can be run to execute this instance of rscons from the current working directory.
348 349 350 351 352 |
# File 'lib/rscons/util.rb', line 348 def command_to_execute_me command = Pathname.new(File.($0)).relative_path_from(Dir.pwd).to_s command = "./#{command}" unless command["/"] command end |
.command_to_s(command) ⇒ String
Return a string representation of a command.
84 85 86 |
# File 'lib/rscons/util.rb', line 84 def command_to_s(command) command.map { |c| c[" "] ? "'#{c.gsub("'", "'\\\\''")}'" : c }.join(" ") end |
.determine_n_threads ⇒ Integer
Determine the number of threads to use by default.
92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 |
# File 'lib/rscons/util.rb', line 92 def determine_n_threads # If the user specifies the number of threads in the environment, then # respect that. if ENV["RSCONS_NTHREADS"] =~ /^(\d+)$/ return $1.to_i end # Otherwise try to figure out how many threads are available on the # host hardware. begin case RbConfig::CONFIG["host_os"] when /linux/ return File.read("/proc/cpuinfo").scan(/^processor\s*:/).size when /mswin|mingw|msys/ if `wmic cpu get NumberOfLogicalProcessors -value` =~ /NumberOfLogicalProcessors=(\d+)/ return $1.to_i end when /darwin/ if `sysctl -n hw.ncpu` =~ /(\d+)/ return $1.to_i end end rescue end # If we can't figure it out, default to 1. 1 end |
.find_executable(name) ⇒ String?
Look for an executable.
142 143 144 145 146 147 148 149 150 151 152 153 154 155 |
# File 'lib/rscons/util.rb', line 142 def find_executable(name) if name["/"] or name["\\"] if File.file?(name) and File.executable?(name) return name end else path_entries = ENV["PATH"].split(File::PATH_SEPARATOR) path_entries.find do |path_entry| if path = test_path_for_executable(path_entry, name) return path end end end end |
.find_import_path_for_d_source(import_paths, source, module_name) ⇒ String?
Find the D import path that will be used to import the given module.
168 169 170 171 172 173 174 175 176 177 178 |
# File 'lib/rscons/util.rb', line 168 def find_import_path_for_d_source(import_paths, source, module_name) source = source.gsub("\\", "/") module_path = module_name.gsub(".", "/") + ".d" import_paths.each do |import_path| path = "#{import_path}/#{module_path}".gsub("\\", "/") if path == source return import_path end end nil end |
.format_elapsed_time(elapsed) ⇒ String
Format an elapsed time in human-readable format.
184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 |
# File 'lib/rscons/util.rb', line 184 def format_elapsed_time(elapsed) hours = (elapsed / (60 * 60)).to_i elapsed -= hours * 60 * 60 minutes = (elapsed / 60).to_i elapsed -= minutes * 60 seconds = elapsed.ceil result = "" if hours > 0 result += "#{hours}h " end if hours > 0 || minutes > 0 result += "#{minutes}m " end result += "#{seconds}s" result end |
.get_module_name(source_path) ⇒ String?
Get the module name for a D source file.
208 209 210 211 212 213 214 215 216 217 218 |
# File 'lib/rscons/util.rb', line 208 def get_module_name(source_path) if File.exist?(source_path) if File.binread(source_path) =~ /^\s*module\s(\S*);/ return $1 end name = File.basename(source_path).sub(/\.d$/, "") if name =~ /^\w+$/ return name end end end |
.glob(*patterns) ⇒ Array<String>
Return a list of paths matching the specified pattern(s).
A pattern can contain a “/**” component to recurse through directories. If the pattern ends with “/**” then only the recursive list of directories will be returned.
Examples:
-
“src/**”: return all directories under “src”, recursively (including “src” itself).
-
“src/*/”: return all files and directories recursively under the src directory.
-
“src/*/.c”: return all .c files recursively under the src directory.
-
“dir/*/”: return all directories in dir, but no files.
235 236 237 238 239 240 241 242 243 244 245 |
# File 'lib/rscons/util.rb', line 235 def glob(*patterns) require "pathname" patterns.reduce([]) do |result, pattern| if pattern.end_with?("/**") pattern += "/" end result += Dir.glob(pattern).map do |path| Pathname.new(path.gsub("\\", "/")).cleanpath.to_s end end.sort end |
.make_relative_path(path) ⇒ String
Make a relative path corresponding to a possibly absolute one.
254 255 256 257 258 259 260 261 262 263 264 |
# File 'lib/rscons/util.rb', line 254 def make_relative_path(path) if absolute_path?(path) if path =~ %r{^(\w):(.*)$} "_#{$1}#{$2}" else "_#{path}" end else path end end |
.parse_dependency_file(mf_fname) ⇒ Array<String>
Parse dependencies from a Makefile or ldc2 dependency file.
This method is used internally by Rscons builders.
275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 |
# File 'lib/rscons/util.rb', line 275 def parse_dependency_file(mf_fname) deps = [] buildup = '' File.read(mf_fname).each_line do |line| if line =~ /^(.*)\\\s*$/ buildup += ' ' + $1 else buildup += ' ' + line if buildup =~ /^[^:]+\(\S+\)\s*:.*?:[^:]+\((\S+)\)/ # ldc2-style dependency line deps << $1 elsif buildup =~ /^.*: (.*)$/ # Makefile-style dependency line mf_deps = $1 deps += mf_deps.split(' ').map(&:strip) end buildup = '' end end deps end |
.short_format_paths(paths) ⇒ String
Return a string showing the path specified, or if more than one, then the first path with a “(+D)” afterward, where D is the number of remaining paths.
130 131 132 133 134 135 136 |
# File 'lib/rscons/util.rb', line 130 def short_format_paths(paths) if paths.size == 1 paths.first else "#{paths.first} (+#{paths.size - 1})" end end |
.task(name, options = {}, &block) ⇒ Task
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Create or modify a task.
303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 |
# File 'lib/rscons/util.rb', line 303 def task(name, = {}, &block) if name == "configure" Rscons.application.silent_configure = false end if task = Task.tasks[name] task.modify(, &block) else task = Task.new(name, , &block) end if name == "configure" if configuration_params = Cache.instance["configuration_data"]["params"] task.param_values.merge!(configuration_params) end end task end |
.wait_for_thread(*threads) ⇒ Thread
Wait for any of a number of threads to complete.
327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 |
# File 'lib/rscons/util.rb', line 327 def wait_for_thread(*threads) if threads.empty? raise "No threads to wait for" end queue = Queue.new threads.each do |thread| # Create a wait thread for each thread we're waiting for. Thread.new do begin thread.join ensure queue.push(thread) end end end # Wait for any thread to complete. queue.pop end |