ocran 1.3.13 → 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 +190 -162
- 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 +6 -5
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})/
|
|
@@ -230,6 +269,7 @@ module Ocran
|
|
|
230
269
|
:force_windows => false,
|
|
231
270
|
:force_console => false,
|
|
232
271
|
:icon_filename => nil,
|
|
272
|
+
:rubyopt => nil,
|
|
233
273
|
:gemfile => nil,
|
|
234
274
|
:inno_script => nil,
|
|
235
275
|
:quiet => false,
|
|
@@ -269,40 +309,23 @@ module Ocran
|
|
|
269
309
|
exit 1
|
|
270
310
|
end
|
|
271
311
|
|
|
272
|
-
# Returns a binary blob store embedded in the current Ruby script.
|
|
273
|
-
def Ocran.get_next_embedded_image
|
|
274
|
-
DATA.read(DATA.readline.to_i).unpack("m")[0]
|
|
275
|
-
end
|
|
276
|
-
|
|
277
312
|
def Ocran.save_environment
|
|
278
313
|
@load_path_before = $LOAD_PATH.dup
|
|
279
314
|
@pwd_before = Dir.pwd
|
|
280
|
-
@env_before =
|
|
315
|
+
@env_before = ENV.to_hash
|
|
281
316
|
end
|
|
282
317
|
|
|
283
318
|
def Ocran.restore_environment
|
|
284
|
-
@env_before
|
|
285
|
-
ENV.each_key { |key| ENV.delete(key) unless @env_before.has_key?(key) }
|
|
319
|
+
ENV.clear.update(@env_before)
|
|
286
320
|
Dir.chdir @pwd_before
|
|
287
321
|
end
|
|
288
322
|
|
|
289
323
|
def Ocran.find_stubs
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
File.open(@lzmapath, "wb") { |file| file << lzmaimage }
|
|
296
|
-
ediconimage = get_next_embedded_image
|
|
297
|
-
@ediconpath = Host.tempdir / "edicon.exe"
|
|
298
|
-
File.open(@ediconpath, "wb") { |file| file << ediconimage }
|
|
299
|
-
else
|
|
300
|
-
ocranpath = Pathname(File.dirname(__FILE__))
|
|
301
|
-
@stubimage = File.open(ocranpath / "../share/ocran/stub.exe", "rb") { |file| file.read }
|
|
302
|
-
@stubwimage = File.open(ocranpath / "../share/ocran/stubw.exe", "rb") { |file| file.read }
|
|
303
|
-
@lzmapath = (ocranpath / "../share/ocran/lzma.exe").expand
|
|
304
|
-
@ediconpath = (ocranpath / "../share/ocran/edicon.exe").expand
|
|
305
|
-
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
|
|
306
329
|
end
|
|
307
330
|
|
|
308
331
|
def Ocran.parseargs(argv)
|
|
@@ -362,6 +385,7 @@ Executable options:
|
|
|
362
385
|
--console Force console application (ruby.exe)
|
|
363
386
|
--chdir-first When exe starts, change working directory to app dir.
|
|
364
387
|
--icon <ico> Replace icon with a custom one.
|
|
388
|
+
--rubyopt <str> Set the RUBYOPT environment variable when running the executable
|
|
365
389
|
--debug Executable will be verbose.
|
|
366
390
|
--debug-extract Executable will unpack to local dir and not delete after.
|
|
367
391
|
EOF
|
|
@@ -375,9 +399,11 @@ EOF
|
|
|
375
399
|
when /\A--add-all-core\z/
|
|
376
400
|
@options[:add_all_core] = true
|
|
377
401
|
when /\A--output\z/
|
|
378
|
-
|
|
402
|
+
path = argv.shift
|
|
403
|
+
@options[:output_override] = Pathname.new(path) if path
|
|
379
404
|
when /\A--dll\z/
|
|
380
|
-
|
|
405
|
+
path = argv.shift
|
|
406
|
+
@options[:extra_dlls] << path if path
|
|
381
407
|
when /\A--quiet\z/
|
|
382
408
|
@options[:quiet] = true
|
|
383
409
|
when /\A--verbose\z/
|
|
@@ -391,14 +417,19 @@ EOF
|
|
|
391
417
|
when /\A--chdir-first\z/
|
|
392
418
|
@options[:chdir_first] = true
|
|
393
419
|
when /\A--icon\z/
|
|
394
|
-
|
|
395
|
-
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)
|
|
423
|
+
when /\A--rubyopt\z/
|
|
424
|
+
@options[:rubyopt] = argv.shift
|
|
396
425
|
when /\A--gemfile\z/
|
|
397
|
-
|
|
398
|
-
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)
|
|
399
429
|
when /\A--innosetup\z/
|
|
400
|
-
|
|
401
|
-
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)
|
|
402
433
|
when /\A--no-autodll\z/
|
|
403
434
|
@options[:autodll] = false
|
|
404
435
|
when /\A--version\z/
|
|
@@ -417,17 +448,18 @@ EOF
|
|
|
417
448
|
@options[:enc] = !$1
|
|
418
449
|
when /\A--(no-)?gem-(\w+)(?:=(.*))?$/
|
|
419
450
|
negate, group, list = $1, $2, $3
|
|
420
|
-
@options[:gem]
|
|
421
|
-
@options[:gem] << [negate, group.to_sym, list && list.split(",")]
|
|
451
|
+
@options[:gem] << [negate, group.to_sym, list&.split(",")] if group
|
|
422
452
|
when /\A--help\z/, /\A--./
|
|
423
453
|
puts usage
|
|
424
454
|
exit 0
|
|
425
455
|
else
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
456
|
+
path = arg.dup
|
|
457
|
+
|
|
458
|
+
if !File.exist?(path) || Dir.empty?(path)
|
|
459
|
+
Ocran.fatal_error "#{path} not found!"
|
|
430
460
|
end
|
|
461
|
+
|
|
462
|
+
@options[:files] << path
|
|
431
463
|
end
|
|
432
464
|
end
|
|
433
465
|
|
|
@@ -449,14 +481,12 @@ EOF
|
|
|
449
481
|
end
|
|
450
482
|
|
|
451
483
|
@options[:files].map! { |path|
|
|
452
|
-
path = path.encode("UTF-8").tr(
|
|
484
|
+
path = path.encode("UTF-8").tr("\\", "/")
|
|
453
485
|
if File.directory?(path)
|
|
454
486
|
# If a directory is passed, we want all files under that directory
|
|
455
487
|
path = "#{path}/**/*"
|
|
456
488
|
end
|
|
457
|
-
|
|
458
|
-
Ocran.fatal_error "#{path} not found!" if files.empty?
|
|
459
|
-
files.map { |path| Pathname(path).expand }
|
|
489
|
+
Pathname.glob(path).map!(&:expand_path)
|
|
460
490
|
}.flatten!
|
|
461
491
|
end
|
|
462
492
|
|
|
@@ -482,8 +512,6 @@ EOF
|
|
|
482
512
|
modules_to_check.each do |mod|
|
|
483
513
|
modules_checked[mod] = true
|
|
484
514
|
mod.constants.each do |const|
|
|
485
|
-
# Module::Config causes warning on Ruby 1.9.3 - prevent autoloading
|
|
486
|
-
next if Module === mod && const == :Config
|
|
487
515
|
if mod.autoload?(const)
|
|
488
516
|
Ocran.msg "Attempting to trigger autoload of #{mod}::#{const}"
|
|
489
517
|
begin
|
|
@@ -505,26 +533,26 @@ EOF
|
|
|
505
533
|
def Ocran.find_load_path(loadpaths, feature)
|
|
506
534
|
if feature.absolute?
|
|
507
535
|
# Choose those loadpaths which contain the feature
|
|
508
|
-
candidate_loadpaths = loadpaths.select { |loadpath| feature.subpath?(loadpath.
|
|
536
|
+
candidate_loadpaths = loadpaths.select { |loadpath| feature.subpath?(loadpath.expand_path) }
|
|
509
537
|
# Guess the require'd feature
|
|
510
|
-
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)] }
|
|
511
539
|
# Select the shortest possible require-path (longest load-path)
|
|
512
540
|
if feature_pairs.empty?
|
|
513
541
|
nil
|
|
514
542
|
else
|
|
515
|
-
feature_pairs.sort_by { |loadpath, feature| feature.
|
|
543
|
+
feature_pairs.sort_by { |loadpath, feature| feature.to_s.size }.first[0]
|
|
516
544
|
end
|
|
517
545
|
else
|
|
518
546
|
# Select the loadpaths that contain 'feature' and select the shortest
|
|
519
|
-
candidates = loadpaths.select { |loadpath| feature.
|
|
520
|
-
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
|
|
521
549
|
end
|
|
522
550
|
end
|
|
523
551
|
|
|
524
552
|
# Find the root of all files specified on the command line and use
|
|
525
553
|
# it as the "src" of the output.
|
|
526
554
|
def Ocran.find_src_root(files)
|
|
527
|
-
src_files = files.map { |file| file.
|
|
555
|
+
src_files = files.map { |file| file.expand_path }
|
|
528
556
|
src_prefix = src_files.inject(src_files.first.dirname) do |srcroot, path|
|
|
529
557
|
if path.subpath?(Host.exec_prefix)
|
|
530
558
|
srcroot
|
|
@@ -575,18 +603,19 @@ EOF
|
|
|
575
603
|
end
|
|
576
604
|
end
|
|
577
605
|
|
|
578
|
-
ENV["BUNDLE_GEMFILE"] = Ocran.gemfile
|
|
606
|
+
ENV["BUNDLE_GEMFILE"] = Ocran.gemfile.to_s
|
|
579
607
|
Bundler.load.specs.each do |spec|
|
|
580
608
|
Ocran.verbose_msg "From Gemfile, adding gem #{spec.full_name}"
|
|
581
609
|
gems[spec.name] ||= spec
|
|
582
610
|
end
|
|
583
611
|
|
|
612
|
+
# This code is implemented for compatibility with older Bundler versions (< v1.16.0.pre.1).
|
|
584
613
|
unless gems.any? { |name, spec| name == "bundler" }
|
|
585
614
|
# Bundler itself wasn't added for some reason, let's put it in directly
|
|
586
615
|
Ocran.verbose_msg "From Gemfile, forcing inclusion of bundler gem itself"
|
|
587
616
|
bundler_spec = Gem.loaded_specs["bundler"]
|
|
588
617
|
bundler_spec or Ocran.fatal_error "Unable to locate bundler gem"
|
|
589
|
-
gems["bundler"] ||=
|
|
618
|
+
gems["bundler"] ||= bundler_spec
|
|
590
619
|
end
|
|
591
620
|
end
|
|
592
621
|
|
|
@@ -606,12 +635,12 @@ EOF
|
|
|
606
635
|
features_from_gems << feature
|
|
607
636
|
next
|
|
608
637
|
end
|
|
609
|
-
gempaths =
|
|
638
|
+
gempaths = Gem.path
|
|
610
639
|
gempaths.each do |gempath|
|
|
611
640
|
geminstallpath = Pathname(gempath) / "gems"
|
|
612
641
|
if feature.subpath?(geminstallpath)
|
|
613
642
|
gemlocalpath = feature.relative_path_from(geminstallpath)
|
|
614
|
-
fullgemname = gemlocalpath.
|
|
643
|
+
fullgemname = gemlocalpath.to_s.split("/").first
|
|
615
644
|
gemspecpath = gempath / "specifications" / "#{fullgemname}.gemspec"
|
|
616
645
|
if spec = Gem::Specification.load(gemspecpath)
|
|
617
646
|
gems[spec.name] ||= spec
|
|
@@ -678,9 +707,9 @@ EOF
|
|
|
678
707
|
Ocran.msg "Detected gem #{spec.full_name} (#{include.join(", ")})"
|
|
679
708
|
|
|
680
709
|
gem_root = Pathname(spec.gem_dir)
|
|
681
|
-
gem_extension = (gem_root / ".." / ".." / "extensions").
|
|
710
|
+
gem_extension = (gem_root / ".." / ".." / "extensions").expand_path
|
|
682
711
|
if gem_extension.exist?
|
|
683
|
-
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 }
|
|
684
713
|
else
|
|
685
714
|
build_complete = nil
|
|
686
715
|
end
|
|
@@ -700,14 +729,14 @@ EOF
|
|
|
700
729
|
when :loaded
|
|
701
730
|
files << features_from_gems.select { |feature| feature.subpath?(gem_root) }
|
|
702
731
|
when :files
|
|
703
|
-
gem_root_files ||= gem_root.find_all_files
|
|
732
|
+
gem_root_files ||= gem_root.find_all_files
|
|
704
733
|
files << gem_root_files.select { |path| path.relative_path_from(gem_root) !~ GEM_NON_FILE_RE }
|
|
705
734
|
files << build_complete if build_complete
|
|
706
735
|
when :extras
|
|
707
|
-
gem_root_files ||= gem_root.find_all_files
|
|
736
|
+
gem_root_files ||= gem_root.find_all_files
|
|
708
737
|
files << gem_root_files.select { |path| path.relative_path_from(gem_root) =~ GEM_EXTRA_RE }
|
|
709
738
|
when :scripts
|
|
710
|
-
gem_root_files ||= gem_root.find_all_files
|
|
739
|
+
gem_root_files ||= gem_root.find_all_files
|
|
711
740
|
files << gem_root_files.select { |path| path.relative_path_from(gem_root) =~ GEM_SCRIPT_RE }
|
|
712
741
|
end
|
|
713
742
|
end
|
|
@@ -719,7 +748,7 @@ EOF
|
|
|
719
748
|
Ocran.warn "#{missing_file} was not found"
|
|
720
749
|
end
|
|
721
750
|
|
|
722
|
-
total_size = actual_files.
|
|
751
|
+
total_size = actual_files.sum(0, &:size)
|
|
723
752
|
Ocran.msg "\t#{actual_files.size} files, #{total_size} bytes"
|
|
724
753
|
|
|
725
754
|
gem_files += actual_files
|
|
@@ -733,9 +762,9 @@ EOF
|
|
|
733
762
|
end
|
|
734
763
|
|
|
735
764
|
def Ocran.build_exe
|
|
736
|
-
all_load_paths = $LOAD_PATH.map { |loadpath| Pathname(loadpath).
|
|
737
|
-
@added_load_paths = ($LOAD_PATH - @load_path_before).map { |loadpath| Pathname(loadpath).
|
|
738
|
-
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
|
|
739
768
|
|
|
740
769
|
restore_environment
|
|
741
770
|
|
|
@@ -780,7 +809,7 @@ EOF
|
|
|
780
809
|
encpath = path / "enc"
|
|
781
810
|
if encpath.exist?
|
|
782
811
|
encfiles = encpath.find_all_files(/\.so$/)
|
|
783
|
-
size = encfiles.
|
|
812
|
+
size = encfiles.sum(0, &:size)
|
|
784
813
|
Ocran.msg "Including #{encfiles.size} encoding support files (#{size} bytes, use --no-enc to exclude)"
|
|
785
814
|
features.push(*encfiles)
|
|
786
815
|
end
|
|
@@ -795,13 +824,13 @@ EOF
|
|
|
795
824
|
libs = []
|
|
796
825
|
features.each do |feature|
|
|
797
826
|
path = find_load_path(all_load_paths, feature)
|
|
798
|
-
if path.nil? || path.
|
|
827
|
+
if path.nil? || path.expand_path == Pathname.pwd
|
|
799
828
|
Ocran.files << feature
|
|
800
829
|
else
|
|
801
830
|
if feature.absolute?
|
|
802
|
-
feature = feature.relative_path_from(path.
|
|
831
|
+
feature = feature.relative_path_from(path.expand_path)
|
|
803
832
|
end
|
|
804
|
-
fullpath = feature.
|
|
833
|
+
fullpath = feature.expand_path(path)
|
|
805
834
|
|
|
806
835
|
if fullpath.subpath?(Host.exec_prefix)
|
|
807
836
|
# Features found in the Ruby installation are put in the
|
|
@@ -864,11 +893,10 @@ EOF
|
|
|
864
893
|
next unless path.to_posix =~
|
|
865
894
|
/\/(ruby\/(?:site_ruby\/|vendor_ruby\/)?[0-9.]+)\/?$/i
|
|
866
895
|
subdir = $1
|
|
867
|
-
|
|
868
|
-
fpath = Pathname.new(f)
|
|
896
|
+
Pathname.glob("#{lp}/**/*").each do |fpath|
|
|
869
897
|
next if fpath.directory?
|
|
870
898
|
tgt = "lib/#{subdir}/#{fpath.relative_path_from(path).to_posix}"
|
|
871
|
-
libs << [
|
|
899
|
+
libs << [fpath, tgt]
|
|
872
900
|
end
|
|
873
901
|
end
|
|
874
902
|
end
|
|
@@ -877,13 +905,19 @@ EOF
|
|
|
877
905
|
dlls = Ocran.autodll ? LibraryDetector.detect_dlls : []
|
|
878
906
|
|
|
879
907
|
# Detect external manifests
|
|
880
|
-
|
|
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
|
|
881
915
|
|
|
882
916
|
executable = nil
|
|
883
917
|
if Ocran.output_override
|
|
884
918
|
executable = Ocran.output_override
|
|
885
919
|
else
|
|
886
|
-
executable = Ocran.files.first.basename.
|
|
920
|
+
executable = Ocran.files.first.basename.sub_ext(".exe")
|
|
887
921
|
executable.append_to_filename!("-debug") if Ocran.debug
|
|
888
922
|
end
|
|
889
923
|
|
|
@@ -959,8 +993,8 @@ EOF
|
|
|
959
993
|
if gemspec.subpath?(Host.exec_prefix)
|
|
960
994
|
path = gemspec.relative_path_from(Host.exec_prefix)
|
|
961
995
|
sb.createfile(gemspec, path)
|
|
962
|
-
elsif defined?(Gem) and gemhome =
|
|
963
|
-
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))
|
|
964
998
|
sb.createfile(gemspec, path)
|
|
965
999
|
else
|
|
966
1000
|
Ocran.fatal_error "Gem spec #{gemspec} does not exist in the Ruby installation. Don't know where to put it."
|
|
@@ -975,11 +1009,12 @@ EOF
|
|
|
975
1009
|
|
|
976
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)
|
|
977
1011
|
# Add an empty file to /msys64/usr/bin/msys-2.0.dll if the dll was not required otherwise
|
|
978
|
-
|
|
979
|
-
|
|
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
|
|
980
1015
|
|
|
981
1016
|
# Set environment variable
|
|
982
|
-
sb.setenv("RUBYOPT", ENV["RUBYOPT"] || "")
|
|
1017
|
+
sb.setenv("RUBYOPT", Ocran.rubyopt || ENV["RUBYOPT"] || "")
|
|
983
1018
|
sb.setenv("RUBYLIB", load_path.map { |path| path.to_native }.uniq.join(";"))
|
|
984
1019
|
|
|
985
1020
|
sb.setenv("GEM_PATH", (TEMPDIR_ROOT / GEMHOMEDIR).to_native)
|
|
@@ -998,71 +1033,64 @@ EOF
|
|
|
998
1033
|
end
|
|
999
1034
|
|
|
1000
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
|
+
|
|
1001
1050
|
def LibraryDetector.init_fiddle
|
|
1002
|
-
require "fiddle"
|
|
1051
|
+
require "fiddle/import"
|
|
1003
1052
|
require "fiddle/types"
|
|
1004
|
-
module_eval {
|
|
1005
|
-
extend Fiddle::Importer
|
|
1006
|
-
dlload "psapi.dll"
|
|
1007
|
-
include Fiddle::Win32Types
|
|
1008
|
-
extern "BOOL EnumProcessModules(HANDLE, HMODULE*, DWORD, DWORD*)"
|
|
1009
|
-
extend Fiddle::Importer
|
|
1010
|
-
dlload "kernel32.dll"
|
|
1011
|
-
include Fiddle::Win32Types
|
|
1012
|
-
|
|
1013
|
-
# https://docs.microsoft.com/en-us/windows/win32/winprog/windows-data-types
|
|
1014
|
-
# typedef PVOID HANDLE
|
|
1015
|
-
# typedef HINSTANCE HMODULE;
|
|
1016
|
-
|
|
1017
|
-
typealias "HMODULE", "voidp"
|
|
1018
|
-
typealias "HANDLE", "voidp"
|
|
1019
|
-
typealias "LPWSTR", "char*"
|
|
1020
|
-
|
|
1021
|
-
extern "DWORD GetModuleFileNameW(HMODULE, LPWSTR, DWORD)"
|
|
1022
|
-
extern "HANDLE GetCurrentProcess(void)"
|
|
1023
|
-
extern "DWORD GetLastError(void)"
|
|
1024
|
-
}
|
|
1025
|
-
end
|
|
1026
1053
|
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
psapi = Fiddle.dlopen("psapi")
|
|
1030
|
-
enumprocessmodules = Fiddle::Function.new(psapi["EnumProcessModules"], [Fiddle::TYPE_UINTPTR_T, Fiddle::TYPE_VOIDP, Fiddle::TYPE_LONG, Fiddle::TYPE_VOIDP], Fiddle::TYPE_LONG)
|
|
1031
|
-
kernel32 = Fiddle.dlopen("kernel32")
|
|
1032
|
-
getcurrentprocess = Fiddle::Function.new(kernel32["GetCurrentProcess"], [], Fiddle::TYPE_LONG)
|
|
1033
|
-
getmodulefilename = Fiddle::Function.new(kernel32["GetModuleFileNameW"], [Fiddle::TYPE_UINTPTR_T, Fiddle::TYPE_VOIDP, Fiddle::TYPE_LONG], Fiddle::TYPE_LONG)
|
|
1034
|
-
getlasterror = Fiddle::Function.new(kernel32["GetLastError"], [], Fiddle::TYPE_LONG)
|
|
1035
|
-
|
|
1036
|
-
# Different packing/unpacking for 64/32 bits systems
|
|
1037
|
-
if Fiddle::SIZEOF_VOIDP == 8 then
|
|
1038
|
-
f_single = "Q"
|
|
1039
|
-
f_array = "Q*"
|
|
1040
|
-
else
|
|
1041
|
-
f_single = "I"
|
|
1042
|
-
f_array = "I*"
|
|
1043
|
-
end
|
|
1054
|
+
extend Fiddle::Importer
|
|
1055
|
+
dlload "kernel32.dll", "psapi.dll"
|
|
1044
1056
|
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
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
|
|
1055
1069
|
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
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()
|
|
1063
1092
|
end
|
|
1064
|
-
|
|
1065
|
-
Ocran.Pathname(modulefilename)
|
|
1093
|
+
Ocran.Pathname(str[0, length])
|
|
1066
1094
|
end
|
|
1067
1095
|
end
|
|
1068
1096
|
|
|
@@ -1108,7 +1136,7 @@ EOF
|
|
|
1108
1136
|
end
|
|
1109
1137
|
|
|
1110
1138
|
if Ocran.icon_filename
|
|
1111
|
-
system Ocran.ediconpath, path, Ocran.icon_filename
|
|
1139
|
+
system Ocran.ediconpath.to_s, path.to_s, Ocran.icon_filename.to_s
|
|
1112
1140
|
end
|
|
1113
1141
|
|
|
1114
1142
|
opcode_offset = File.size(path)
|
|
@@ -1138,7 +1166,7 @@ EOF
|
|
|
1138
1166
|
begin
|
|
1139
1167
|
data_size = File.size(tmpinpath)
|
|
1140
1168
|
Ocran.msg "Compressing #{data_size} bytes"
|
|
1141
|
-
system(Ocran.lzmapath, "e", tmpinpath, tmpoutpath) or fail
|
|
1169
|
+
system(Ocran.lzmapath.to_s, "e", tmpinpath, tmpoutpath) or fail
|
|
1142
1170
|
compressed_data_size = File.size?(tmpoutpath)
|
|
1143
1171
|
ocranfile.write([OP_DECOMPRESS_LZMA, compressed_data_size].pack("VV"))
|
|
1144
1172
|
IO.copy_stream(tmpoutpath, ocranfile)
|
|
@@ -1185,7 +1213,7 @@ EOF
|
|
|
1185
1213
|
Ocran.msg "Running InnoSetup compiler ISCC"
|
|
1186
1214
|
result = system(*iscc_cmd)
|
|
1187
1215
|
if not result
|
|
1188
|
-
case
|
|
1216
|
+
case $?.exitstatus
|
|
1189
1217
|
when 0 then raise RuntimeError.new("ISCC reported success, but system reported error?")
|
|
1190
1218
|
when 1 then raise RuntimeError.new("ISCC reports invalid command line parameters")
|
|
1191
1219
|
when 2 then raise RuntimeError.new("ISCC reports that compilation failed")
|
|
@@ -1202,8 +1230,8 @@ EOF
|
|
|
1202
1230
|
end
|
|
1203
1231
|
|
|
1204
1232
|
def mkdir(path)
|
|
1205
|
-
return if @paths[path.
|
|
1206
|
-
@paths[path.
|
|
1233
|
+
return if @paths[path.to_s.downcase]
|
|
1234
|
+
@paths[path.to_posix.downcase] = true
|
|
1207
1235
|
Ocran.verbose_msg "m #{showtempdir path}"
|
|
1208
1236
|
unless Ocran.inno_script # The directory will be created by InnoSetup with a [Dirs] statement
|
|
1209
1237
|
@of << [OP_CREATE_DIRECTORY, path.to_native].pack("VZ*")
|
|
@@ -1212,7 +1240,7 @@ EOF
|
|
|
1212
1240
|
|
|
1213
1241
|
def ensuremkdir(tgt)
|
|
1214
1242
|
tgt = Ocran.Pathname(tgt)
|
|
1215
|
-
return if tgt.
|
|
1243
|
+
return if tgt.to_s == "."
|
|
1216
1244
|
if not @paths[tgt.to_posix.downcase]
|
|
1217
1245
|
ensuremkdir(tgt.dirname)
|
|
1218
1246
|
mkdir(tgt)
|
|
@@ -1230,7 +1258,7 @@ EOF
|
|
|
1230
1258
|
@files[tgt] = src
|
|
1231
1259
|
src, tgt = Ocran.Pathname(src), Ocran.Pathname(tgt)
|
|
1232
1260
|
ensuremkdir(tgt.dirname)
|
|
1233
|
-
str =
|
|
1261
|
+
str = src.binread
|
|
1234
1262
|
Ocran.verbose_msg "a #{showtempdir tgt}"
|
|
1235
1263
|
unless Ocran.inno_script # InnoSetup will install the file with a [Files] statement
|
|
1236
1264
|
@of << [OP_CREATE_FILE, tgt.to_native, str.size].pack("VZ*V")
|
|
@@ -1261,7 +1289,7 @@ EOF
|
|
|
1261
1289
|
end
|
|
1262
1290
|
|
|
1263
1291
|
def showtempdir(x)
|
|
1264
|
-
x.to_s.gsub(TEMPDIR_ROOT, "<tempdir>")
|
|
1292
|
+
x.to_s.gsub(TEMPDIR_ROOT.to_s, "<tempdir>")
|
|
1265
1293
|
end
|
|
1266
1294
|
end # class OcranBuilder
|
|
1267
1295
|
end # module Ocran
|
|
@@ -1283,7 +1311,7 @@ if File.basename(__FILE__) == File.basename($0)
|
|
|
1283
1311
|
|
|
1284
1312
|
if Ocran.run_script
|
|
1285
1313
|
Ocran.msg "Loading script to check dependencies"
|
|
1286
|
-
$0 = Ocran.files.first
|
|
1314
|
+
$0 = Ocran.files.first.to_s
|
|
1287
1315
|
load Ocran.files.first
|
|
1288
1316
|
end
|
|
1289
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
|
|
@@ -40,7 +41,7 @@ licenses:
|
|
|
40
41
|
metadata:
|
|
41
42
|
homepage_uri: https://github.com/largo/ocran
|
|
42
43
|
source_code_uri: https://github.com/largo/ocran
|
|
43
|
-
changelog_uri: https://github.com/largo/ocran/
|
|
44
|
+
changelog_uri: https://github.com/largo/ocran/CHANGELOG.txt
|
|
44
45
|
post_install_message:
|
|
45
46
|
rdoc_options: []
|
|
46
47
|
require_paths:
|
|
@@ -49,14 +50,14 @@ 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
|
- - ">="
|
|
56
57
|
- !ruby/object:Gem::Version
|
|
57
58
|
version: '0'
|
|
58
59
|
requirements: []
|
|
59
|
-
rubygems_version: 3.4.
|
|
60
|
+
rubygems_version: 3.4.10
|
|
60
61
|
signing_key:
|
|
61
62
|
specification_version: 4
|
|
62
63
|
summary: OCRAN (One-Click Ruby Application Next) builds Windows executables from Ruby
|