Class: Ocran::Option
- Inherits:
-
Object
- Object
- Ocran::Option
- Defined in:
- lib/ocran/option.rb
Instance Method Summary collapse
- #add_all_core? ⇒ Boolean
- #add_all_encoding? ⇒ Boolean
-
#application_gemfile ⇒ Object
The Gemfile the application runs under: the one named by --gemfile, or else the nearest Gemfile at or above the script's directory, which is where Bundler itself would look.
- #argv ⇒ Object
- #auto_detect_dlls? ⇒ Boolean
- #bundle_identifier ⇒ Object
- #chdir_before? ⇒ Boolean
- #chdir_exe_dir? ⇒ Boolean
-
#cosmo? ⇒ Boolean
True when the build produces an APE (Actually Portable Executable), i.e.
- #cosmo_cc ⇒ Object
- #cosmo_ruby ⇒ Object
-
#cosmo_zip? ⇒ Boolean
True when the application is packaged by injecting it into the ZIP store of the cosmopolitan Ruby itself: no cosmocc, no launcher stub, and no extraction to a temporary directory at run time.
- #enable_compression? ⇒ Boolean
- #enable_debug_extract? ⇒ Boolean
- #enable_debug_mode? ⇒ Boolean
- #extra_dlls ⇒ Object
- #force_autoload? ⇒ Boolean
- #force_console? ⇒ Boolean
- #force_windows? ⇒ Boolean
- #gem_options ⇒ Object
- #gemfile ⇒ Object
- #icon_filename ⇒ Object
-
#initialize ⇒ Option
constructor
A new instance of Option.
- #inno_setup_script ⇒ Object
- #load_autoload? ⇒ Boolean
-
#load_cosmo_toolchain ⇒ Object
Pulls in Ocran::CosmoToolchain for the --cosmo/--cosmo-ruby options.
- #macosx_bundle ⇒ Object
- #output_dir ⇒ Object
- #output_executable ⇒ Object
- #output_override ⇒ Object
- #output_zip ⇒ Object
- #parse(argv) ⇒ Object
- #quiet? ⇒ Boolean
- #rubyopt ⇒ Object
- #run_script? ⇒ Boolean
- #script ⇒ Object
- #source_files ⇒ Object
- #usage ⇒ Object
- #use_inno_setup? ⇒ Boolean
- #verbose? ⇒ Boolean
- #warning? ⇒ Boolean
- #windowed? ⇒ Boolean
- #wrapper_exe? ⇒ Boolean
Constructor Details
#initialize ⇒ Option
Returns a new instance of Option.
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 |
# File 'lib/ocran/option.rb', line 9 def initialize @options = { :add_all_core? => false, :add_all_encoding? => true, :argv => [], :auto_detect_dlls? => true, :bundle_identifier => nil, :macosx_bundle => nil, :macosx_bundle? => false, :chdir_before? => false, :chdir_exe_dir? => false, :cosmo_cc => nil, :cosmo_ruby => nil, :cosmo_zip? => false, :enable_compression? => true, :enable_debug_extract? => false, :enable_debug_mode? => false, :extra_dlls => [], :force_console? => false, :force_windows? => false, :gem_options => [], :gemfile => nil, :icon_filename => nil, :inno_setup_script => nil, :load_autoload? => true, :output_dir => nil, :output_override => nil, :output_zip => nil, :quiet? => false, :rubyopt => nil, :run_script? => true, :script => nil, :source_files => [], :verbose? => false, :warning? => true, :wrapper_exe? => true, } end |
Instance Method Details
#add_all_core? ⇒ Boolean
370 |
# File 'lib/ocran/option.rb', line 370 def add_all_core? = @options[__method__] |
#add_all_encoding? ⇒ Boolean
372 |
# File 'lib/ocran/option.rb', line 372 def add_all_encoding? = @options[__method__] |
#application_gemfile ⇒ Object
The Gemfile the application runs under: the one named by --gemfile, or else the nearest Gemfile at or above the script's directory, which is where Bundler itself would look. Returns nil when the application has no Gemfile at all.
This is how the application's own bundle is told apart from whatever
bundle OCRAN happens to have been started under. Running
bundle exec ocran app.rb from the application's own directory is the
ordinary case, and there the two are the same file; packaging some
other project from inside this one's bundle is not.
463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 |
# File 'lib/ocran/option.rb', line 463 def application_gemfile return gemfile if gemfile dir = script..dirname loop do GEMFILE_NAMES.each do |name| candidate = dir + name return candidate if candidate.file? end parent = dir.parent return nil if parent == dir dir = parent end end |
#argv ⇒ Object
374 |
# File 'lib/ocran/option.rb', line 374 def argv = @options[__method__] |
#auto_detect_dlls? ⇒ Boolean
380 |
# File 'lib/ocran/option.rb', line 380 def auto_detect_dlls? = @options[__method__] |
#bundle_identifier ⇒ Object
376 |
# File 'lib/ocran/option.rb', line 376 def bundle_identifier = @options[__method__] |
#chdir_before? ⇒ Boolean
382 |
# File 'lib/ocran/option.rb', line 382 def chdir_before? = @options[__method__] |
#chdir_exe_dir? ⇒ Boolean
384 |
# File 'lib/ocran/option.rb', line 384 def chdir_exe_dir? = @options[__method__] |
#cosmo? ⇒ Boolean
True when the build produces an APE (Actually Portable Executable), i.e. an APE launcher stub is used: an explicit toolchain (--cosmo), a cosmopolitan Ruby payload (--cosmo-ruby, whose toolchain is inferred), or both.
405 |
# File 'lib/ocran/option.rb', line 405 def cosmo? = !!(cosmo_cc || cosmo_ruby) |
#cosmo_cc ⇒ Object
385 |
# File 'lib/ocran/option.rb', line 385 def cosmo_cc = @options[__method__] |
#cosmo_ruby ⇒ Object
387 |
# File 'lib/ocran/option.rb', line 387 def cosmo_ruby = @options[__method__] |
#cosmo_zip? ⇒ Boolean
True when the application is packaged by injecting it into the ZIP store of the cosmopolitan Ruby itself: no cosmocc, no launcher stub, and no extraction to a temporary directory at run time.
392 |
# File 'lib/ocran/option.rb', line 392 def cosmo_zip? = @options[__method__] |
#enable_compression? ⇒ Boolean
407 |
# File 'lib/ocran/option.rb', line 407 def enable_compression? = @options[__method__] |
#enable_debug_extract? ⇒ Boolean
409 |
# File 'lib/ocran/option.rb', line 409 def enable_debug_extract? = @options[__method__] |
#enable_debug_mode? ⇒ Boolean
411 |
# File 'lib/ocran/option.rb', line 411 def enable_debug_mode? = @options[__method__] |
#extra_dlls ⇒ Object
413 |
# File 'lib/ocran/option.rb', line 413 def extra_dlls = @options[__method__] |
#force_autoload? ⇒ Boolean
415 |
# File 'lib/ocran/option.rb', line 415 def force_autoload? = @options[__method__] |
#force_console? ⇒ Boolean
417 |
# File 'lib/ocran/option.rb', line 417 def force_console? = @options[__method__] |
#force_windows? ⇒ Boolean
419 |
# File 'lib/ocran/option.rb', line 419 def force_windows? = @options[__method__] |
#gem_options ⇒ Object
421 |
# File 'lib/ocran/option.rb', line 421 def = @options[__method__] |
#gemfile ⇒ Object
423 |
# File 'lib/ocran/option.rb', line 423 def gemfile = @options[__method__] |
#icon_filename ⇒ Object
425 |
# File 'lib/ocran/option.rb', line 425 def icon_filename = @options[__method__] |
#inno_setup_script ⇒ Object
427 |
# File 'lib/ocran/option.rb', line 427 def inno_setup_script = @options[__method__] |
#load_autoload? ⇒ Boolean
429 |
# File 'lib/ocran/option.rb', line 429 def load_autoload? = @options[__method__] |
#load_cosmo_toolchain ⇒ Object
Pulls in Ocran::CosmoToolchain for the --cosmo/--cosmo-ruby options.
Deliberately Kernel#load and not require_relative: OCRAN detects the application's dependencies by diffing $LOADED_FEATURES around the dependency run, and the "before" snapshot is taken before the command line is parsed (Runner#initialize). Anything require'd from here would therefore show up in that diff and be packed into the user's application - packing OCRAN's own source file with it, and (because the src prefix is the common parent of all source files) moving the whole application down into a deeper src/ subdirectory. Kernel#load leaves $LOADED_FEATURES untouched; the same idiom is used for refine_pathname.rb above.
162 163 164 |
# File 'lib/ocran/option.rb', line 162 def load_cosmo_toolchain load File.("cosmo_toolchain.rb", __dir__) unless defined? CosmoToolchain end |
#macosx_bundle ⇒ Object
378 |
# File 'lib/ocran/option.rb', line 378 def macosx_bundle = @options[__method__] |
#output_dir ⇒ Object
431 |
# File 'lib/ocran/option.rb', line 431 def output_dir = @options[__method__] |
#output_executable ⇒ Object
433 |
# File 'lib/ocran/option.rb', line 433 def output_executable = @options[__method__] |
#output_override ⇒ Object
435 |
# File 'lib/ocran/option.rb', line 435 def output_override = @options[__method__] |
#output_zip ⇒ Object
437 |
# File 'lib/ocran/option.rb', line 437 def output_zip = @options[__method__] |
#parse(argv) ⇒ Object
166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 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 233 234 235 236 237 238 239 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 |
# File 'lib/ocran/option.rb', line 166 def parse(argv) while (arg = argv.shift) case arg when /\A--(no-)?lzma\z/ @options[:enable_compression?] = !$1 when "--no-dep-run" @options[:run_script?] = false when "--add-all-core" @options[:add_all_core?] = true when "--output" path = argv.shift @options[:output_override] = Pathname.new(path). if path when "--output-dir" path = argv.shift @options[:output_dir] = Pathname.new(path). if path when "--output-zip" path = argv.shift @options[:output_zip] = Pathname.new(path). if path when "--no-wrapper-exe" @options[:wrapper_exe?] = false when "--macosx-bundle" @options[:macosx_bundle?] = true when "--bundle-id" @options[:bundle_identifier] = argv.shift when "--dll" path = argv.shift @options[:extra_dlls] << path if path when "--quiet" @options[:quiet?] = true when "--verbose" @options[:verbose?] = true when "--windows" @options[:force_windows?] = true when "--console" @options[:force_console?] = true when "--no-autoload" @options[:load_autoload?] = false when "--chdir-first" @options[:chdir_before?] = true when "--chdir-exe-dir" @options[:chdir_exe_dir?] = true when "--icon" path = argv.shift raise "Icon file #{path} not found" unless path && File.exist?(path) @options[:icon_filename] = Pathname.new(path). when "--rubyopt" @options[:rubyopt] = argv.shift when "--cosmo", "--cosmo-toolchain" # Kept unresolved until validation: resolving here would report # "cosmocc ... is not executable" on a Windows build host, ahead of # the clearer "not supported when building on Windows" check. @options[:cosmo_cc] = argv.shift when "--cosmo-ruby" load_cosmo_toolchain @options[:cosmo_ruby] = CosmoToolchain.resolve_ruby(argv.shift) when "--gemfile" path = argv.shift raise "Gemfile #{path} not found" unless path && File.exist?(path) @options[:gemfile] = Pathname.new(path). when "--innosetup" path = argv.shift raise "Inno Script #{path} not found" unless path && File.exist?(path) @options[:inno_setup_script] = Pathname.new(path). when "--no-autodll" @options[:auto_detect_dlls?] = false when "--version" require_relative "version" puts "Ocran #{VERSION}" raise SystemExit when "--no-warnings" @options[:warning?] = false when "--debug" @options[:enable_debug_mode?] = true when "--debug-extract" @options[:enable_debug_extract?] = true when "--" @options[:argv] = argv.dup argv.clear break when /\A--(no-)?enc\z/ @options[:add_all_encoding?] = !$1 when /\A--(no-)?gem-(\w+)(?:=(.*))?$/ negate, group, list = $1, $2, $3 @options[:gem_options] << [negate, group.to_sym, list&.split(",")] if group when "--help", "-h", /\A--./ puts usage raise SystemExit else = Dir.glob(arg) if .empty? raise "#{arg} not found!" unless File.exist?(arg) = [arg] end .each do |f| if File.directory?(f) raise "#{f} is empty!" if Dir.empty?(f) # If a directory is passed, we want all files under that directory @options[:source_files] += Pathname.new(f).find.reject(&:directory?).map(&:expand_path) else @options[:source_files] << Pathname.new(f). end end end end raise "No script file specified" if source_files.empty? @options[:script] = source_files.first @options[:force_autoload?] = run_script? && load_autoload? @options[:output_executable] = if output_override output_override else executable = script # If debug mode is enabled, append "-debug" to the filename executable = executable.append_to_filename("-debug") if enable_debug_mode? # Build output files are created in the current directory. # APE binaries built with cosmocc conventionally use .com. ext = if cosmo? ".com" elsif Gem.win_platform? ".exe" else "" end executable.basename.sub_ext(ext). end if @options[:macosx_bundle?] bundle_base = output_override || script.basename @options[:macosx_bundle] = Pathname(bundle_base).sub_ext(".app"). end if chdir_before? && chdir_exe_dir? raise "--chdir-first and --chdir-exe-dir cannot be used together" end @options[:use_inno_setup?] = !!inno_setup_script @options[:verbose?] &&= !quiet? @options[:windowed?] = (script.extname?(".rbw") || force_windows?) && !force_console? if inno_setup_script if enable_debug_extract? raise "The --debug-extract option conflicts with use of Inno Setup" end if enable_compression? raise "LZMA compression must be disabled (--no-lzma) when using Inno Setup" end unless chdir_before? raise "Chdir-first mode must be enabled (--chdir-first) when using Inno Setup" end end if output_dir && output_zip raise "--output-dir and --output-zip cannot be used together" end if cosmo? opt = cosmo_cc ? "--cosmo" : "--cosmo-ruby" if Gem.win_platform? raise "#{opt} is not supported when building on Windows (build the APE package on a Linux/macOS host)" end if force_windows? raise "--windows cannot be used with #{opt}: cosmocc has no GUI (stubw) equivalent; APE stubs are console-only" end load_cosmo_toolchain # A cosmopolitan Ruby that runs an embedded /zip/main.rb can carry # the application inside its own ZIP store, which needs no compiler # and no launcher stub at all - so that is what --cosmo-ruby does # on its own. Naming a toolchain with --cosmo is the way to ask for # the launcher stub explicitly; the other output formats # (--output-dir, --output-zip, --innosetup, --macosx-bundle) are # directory layouts rather than a single binary, so they keep using # it too. @options[:cosmo_zip?] = !!cosmo_ruby && !cosmo_cc && !single_binary_output_conflict && CosmoToolchain.zip_main_support?(cosmo_ruby) unless cosmo_zip? # The APE stub is compiled with cosmocc. --cosmo names that # toolchain explicitly; otherwise it is discovered on the build # host (COSMOCC, PATH, conventional install locations), so one # option is still enough. Resolved here, before the dependency # run, so a missing toolchain fails fast. @options[:cosmo_cc] = CosmoToolchain.require_cc(cosmo_cc) end end if macosx_bundle && (output_dir || output_zip || inno_setup_script) raise "--macosx-bundle cannot be combined with --output-dir, --output-zip, or --innosetup" end end |
#quiet? ⇒ Boolean
439 |
# File 'lib/ocran/option.rb', line 439 def quiet? = @options[__method__] |
#rubyopt ⇒ Object
443 |
# File 'lib/ocran/option.rb', line 443 def rubyopt = @options[__method__] |
#run_script? ⇒ Boolean
445 |
# File 'lib/ocran/option.rb', line 445 def run_script? = @options[__method__] |
#script ⇒ Object
447 |
# File 'lib/ocran/option.rb', line 447 def script = @options[__method__] |
#source_files ⇒ Object
479 |
# File 'lib/ocran/option.rb', line 479 def source_files = @options[__method__] |
#usage ⇒ Object
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 |
# File 'lib/ocran/option.rb', line 48 def usage <<EOF ocran [options] script.rb Ocran options: --help, -h 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 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. --output-dir <dir> Output all files to a directory with a launch script instead of an exe. --output-zip <file> Output a zip archive containing all files and a launch script. --no-wrapper-exe Do not add the wrapper executable to installer, directory or zip output (a launch script is always included there). --macosx-bundle Build a macOS .app bundle. Use --output to name it (default: <scriptname>.app). --bundle-id <id> Bundle identifier for the macOS app bundle (default: com.example.<appname>). --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. --chdir-exe-dir When exe starts, change working directory to the directory containing the executable itself. --icon <ico> Replace icon with a custom one. --rubyopt <str> Set the RUBYOPT environment variable when running the executable. -I/-r entries with absolute build-machine paths are translated to their packed locations at build time. --debug Executable will be verbose. --debug-extract Executable will unpack to local dir and not delete after. Experimental options: --cosmo-ruby <ruby.com> Package the given cosmopolitan-built Ruby (an APE, e.g. ruby.com) as the interpreter instead of the host Ruby: the result is a single <scriptname>.com that runs on Linux, Windows and macOS. The APE must be fully self-contained (stdlib embedded in its ZIP store). Dependency detection still runs under the host Ruby; native-extension gems are rejected (pure-Ruby gems are packed as usual). When the given interpreter runs an embedded /zip/main.rb (CosmoRuby builds do), the application is injected into its ZIP store: no compiler is needed and the executable starts without unpacking anything. Otherwise OCRAN falls back to an APE launcher stub that extracts the application at every start, and locates the cosmocc toolchain to build that stub automatically (COSMOCC environment variable, cosmocc in PATH, then conventional install locations such as ~/.cosmocc/*/bin/cosmocc). --cosmo <path> Use the Cosmopolitan toolchain (cosmocc) at <path> to build the launcher stub, overriding the automatic toolchain lookup. <path> is the cosmocc executable or its install dir. Given together with --cosmo-ruby it forces the launcher-stub build even when the interpreter supports ZIP packaging. Given without --cosmo-ruby, it packages the host Ruby behind an APE stub. Console-only; output defaults to <scriptname>.com. (Alias: --cosmo-toolchain) EOF end |
#use_inno_setup? ⇒ Boolean
481 |
# File 'lib/ocran/option.rb', line 481 def use_inno_setup? = @options[__method__] |
#verbose? ⇒ Boolean
483 |
# File 'lib/ocran/option.rb', line 483 def verbose? = @options[__method__] |
#warning? ⇒ Boolean
485 |
# File 'lib/ocran/option.rb', line 485 def warning? = @options[__method__] |
#windowed? ⇒ Boolean
487 488 489 490 |
# File 'lib/ocran/option.rb', line 487 def windowed? return false unless Gem.win_platform? @options[:windowed?] end |
#wrapper_exe? ⇒ Boolean
441 |
# File 'lib/ocran/option.rb', line 441 def wrapper_exe? = @options[__method__] |