Module: Aibika
- Defined in:
- lib/aibika/cli.rb,
lib/aibika.rb,
lib/aibika/host.rb,
lib/aibika/version.rb,
lib/aibika/pathname.rb,
lib/aibika/aibika_builder.rb,
lib/aibika/library_detector.rb
Overview
Aibika front-end
Defined Under Namespace
Modules: Host, LibraryDetector Classes: AibikaBuilder, Pathname
Constant Summary collapse
- IGNORE_MODULE_NAMES =
%r{/(enumerator.so|rational.so|complex.so|fiber.so|thread.rb|ruby2_keywords.rb)$}.freeze
- GEM_SCRIPT_RE =
/\.rbw?$/.freeze
- GEM_EXTRA_RE =
%r{( # Auxiliary files in the root of the gem ^(\./)?(History|Install|Manifest|README|CHANGES|Licen[sc]e|Contributors|ChangeLog|BSD|GPL).*$ | # Installation files in the root of the gem ^(\./)?(Rakefile|setup.rb|extconf.rb)$ | # Documentation/test directories in the root of the gem ^(\./)?(doc|ext|examples|test|tests|benchmarks|spec)/ | # Directories anywhere (^|/)(\.autotest|\.svn|\.cvs|\.git)(/|$) | # Unlikely extensions \.(rdoc|c|cpp|c\+\+|cxx|h|hxx|hpp|obj|o|a)$/ )}xi.freeze
- GEM_NON_FILE_RE =
/(#{GEM_EXTRA_RE}|#{GEM_SCRIPT_RE})/.freeze
- TEMPDIR_ROOT =
Alias for the temporary directory where files are extracted.
Pathname.new('|')
- SRCDIR =
Directory for source files in temporary directory.
Pathname.new('src')
- BINDIR =
Directory for Ruby binaries in temporary directory.
Pathname.new('bin')
- GEMHOMEDIR =
Directory for GEMHOME files in temporary directory.
Pathname.new('gemhome')
- VERSION =
'1.3.14'
Class Attribute Summary collapse
-
.ediconpath ⇒ Object
readonly
Returns the value of attribute ediconpath.
-
.lzmapath ⇒ Object
readonly
Returns the value of attribute lzmapath.
-
.stubimage ⇒ Object
readonly
Returns the value of attribute stubimage.
-
.stubwimage ⇒ Object
readonly
Returns the value of attribute stubwimage.
Class Method Summary collapse
-
.attempt_load_autoload ⇒ Object
Force loading autoloaded constants.
- .build_exe ⇒ Object
- .fatal_error(msg) ⇒ Object
-
.fence_self?(name) ⇒ Boolean
Fence against packaging of self (aibika gem) unless implicitly requestd String, NilClass and arrays of any of these.
- .fence_self_dir?(dir) ⇒ Boolean
-
.find_gem_files(features) ⇒ Object
Searches for features that are loaded from gems, then produces a list of files included in those gems’ manifests.
-
.find_load_path(loadpaths, feature) ⇒ Object
Guess the load path (from ‘paths’) that was used to load ‘path’.
-
.find_src_root(files) ⇒ Object
Find the root of all files specified on the command line and use it as the “src” of the output.
- .find_stubs ⇒ Object
- .init(argv) ⇒ Object
- .msg(msg) ⇒ Object
-
.next_embedded_image ⇒ Object
Returns a binary blob store embedded in the current Ruby script.
- .parseargs(argv) ⇒ Object
-
.Pathname(obj) ⇒ Object
Type conversion for the Pathname class.
- .restore_environment ⇒ Object
- .save_environment ⇒ Object
-
.sort_uniq(arr) ⇒ Object
Sorts and returns an array without duplicates.
- .verbose_msg(msg) ⇒ Object
- .warn(msg) ⇒ Object
Class Attribute Details
.ediconpath ⇒ Object (readonly)
Returns the value of attribute ediconpath.
102 103 104 |
# File 'lib/aibika.rb', line 102 def ediconpath @ediconpath end |
.lzmapath ⇒ Object (readonly)
Returns the value of attribute lzmapath.
102 103 104 |
# File 'lib/aibika.rb', line 102 def lzmapath @lzmapath end |
.stubimage ⇒ Object (readonly)
Returns the value of attribute stubimage.
102 103 104 |
# File 'lib/aibika.rb', line 102 def stubimage @stubimage end |
.stubwimage ⇒ Object (readonly)
Returns the value of attribute stubwimage.
102 103 104 |
# File 'lib/aibika.rb', line 102 def stubwimage @stubwimage end |
Class Method Details
.attempt_load_autoload ⇒ Object
Force loading autoloaded constants. Searches through all modules (and hence classes), and checks their constants for autoloaded ones, then attempts to load them.
152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 |
# File 'lib/aibika.rb', line 152 def self.attempt_load_autoload modules_checked = {} @ignore_modules.each { |m| modules_checked[m] = true } loop do modules_to_check = [] ObjectSpace.each_object(Module) do |mod| modules_to_check << mod unless modules_checked.include?(mod) end break if modules_to_check.empty? modules_to_check.each do |mod| modules_checked[mod] = true mod.constants.each do |const| # Module::Config causes warning on Ruby 1.9.3 - prevent autoloading next if mod.is_a?(Module) && const == :Config next unless mod.autoload?(const) Aibika.msg "Attempting to trigger autoload of #{mod}::#{const}" begin mod.const_get(const) rescue NameError Aibika.warn "#{mod}::#{const} was defined autoloadable, but caused NameError" rescue LoadError Aibika.warn "#{mod}::#{const} was not loadable" end end end end end |
.build_exe ⇒ Object
413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 |
# File 'lib/aibika.rb', line 413 def self.build_exe all_load_paths = $LOAD_PATH.map { |loadpath| Pathname(loadpath). } @added_load_paths = ($LOAD_PATH - @load_path_before).map { |loadpath| Pathname(loadpath). } working_directory = Pathname.pwd. restore_environment # If the script was run, then detect the features it used if Aibika.run_script && Aibika.load_autoload # Attempt to autoload libraries before doing anything else. attempt_load_autoload end # Reject own aibika itself, store the currently loaded files (before we require rbconfig for # our own use). features = $LOADED_FEATURES.reject { |feature| fence_self_dir?(feature) } features.map! { |feature| Pathname(feature) } # Since https://github.com/rubygems/rubygems/commit/cad4cf16cf8fcc637d9da643ef97cf0be2ed63cb # rubygems/core_ext/kernel_require.rb is evaled and thus missing in $LOADED_FEATURES, # so we can't find it and need to add it manually features.push(Pathname('rubygems/core_ext/kernel_require.rb')) # Find gemspecs to include if defined?(Gem) loaded_specs = Gem.loaded_specs.reject { |name, _info| fence_self?(name) } @gemspecs = loaded_specs.map { |_name, info| Pathname(info.loaded_from) } else @gemspecs = [] end require 'rbconfig' instsitelibdir = Host.sitelibdir.relative_path_from(Host.exec_prefix) load_path = [] src_load_path = [] # Find gems files and remove them from features gem_files, features_from_gems = find_gem_files(features) features -= features_from_gems # Find the source root and adjust paths src_prefix, = find_src_root(Aibika.files) # Include encoding support files if Aibika.enc all_load_paths.each do |path| next unless path.subpath?(Host.exec_prefix) encpath = path / 'enc' next unless encpath.exist? encfiles = encpath.find_all_files(/\.so$/) size = encfiles.inject(0) { |sum, pn| sum + pn.size } Aibika.msg "Including #{encfiles.size} encoding support files (#{size} bytes, use --no-enc to exclude)" features.push(*encfiles) end else Aibika.msg 'Not including encoding support files' end # Find features and decide where to put them in the temporary # directory layout. libs = [] features.each do |feature| path = find_load_path(all_load_paths, feature) if path.nil? || path. == Pathname.pwd Aibika.files << feature else feature = feature.relative_path_from(path.) if feature.absolute? fullpath = feature.(path) if fullpath.subpath?(Host.exec_prefix) # Features found in the Ruby installation are put in the # temporary Ruby installation. libs << [fullpath, fullpath.relative_path_from(Host.exec_prefix)] elsif defined?(Gem) && ((gemhome = Gem.path.find { |pth| fullpath.subpath?(pth) })) # Features found in any other Gem path (e.g. ~/.gems) is put # in a special 'gemhome' folder. targetpath = GEMHOMEDIR / fullpath.relative_path_from(Pathname(gemhome)) libs << [fullpath, targetpath] elsif fullpath.subpath?(src_prefix) || path == working_directory # Any feature found inside the src_prefix automatically gets # added as a source file (to go in 'src'). Aibika.files << fullpath # Add the load path unless it was added by the script while # running (or we assume that the script can also set it up # correctly when running from the resulting executable). src_load_path << path unless @added_load_paths.include?(path) elsif @added_load_paths.include?(path) # Any feature that exist in a load path added by the script # itself is added as a file to go into the 'src' (src_prefix # will be adjusted below to point to the common parent). Aibika.files << fullpath else # All other feature that can not be resolved go in the the # Ruby sitelibdir. This is automatically in the load path # when Ruby starts. libs << [fullpath, instsitelibdir / feature] end end end # Recompute the src_prefix. Files may have been added implicitly # while scanning through features. src_prefix, src_files = find_src_root(Aibika.files) Aibika.files.replace(src_files) # Add the load path that are required with the correct path after # src_prefix was adjusted. load_path += src_load_path.map { |loadpath| TEMPDIR_ROOT / SRCDIR / loadpath.relative_path_from(src_prefix) } # Decide where to put gem files, either the system gem folder, or # GEMHOME. gem_files.each do |gemfile| if gemfile.subpath?(Host.exec_prefix) libs << [gemfile, gemfile.relative_path_from(Host.exec_prefix)] elsif defined?(Gem) && ((gemhome = Gem.path.find { |pth| gemfile.subpath?(pth) })) targetpath = GEMHOMEDIR / gemfile.relative_path_from(Pathname(gemhome)) libs << [gemfile, targetpath] else Aibika.msg "Processing #{gemfile}" Aibika.msg "Host.exec_prefix #{Host.exec_prefix}" Aibika.msg "Gem: #{Gem}" if defined?(Gem) Aibika.fatal_error "Don't know where to put gem file #{gemfile}" end end # If requested, add all ruby standard libraries if Aibika.add_all_core Aibika.msg 'Will include all ruby core libraries' @load_path_before.each do |lp| path = Pathname.new(lp) next unless path.to_posix =~ %r{/(ruby/(?:site_ruby/|vendor_ruby/)?[0-9.]+)/?$}i subdir = ::Regexp.last_match(1) Dir["#{lp}/**/*"].each do |f| fpath = Pathname.new(f) next if fpath.directory? tgt = "lib/#{subdir}/#{fpath.relative_path_from(path).to_posix}" libs << [f, tgt] end end end # Detect additional DLLs dlls = Aibika.autodll ? LibraryDetector.detect_dlls : [] # Detect external manifests manifests = Host.exec_prefix.find_all_files(/\.manifest$/) executable = nil if Aibika.output_override executable = Aibika.output_override else executable = Aibika.files.first.basename.ext('.exe') executable.append_to_filename!('-debug') if Aibika.debug end windowed = (Aibika.files.first.ext?('.rbw') || Aibika.force_windows) && !Aibika.force_console Aibika.msg "Building #{executable}" target_script = nil AibikaBuilder.new(executable, windowed) do |sb| # Add explicitly mentioned files Aibika.msg 'Adding user-supplied source files' Aibika.files.each do |file| file = src_prefix / file target = if file.subpath?(Host.exec_prefix) file.relative_path_from(Host.exec_prefix) elsif file.subpath?(src_prefix) SRCDIR / file.relative_path_from(src_prefix) else SRCDIR / file.basename end target_script ||= target if file.directory? sb.ensuremkdir(target) else begin sb.createfile(file, target) rescue Errno::ENOENT raise unless file =~ IGNORE_MODULE_NAMES end end end # Add the ruby executable and DLL rubyexe = if windowed Host.rubyw_exe else Host.ruby_exe end Aibika.msg "Adding ruby executable #{rubyexe}" sb.createfile(Host.bindir / rubyexe, BINDIR / rubyexe) sb.createfile(Host.bindir / Host.libruby_so, BINDIR / Host.libruby_so) if Host.libruby_so # Add detected DLLs dlls.each do |dll| Aibika.msg "Adding detected DLL #{dll}" target = if dll.subpath?(Host.exec_prefix) dll.relative_path_from(Host.exec_prefix) else BINDIR / File.basename(dll) end sb.createfile(dll, target) end # Add external manifest files manifests.each do |manifest| Aibika.msg "Adding external manifest #{manifest}" target = manifest.relative_path_from(Host.exec_prefix) sb.createfile(manifest, target) end # Add extra DLLs specified on the command line Aibika.extra_dlls.each do |dll| Aibika.msg "Adding supplied DLL #{dll}" sb.createfile(Host.bindir / dll, BINDIR / dll) end # Add gemspec files @gemspecs = sort_uniq(@gemspecs) @gemspecs.each do |gemspec| if gemspec.subpath?(Host.exec_prefix) path = gemspec.relative_path_from(Host.exec_prefix) sb.createfile(gemspec, path) elsif defined?(Gem) && ((gemhome = Pathname(Gem.path.find { |pth| gemspec.subpath?(pth) }))) path = GEMHOMEDIR / gemspec.relative_path_from(gemhome) sb.createfile(gemspec, path) else Aibika.fatal_error "Gem spec #{gemspec} does not exist in the Ruby installation. Don't know where to put it." end end # Add loaded libraries (features, gems) Aibika.msg 'Adding library files' libs.each do |path, target| sb.createfile(path, target) end # Set environment variable sb.setenv('RUBYOPT', ENV['RUBYOPT'] || '') sb.setenv('RUBYLIB', load_path.map(&:to_native).uniq.join(';')) sb.setenv('GEM_PATH', (TEMPDIR_ROOT / GEMHOMEDIR).to_native) # Add the opcode to launch the script extra_arg = Aibika.arg.map { |arg| " \"#{arg.gsub('"', '\"')}\"" }.join installed_ruby_exe = TEMPDIR_ROOT / BINDIR / rubyexe launch_script = (TEMPDIR_ROOT / target_script).to_native sb.postcreateprocess(installed_ruby_exe, "#{rubyexe} \"#{launch_script}\"#{extra_arg}") end return if Aibika.inno_script Aibika.msg "Finished building #{executable} (#{File.size(executable)} bytes)" end |
.fatal_error(msg) ⇒ Object
177 178 179 180 |
# File 'lib/aibika/cli.rb', line 177 def self.fatal_error(msg) puts "ERROR: #{msg}" exit 1 end |
.fence_self?(name) ⇒ Boolean
Fence against packaging of self (aibika gem) unless implicitly requestd String, NilClass and arrays of any of these.
13 14 15 |
# File 'lib/aibika.rb', line 13 def self.fence_self?(name) !Aibika.allow_self && name == 'aibika' end |
.fence_self_dir?(dir) ⇒ Boolean
17 18 19 |
# File 'lib/aibika.rb', line 17 def self.fence_self_dir?(dir) !Aibika.allow_self && dir.start_with?(__dir__) end |
.find_gem_files(features) ⇒ Object
Searches for features that are loaded from gems, then produces a list of files included in those gems’ manifests. Also returns a list of original features that are caused gems to be included. Ruby 1.8 provides Gem.loaded_specs to detect gems, but this is empty with Ruby 1.9. So instead, we look for any loaded file from a gem path.
240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 |
# File 'lib/aibika.rb', line 240 def self.find_gem_files(features) features_from_gems = [] gems = {} # If a Bundler Gemfile was provided, add all gems it specifies if Aibika.gemfile Aibika.msg 'Scanning Gemfile' # Load Rubygems and Bundler so we can scan the Gemfile %w[rubygems bundler].each do |lib| require lib rescue LoadError Aibika.fatal_error "Couldn't scan Gemfile, unable to load #{lib}" end ENV['BUNDLE_GEMFILE'] = Aibika.gemfile Bundler.load.specs.each do |spec| Aibika.verbose_msg "From Gemfile, adding gem #{spec.full_name}" gems[spec.name] ||= spec unless fence_self?(spec.name) end unless gems.any? { |name, _spec| name == 'bundler' } # Bundler itself wasn't added for some reason, let's put it in directly Aibika.verbose_msg 'From Gemfile, forcing inclusion of bundler gem itself' bundler_spec = Gem.loaded_specs['bundler'] bundler_spec or Aibika.fatal_error 'Unable to locate bundler gem' gems['bundler'] ||= spec end end if defined?(Gem) # Include Gems that are loaded Gem.loaded_specs.each { |gemname, spec| gems[gemname] ||= spec unless fence_self?(gemname) } # Fall back to gem detection (loaded_specs are not population on # all Ruby versions) features.each do |feature| # Detect load path unless absolute unless feature.absolute? feature = find_load_path(Pathname($LOAD_PATH), feature) next if feature.nil? # Could be enumerator.so end # Skip if found in known Gem dir if gems.find { |_gem, spec| feature.subpath?(spec.gem_dir) } features_from_gems << feature next end gempaths = Pathname(Gem.path) gempaths.each do |gempath| geminstallpath = Pathname(gempath) / 'gems' next unless feature.subpath?(geminstallpath) gemlocalpath = feature.relative_path_from(geminstallpath) fullgemname = gemlocalpath.path.split('/').first gemspecpath = gempath / 'specifications' / "#{fullgemname}.gemspec" if (spec = Gem::Specification.load(gemspecpath)) gems[spec.name] ||= spec features_from_gems << feature else Aibika.warn "Failed to load gemspec for '#{fullgemname}'" end end end gem_files = [] gems.each do |gemname, spec| next if fence_self?(gemname) if File.exist?(spec.spec_file) @gemspecs << Pathname(spec.spec_file) else spec_name = File.basename(spec.spec_file) spec_path = File.dirname(spec.spec_file) default_spec_file = "#{spec_path}/default/#{spec_name}" if File.exist?(default_spec_file) @gemspecs << Pathname(default_spec_file) Aibika.msg "Using default specification #{default_spec_file} for gem #{spec.full_name}" end end # Determine which set of files to include for this particular gem include = %i[loaded files] Aibika.gem.each do |negate, option, list| next unless list.nil? || list.include?(spec.name) case option when :minimal include = [:loaded] when :guess include = %i[loaded files] when :all include = %i[scripts files] when :full include = %i[scripts files extras] when :spec include = [:spec] when :scripts if negate include.delete(:scripts) else include.push(:scripts) end when :files if negate include.delete(:files) else include.push(:files) end when :extras if negate include.delete(:extras) else include.push(:extras) end end end Aibika.msg "Detected gem #{spec.full_name} (#{include.join(', ')})" gem_root = Pathname(spec.gem_dir) gem_extension = (gem_root / '..' / '..' / 'extensions'). build_complete = if gem_extension.exist? gem_extension.find_all_files(/gem.build_complete/).select do |p| p.dirname.basename.to_s == spec.full_name end end gem_root_files = nil files = [] unless gem_root.directory? Aibika.warn "Gem #{spec.full_name} root folder was not found, skipping" next end # Find the selected files include.each do |set| case set when :spec files << Pathname(spec.files) when :loaded files << features_from_gems.select { |feature| feature.subpath?(gem_root) } when :files gem_root_files ||= gem_root.find_all_files(//) files << gem_root_files.reject { |path| path.relative_path_from(gem_root) =~ GEM_NON_FILE_RE } files << build_complete if build_complete when :extras gem_root_files ||= gem_root.find_all_files(//) files << gem_root_files.select { |path| path.relative_path_from(gem_root) =~ GEM_EXTRA_RE } when :scripts gem_root_files ||= gem_root.find_all_files(//) files << gem_root_files.select { |path| path.relative_path_from(gem_root) =~ GEM_SCRIPT_RE } end end files.flatten! actual_files = files.select(&:file?) (files - actual_files).each do |missing_file| Aibika.warn "#{missing_file} was not found" end total_size = actual_files.inject(0) { |size, path| size + path.size } Aibika.msg "\t#{actual_files.size} files, #{total_size} bytes" gem_files += actual_files end gem_files = sort_uniq(gem_files) else gem_files = [] end features_from_gems -= gem_files [gem_files, features_from_gems] end |
.find_load_path(loadpaths, feature) ⇒ Object
Guess the load path (from ‘paths’) that was used to load ‘path’. This is primarily relevant on Ruby 1.8 which stores “unqualified” paths in $LOADED_FEATURES.
186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 |
# File 'lib/aibika.rb', line 186 def self.find_load_path(loadpaths, feature) if feature.absolute? # Choose those loadpaths which contain the feature candidate_loadpaths = loadpaths.select { |loadpath| feature.subpath?(loadpath.) } # Guess the require'd feature feature_pairs = candidate_loadpaths.map { |loadpath| [loadpath, feature.relative_path_from(loadpath.)] } # Select the shortest possible require-path (longest load-path) if feature_pairs.empty? nil else feature_pairs.min_by { |_loadpath, feature| feature.path.size }[0] end else # Select the loadpaths that contain 'feature' and select the shortest candidates = loadpaths.select { |loadpath| feature.(loadpath).exist? } candidates.max_by { |loadpath| loadpath.path.size } end end |
.find_src_root(files) ⇒ Object
Find the root of all files specified on the command line and use it as the “src” of the output.
207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 |
# File 'lib/aibika.rb', line 207 def self.find_src_root(files) src_files = files.map(&:expand) src_prefix = src_files.inject(src_files.first.dirname) do |srcroot, path| unless path.subpath?(Host.exec_prefix) loop do relpath = path.relative_path_from(srcroot) Aibika.fatal_error 'No common directory contains all specified files' if relpath.absolute? break unless relpath.to_s =~ %r{^\.\./} srcroot = srcroot.dirname if srcroot == srcroot.dirname Aibika.fatal_error "Endless loop detected in find_src_root method. Reducing srcroot --> #{srcroot.dirname}" end end end srcroot end src_files = src_files.map do |file| if file.subpath?(src_prefix) file.relative_path_from(src_prefix) else file end end [src_prefix, src_files] end |
.find_stubs ⇒ Object
123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 |
# File 'lib/aibika.rb', line 123 def self.find_stubs if defined?(DATA) @stubimage = @stubwimage = lzmaimage = @lzmapath = Host.tempdir / 'lzma.exe' File.open(@lzmapath, 'wb') { |file| file << lzmaimage } ediconimage = @ediconpath = Host.tempdir / 'edicon.exe' File.open(@ediconpath, 'wb') { |file| file << ediconimage } else aibikapath = Pathname(File.dirname(__FILE__)) @stubimage = File.open(aibikapath / '../share/aibika/stub.exe', 'rb', &:read) @stubwimage = File.open(aibikapath / '../share/aibika/stubw.exe', 'rb', &:read) @lzmapath = (aibikapath / '../share/aibika/lzma.exe'). @ediconpath = (aibikapath / '../share/aibika/edicon.exe'). end end |
.init(argv) ⇒ Object
142 143 144 145 146 147 |
# File 'lib/aibika.rb', line 142 def self.init(argv) save_environment parseargs(argv) find_stubs @ignore_modules.push(*ObjectSpace.each_object(Module).to_a) end |
.msg(msg) ⇒ Object
165 166 167 |
# File 'lib/aibika/cli.rb', line 165 def self.msg(msg) puts "=== #{msg}" unless Aibika.quiet end |
.next_embedded_image ⇒ Object
Returns a binary blob store embedded in the current Ruby script.
106 107 108 |
# File 'lib/aibika.rb', line 106 def self. DATA.read(DATA.readline.to_i).unpack1('m') end |
.parseargs(argv) ⇒ Object
5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 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 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 |
# File 'lib/aibika/cli.rb', line 5 def self.parseargs(argv) usage = <<~USG aibika [options] script.rb Aibika options: --help Display this information. --quiet Suppress output while building executable. --verbose Show extra output while building executable. --version Display version number and exit. Packaging options: --dll dllname Include additional DLLs from the Ruby bindir. --add-all-core Add all core ruby libraries to the executable. --gemfile <file> Add all gems and dependencies listed in a Bundler Gemfile. --no-enc Exclude encoding support files --allow-self Include self (aibika gem) if detected or specified This option is required only if aibika gem is deployed as a part of broader bundled your solution Gem content detection modes: --gem-minimal[=gem1,..] Include only loaded scripts --gem-guess=[gem1,...] Include loaded scripts & best guess (DEFAULT) --gem-all[=gem1,..] Include all scripts & files --gem-full[=gem1,..] Include EVERYTHING --gem-spec[=gem1,..] Include files in gemspec (Does not work with Rubygems 1.7+) minimal: loaded scripts guess: loaded scripts and other files all: loaded scripts, other scripts, other files (except extras) full: Everything found in the gem directory --[no-]gem-scripts[=..] Other script files than those loaded --[no-]gem-files[=..] Other files (e.g. data files) --[no-]gem-extras[=..] Extra files (README, etc.) scripts: .rb/.rbw files extras: C/C++ sources, object files, test, spec, README files: all other files Auto-detection options: --no-dep-run Don't run script.rb to check for dependencies. --no-autoload Don't load/include script.rb's autoloads. --no-autodll Disable detection of runtime DLL dependencies. Output options: --output <file> Name the exe to generate. Defaults to ./<scriptname>.exe. --no-lzma Disable LZMA compression of the executable. --innosetup <file> Use given Inno Setup script (.iss) to create an installer. Executable options: --windows Force Windows application (rubyw.exe) --console Force console application (ruby.exe) --chdir-first When exe starts, change working directory to app dir. --icon <ico> Replace icon with a custom one. --debug Executable will be verbose. --debug-extract Executable will unpack to local dir and not delete after. USG while (arg = argv.shift) case arg when /\A--(no-)?lzma\z/ @options[:lzma_mode] = !::Regexp.last_match(1) when /\A--no-dep-run\z/ @options[:run_script] = false when /\A--add-all-core\z/ @options[:add_all_core] = true when /\A--output\z/ @options[:output_override] = Pathname(argv.shift) when /\A--dll\z/ @options[:extra_dlls] << argv.shift when /\A--quiet\z/ @options[:quiet] = true when /\A--verbose\z/ @options[:verbose] = true when /\A--windows\z/ @options[:force_windows] = true when /\A--console\z/ @options[:force_console] = true when /\A--no-autoload\z/ @options[:load_autoload] = false when /\A--chdir-first\z/ @options[:chdir_first] = true when /\A--icon\z/ @options[:icon_filename] = Pathname(argv.shift) Aibika.fatal_error "Icon file #{icon_filename} not found.\n" unless icon_filename.exist? when /\A--gemfile\z/ @options[:gemfile] = Pathname(argv.shift) Aibika.fatal_error "Gemfile #{gemfile} not found.\n" unless gemfile.exist? when /\A--innosetup\z/ @options[:inno_script] = Pathname(argv.shift) Aibika.fatal_error "Inno Script #{inno_script} not found.\n" unless inno_script.exist? when /\A--no-autodll\z/ @options[:autodll] = false when /\A--version\z/ puts "Aibika #{VERSION}" exit 0 when /\A--no-warnings\z/ @options[:show_warnings] = false when /\A--debug\z/ @options[:debug] = true when /\A--debug-extract\z/ @options[:debug_extract] = true when /\A--\z/ @options[:arg] = ARGV.dup ARGV.clear when /\A--(no-)?enc\z/ @options[:enc] = !::Regexp.last_match(1) when /\A--(no-)?gem-(\w+)(?:=(.*))?$/ negate = ::Regexp.last_match(1) group = ::Regexp.last_match(2) list = ::Regexp.last_match(3) @options[:gem] ||= [] @options[:gem] << [negate, group.to_sym, list && list.split(',')] when /\A--help\z/, /\A--./ puts usage exit 0 else @options[:files] << if __FILE__.respond_to?(:encoding) arg.dup.force_encoding(__FILE__.encoding) else arg end end end if Aibika.debug_extract && Aibika.inno_script Aibika.fatal_error 'The --debug-extract option conflicts with use of Inno Setup' end if Aibika.lzma_mode && Aibika.inno_script Aibika.fatal_error 'LZMA compression must be disabled (--no-lzma) when using Inno Setup' end if !Aibika.chdir_first && Aibika.inno_script Aibika.fatal_error 'Chdir-first mode must be enabled (--chdir-first) when using Inno Setup' end if files.empty? puts usage exit 1 end @options[:files].map! do |path| path = path.encode('UTF-8').tr('\\', '/') if File.directory?(path) # If a directory is passed, we want all files under that directory path = "#{path}/**/*" end files = Dir[path] Aibika.fatal_error "#{path} not found!" if files.empty? files.map { |pth| Pathname(pth). } end.flatten! end |
.Pathname(obj) ⇒ Object
Type conversion for the Pathname class. Works with Pathname, String, NilClass and arrays of any of these.
23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
# File 'lib/aibika.rb', line 23 def self.Pathname(obj) case obj when Pathname obj when Array obj.map { |x| Pathname(x) } when String Pathname.new(obj) when NilClass nil else raise ArgumentError, obj end end |
.restore_environment ⇒ Object
117 118 119 120 121 |
# File 'lib/aibika.rb', line 117 def self.restore_environment @env_before.each { |key, value| ENV[key] = value } ENV.each_key { |key| ENV.delete(key) unless @env_before.key?(key) } Dir.chdir @pwd_before end |
.save_environment ⇒ Object
110 111 112 113 114 115 |
# File 'lib/aibika.rb', line 110 def self.save_environment @load_path_before = $LOAD_PATH.dup @pwd_before = Dir.pwd @env_before = {} ENV.each { |key, value| @env_before[key] = value } end |
.sort_uniq(arr) ⇒ Object
Sorts and returns an array without duplicates. Works with complex objects (such as Pathname), in contrast to Array#uniq.
40 41 42 |
# File 'lib/aibika.rb', line 40 def self.sort_uniq(arr) arr.sort.inject([]) { |r, e| r.last == e ? r : r << e } end |
.verbose_msg(msg) ⇒ Object
169 170 171 |
# File 'lib/aibika/cli.rb', line 169 def self.verbose_msg(msg) puts msg if Aibika.verbose && !Aibika.quiet end |
.warn(msg) ⇒ Object
173 174 175 |
# File 'lib/aibika/cli.rb', line 173 def self.warn(msg) msg "WARNING: #{msg}" if Aibika.show_warnings end |