neri 0.9.2 → 0.9.6

Sign up to get free protection for your applications and to get access to all the features.
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
+ nputs "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