neri 0.9.1 → 0.9.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/lib/neri/build.rb CHANGED
@@ -1,39 +1,39 @@
1
1
  #!/usr/bin/env ruby
2
- # encoding: UTF-8
3
2
 
4
3
  require "neri"
5
4
 
6
5
  module Neri
7
6
  @data_files = []
8
-
7
+
9
8
  @options = {
10
9
  quiet: false,
11
10
  verbose: false,
12
-
11
+
13
12
  external_encoding: nil,
14
-
13
+
15
14
  dlls: [],
16
15
  libs: [],
17
16
  gems: [],
18
17
  encoding: "*",
19
-
18
+
20
19
  enable_gems: false,
21
20
  enable_did_you_mean: false,
22
- chdir_first: false,
21
+ chdir_first: true,
23
22
  pause_last: nil,
24
23
  pause_text: nil,
25
-
24
+
26
25
  output_dir: "./",
27
26
  system_dir: "system",
28
-
27
+
29
28
  datafile: nil,
30
29
  encryption_key: nil,
31
-
30
+ virtual_directory: nil,
31
+
32
32
  no_exe: false,
33
33
  use_b2ec: false,
34
34
  b2ec_path: "Bat_To_Exe_Converter",
35
35
  b2ec: {
36
- icon: "#{File.expand_path(File.dirname(__FILE__) + '/../../share/default.ico')}",
36
+ icon: File.expand_path("#{File.dirname(__FILE__)}/../../share/default.ico"),
37
37
  invisible: nil,
38
38
  x64: nil,
39
39
  uac_admin: nil,
@@ -50,50 +50,49 @@ module Neri
50
50
  specialbuild: nil,
51
51
  comments: nil
52
52
  },
53
-
53
+
54
54
  use_upx: false,
55
55
  upx_path: "upx",
56
56
  upx_targets: ["bin/**/*.dll"],
57
57
  upx_options: "",
58
-
58
+
59
59
  zipfile: nil,
60
60
  sevenzip_path: "7z",
61
-
61
+
62
62
  inno_script: nil,
63
- iscc_path: "iscc",
63
+ iscc_path: "iscc"
64
64
  }
65
65
  @rubyopt = ENV["RUBYOPT"].to_s
66
66
  @args = ""
67
67
  @encryption_key = nil
68
-
68
+
69
69
  @use_dxruby = false
70
70
  @use_dxruby_tiled = false
71
71
  @use_ayame = false
72
-
72
+
73
73
  class << self
74
-
75
74
  attr_reader :options
76
-
77
- def relative_path(path, basedir=rubydir, prepath = "")
75
+
76
+ def relative_path(path, basedir = rubydir, prepath = "")
78
77
  basedir.concat(File::SEPARATOR) unless basedir.end_with?(File::SEPARATOR)
79
- return path.start_with?(basedir) ? path.sub(basedir, prepath) : path
78
+ path.start_with?(basedir) ? path.sub(basedir, prepath) : path
80
79
  end
81
-
80
+
82
81
  def to_winpath(path)
83
- return File::ALT_SEPARATOR ? path.tr(File::SEPARATOR, File::ALT_SEPARATOR) : path
82
+ File::ALT_SEPARATOR ? path.tr(File::SEPARATOR, File::ALT_SEPARATOR) : path
84
83
  end
85
-
86
- def bindir( ); RbConfig::CONFIG["bindir"] || File.join(rubydir, "bin"); end
87
- def rubydir( ); File.join(RbConfig::TOPDIR, ""); end
88
- def rubyexe( ); RbConfig.ruby; end
89
- def scriptfile(); @data_files.first; end
90
- def basename( ); File.basename(scriptfile, ".*"); end
91
- def basepath( ); File.join(options[:output_dir], basename); end
92
- def datafile( ); File.join(options[:output_dir], options[:system_dir], options[:datafile]); end
93
-
84
+
85
+ def bindir ; RbConfig::CONFIG["bindir"] || File.join(rubydir, "bin"); end
86
+ def rubydir ; File.join(RbConfig::TOPDIR, ""); end
87
+ def rubyexe ; RbConfig.ruby; end
88
+ def scriptfile; @data_files.first; end
89
+ def basename ; File.basename(scriptfile, ".*"); end
90
+ def basepath ; File.join(options[:output_dir], basename); end
91
+ def datafile ; File.join(options[:output_dir], options[:system_dir], options[:datafile]); end
92
+
94
93
  # --help
95
94
  def output_help
96
- puts <<-EOF
95
+ puts <<-HELP_MESSAGE
97
96
  usage: neri [options] script.rb (other_files...) -- script_arguments
98
97
 
99
98
  options:
@@ -101,28 +100,28 @@ options:
101
100
  --version or -v
102
101
  --quiet
103
102
  --verbose
104
-
103
+
105
104
  --external-encoding <encoding>
106
-
105
+
107
106
  --dll <dll1>,<dll2>,...
108
107
  --lib <lib1>,<lib2>,...
109
108
  --gem <gem1>,<gem2>,...
110
-
109
+
111
110
  --no-enc
112
111
  --encoding <enc1>,<enc2>,...
113
-
112
+
114
113
  --enable-gems
115
114
  --enable-did-you-mean
116
- --chdir-first
115
+ --no-chdir
117
116
  --pause-last
118
117
  --no-pause-last
119
118
  --pause-text <text>
120
-
119
+
121
120
  --output-dir <dirname>
122
121
  --system-dir <dirname>
123
122
  --datafile <filename>
124
123
  --encryption-key <key>
125
-
124
+
126
125
  --no-exe
127
126
  --use-b2ec
128
127
  --b2ec-path <bat_to_exe_converter_path>
@@ -143,28 +142,29 @@ options:
143
142
  --privatebuild <string>
144
143
  --specialbuild <string>
145
144
  --comments <string>
146
-
145
+
147
146
  --use-upx
148
147
  --upx-path <upx path>
149
148
  --upx_targets '<glob>' # ex) 'bin/**/*.dll'
150
149
  --upx-options <options>
151
-
150
+
152
151
  --zipfile <filename>
153
152
  --7zip-path <7-zip path>
154
-
153
+
155
154
  --innosetup <inno_script>
156
155
  --iscc-path <iscc path>
157
-
156
+
158
157
  --create-recipe <recipefile>
159
158
  --recipe <recipefile>
160
- EOF
159
+ --virtual-directory <string>
160
+ HELP_MESSAGE
161
161
  end
162
-
162
+
163
163
  # --version
164
164
  def output_version
165
165
  puts "Neri #{Neri::VERSION}"
166
166
  end
167
-
167
+
168
168
  # --create-recipe
169
169
  def create_recipe(file, hash = options, pre = "Neri.options")
170
170
  hash.each_pair do |key, value|
@@ -180,8 +180,7 @@ options:
180
180
  end
181
181
  end
182
182
  end
183
-
184
-
183
+
185
184
  def check_options
186
185
  nputs_v "Checking Neri options."
187
186
  while arg = ARGV.shift
@@ -194,7 +193,7 @@ options:
194
193
  exit
195
194
  when "--quiet", "-q"
196
195
  options[:quiet] = true
197
- when "--verbose", "-v"
196
+ when "--verbose"
198
197
  options[:verbose] = true
199
198
  when "--external_encoding"
200
199
  options[:external_encoding] = ARGV.shift
@@ -212,7 +211,9 @@ options:
212
211
  options[:enable_gems] = true
213
212
  when "--enable-did-you-mean"
214
213
  options[:enable_did_you_mean] = true
215
- when "--chdir-first"
214
+ when "--no-chdir"
215
+ options[:chdir_first] = false
216
+ when "--chdir-first" # deprecated
216
217
  options[:chdir_first] = true
217
218
  when "--pause-last"
218
219
  options[:pause_last] = true
@@ -278,7 +279,7 @@ options:
278
279
  when "--upx-options"
279
280
  options[:upx_options] = ARGV.shift
280
281
  when "--zipfile"
281
- options[:zipfile] = ARGV.shift.encode("utf-8").sub(/\.zip$/, "") + ".zip"
282
+ options[:zipfile] = "#{ARGV.shift.encode('utf-8').sub(/\.zip$/, '')}.zip"
282
283
  when "--7zip-path"
283
284
  options[:sevenzip_path] = ARGV.shift.encode("utf-8")
284
285
  when "--innosetup"
@@ -289,12 +290,14 @@ options:
289
290
  require "json"
290
291
  filename = ARGV.shift.encode("utf-8")
291
292
  nputs "Creating recipe_file '#{filename}'."
292
- open(filename, "w:utf-8"){ |file| create_recipe(file) }
293
+ File.open(filename, "w:utf-8") { |file| create_recipe(file) }
293
294
  exit
294
295
  when "--recipe"
295
296
  filename = ARGV.shift.encode("utf-8")
296
297
  nputs_v "Loading recipe_file '#{filename}'."
297
298
  load File.expand_path(filename)
299
+ when "--virtual-directory"
300
+ options[:virtual_directory] = ARGV.shift.encode("utf-8")
298
301
  when "--"
299
302
  break
300
303
  when /^(--.+)/
@@ -305,116 +308,142 @@ options:
305
308
  @data_files.push(arg.encode("utf-8"))
306
309
  end
307
310
  end
308
-
311
+
309
312
  if @data_files.empty?
310
313
  error "No Script File!"
311
314
  output_help
312
315
  exit
313
316
  end
314
-
315
- @args = ARGV.map{ |arg| %[ "#{arg}"] }.join("")
316
- @options[:external_encoding] ||= Encoding::default_external.name
317
- unless options[:enable_gems]
318
- @rubyopt += " --disable-gems" unless @rubyopt.index("--disable-gems")
317
+
318
+ @args = ARGV.map { |a| %( "#{a}") }.join("")
319
+ @options[:external_encoding] ||= Encoding.default_external.name
320
+ unless options[:enable_gems] || @rubyopt.index("--disable-gems")
321
+ @rubyopt += " --disable-gems"
319
322
  end
320
- unless options[:enable_did_you_mean]
321
- @rubyopt += " --disable-did_you_mean" unless @rubyopt.index("--disable-did_you_mean")
323
+ unless options[:enable_did_you_mean] || @rubyopt.index("--disable-did_you_mean")
324
+ @rubyopt += " --disable-did_you_mean"
322
325
  end
323
326
  if @data_files.size > 1 || options[:encryption_key]
324
- options[:datafile] ||= basename + ".dat"
327
+ options[:datafile] ||= "#{basename}.dat"
325
328
  end
326
329
  end
327
-
328
-
330
+
329
331
  # check dependencies
330
- def rb_dependencies()
331
- return $LOADED_FEATURES.uniq
332
+ def rb_dependencies
333
+ $LOADED_FEATURES.uniq
332
334
  end
333
-
334
- def dll_dependencies()
335
- require "Win32API"
336
-
337
- enumprocessmodules = Win32API.new("psapi" , "EnumProcessModules", ["L","P","L","P"], "L")
338
- getmodulefilename = Win32API.new("kernel32", "GetModuleFileNameW", ["L","P","L"], "L")
339
- getcurrentprocess = Win32API.new("kernel32", "GetCurrentProcess" , [], "L")
335
+
336
+ def dll_dependencies
337
+ require "fiddle/import"
338
+
339
+ pointer_type = Fiddle::SIZEOF_VOIDP == Fiddle::SIZEOF_LONG_LONG ? 'q*' : 'l!*'
340
+ psapi = Fiddle.dlopen("psapi.dll")
341
+ kernel32 = Fiddle.dlopen("kernel32.dll")
342
+ enumprocessmodules = Fiddle::Function.new(
343
+ psapi["EnumProcessModules"],
344
+ [Fiddle::TYPE_LONG, Fiddle::TYPE_VOIDP, Fiddle::TYPE_LONG, Fiddle::TYPE_VOIDP],
345
+ Fiddle::TYPE_LONG,
346
+ Fiddle::Importer.const_get(:CALL_TYPE_TO_ABI)[:stdcall]
347
+ )
348
+ getmodulefilename = Fiddle::Function.new(
349
+ kernel32["GetModuleFileNameW"],
350
+ [Fiddle::TYPE_LONG, Fiddle::TYPE_VOIDP, Fiddle::TYPE_LONG],
351
+ Fiddle::TYPE_LONG,
352
+ Fiddle::Importer.const_get(:CALL_TYPE_TO_ABI)[:stdcall]
353
+ )
354
+ getcurrentprocess = Fiddle::Function.new(
355
+ kernel32["GetCurrentProcess"],
356
+ [],
357
+ Fiddle::TYPE_LONG,
358
+ Fiddle::Importer.const_get(:CALL_TYPE_TO_ABI)[:stdcall]
359
+ )
340
360
 
341
361
  bytes_needed = 4 * 32
342
362
  module_handle_buffer = nil
343
- process_handle = getcurrentprocess.call()
363
+ process_handle = getcurrentprocess.call
344
364
  loop do
345
365
  module_handle_buffer = "\x00" * bytes_needed
346
366
  bytes_needed_buffer = [0].pack("I")
347
- r = enumprocessmodules.call(process_handle, module_handle_buffer, module_handle_buffer.size, bytes_needed_buffer)
348
- bytes_needed = bytes_needed_buffer.unpack("I")[0]
367
+ enumprocessmodules.call(
368
+ [process_handle].pack("I").unpack1("i"),
369
+ [module_handle_buffer].pack("p").unpack1(pointer_type),
370
+ [module_handle_buffer.size].pack("I").unpack1("i"),
371
+ [bytes_needed_buffer].pack("p").unpack1(pointer_type)
372
+ )
373
+ bytes_needed = bytes_needed_buffer.unpack1("I")
349
374
  break if bytes_needed <= module_handle_buffer.size
350
375
  end
351
376
 
352
377
  handles = module_handle_buffer.unpack("I*")
353
378
  dependencies = handles.select { |handle| handle > 0 }.map do |handle|
354
379
  str = "\x00\x00" * 256
355
- modulefilename_length = getmodulefilename.call(handle, str, str.size)
356
- modulefilename = str[0, modulefilename_length * 2].force_encoding("UTF-16LE").encode("UTF-8")
357
- end
358
-
359
- dependencies.map!{|dep| dep.sub(/^\\\\\?\\/, "")}
360
- if File::ALT_SEPARATOR
361
- dependencies.map!{|dep| dep.tr(File::ALT_SEPARATOR, File::SEPARATOR)}
380
+ modulefilename_length = getmodulefilename.call(
381
+ [handle].pack("I").unpack1("i"),
382
+ [str].pack("p").unpack1(pointer_type),
383
+ [str.size].pack("I").unpack1("i")
384
+ )
385
+ str[0, modulefilename_length * 2].force_encoding("UTF-16LE").encode("UTF-8")
362
386
  end
387
+
388
+ dependencies.map! { |dep| dep.sub(/^\\\\\?\\/, "") }
389
+ dependencies.map! { |dep| dep.tr(File::ALT_SEPARATOR, File::SEPARATOR) } if File::ALT_SEPARATOR
363
390
  dependencies.delete(rubyexe)
364
-
365
- return dependencies.uniq
391
+
392
+ dependencies.uniq
366
393
  end
367
-
368
- def ruby_dependencies()
394
+
395
+ def ruby_dependencies
369
396
  dependencies = Dir.glob(File.join(bindir, "**", "*.manifest"))
370
397
  dependencies.push(rubyexe)
371
- return dependencies.uniq
398
+ dependencies.uniq
372
399
  end
373
-
374
- def additional_dlls_dependencies()
400
+
401
+ def additional_dlls_dependencies
375
402
  dependencies = []
376
403
  options[:dlls].each do |dll|
377
404
  dependencies += Dir.glob(File.join(bindir, "**", dll))
378
- dependencies += Dir.glob(File.join(bindir, "**", dll + ".*"))
405
+ dependencies += Dir.glob(File.join(bindir, "**", "#{dll}.*"))
379
406
  end
380
- return dependencies.uniq
407
+ dependencies.uniq
381
408
  end
382
-
383
- def additional_libs_dependencies()
409
+
410
+ def additional_libs_dependencies
384
411
  dependencies = []
385
412
  options[:libs].each do |lib|
386
413
  $LOAD_PATH.each do |path|
387
414
  dependencies += Dir.glob(File.join(path, lib))
388
- dependencies += Dir.glob(File.join(path, lib + ".*"))
415
+ dependencies += Dir.glob(File.join(path, "#{lib}.*"))
389
416
  dependencies += Dir.glob(File.join(path, lib, "**", "*"))
390
417
  end
391
418
  end
392
- return dependencies.uniq
419
+ dependencies.uniq
393
420
  end
394
-
395
- def additional_gems_dependencies()
421
+
422
+ def additional_gems_dependencies
396
423
  require "rubygems"
397
424
  dependencies = []
398
425
  rubygems_dir = File.join(Gem.dir, "gems")
399
426
  options[:gems].each do |gem|
400
- gem.sub!(/\:(.+)/, "")
401
- targets = $1.to_s.split("|")
427
+ gem.sub!(/:(.+)/, "")
428
+ targets = Regexp.last_match(1).to_s.split("|")
402
429
  targets.push("lib/**/*")
403
430
  gem += "-*" unless gem.match("-")
404
- gemdir = Dir.glob(File.join(rubygems_dir, gem)).sort.last
431
+ gemdir = Dir.glob(File.join(rubygems_dir, gem)).max
405
432
  next unless gemdir
433
+
406
434
  targets.each do |target|
407
435
  dependencies += Dir.glob(File.join(gemdir, target))
408
436
  end
409
437
  end
410
- return dependencies.uniq
438
+ dependencies.uniq
411
439
  end
412
-
413
- def encoding_dependencies()
440
+
441
+ def encoding_dependencies
414
442
  return [] unless options[:encoding]
443
+
415
444
  dependencies = []
416
445
  enc_dir = Dir.glob(File.join(RbConfig::CONFIG["archdir"] || RbConfig::TOPDIR, "**", "enc")).first
417
-
446
+
418
447
  options[:encoding].split(",").map(&:strip).each do |enc|
419
448
  case enc
420
449
  when "ja"
@@ -423,21 +452,21 @@ options:
423
452
  end
424
453
  else
425
454
  dependencies += Dir.glob(File.join(enc_dir, "**", enc))
426
- dependencies += Dir.glob(File.join(enc_dir, "**", enc + ".*"))
455
+ dependencies += Dir.glob(File.join(enc_dir, "**", "#{enc}.*"))
427
456
  end
428
457
  end
429
-
430
- return dependencies.uniq
458
+
459
+ dependencies.uniq
431
460
  end
432
-
433
- def check_dependencies()
461
+
462
+ def check_dependencies
434
463
  nputs "Running script '#{scriptfile}' to check dependencies."
435
464
  begin
436
465
  load File.expand_path(scriptfile)
437
466
  rescue SystemExit, Interrupt
438
467
  end
439
468
  nputs "Script '#{scriptfile}' end."
440
-
469
+
441
470
  if defined? DXRuby
442
471
  require "neri/dxruby"
443
472
  @use_dxruby = true
@@ -450,15 +479,15 @@ options:
450
479
  require "neri/ayame"
451
480
  @use_ayame = true
452
481
  end
453
-
454
- if options[:b2ec][:invisible] == nil &&
482
+
483
+ if options[:b2ec][:invisible].nil? &&
455
484
  (File.extname(scriptfile) == ".rbw" || @use_dxruby)
456
485
  options[:b2ec][:invisible] = true
457
486
  end
458
- if options[:pause_last] == nil
459
- options[:pause_last] = true unless options[:b2ec][:invisible]
487
+ if options[:pause_last].nil? && !options[:b2ec][:invisible]
488
+ options[:pause_last] = true
460
489
  end
461
-
490
+
462
491
  require "rbconfig"
463
492
  dependencies = []
464
493
  dependencies += rb_dependencies
@@ -469,59 +498,58 @@ options:
469
498
  dependencies += additional_gems_dependencies
470
499
  dependencies += encoding_dependencies
471
500
  dependencies = select_dependencies(dependencies)
472
-
473
- size = dependencies.map{|d| File.size(d)}.inject(&:+)
501
+
502
+ size = dependencies.map { |d| File.size(d) }.inject(&:+)
474
503
  nputs "#{dependencies.size} files, #{size} bytes dependencies."
475
504
  if options[:verbose]
476
505
  dependencies.each do |dependency|
477
506
  nputs_v " - #{dependency}"
478
507
  end
479
508
  end
480
-
481
- return dependencies
509
+
510
+ dependencies
482
511
  end
483
-
512
+
484
513
  def select_dependencies(dependencies)
485
514
  dependencies.select! do |dependency|
486
515
  dependency.start_with?(rubydir)
487
516
  end
488
-
517
+
489
518
  @data_files.each do |file|
490
519
  dependencies.delete(File.expand_path(file))
491
520
  end
492
-
521
+
493
522
  unless options[:enable_gems]
494
523
  dependencies.delete_if do |dependency|
495
524
  File.basename(dependency) == "rubygems.rb" ||
496
- dependency.split(File::SEPARATOR).index("rubygems")
525
+ dependency.split(File::SEPARATOR).index("rubygems")
497
526
  end
498
527
  end
499
528
  unless options[:enable_did_you_mean]
500
529
  dependencies.delete_if do |dependency|
501
530
  File.basename(dependency) == "did_you_mean.rb" ||
502
- dependency.split(File::SEPARATOR).index("did_you_mean")
531
+ dependency.split(File::SEPARATOR).index("did_you_mean")
503
532
  end
504
533
  end
505
-
506
- return dependencies.uniq
534
+
535
+ dependencies.uniq
507
536
  end
508
-
509
-
537
+
510
538
  def copy_files(dependencies)
511
539
  nputs "Copying dependencies."
512
540
  require "fileutils"
513
541
  src_dir = rubydir
514
542
  desc_dir = File.join(options[:output_dir], options[:system_dir], "")
515
-
543
+
516
544
  system_files = dependencies.map do |file|
517
545
  [file, file.sub(src_dir, desc_dir)]
518
546
  end
519
547
  unless options[:enable_gems]
520
- system_files.each do |src, desc|
521
- desc.sub!(/\/gems(\/\d+\.\d+\.\d+\/)gems\/(.+?)\-[^\/]+\/lib\//, "/vendor_ruby\\1")
548
+ system_files.each do |_src, desc|
549
+ desc.sub!(%r{/gems(/\d+\.\d+\.\d+/)gems/(.+?)-[^/]+/lib/}, "/vendor_ruby\\1")
522
550
  end
523
551
  end
524
-
552
+
525
553
  system_files.each do |src, desc|
526
554
  FileUtils.makedirs(File.dirname(desc))
527
555
  if File.file?(src)
@@ -531,49 +559,62 @@ options:
531
559
  end
532
560
  FileUtils.copy(scriptfile, desc_dir) unless options[:datafile]
533
561
  end
534
-
535
-
536
- def create_datafile()
537
- if @data_files.size > 1 || options[:encryption_key]
538
- options[:datafile] ||= basename + ".dat"
539
- end
562
+
563
+ def create_datafile
540
564
  return unless options[:datafile]
541
-
565
+
542
566
  nputs "Creating datafile '#{datafile}'."
543
567
  data_files = @data_files.select { |file| File.file? file }
544
568
  @data_files.select { |file| File.directory? file }.each do |dir|
545
- data_files += Dir.glob(dir + "/**/*").select { |file| File.file? file }
569
+ data_files += Dir.glob("#{dir}/**/*").select { |file| File.file? file }
546
570
  end
571
+ data_files.uniq! { |file| File.expand_path(file) }
572
+
573
+ unless options[:virtual_directory]
574
+ dir_pwd = Dir.pwd.encode(Encoding::UTF_8)
575
+ virtual_directories = Pathname.new(dir_pwd).ascend.to_a.map(&:to_s)
576
+ data_files.each do |file|
577
+ fullpath = File.expand_path(file)
578
+ next if fullpath.start_with?(rubydir) || Pathname.new(file).absolute?
579
+ virtual_directories.shift until fullpath.start_with?(virtual_directories.first)
580
+ end
581
+ options[:virtual_directory] = relative_path(dir_pwd, virtual_directories.first, "/_neri_virtual_directory_/")
582
+ puts "virtual_directory: #{options[:virtual_directory]}"
583
+ end
584
+
547
585
  if options[:encryption_key]
548
586
  require "digest/sha2"
549
587
  @encryption_key = Digest::SHA2.hexdigest(options[:encryption_key])
550
588
  end
551
589
  Neri.key = @encryption_key || "0" * 64
552
- open(datafile, "wb") do |f|
590
+ File.open(datafile, "wb") do |f|
553
591
  pos = 0
554
- files_str = data_files.map{|file|
555
- filename = File.expand_path(file)
556
- filename = relative_path(filename, rubydir, "*neri*" + File::SEPARATOR)
557
- filename = relative_path(filename, Dir.pwd)
558
- filedata = [filename, File.size(file), pos]
592
+ file_informations = data_files.map do |file|
593
+ fullpath = File.expand_path(file)
594
+ filename = if fullpath.start_with?(rubydir)
595
+ relative_path(fullpath, rubydir, "#{options[:system_dir]}#{File::SEPARATOR}")
596
+ else
597
+ file
598
+ end
599
+ filedata = [filename, File.size(file), pos].join("\t")
600
+ nputs_v " - #{filename}:#{File.size(file)} bytes"
559
601
  pos += File.size(file)
560
602
  pos += BLOCK_LENGTH - pos % BLOCK_LENGTH unless pos % BLOCK_LENGTH == 0
561
- nputs_v " - #{filename}:#{File.size(file)} bytes"
562
- filedata.join("\t")
563
- }.join("\n").encode(Encoding::UTF_8)
564
-
565
- f.write(sprintf("%#{BLOCK_LENGTH}d", files_str.bytesize))
603
+ filedata
604
+ end
605
+ files_str = file_informations.join("\n").encode(Encoding::UTF_8)
606
+
607
+ f.write(format("%#{BLOCK_LENGTH}d", files_str.bytesize))
566
608
  f.write(xor(files_str))
567
609
  data_files.each do |file|
568
610
  f.write(xor(File.binread(file)))
569
611
  end
570
612
  end
571
613
  end
572
-
573
-
574
- def create_batfile()
614
+
615
+ def create_batfile
575
616
  nputs "Creating batch_file '#{basepath}.bat'."
576
-
617
+
577
618
  pause_command = ""
578
619
  if options[:pause_last]
579
620
  pause_command += "echo.\n"
@@ -585,37 +626,37 @@ options:
585
626
  end
586
627
  end
587
628
  chdir = options[:chdir_first] ? 'cd /d "%~dp0"' : ""
588
-
589
- open(basepath + ".bat", "w:#{options[:external_encoding]}") do |f|
590
- f.puts <<-EOF
629
+
630
+ File.open("#{basepath}.bat", "w:#{options[:external_encoding]}") do |f|
631
+ f.puts <<-BATCH
591
632
  @echo off
592
633
  setlocal
593
634
  set PATH=%~dp0#{options[:system_dir]}\\#{relative_path(bindir)};%PATH%
594
635
  set NERI_EXECUTABLE=%~0
595
636
  #{chdir}
596
637
  if %~x0 == .exe ( shift )
597
- #{ruby_command(options[:chdir_first] ? "" : "%~dp0")} %1 %2 %3 %4 %5 %6 %7 %8 %9
638
+ #{ruby_command(options[:chdir_first] ? '' : '%~dp0')} %1 %2 %3 %4 %5 %6 %7 %8 %9
598
639
  #{pause_command}
599
640
  endlocal
600
- EOF
641
+ BATCH
601
642
  end
602
643
  end
603
-
604
- def create_exefile()
644
+
645
+ def create_exefile
605
646
  unless system("gcc --version >nul 2>&1 && windres --version >nul 2>&1")
606
647
  error "gcc or windres not found !"
607
648
  create_batfile
608
649
  return
609
650
  end
610
-
611
- exe_file = to_winpath(basepath + ".exe" )
612
- c_file = to_winpath(basepath + "_tmp.c" )
613
- o_file = to_winpath(basepath + "_tmp.o" )
614
- rc_file = to_winpath(basepath + "_tmp.rc")
651
+
652
+ exe_file = to_winpath("#{basepath}.exe" )
653
+ c_file = to_winpath("#{basepath}_tmp.c" )
654
+ o_file = to_winpath("#{basepath}_tmp.o" )
655
+ rc_file = to_winpath("#{basepath}_tmp.rc")
615
656
  system_dir = escape_cstr(to_winpath(File.join(options[:system_dir], "")))
616
657
  nputs "Creating exe_file '#{exe_file}'."
617
- open(c_file, "w:#{options[:external_encoding]}") do |f|
618
- f.puts <<-EOF
658
+ File.open(c_file, "w:#{options[:external_encoding]}") do |f|
659
+ f.puts <<-CFILE
619
660
  #include <stdio.h>
620
661
  #include <stdlib.h>
621
662
  #include <windows.h>
@@ -623,17 +664,17 @@ endlocal
623
664
 
624
665
  int main(int argc, char *argv[])
625
666
  {
626
- char exepath[_MAX_PATH * 2 + 1],
667
+ char exepath[_MAX_PATH * 2 + 1],
627
668
  drive [_MAX_DRIVE + 1],
628
669
  dir [_MAX_DIR * 2 + 1],
629
670
  fname [_MAX_FNAME * 2 + 1],
630
671
  ext [_MAX_EXT * 2 + 1],
631
672
  paths [_MAX_PATH * 32 + 1],
632
673
  runruby[_MAX_PATH * 32 + 1];
633
- PROCESS_INFORMATION pi;
674
+ PROCESS_INFORMATION pi;
634
675
  STARTUPINFO si;
635
676
  ZeroMemory(&si, sizeof(STARTUPINFO));
636
-
677
+
637
678
  if(GetModuleFileName(NULL, exepath, MAX_PATH * 2) != 0){
638
679
  _splitpath_s(exepath, drive, _MAX_DRIVE, dir, _MAX_DIR * 2, fname, _MAX_FNAME * 2, ext, _MAX_EXT * 2);
639
680
  } else {
@@ -644,8 +685,8 @@ int main(int argc, char *argv[])
644
685
  snprintf(paths, sizeof(paths), "PATH=%s%s#{system_dir}bin;%s", drive, dir, getenv("PATH"));
645
686
  putenv(paths);
646
687
  #{options[:chdir_first] ? 'snprintf(paths, sizeof(paths), "%s%s", drive, dir);chdir(paths);' : ''}
647
- snprintf(runruby, sizeof(runruby), "#{escape_cstr(ruby_command(options[:chdir_first] ? "" : "%s%s"))} %s %s %s %s %s %s %s %s %s",
648
- #{options[:chdir_first] ? "" : "drive, dir,"}
688
+ snprintf(runruby, sizeof(runruby), "#{escape_cstr(ruby_command(options[:chdir_first] ? '' : '%s%s'))} %s %s %s %s %s %s %s %s %s",
689
+ #{options[:chdir_first] ? '' : 'drive, dir,'}
649
690
  argc > 1 ? argv[1] : "",
650
691
  argc > 2 ? argv[2] : "",
651
692
  argc > 3 ? argv[3] : "",
@@ -656,7 +697,7 @@ int main(int argc, char *argv[])
656
697
  argc > 8 ? argv[8] : "",
657
698
  argc > 9 ? argv[9] : ""
658
699
  );
659
- EOF
700
+ CFILE
660
701
  if options[:b2ec][:invisible]
661
702
  f.puts %[ CreateProcess(NULL, runruby, NULL, NULL, FALSE, NORMAL_PRIORITY_CLASS | CREATE_NO_WINDOW, NULL, NULL, &si, &pi);]
662
703
  else
@@ -673,14 +714,14 @@ int main(int argc, char *argv[])
673
714
  end
674
715
  f.puts " return 0;\n}"
675
716
  end
676
-
677
- open(rc_file, "w:#{options[:external_encoding]}") do |f|
678
- f.puts <<-EOF
717
+
718
+ File.open(rc_file, "w:#{options[:external_encoding]}") do |f|
719
+ f.puts <<-RCFILE
679
720
  #include <winver.h>
680
721
 
681
722
  1 VERSIONINFO
682
- #{options[:b2ec][:fileversion ] ? "FILEVERSION " + escape_cstr(options[:b2ec][:fileversion ]) : ""}
683
- #{options[:b2ec][:productversion] ? "PRODUCTVERSION " + escape_cstr(options[:b2ec][:productversion]) : ""}
723
+ #{options[:b2ec][:fileversion ] ? "FILEVERSION #{escape_cstr(options[:b2ec][:fileversion ])}" : ""}
724
+ #{options[:b2ec][:productversion] ? "PRODUCTVERSION #{escape_cstr(options[:b2ec][:productversion])}" : ""}
684
725
  FILETYPE VFT_APP
685
726
  BEGIN
686
727
  BLOCK "StringFileInfo"
@@ -709,36 +750,38 @@ BEGIN
709
750
  END
710
751
 
711
752
  2 ICON "#{escape_cstr(options[:b2ec][:icon])}"
712
- EOF
753
+ RCFILE
713
754
  end
714
- nsystem(%[windres -o "#{o_file}" "#{rc_file}"])
715
- nsystem(%[gcc#{options[:b2ec][:invisible] ? " -mwindows" : ""} -o "#{exe_file}" "#{c_file}" "#{o_file}"])
716
- nsystem(%[strip "#{exe_file}"])
755
+ nsystem(%(windres -o "#{o_file}" "#{rc_file}"))
756
+ nsystem(%(gcc#{options[:b2ec][:invisible] ? ' -mwindows' : ''} -o "#{exe_file}" "#{c_file}" "#{o_file}"))
757
+ nsystem(%(strip "#{exe_file}"))
717
758
  File.delete(c_file, rc_file, o_file)
718
759
  end
719
-
760
+
720
761
  def ruby_command(path)
721
- system_dir = "#{path}#{File.join(options[:system_dir], "")}"
762
+ system_dir = "#{path}#{File.join(options[:system_dir], '')}"
722
763
  ruby_code = ""
723
764
  ruby_code = "Neri.key='#{@encryption_key}';" if @encryption_key
724
765
  if options[:datafile]
725
766
  ruby_code += "Neri.datafile='#{system_dir}' + #{unpack_filename(options[:datafile])};"
767
+ if options[:virtual_directory]
768
+ ruby_code += "Neri.virtual_directory=#{unpack_filename(options[:virtual_directory])};"
769
+ end
726
770
  ruby_code += "load #{unpack_filename(File.basename(scriptfile))}"
727
771
  else
728
772
  ruby_code += "load File.expand_path('#{system_dir}' + #{unpack_filename(scriptfile)})"
729
773
  end
730
-
774
+
731
775
  r = " -rneri"
732
776
  r += " -rneri/dxruby" if @use_dxruby
733
777
  r += " -rneri/dxruby_tiled" if @use_dxruby_tiled
734
778
  r += " -rneri/ayame" if @use_ayame
735
-
779
+
736
780
  ruby = to_winpath(relative_path(rubyexe, bindir))
737
- return %[#{ruby}#{r} #{@rubyopt} -e "# coding:utf-8" -e "#{ruby_code}" #{@args}]
781
+ %(#{ruby}#{r} #{@rubyopt} -e "# coding:utf-8" -e "#{ruby_code}" #{@args})
738
782
  end
739
-
740
-
741
- def bat_to_exe_converter()
783
+
784
+ def bat_to_exe_converter
742
785
  create_batfile
743
786
  begin
744
787
  `#{options[:b2ec_path]} /help`
@@ -746,36 +789,32 @@ END
746
789
  error "Bat To Exe Converter not found !"
747
790
  return
748
791
  end
749
-
750
- batch_file = basepath + ".bat"
751
- exe_file = basepath + ".exe"
792
+
793
+ batch_file = "#{basepath}.bat"
794
+ exe_file = "#{basepath}.exe"
752
795
  nputs "Creating exe_file '#{exe_file}' with Bat To Exe Converter."
753
796
  File.delete(exe_file) if File.exist?(exe_file)
754
- if options[:b2ec][:x64] == nil
755
- options[:b2ec][:x64] = true if RbConfig::CONFIG["target"].to_s.index("64")
797
+ if options[:b2ec][:x64].nil? && RbConfig::CONFIG["target"].to_s.index("64")
798
+ options[:b2ec][:x64] = true
756
799
  end
757
- args = %[ /bat "#{batch_file}" /exe "#{exe_file}"]
758
- args += options[:b2ec].map{|key, value|
800
+ args = %( /bat "#{batch_file}" /exe "#{exe_file}")
801
+ args += options[:b2ec].map { |key, value|
759
802
  case value
760
- when String; %[ /#{key.to_s.tr("_", "-")} "#{value}"]
761
- when true; %[ /#{key.to_s.tr("_", "-")}]
762
- else; %[]
803
+ when String then %( /#{key.to_s.tr('_', '-')} "#{value}")
804
+ when true then %( /#{key.to_s.tr('_', '-')})
805
+ else; %()
763
806
  end
764
807
  }.join("")
765
-
766
-
767
- unless nsystem "#{options[:b2ec_path]}#{args}"
768
- error "Failed to create exe_file !"
769
- end
808
+
809
+ error "Failed to create exe_file !" unless nsystem "#{options[:b2ec_path]}#{args}"
770
810
  end
771
-
772
-
773
- def upx()
811
+
812
+ def upx
774
813
  unless system("#{options[:upx_path]} --version >nul 2>&1")
775
814
  error "UPX not found !"
776
815
  return
777
816
  end
778
-
817
+
779
818
  nputs "Compressing with UPX."
780
819
  options[:upx_targets].each do |target|
781
820
  Dir.glob(File.join(options[:output_dir], options[:system_dir], target)).each do |target_path|
@@ -784,78 +823,76 @@ END
784
823
  end
785
824
  end
786
825
  end
787
-
788
-
789
- def create_zipfile()
826
+
827
+ def create_zipfile
790
828
  unless system("#{options[:sevenzip_path]} >nul 2>&1")
791
829
  error "7-Zip not found !"
792
830
  return
793
831
  end
794
-
832
+
795
833
  nputs "Creating zip_file '#{options[:zipfile]}'."
796
834
  File.delete(options[:zipfile]) if File.exist?(options[:zipfile])
797
835
  files = []
798
836
  if options[:output_dir] == "./"
799
837
  files.push(options[:system_dir])
800
- files.push(File.exist?(basepath + ".exe") ? basepath + ".exe" : basepath + ".bat")
838
+ files.push(File.exist?("#{basepath}.exe") ? "#{basepath}.exe" : "#{basepath}.bat")
801
839
  else
802
840
  files.push(options[:output_dir])
803
841
  end
804
842
  command = %("#{options[:sevenzip_path]}" a "#{options[:zipfile]}" "#{files.join('" "')}")
805
843
  nsystem command
806
844
  end
807
-
808
-
809
- def inno_setup()
845
+
846
+ def inno_setup
810
847
  unless system("#{options[:iscc_path]} /? >nul 2>&1")
811
848
  error("Inno Setup not found !")
812
849
  return
813
850
  end
814
-
851
+
815
852
  filename = options[:inno_script]
816
853
  nputs "Creating Installer '#{filename}'."
817
854
  script = "[Setup]\n"
818
855
  if File.exist?(filename)
819
856
  script = File.read(filename, encoding: Encoding::UTF_8)
820
- filename = File.basename(filename, ".*") + "_tmp" + File.extname(filename)
857
+ filename = "#{File.basename(filename, '.*')}_tmp#{File.extname(filename)}"
821
858
  end
822
-
859
+
823
860
  version = options[:b2ec][:productversion] || options[:b2ec][:fileversion]
824
861
  if !script.match(/^AppName=/) && options[:b2ec][:productname]
825
- script.sub!(/^(\[Setup\])(\s+)/i){ "#{$1}\nAppName=#{options[:b2ec][:productname]}#{$2}" }
862
+ script.sub!(/^(\[Setup\])(\s+)/i) { "#{$1}\nAppName=#{options[:b2ec][:productname]}#{$2}" }
826
863
  end
827
864
  if !script.match(/^AppVersion=/) && version
828
- script.sub!(/^(\[Setup\])(\s+)/i){ "#{$1}\nAppVersion=#{version}#{$2}" }
865
+ script.sub!(/^(\[Setup\])(\s+)/i) { "#{$1}\nAppVersion=#{version}#{$2}" }
829
866
  end
830
867
  if !script.match(/^AppVerName=/) && options[:b2ec][:productname] && version
831
- script.sub!(/^(\[Setup\])(\s+)/i){ "#{$1}\nAppVerName=#{options[:b2ec][:productname]} #{version}#{$2}" }
868
+ script.sub!(/^(\[Setup\])(\s+)/i) { "#{$1}\nAppVerName=#{options[:b2ec][:productname]} #{version}#{$2}" }
832
869
  end
833
870
  if !script.match(/^AppPublisher=/) && options[:b2ec][:company]
834
- script.sub!(/^(\[Setup\])(\s+)/i){ "#{$1}\nAppPublisher=#{options[:b2ec][:company]}#{$2}" }
871
+ script.sub!(/^(\[Setup\])(\s+)/i) { "#{$1}\nAppPublisher=#{options[:b2ec][:company]}#{$2}" }
835
872
  end
836
873
  if !script.match(/^AppCopyright=/) && options[:b2ec][:copyright]
837
- script.sub!(/^(\[Setup\])(\s+)/i){ "#{$1}\nAppCopyright=#{options[:b2ec][:copyright]}#{$2}" }
874
+ script.sub!(/^(\[Setup\])(\s+)/i) { "#{$1}\nAppCopyright=#{options[:b2ec][:copyright]}#{$2}" }
838
875
  end
839
-
876
+
840
877
  script += "\n[Files]\n" unless script.match(/^\[Files\]/)
841
878
  dir = File.expand_path(options[:output_dir])
842
879
  files_str = ""
843
880
  Dir.glob(File.join(dir, "**", "*")).each do |file|
844
881
  next unless File.file? file
882
+
845
883
  dist_dir = to_winpath(File::SEPARATOR + File.dirname(relative_path(file, dir)))
846
884
  dist_dir = "" if dist_dir == "\\."
847
885
  files_str += "\nSource: \"#{to_winpath(file)}\"; DistDir: \"{app}#{dist_dir}"
848
886
  files_str += "; Flags: isreadme" if File.basename(file).match(/^readme/i)
849
887
  end
850
- script.sub!(/^(\[Files\])(\s*)/i){ "#{$1}#{files_str}#{$2}" }
851
-
888
+ script.sub!(/^(\[Files\])(\s*)/i) { "#{$1}#{files_str}#{$2}" }
889
+
852
890
  File.write(filename, script)
853
891
  command = %(#{options[:iscc_path]} "#{filename}")
854
892
  nsystem command
855
893
  end
856
-
857
-
858
- def run()
894
+
895
+ def run
859
896
  check_options
860
897
  dependencies = check_dependencies
861
898
  copy_files(dependencies)
@@ -870,34 +907,33 @@ END
870
907
  inno_setup if options[:inno_script]
871
908
  nputs "Neri Finished."
872
909
  end
873
-
874
910
 
875
911
  private
876
-
912
+
877
913
  def nputs(str)
878
914
  puts "=== #{str}" unless options[:quiet]
879
915
  end
880
-
916
+
881
917
  def nputs_v(str)
882
918
  puts str if options[:verbose]
883
919
  end
884
-
920
+
885
921
  def error(str)
886
922
  puts "\e[31m#{str}\e[0m"
887
923
  end
888
-
924
+
889
925
  def unpack_filename(filename)
890
- "[" + filename.unpack("U*").map { |u| u.to_s }.join(",") + "].pack('U*')"
926
+ "[#{filename.unpack('U*').map(&:to_s).join(',')}].pack('U*')"
891
927
  end
892
-
928
+
893
929
  def escape_cstr(str)
894
- str.gsub("\\"){ "\\\\" }.gsub('"'){ '\\"' }.gsub("'"){ "\\'" }
930
+ str.gsub("\\") { "\\\\" }.gsub('"') { '\\"' }.gsub("'") { "\\'" }
895
931
  end
896
-
932
+
897
933
  def nsystem(str)
898
934
  nputs_v(str)
899
935
  command = str.encode(options[:external_encoding])
900
- return system(command + (options[:quiet] ? " >nul 2>&1" : ""))
936
+ system(command + (options[:quiet] ? " >nul 2>&1" : ""))
901
937
  end
902
938
  end
903
939
  end