ocran 1.3.14 → 1.3.15
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.
- checksums.yaml +4 -4
- data/bin/ocran +185 -161
- data/lib/ocran/version.rb +2 -2
- data/share/ocran/edicon.exe +0 -0
- data/share/ocran/empty-msys-2.0.dll +0 -0
- data/share/ocran/stub.exe +0 -0
- data/share/ocran/stubw.exe +0 -0
- metadata +4 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a782f6a9d0c148e6270aa19573c86e5f6518e9511bcfda3aec59de84a1291e41
|
4
|
+
data.tar.gz: 4eff772bc2997a4a99d08ea925c9e9d2eb0e8a1da48c687588dbf7c46d3d3453
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3f94bc970689b64b199584baa2ee27f5f371ba6220b3fd736ef24314ab49644eb21932ba2e9397add861bfc609da6b5e4d0be5e45a6804a8bcf64057a1c51978
|
7
|
+
data.tar.gz: b881a6a9f0832490a5875360531e367b0f6efb008b2c8f94c54815fb63885f5350a19c40800f13da70fe714607ee774fd2a4e598373318d2b15a2b4b6fb9fc75
|
data/bin/ocran
CHANGED
@@ -15,6 +15,16 @@ module Ocran
|
|
15
15
|
a.downcase == b.downcase
|
16
16
|
end
|
17
17
|
|
18
|
+
def Pathname.glob(pattern, flags = 0)
|
19
|
+
if block_given?
|
20
|
+
Dir.glob(pattern, flags) { |s| yield Pathname.new(s) }
|
21
|
+
else
|
22
|
+
ary = Dir.glob(pattern, flags)
|
23
|
+
ary.map! { |s| Pathname.new(s) }
|
24
|
+
ary
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
18
28
|
attr_reader :path
|
19
29
|
if File::ALT_SEPARATOR.nil?
|
20
30
|
File::ALT_SEPARATOR = "\\"
|
@@ -23,7 +33,7 @@ module Ocran
|
|
23
33
|
ABSOLUTE_PAT = /\A([A-Z]:)?#{SEPARATOR_PAT}/i
|
24
34
|
|
25
35
|
def initialize(path)
|
26
|
-
@path = path
|
36
|
+
@path = path.encode("UTF-8")
|
27
37
|
end
|
28
38
|
|
29
39
|
def to_native
|
@@ -39,20 +49,20 @@ module Ocran
|
|
39
49
|
# be reached from 'src'.
|
40
50
|
def relative_path_from(other)
|
41
51
|
a = @path.split(SEPARATOR_PAT)
|
42
|
-
b = other.
|
52
|
+
b = other.to_s.split(SEPARATOR_PAT)
|
43
53
|
while a.first && b.first && Pathname.pathequal(a.first, b.first)
|
44
54
|
a.shift
|
45
55
|
b.shift
|
46
56
|
end
|
47
|
-
return other if Pathname.new(b.first).absolute?
|
57
|
+
return other if b.first && Pathname.new(b.first).absolute?
|
48
58
|
b.size.times { a.unshift ".." }
|
49
|
-
|
59
|
+
Pathname.new(File.join(*a))
|
50
60
|
end
|
51
61
|
|
52
62
|
# Determines if 'src' is contained in 'tgt' (i.e. it is a subpath of
|
53
63
|
# 'tgt'). Both must be absolute paths and not contain '..'
|
54
64
|
def subpath?(other)
|
55
|
-
other =
|
65
|
+
other = Pathname.new(other)
|
56
66
|
src_normalized = to_posix.downcase
|
57
67
|
tgt_normalized = other.to_posix.downcase
|
58
68
|
src_normalized =~ /^#{Regexp.escape tgt_normalized}#{SEPARATOR_PAT}/i
|
@@ -62,37 +72,49 @@ module Ocran
|
|
62
72
|
# is an absolute path. Otherwise, returns the full path of the
|
63
73
|
# left + right.
|
64
74
|
def /(other)
|
65
|
-
other =
|
75
|
+
other = Pathname.new(other)
|
66
76
|
if other.absolute?
|
67
77
|
other
|
68
78
|
else
|
69
|
-
|
79
|
+
Pathname.new(File.join(@path, other.to_s))
|
70
80
|
end
|
71
81
|
end
|
72
82
|
|
73
83
|
def append_to_filename!(s)
|
74
|
-
@path
|
84
|
+
@path = sub(/(\.[^.]*?|)$/) { s.to_s + $1 }
|
85
|
+
end
|
86
|
+
|
87
|
+
def sub(*a, &b)
|
88
|
+
Pathname.new(@path.sub(*a, &b))
|
89
|
+
end
|
90
|
+
|
91
|
+
def sub_ext(new_ext)
|
92
|
+
sub(/(\.[^.]*?)?$/, new_ext)
|
93
|
+
end
|
94
|
+
|
95
|
+
def extname
|
96
|
+
File.extname(@path)
|
75
97
|
end
|
76
98
|
|
77
99
|
def ext(new_ext = nil)
|
78
100
|
if new_ext
|
79
|
-
|
101
|
+
sub_ext(new_ext)
|
80
102
|
else
|
81
|
-
|
103
|
+
extname
|
82
104
|
end
|
83
105
|
end
|
84
106
|
|
85
107
|
def ext?(expected_ext)
|
86
|
-
Pathname.pathequal(
|
108
|
+
Pathname.pathequal(extname, expected_ext)
|
87
109
|
end
|
88
110
|
|
89
111
|
def entries
|
90
|
-
Dir.entries(@path).map { |e| self / e
|
112
|
+
Dir.entries(@path, encoding: "UTF-8").map { |e| self / e }
|
91
113
|
end
|
92
114
|
|
93
115
|
# Recursively find all files which match a specified regular
|
94
116
|
# expression.
|
95
|
-
def find_all_files(re)
|
117
|
+
def find_all_files(re = //)
|
96
118
|
entries.map do |pn|
|
97
119
|
if pn.directory?
|
98
120
|
if pn.basename =~ /^\.\.?$/
|
@@ -111,18 +133,35 @@ module Ocran
|
|
111
133
|
end
|
112
134
|
|
113
135
|
def ==(other); to_posix.downcase == other.to_posix.downcase; end
|
136
|
+
alias === ==
|
137
|
+
alias eql? ==
|
114
138
|
def =~(o); @path =~ o; end
|
115
|
-
def <=>(other); @path.casecmp(other.
|
139
|
+
def <=>(other); @path.casecmp(other.to_s); end
|
116
140
|
def exist?; File.exist?(@path); end
|
117
141
|
def file?; File.file?(@path); end
|
118
142
|
def directory?; File.directory?(@path); end
|
119
143
|
def absolute?; @path =~ ABSOLUTE_PAT; end
|
120
144
|
def dirname; Pathname.new(File.dirname(@path)); end
|
121
145
|
def basename; Pathname.new(File.basename(@path)); end
|
122
|
-
|
146
|
+
|
147
|
+
def expand_path(dir = ".")
|
148
|
+
Pathname.new(File.expand_path(@path, dir))
|
149
|
+
end
|
150
|
+
|
151
|
+
def expand(dir = nil); dir ? expand_path(dir) : expand_path; end
|
123
152
|
def size; File.size(@path); end
|
124
153
|
def encode(e); to_posix.encode(e); end # called when creating an installer with innosetup
|
125
154
|
|
155
|
+
def binread(*args)
|
156
|
+
File.binread(@path, *args)
|
157
|
+
end
|
158
|
+
|
159
|
+
def parent
|
160
|
+
Pathname.new(File.basename(File.dirname(@path)))
|
161
|
+
end
|
162
|
+
|
163
|
+
alias to_path to_posix
|
164
|
+
|
126
165
|
alias to_s to_posix
|
127
166
|
alias to_str to_posix
|
128
167
|
end
|
@@ -187,7 +226,7 @@ module Ocran
|
|
187
226
|
a.sort.inject([]) { |r, e| r.last == e ? r : r << e }
|
188
227
|
end
|
189
228
|
|
190
|
-
VERSION = "1.3.
|
229
|
+
VERSION = "1.3.15"
|
191
230
|
|
192
231
|
IGNORE_MODULE_NAMES = /\/(enumerator.so|rational.so|complex.so|fiber.so|thread.rb|ruby2_keywords.rb)$/
|
193
232
|
|
@@ -202,7 +241,7 @@ module Ocran
|
|
202
241
|
# Directories anywhere
|
203
242
|
(^|\/)(\.autotest|\.svn|\.cvs|\.git)(\/|$) |
|
204
243
|
# Unlikely extensions
|
205
|
-
\.(rdoc|c|cpp|c\+\+|cxx|h|hxx|hpp|obj|o|a)
|
244
|
+
\.(rdoc|c|cpp|c\+\+|cxx|h|hxx|hpp|obj|o|a)$
|
206
245
|
)}xi
|
207
246
|
|
208
247
|
GEM_NON_FILE_RE = /(#{GEM_EXTRA_RE}|#{GEM_SCRIPT_RE})/
|
@@ -270,40 +309,23 @@ module Ocran
|
|
270
309
|
exit 1
|
271
310
|
end
|
272
311
|
|
273
|
-
# Returns a binary blob store embedded in the current Ruby script.
|
274
|
-
def Ocran.get_next_embedded_image
|
275
|
-
DATA.read(DATA.readline.to_i).unpack("m")[0]
|
276
|
-
end
|
277
|
-
|
278
312
|
def Ocran.save_environment
|
279
313
|
@load_path_before = $LOAD_PATH.dup
|
280
314
|
@pwd_before = Dir.pwd
|
281
|
-
@env_before =
|
315
|
+
@env_before = ENV.to_hash
|
282
316
|
end
|
283
317
|
|
284
318
|
def Ocran.restore_environment
|
285
|
-
@env_before
|
286
|
-
ENV.each_key { |key| ENV.delete(key) unless @env_before.has_key?(key) }
|
319
|
+
ENV.clear.update(@env_before)
|
287
320
|
Dir.chdir @pwd_before
|
288
321
|
end
|
289
322
|
|
290
323
|
def Ocran.find_stubs
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
-
|
295
|
-
|
296
|
-
File.open(@lzmapath, "wb") { |file| file << lzmaimage }
|
297
|
-
ediconimage = get_next_embedded_image
|
298
|
-
@ediconpath = Host.tempdir / "edicon.exe"
|
299
|
-
File.open(@ediconpath, "wb") { |file| file << ediconimage }
|
300
|
-
else
|
301
|
-
ocranpath = Pathname(File.dirname(__FILE__))
|
302
|
-
@stubimage = File.open(ocranpath / "../share/ocran/stub.exe", "rb") { |file| file.read }
|
303
|
-
@stubwimage = File.open(ocranpath / "../share/ocran/stubw.exe", "rb") { |file| file.read }
|
304
|
-
@lzmapath = (ocranpath / "../share/ocran/lzma.exe").expand
|
305
|
-
@ediconpath = (ocranpath / "../share/ocran/edicon.exe").expand
|
306
|
-
end
|
324
|
+
ocranpath = Pathname(File.dirname(__FILE__))
|
325
|
+
@stubimage = (ocranpath / "../share/ocran/stub.exe").binread
|
326
|
+
@stubwimage = (ocranpath / "../share/ocran/stubw.exe").binread
|
327
|
+
@lzmapath = (ocranpath / "../share/ocran/lzma.exe").expand_path
|
328
|
+
@ediconpath = (ocranpath / "../share/ocran/edicon.exe").expand_path
|
307
329
|
end
|
308
330
|
|
309
331
|
def Ocran.parseargs(argv)
|
@@ -377,9 +399,11 @@ EOF
|
|
377
399
|
when /\A--add-all-core\z/
|
378
400
|
@options[:add_all_core] = true
|
379
401
|
when /\A--output\z/
|
380
|
-
|
402
|
+
path = argv.shift
|
403
|
+
@options[:output_override] = Pathname.new(path) if path
|
381
404
|
when /\A--dll\z/
|
382
|
-
|
405
|
+
path = argv.shift
|
406
|
+
@options[:extra_dlls] << path if path
|
383
407
|
when /\A--quiet\z/
|
384
408
|
@options[:quiet] = true
|
385
409
|
when /\A--verbose\z/
|
@@ -393,16 +417,19 @@ EOF
|
|
393
417
|
when /\A--chdir-first\z/
|
394
418
|
@options[:chdir_first] = true
|
395
419
|
when /\A--icon\z/
|
396
|
-
|
397
|
-
Ocran.fatal_error "Icon file #{
|
420
|
+
path = argv.shift
|
421
|
+
Ocran.fatal_error "Icon file #{path} not found.\n" unless path && File.exist?(path)
|
422
|
+
@options[:icon_filename] = Pathname.new(path)
|
398
423
|
when /\A--rubyopt\z/
|
399
424
|
@options[:rubyopt] = argv.shift
|
400
425
|
when /\A--gemfile\z/
|
401
|
-
|
402
|
-
Ocran.fatal_error "Gemfile #{
|
426
|
+
path = argv.shift
|
427
|
+
Ocran.fatal_error "Gemfile #{path} not found.\n" unless path && File.exist?(path)
|
428
|
+
@options[:gemfile] = Pathname.new(path)
|
403
429
|
when /\A--innosetup\z/
|
404
|
-
|
405
|
-
Ocran.fatal_error "Inno Script #{
|
430
|
+
path = argv.shift
|
431
|
+
Ocran.fatal_error "Inno Script #{path} not found.\n" unless path && File.exist?(path)
|
432
|
+
@options[:inno_script] = Pathname.new(path)
|
406
433
|
when /\A--no-autodll\z/
|
407
434
|
@options[:autodll] = false
|
408
435
|
when /\A--version\z/
|
@@ -421,17 +448,18 @@ EOF
|
|
421
448
|
@options[:enc] = !$1
|
422
449
|
when /\A--(no-)?gem-(\w+)(?:=(.*))?$/
|
423
450
|
negate, group, list = $1, $2, $3
|
424
|
-
@options[:gem]
|
425
|
-
@options[:gem] << [negate, group.to_sym, list && list.split(",")]
|
451
|
+
@options[:gem] << [negate, group.to_sym, list&.split(",")] if group
|
426
452
|
when /\A--help\z/, /\A--./
|
427
453
|
puts usage
|
428
454
|
exit 0
|
429
455
|
else
|
430
|
-
|
431
|
-
|
432
|
-
|
433
|
-
|
456
|
+
path = arg.dup
|
457
|
+
|
458
|
+
if !File.exist?(path) || Dir.empty?(path)
|
459
|
+
Ocran.fatal_error "#{path} not found!"
|
434
460
|
end
|
461
|
+
|
462
|
+
@options[:files] << path
|
435
463
|
end
|
436
464
|
end
|
437
465
|
|
@@ -453,14 +481,12 @@ EOF
|
|
453
481
|
end
|
454
482
|
|
455
483
|
@options[:files].map! { |path|
|
456
|
-
path = path.encode("UTF-8").tr(
|
484
|
+
path = path.encode("UTF-8").tr("\\", "/")
|
457
485
|
if File.directory?(path)
|
458
486
|
# If a directory is passed, we want all files under that directory
|
459
487
|
path = "#{path}/**/*"
|
460
488
|
end
|
461
|
-
|
462
|
-
Ocran.fatal_error "#{path} not found!" if files.empty?
|
463
|
-
files.map { |path| Pathname(path).expand }
|
489
|
+
Pathname.glob(path).map!(&:expand_path)
|
464
490
|
}.flatten!
|
465
491
|
end
|
466
492
|
|
@@ -486,8 +512,6 @@ EOF
|
|
486
512
|
modules_to_check.each do |mod|
|
487
513
|
modules_checked[mod] = true
|
488
514
|
mod.constants.each do |const|
|
489
|
-
# Module::Config causes warning on Ruby 1.9.3 - prevent autoloading
|
490
|
-
next if Module === mod && const == :Config
|
491
515
|
if mod.autoload?(const)
|
492
516
|
Ocran.msg "Attempting to trigger autoload of #{mod}::#{const}"
|
493
517
|
begin
|
@@ -509,26 +533,26 @@ EOF
|
|
509
533
|
def Ocran.find_load_path(loadpaths, feature)
|
510
534
|
if feature.absolute?
|
511
535
|
# Choose those loadpaths which contain the feature
|
512
|
-
candidate_loadpaths = loadpaths.select { |loadpath| feature.subpath?(loadpath.
|
536
|
+
candidate_loadpaths = loadpaths.select { |loadpath| feature.subpath?(loadpath.expand_path) }
|
513
537
|
# Guess the require'd feature
|
514
|
-
feature_pairs = candidate_loadpaths.map { |loadpath| [loadpath, feature.relative_path_from(loadpath.
|
538
|
+
feature_pairs = candidate_loadpaths.map { |loadpath| [loadpath, feature.relative_path_from(loadpath.expand_path)] }
|
515
539
|
# Select the shortest possible require-path (longest load-path)
|
516
540
|
if feature_pairs.empty?
|
517
541
|
nil
|
518
542
|
else
|
519
|
-
feature_pairs.sort_by { |loadpath, feature| feature.
|
543
|
+
feature_pairs.sort_by { |loadpath, feature| feature.to_s.size }.first[0]
|
520
544
|
end
|
521
545
|
else
|
522
546
|
# Select the loadpaths that contain 'feature' and select the shortest
|
523
|
-
candidates = loadpaths.select { |loadpath| feature.
|
524
|
-
candidates.sort_by { |loadpath| loadpath.
|
547
|
+
candidates = loadpaths.select { |loadpath| feature.expand_path(loadpath).exist? }
|
548
|
+
candidates.sort_by { |loadpath| loadpath.to_s.size }.last
|
525
549
|
end
|
526
550
|
end
|
527
551
|
|
528
552
|
# Find the root of all files specified on the command line and use
|
529
553
|
# it as the "src" of the output.
|
530
554
|
def Ocran.find_src_root(files)
|
531
|
-
src_files = files.map { |file| file.
|
555
|
+
src_files = files.map { |file| file.expand_path }
|
532
556
|
src_prefix = src_files.inject(src_files.first.dirname) do |srcroot, path|
|
533
557
|
if path.subpath?(Host.exec_prefix)
|
534
558
|
srcroot
|
@@ -579,18 +603,19 @@ EOF
|
|
579
603
|
end
|
580
604
|
end
|
581
605
|
|
582
|
-
ENV["BUNDLE_GEMFILE"] = Ocran.gemfile
|
606
|
+
ENV["BUNDLE_GEMFILE"] = Ocran.gemfile.to_s
|
583
607
|
Bundler.load.specs.each do |spec|
|
584
608
|
Ocran.verbose_msg "From Gemfile, adding gem #{spec.full_name}"
|
585
609
|
gems[spec.name] ||= spec
|
586
610
|
end
|
587
611
|
|
612
|
+
# This code is implemented for compatibility with older Bundler versions (< v1.16.0.pre.1).
|
588
613
|
unless gems.any? { |name, spec| name == "bundler" }
|
589
614
|
# Bundler itself wasn't added for some reason, let's put it in directly
|
590
615
|
Ocran.verbose_msg "From Gemfile, forcing inclusion of bundler gem itself"
|
591
616
|
bundler_spec = Gem.loaded_specs["bundler"]
|
592
617
|
bundler_spec or Ocran.fatal_error "Unable to locate bundler gem"
|
593
|
-
gems["bundler"] ||=
|
618
|
+
gems["bundler"] ||= bundler_spec
|
594
619
|
end
|
595
620
|
end
|
596
621
|
|
@@ -610,12 +635,12 @@ EOF
|
|
610
635
|
features_from_gems << feature
|
611
636
|
next
|
612
637
|
end
|
613
|
-
gempaths =
|
638
|
+
gempaths = Gem.path
|
614
639
|
gempaths.each do |gempath|
|
615
640
|
geminstallpath = Pathname(gempath) / "gems"
|
616
641
|
if feature.subpath?(geminstallpath)
|
617
642
|
gemlocalpath = feature.relative_path_from(geminstallpath)
|
618
|
-
fullgemname = gemlocalpath.
|
643
|
+
fullgemname = gemlocalpath.to_s.split("/").first
|
619
644
|
gemspecpath = gempath / "specifications" / "#{fullgemname}.gemspec"
|
620
645
|
if spec = Gem::Specification.load(gemspecpath)
|
621
646
|
gems[spec.name] ||= spec
|
@@ -682,9 +707,9 @@ EOF
|
|
682
707
|
Ocran.msg "Detected gem #{spec.full_name} (#{include.join(", ")})"
|
683
708
|
|
684
709
|
gem_root = Pathname(spec.gem_dir)
|
685
|
-
gem_extension = (gem_root / ".." / ".." / "extensions").
|
710
|
+
gem_extension = (gem_root / ".." / ".." / "extensions").expand_path
|
686
711
|
if gem_extension.exist?
|
687
|
-
build_complete = gem_extension.find_all_files(/gem.build_complete/).select { |p| p.
|
712
|
+
build_complete = gem_extension.find_all_files(/gem.build_complete/).select { |p| p.parent.to_s == spec.full_name }
|
688
713
|
else
|
689
714
|
build_complete = nil
|
690
715
|
end
|
@@ -704,14 +729,14 @@ EOF
|
|
704
729
|
when :loaded
|
705
730
|
files << features_from_gems.select { |feature| feature.subpath?(gem_root) }
|
706
731
|
when :files
|
707
|
-
gem_root_files ||= gem_root.find_all_files
|
732
|
+
gem_root_files ||= gem_root.find_all_files
|
708
733
|
files << gem_root_files.select { |path| path.relative_path_from(gem_root) !~ GEM_NON_FILE_RE }
|
709
734
|
files << build_complete if build_complete
|
710
735
|
when :extras
|
711
|
-
gem_root_files ||= gem_root.find_all_files
|
736
|
+
gem_root_files ||= gem_root.find_all_files
|
712
737
|
files << gem_root_files.select { |path| path.relative_path_from(gem_root) =~ GEM_EXTRA_RE }
|
713
738
|
when :scripts
|
714
|
-
gem_root_files ||= gem_root.find_all_files
|
739
|
+
gem_root_files ||= gem_root.find_all_files
|
715
740
|
files << gem_root_files.select { |path| path.relative_path_from(gem_root) =~ GEM_SCRIPT_RE }
|
716
741
|
end
|
717
742
|
end
|
@@ -723,7 +748,7 @@ EOF
|
|
723
748
|
Ocran.warn "#{missing_file} was not found"
|
724
749
|
end
|
725
750
|
|
726
|
-
total_size = actual_files.
|
751
|
+
total_size = actual_files.sum(0, &:size)
|
727
752
|
Ocran.msg "\t#{actual_files.size} files, #{total_size} bytes"
|
728
753
|
|
729
754
|
gem_files += actual_files
|
@@ -737,9 +762,9 @@ EOF
|
|
737
762
|
end
|
738
763
|
|
739
764
|
def Ocran.build_exe
|
740
|
-
all_load_paths = $LOAD_PATH.map { |loadpath| Pathname(loadpath).
|
741
|
-
@added_load_paths = ($LOAD_PATH - @load_path_before).map { |loadpath| Pathname(loadpath).
|
742
|
-
working_directory = Pathname.pwd
|
765
|
+
all_load_paths = $LOAD_PATH.map { |loadpath| Pathname(loadpath).expand_path }
|
766
|
+
@added_load_paths = ($LOAD_PATH - @load_path_before).map { |loadpath| Pathname(loadpath).expand_path }
|
767
|
+
working_directory = Pathname.pwd
|
743
768
|
|
744
769
|
restore_environment
|
745
770
|
|
@@ -784,7 +809,7 @@ EOF
|
|
784
809
|
encpath = path / "enc"
|
785
810
|
if encpath.exist?
|
786
811
|
encfiles = encpath.find_all_files(/\.so$/)
|
787
|
-
size = encfiles.
|
812
|
+
size = encfiles.sum(0, &:size)
|
788
813
|
Ocran.msg "Including #{encfiles.size} encoding support files (#{size} bytes, use --no-enc to exclude)"
|
789
814
|
features.push(*encfiles)
|
790
815
|
end
|
@@ -799,13 +824,13 @@ EOF
|
|
799
824
|
libs = []
|
800
825
|
features.each do |feature|
|
801
826
|
path = find_load_path(all_load_paths, feature)
|
802
|
-
if path.nil? || path.
|
827
|
+
if path.nil? || path.expand_path == Pathname.pwd
|
803
828
|
Ocran.files << feature
|
804
829
|
else
|
805
830
|
if feature.absolute?
|
806
|
-
feature = feature.relative_path_from(path.
|
831
|
+
feature = feature.relative_path_from(path.expand_path)
|
807
832
|
end
|
808
|
-
fullpath = feature.
|
833
|
+
fullpath = feature.expand_path(path)
|
809
834
|
|
810
835
|
if fullpath.subpath?(Host.exec_prefix)
|
811
836
|
# Features found in the Ruby installation are put in the
|
@@ -868,11 +893,10 @@ EOF
|
|
868
893
|
next unless path.to_posix =~
|
869
894
|
/\/(ruby\/(?:site_ruby\/|vendor_ruby\/)?[0-9.]+)\/?$/i
|
870
895
|
subdir = $1
|
871
|
-
|
872
|
-
fpath = Pathname.new(f)
|
896
|
+
Pathname.glob("#{lp}/**/*").each do |fpath|
|
873
897
|
next if fpath.directory?
|
874
898
|
tgt = "lib/#{subdir}/#{fpath.relative_path_from(path).to_posix}"
|
875
|
-
libs << [
|
899
|
+
libs << [fpath, tgt]
|
876
900
|
end
|
877
901
|
end
|
878
902
|
end
|
@@ -881,13 +905,19 @@ EOF
|
|
881
905
|
dlls = Ocran.autodll ? LibraryDetector.detect_dlls : []
|
882
906
|
|
883
907
|
# Detect external manifests
|
884
|
-
|
908
|
+
# For RubyInstaller environments supporting Ruby 2.4 and above,
|
909
|
+
# a manifest file is required.
|
910
|
+
if (manifest = Host.exec_prefix / "bin/ruby_builtin_dlls/ruby_builtin_dlls.manifest").exist?
|
911
|
+
manifests = [manifest]
|
912
|
+
else
|
913
|
+
manifests = []
|
914
|
+
end
|
885
915
|
|
886
916
|
executable = nil
|
887
917
|
if Ocran.output_override
|
888
918
|
executable = Ocran.output_override
|
889
919
|
else
|
890
|
-
executable = Ocran.files.first.basename.
|
920
|
+
executable = Ocran.files.first.basename.sub_ext(".exe")
|
891
921
|
executable.append_to_filename!("-debug") if Ocran.debug
|
892
922
|
end
|
893
923
|
|
@@ -963,8 +993,8 @@ EOF
|
|
963
993
|
if gemspec.subpath?(Host.exec_prefix)
|
964
994
|
path = gemspec.relative_path_from(Host.exec_prefix)
|
965
995
|
sb.createfile(gemspec, path)
|
966
|
-
elsif defined?(Gem) and gemhome =
|
967
|
-
path = GEMHOMEDIR / gemspec.relative_path_from(gemhome)
|
996
|
+
elsif defined?(Gem) and gemhome = Gem.path.find { |pth| gemspec.subpath?(pth) }
|
997
|
+
path = GEMHOMEDIR / gemspec.relative_path_from(Pathname(gemhome))
|
968
998
|
sb.createfile(gemspec, path)
|
969
999
|
else
|
970
1000
|
Ocran.fatal_error "Gem spec #{gemspec} does not exist in the Ruby installation. Don't know where to put it."
|
@@ -979,8 +1009,9 @@ EOF
|
|
979
1009
|
|
980
1010
|
# Workaround: RubyInstaller cannot find the msys folder if ../msys64/usr/bin/msys-2.0.dll is not present (since RubyInstaller-2.4.1 rubyinstaller 2 issue 23)
|
981
1011
|
# Add an empty file to /msys64/usr/bin/msys-2.0.dll if the dll was not required otherwise
|
982
|
-
|
983
|
-
|
1012
|
+
unless sb.files.keys.any? { |entry| entry.to_s.include?("msys-2.0.dll") }
|
1013
|
+
sb.createfile(Pathname(File.dirname(__FILE__)) / "../share/ocran/empty-msys-2.0.dll".to_s, 'msys64/usr/bin/msys-2.0.dll')
|
1014
|
+
end
|
984
1015
|
|
985
1016
|
# Set environment variable
|
986
1017
|
sb.setenv("RUBYOPT", Ocran.rubyopt || ENV["RUBYOPT"] || "")
|
@@ -1002,71 +1033,64 @@ EOF
|
|
1002
1033
|
end
|
1003
1034
|
|
1004
1035
|
module LibraryDetector
|
1036
|
+
# Windows API functions for handling files may return long paths,
|
1037
|
+
# with a maximum character limit of 32,767.
|
1038
|
+
# "\\?\" prefix(4 characters) + long path(32762 characters) + NULL = 32767 characters
|
1039
|
+
# https://learn.microsoft.com/en-us/windows/win32/fileio/maximum-file-path-limitation
|
1040
|
+
MAX_PATH = 32767
|
1041
|
+
|
1042
|
+
# The byte size of the buffer given as an argument to the EnumProcessModules function.
|
1043
|
+
# This buffer is used to store the handles of the loaded modules.
|
1044
|
+
# If the buffer size is smaller than the number of loaded modules,
|
1045
|
+
# it will automatically increase the buffer size and call the EnumProcessModules function again.
|
1046
|
+
# Increasing the initial buffer size can reduce the number of iterations required.
|
1047
|
+
# https://learn.microsoft.com/en-us/windows/win32/psapi/enumerating-all-modules-for-a-process
|
1048
|
+
DEFAULT_HMODULE_BUFFER_SIZE = 1024
|
1049
|
+
|
1005
1050
|
def LibraryDetector.init_fiddle
|
1006
|
-
require "fiddle"
|
1051
|
+
require "fiddle/import"
|
1007
1052
|
require "fiddle/types"
|
1008
|
-
module_eval {
|
1009
|
-
extend Fiddle::Importer
|
1010
|
-
dlload "psapi.dll"
|
1011
|
-
include Fiddle::Win32Types
|
1012
|
-
extern "BOOL EnumProcessModules(HANDLE, HMODULE*, DWORD, DWORD*)"
|
1013
|
-
extend Fiddle::Importer
|
1014
|
-
dlload "kernel32.dll"
|
1015
|
-
include Fiddle::Win32Types
|
1016
|
-
|
1017
|
-
# https://docs.microsoft.com/en-us/windows/win32/winprog/windows-data-types
|
1018
|
-
# typedef PVOID HANDLE
|
1019
|
-
# typedef HINSTANCE HMODULE;
|
1020
|
-
|
1021
|
-
typealias "HMODULE", "voidp"
|
1022
|
-
typealias "HANDLE", "voidp"
|
1023
|
-
typealias "LPWSTR", "char*"
|
1024
|
-
|
1025
|
-
extern "DWORD GetModuleFileNameW(HMODULE, LPWSTR, DWORD)"
|
1026
|
-
extern "HANDLE GetCurrentProcess(void)"
|
1027
|
-
extern "DWORD GetLastError(void)"
|
1028
|
-
}
|
1029
|
-
end
|
1030
1053
|
|
1031
|
-
|
1032
|
-
|
1033
|
-
psapi = Fiddle.dlopen("psapi")
|
1034
|
-
enumprocessmodules = Fiddle::Function.new(psapi["EnumProcessModules"], [Fiddle::TYPE_UINTPTR_T, Fiddle::TYPE_VOIDP, Fiddle::TYPE_LONG, Fiddle::TYPE_VOIDP], Fiddle::TYPE_LONG)
|
1035
|
-
kernel32 = Fiddle.dlopen("kernel32")
|
1036
|
-
getcurrentprocess = Fiddle::Function.new(kernel32["GetCurrentProcess"], [], Fiddle::TYPE_LONG)
|
1037
|
-
getmodulefilename = Fiddle::Function.new(kernel32["GetModuleFileNameW"], [Fiddle::TYPE_UINTPTR_T, Fiddle::TYPE_VOIDP, Fiddle::TYPE_LONG], Fiddle::TYPE_LONG)
|
1038
|
-
getlasterror = Fiddle::Function.new(kernel32["GetLastError"], [], Fiddle::TYPE_LONG)
|
1039
|
-
|
1040
|
-
# Different packing/unpacking for 64/32 bits systems
|
1041
|
-
if Fiddle::SIZEOF_VOIDP == 8 then
|
1042
|
-
f_single = "Q"
|
1043
|
-
f_array = "Q*"
|
1044
|
-
else
|
1045
|
-
f_single = "I"
|
1046
|
-
f_array = "I*"
|
1047
|
-
end
|
1054
|
+
extend Fiddle::Importer
|
1055
|
+
dlload "kernel32.dll", "psapi.dll"
|
1048
1056
|
|
1049
|
-
|
1050
|
-
|
1051
|
-
|
1052
|
-
|
1053
|
-
|
1054
|
-
|
1055
|
-
|
1056
|
-
|
1057
|
-
|
1058
|
-
|
1057
|
+
include Fiddle::Win32Types
|
1058
|
+
# https://docs.microsoft.com/en-us/windows/win32/winprog/windows-data-types
|
1059
|
+
typealias "HINSTANCE", "HANDLE" # for Ruby2.6 only
|
1060
|
+
typealias "HMODULE", "HINSTANCE"
|
1061
|
+
typealias "LPDWORD", "PDWORD"
|
1062
|
+
typealias "LPWSTR", "char*"
|
1063
|
+
|
1064
|
+
extern "BOOL EnumProcessModules(HANDLE, HMODULE*, DWORD, LPDWORD)"
|
1065
|
+
extern "DWORD GetModuleFileNameW(HMODULE, LPWSTR, DWORD)"
|
1066
|
+
extern "HANDLE GetCurrentProcess()"
|
1067
|
+
extern "DWORD GetLastError()"
|
1068
|
+
end
|
1059
1069
|
|
1060
|
-
|
1061
|
-
|
1062
|
-
|
1063
|
-
|
1064
|
-
|
1065
|
-
|
1066
|
-
|
1070
|
+
def LibraryDetector.loaded_dlls
|
1071
|
+
init_fiddle
|
1072
|
+
|
1073
|
+
dword = "L" # A DWORD is a 32-bit unsigned integer.
|
1074
|
+
bytes_needed = [0].pack(dword)
|
1075
|
+
bytes = DEFAULT_HMODULE_BUFFER_SIZE
|
1076
|
+
process_handle = GetCurrentProcess()
|
1077
|
+
handles = while true
|
1078
|
+
buffer = "\x00" * bytes
|
1079
|
+
if EnumProcessModules(process_handle, buffer, buffer.bytesize, bytes_needed) == 0
|
1080
|
+
Ocran.fatal_error "LibraryDetector: EnumProcessModules failed with error code %#010x" % GetLastError()
|
1081
|
+
end
|
1082
|
+
bytes = bytes_needed.unpack1(dword)
|
1083
|
+
if bytes <= buffer.bytesize
|
1084
|
+
break buffer.unpack("J#{bytes / Fiddle::SIZEOF_VOIDP}")
|
1085
|
+
end
|
1086
|
+
end
|
1087
|
+
str = "\x00".encode("UTF-16LE") * MAX_PATH
|
1088
|
+
handles.map do |handle|
|
1089
|
+
length = GetModuleFileNameW(handle, str, str.bytesize)
|
1090
|
+
if length == 0
|
1091
|
+
Ocran.fatal_error "LibraryDetector: GetModuleFileNameW failed with error code %#010x" % GetLastError()
|
1067
1092
|
end
|
1068
|
-
|
1069
|
-
Ocran.Pathname(modulefilename)
|
1093
|
+
Ocran.Pathname(str[0, length])
|
1070
1094
|
end
|
1071
1095
|
end
|
1072
1096
|
|
@@ -1112,7 +1136,7 @@ EOF
|
|
1112
1136
|
end
|
1113
1137
|
|
1114
1138
|
if Ocran.icon_filename
|
1115
|
-
system Ocran.ediconpath, path, Ocran.icon_filename
|
1139
|
+
system Ocran.ediconpath.to_s, path.to_s, Ocran.icon_filename.to_s
|
1116
1140
|
end
|
1117
1141
|
|
1118
1142
|
opcode_offset = File.size(path)
|
@@ -1142,7 +1166,7 @@ EOF
|
|
1142
1166
|
begin
|
1143
1167
|
data_size = File.size(tmpinpath)
|
1144
1168
|
Ocran.msg "Compressing #{data_size} bytes"
|
1145
|
-
system(Ocran.lzmapath, "e", tmpinpath, tmpoutpath) or fail
|
1169
|
+
system(Ocran.lzmapath.to_s, "e", tmpinpath, tmpoutpath) or fail
|
1146
1170
|
compressed_data_size = File.size?(tmpoutpath)
|
1147
1171
|
ocranfile.write([OP_DECOMPRESS_LZMA, compressed_data_size].pack("VV"))
|
1148
1172
|
IO.copy_stream(tmpoutpath, ocranfile)
|
@@ -1189,7 +1213,7 @@ EOF
|
|
1189
1213
|
Ocran.msg "Running InnoSetup compiler ISCC"
|
1190
1214
|
result = system(*iscc_cmd)
|
1191
1215
|
if not result
|
1192
|
-
case
|
1216
|
+
case $?.exitstatus
|
1193
1217
|
when 0 then raise RuntimeError.new("ISCC reported success, but system reported error?")
|
1194
1218
|
when 1 then raise RuntimeError.new("ISCC reports invalid command line parameters")
|
1195
1219
|
when 2 then raise RuntimeError.new("ISCC reports that compilation failed")
|
@@ -1206,8 +1230,8 @@ EOF
|
|
1206
1230
|
end
|
1207
1231
|
|
1208
1232
|
def mkdir(path)
|
1209
|
-
return if @paths[path.
|
1210
|
-
@paths[path.
|
1233
|
+
return if @paths[path.to_s.downcase]
|
1234
|
+
@paths[path.to_posix.downcase] = true
|
1211
1235
|
Ocran.verbose_msg "m #{showtempdir path}"
|
1212
1236
|
unless Ocran.inno_script # The directory will be created by InnoSetup with a [Dirs] statement
|
1213
1237
|
@of << [OP_CREATE_DIRECTORY, path.to_native].pack("VZ*")
|
@@ -1216,7 +1240,7 @@ EOF
|
|
1216
1240
|
|
1217
1241
|
def ensuremkdir(tgt)
|
1218
1242
|
tgt = Ocran.Pathname(tgt)
|
1219
|
-
return if tgt.
|
1243
|
+
return if tgt.to_s == "."
|
1220
1244
|
if not @paths[tgt.to_posix.downcase]
|
1221
1245
|
ensuremkdir(tgt.dirname)
|
1222
1246
|
mkdir(tgt)
|
@@ -1234,7 +1258,7 @@ EOF
|
|
1234
1258
|
@files[tgt] = src
|
1235
1259
|
src, tgt = Ocran.Pathname(src), Ocran.Pathname(tgt)
|
1236
1260
|
ensuremkdir(tgt.dirname)
|
1237
|
-
str =
|
1261
|
+
str = src.binread
|
1238
1262
|
Ocran.verbose_msg "a #{showtempdir tgt}"
|
1239
1263
|
unless Ocran.inno_script # InnoSetup will install the file with a [Files] statement
|
1240
1264
|
@of << [OP_CREATE_FILE, tgt.to_native, str.size].pack("VZ*V")
|
@@ -1265,7 +1289,7 @@ EOF
|
|
1265
1289
|
end
|
1266
1290
|
|
1267
1291
|
def showtempdir(x)
|
1268
|
-
x.to_s.gsub(TEMPDIR_ROOT, "<tempdir>")
|
1292
|
+
x.to_s.gsub(TEMPDIR_ROOT.to_s, "<tempdir>")
|
1269
1293
|
end
|
1270
1294
|
end # class OcranBuilder
|
1271
1295
|
end # module Ocran
|
@@ -1287,7 +1311,7 @@ if File.basename(__FILE__) == File.basename($0)
|
|
1287
1311
|
|
1288
1312
|
if Ocran.run_script
|
1289
1313
|
Ocran.msg "Loading script to check dependencies"
|
1290
|
-
$0 = Ocran.files.first
|
1314
|
+
$0 = Ocran.files.first.to_s
|
1291
1315
|
load Ocran.files.first
|
1292
1316
|
end
|
1293
1317
|
end
|
data/lib/ocran/version.rb
CHANGED
data/share/ocran/edicon.exe
CHANGED
Binary file
|
File without changes
|
data/share/ocran/stub.exe
CHANGED
Binary file
|
data/share/ocran/stubw.exe
CHANGED
Binary file
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ocran
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.3.
|
4
|
+
version: 1.3.15
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Andi Idogawa
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2023-
|
12
|
+
date: 2023-11-30 00:00:00.000000000 Z
|
13
13
|
dependencies: []
|
14
14
|
description: "OCRAN (One-Click Ruby Application Next) builds Windows executables from
|
15
15
|
Ruby source code. \n The executable is a self-extracting, self-running executable
|
@@ -31,6 +31,7 @@ files:
|
|
31
31
|
- lib/ocran.rb
|
32
32
|
- lib/ocran/version.rb
|
33
33
|
- share/ocran/edicon.exe
|
34
|
+
- share/ocran/empty-msys-2.0.dll
|
34
35
|
- share/ocran/lzma.exe
|
35
36
|
- share/ocran/stub.exe
|
36
37
|
- share/ocran/stubw.exe
|
@@ -49,7 +50,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
49
50
|
requirements:
|
50
51
|
- - ">="
|
51
52
|
- !ruby/object:Gem::Version
|
52
|
-
version: 2.
|
53
|
+
version: 2.6.0
|
53
54
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
54
55
|
requirements:
|
55
56
|
- - ">="
|