ocran 1.3.18 → 1.4.0

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.
Files changed (54) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.txt +306 -292
  3. data/LICENSE.txt +22 -22
  4. data/README.md +549 -533
  5. data/exe/ocran +5 -5
  6. data/ext/extconf.rb +15 -0
  7. data/lib/ocran/build_constants.rb +16 -16
  8. data/lib/ocran/build_facade.rb +17 -17
  9. data/lib/ocran/build_helper.rb +110 -105
  10. data/lib/ocran/command_output.rb +22 -22
  11. data/lib/ocran/dir_builder.rb +162 -0
  12. data/lib/ocran/direction.rb +623 -458
  13. data/lib/ocran/file_path_set.rb +69 -69
  14. data/lib/ocran/gem_spec_queryable.rb +172 -172
  15. data/lib/ocran/host_config_helper.rb +57 -44
  16. data/lib/ocran/inno_setup_script_builder.rb +111 -111
  17. data/lib/ocran/launcher_batch_builder.rb +85 -85
  18. data/lib/ocran/library_detector.rb +61 -61
  19. data/lib/ocran/library_detector_posix.rb +55 -0
  20. data/lib/ocran/option.rb +323 -273
  21. data/lib/ocran/refine_pathname.rb +104 -104
  22. data/lib/ocran/runner.rb +115 -105
  23. data/lib/ocran/runtime_environment.rb +46 -46
  24. data/lib/ocran/stub_builder.rb +298 -264
  25. data/lib/ocran/version.rb +5 -5
  26. data/lib/ocran/windows_command_escaping.rb +15 -15
  27. data/lib/ocran.rb +7 -7
  28. data/share/ocran/lzma.exe +0 -0
  29. data/src/Makefile +75 -0
  30. data/src/edicon.c +161 -0
  31. data/src/error.c +100 -0
  32. data/src/error.h +66 -0
  33. data/src/inst_dir.c +334 -0
  34. data/src/inst_dir.h +157 -0
  35. data/src/lzma/7zTypes.h +529 -0
  36. data/src/lzma/Compiler.h +43 -0
  37. data/src/lzma/LzmaDec.c +1363 -0
  38. data/src/lzma/LzmaDec.h +236 -0
  39. data/src/lzma/Precomp.h +10 -0
  40. data/src/script_info.c +246 -0
  41. data/src/script_info.h +7 -0
  42. data/src/stub.c +133 -0
  43. data/src/stub.manifest +29 -0
  44. data/src/stub.rc +3 -0
  45. data/src/system_utils.c +1002 -0
  46. data/src/system_utils.h +209 -0
  47. data/src/system_utils_posix.c +500 -0
  48. data/src/unpack.c +574 -0
  49. data/src/unpack.h +85 -0
  50. data/src/vit-ruby.ico +0 -0
  51. metadata +52 -16
  52. data/share/ocran/edicon.exe +0 -0
  53. data/share/ocran/stub.exe +0 -0
  54. data/share/ocran/stubw.exe +0 -0
@@ -1,69 +1,69 @@
1
- # frozen_string_literal: true
2
- require "pathname"
3
- require_relative "refine_pathname"
4
-
5
- module Ocran
6
- class FilePathSet
7
- using RefinePathname
8
- include Enumerable
9
-
10
- def initialize
11
- @set = {}
12
- end
13
-
14
- def add(source, target)
15
- add?(source, target)
16
- self
17
- end
18
-
19
- # Adds a source and target path pair to the set and validates the paths before adding.
20
- # This method performs various checks to ensure the source path is an absolute path
21
- # and the target path is a relative path that does not include '.' or '..'.
22
- # If a conflict is detected (i.e., different source for the same target),
23
- # it raises an exception.
24
- #
25
- # @param [String, Pathname] source - The source file path; must be an absolute path.
26
- # @param [String, Pathname] target - The target file path; must be a relative path.
27
- # @return [self, nil] Returns self if the path pair is added successfully,
28
- # returns nil if the same source and target pair is already present.
29
- # @raise [ArgumentError] If the source is not an absolute path, if the target is not a relative path,
30
- # or if the target includes '.' or '..'.
31
- # @raise [RuntimeError] If a conflicting source is found for the same target.
32
- def add?(source, target)
33
- source = Pathname.new(source) unless source.is_a?(Pathname)
34
- source = source.cleanpath
35
- unless source.absolute?
36
- raise ArgumentError, "Source path must be absolute, given: #{source}"
37
- end
38
-
39
- target = Pathname.new(target) unless target.is_a?(Pathname)
40
- target = target.cleanpath
41
- unless target.relative?
42
- raise ArgumentError, "Target path must be relative, given: #{target}"
43
- end
44
- if %w(. ..).include?(target.each_filename.first)
45
- raise ArgumentError, "Relative paths such as '.' or '..' are not allowed, given: #{target}"
46
- end
47
-
48
- if (path = @set[target])
49
- if path.eql?(source)
50
- return nil
51
- else
52
- raise "Conflicting sources for the same target. Target: #{target}, Existing Source: #{path}, Given Source: #{source}"
53
- end
54
- end
55
-
56
- @set[target] = source
57
- self
58
- end
59
-
60
- def each
61
- return to_enum(__method__) unless block_given?
62
- @set.each { |target, source| yield(source, target) }
63
- end
64
-
65
- def to_a
66
- each.to_a
67
- end
68
- end
69
- end
1
+ # frozen_string_literal: true
2
+ require "pathname"
3
+ require_relative "refine_pathname"
4
+
5
+ module Ocran
6
+ class FilePathSet
7
+ using RefinePathname
8
+ include Enumerable
9
+
10
+ def initialize
11
+ @set = {}
12
+ end
13
+
14
+ def add(source, target)
15
+ add?(source, target)
16
+ self
17
+ end
18
+
19
+ # Adds a source and target path pair to the set and validates the paths before adding.
20
+ # This method performs various checks to ensure the source path is an absolute path
21
+ # and the target path is a relative path that does not include '.' or '..'.
22
+ # If a conflict is detected (i.e., different source for the same target),
23
+ # it raises an exception.
24
+ #
25
+ # @param [String, Pathname] source - The source file path; must be an absolute path.
26
+ # @param [String, Pathname] target - The target file path; must be a relative path.
27
+ # @return [self, nil] Returns self if the path pair is added successfully,
28
+ # returns nil if the same source and target pair is already present.
29
+ # @raise [ArgumentError] If the source is not an absolute path, if the target is not a relative path,
30
+ # or if the target includes '.' or '..'.
31
+ # @raise [RuntimeError] If a conflicting source is found for the same target.
32
+ def add?(source, target)
33
+ source = Pathname.new(source) unless source.is_a?(Pathname)
34
+ source = source.cleanpath
35
+ unless source.absolute?
36
+ raise ArgumentError, "Source path must be absolute, given: #{source}"
37
+ end
38
+
39
+ target = Pathname.new(target) unless target.is_a?(Pathname)
40
+ target = target.cleanpath
41
+ unless target.relative?
42
+ raise ArgumentError, "Target path must be relative, given: #{target}"
43
+ end
44
+ if %w(. ..).include?(target.each_filename.first)
45
+ raise ArgumentError, "Relative paths such as '.' or '..' are not allowed, given: #{target}"
46
+ end
47
+
48
+ if (path = @set[target])
49
+ if path.eql?(source)
50
+ return nil
51
+ else
52
+ raise "Conflicting sources for the same target. Target: #{target}, Existing Source: #{path}, Given Source: #{source}"
53
+ end
54
+ end
55
+
56
+ @set[target] = source
57
+ self
58
+ end
59
+
60
+ def each
61
+ return to_enum(__method__) unless block_given?
62
+ @set.each { |target, source| yield(source, target) }
63
+ end
64
+
65
+ def to_a
66
+ each.to_a
67
+ end
68
+ end
69
+ end
@@ -1,172 +1,172 @@
1
- # frozen_string_literal: true
2
- require "rubygems"
3
- require "pathname"
4
- require_relative "refine_pathname"
5
-
6
- module Ocran
7
- module GemSpecQueryable
8
- using RefinePathname
9
-
10
- GEM_SCRIPT_RE = /\.rbw?$/
11
- GEM_EXTRA_RE = %r{(
12
- # Auxiliary files in the root of the gem
13
- ^(\.\/)?(History|Install|Manifest|README|CHANGES|Licen[sc]e|Contributors|ChangeLog|BSD|GPL).*$ |
14
- # Installation files in the root of the gem
15
- ^(\.\/)?(Rakefile|setup.rb|extconf.rb)$ |
16
- # Documentation/test directories in the root of the gem
17
- ^(\.\/)?(doc|ext|examples|test|tests|benchmarks|spec)\/ |
18
- # Directories anywhere
19
- (^|\/)(\.autotest|\.svn|\.cvs|\.git)(\/|$) |
20
- # Unlikely extensions
21
- \.(rdoc|c|cpp|c\+\+|cxx|h|hxx|hpp|obj|o|a)$
22
- )}xi
23
- GEM_NON_FILE_RE = /(#{GEM_EXTRA_RE}|#{GEM_SCRIPT_RE})/
24
-
25
- class << self
26
- # find_gem_path method searches for the path of the gem containing the
27
- # specified path. The 'path' argument is a file or directory path.
28
- # It checks each gem's installation path in Gem.path to see if the
29
- # specified path is a subpath. Returns the gem's path if found, or
30
- # nil if not found.
31
- def find_gem_path(path)
32
- return unless defined?(Gem)
33
-
34
- Gem.path.find { |gem_path| Pathname(path).subpath?(gem_path) }
35
- end
36
-
37
- # find_spec_file method searches for the path of the gemspec file of
38
- # the gem containing the specified path. The 'path' argument is a file
39
- # or directory path. It searches within the "gems" directory in each
40
- # directory listed in Gem.path to check if the specified path is a
41
- # subpath. If the gemspec file exists, it returns its path; otherwise,
42
- # it returns nil.
43
- def find_spec_file(path)
44
- return unless defined?(Gem)
45
-
46
- feature = Pathname(path)
47
- Gem.path.each do |gem_path|
48
- gems_dir = File.join(gem_path, "gems")
49
- next unless feature.subpath?(gems_dir)
50
-
51
- full_name = feature.relative_path_from(gems_dir).each_filename.first
52
- spec_path = File.join(gem_path, "specifications", "#{full_name}.gemspec")
53
- return spec_path if File.exist?(spec_path)
54
- end
55
- nil
56
- end
57
-
58
- # find_spec method searches and returns a Gem::Specification object
59
- # based on the specified path. Internally, it uses find_spec_file to
60
- # obtain the path to the gemspec file, and if that file exists, it
61
- # calls Gem::Specification.load to load the gem's specifications.
62
- # Returns the loaded Gem::Specification object, or nil if the gemspec
63
- # file does not exist.
64
- def find_spec(path)
65
- return unless defined?(Gem)
66
-
67
- spec_file = find_spec_file(path)
68
- spec_file && Gem::Specification.load(spec_file)
69
- end
70
-
71
- def scanning_gemfile(gemfile_path)
72
- # Ensure the necessary libraries are loaded to scan the Gemfile.
73
- # This is particularly useful in custom-built Ruby environments or
74
- # where certain libraries might be excluded.
75
- %w[rubygems bundler].each do |lib|
76
- require lib
77
- rescue LoadError
78
- raise "Couldn't scan Gemfile, unable to load #{lib}"
79
- end
80
-
81
- ENV["BUNDLE_GEMFILE"] = gemfile_path.to_s
82
- # Bundler.load.specs includes the spec for Bundler itself
83
- Bundler.load.specs.to_a
84
- end
85
-
86
- # Fall back to gem detection
87
- def detect_gems_from(features, verbose: false)
88
- features.inject([]) do |gems, feature|
89
- if gems.any? { |spec| feature.subpath?(spec.gem_dir) }
90
- # Skip if found in known Gem dir
91
- elsif (spec = GemSpecQueryable.find_spec(feature))
92
- gems << spec
93
- else
94
- puts "Failed to load gemspec for #{feature}" if verbose
95
- end
96
-
97
- gems
98
- end
99
- end
100
-
101
- def gem_inclusion_set(spec_name, gem_options)
102
- include = [:loaded, :files]
103
- gem_options.each do |negate, option, list|
104
- next unless list.nil? || list.include?(spec_name)
105
-
106
- case option
107
- when :minimal
108
- include = [:loaded]
109
- when :guess
110
- include = [:loaded, :files]
111
- when :all
112
- include = [:scripts, :files]
113
- when :full
114
- include = [:scripts, :files, :extras]
115
- when :spec
116
- include = [:spec]
117
- when :scripts, :files, :extras
118
- if negate
119
- include.delete(option)
120
- else
121
- include.push(option)
122
- end
123
- else
124
- raise "Invalid Gem content detection option: #{option}"
125
- end
126
- end
127
- include.uniq!
128
- include
129
- end
130
- end
131
-
132
- def gem_root = Pathname(gem_dir)
133
-
134
- # Find the selected files
135
- def gem_root_files = gem_root.find.select(&:file?)
136
-
137
- def script_files
138
- gem_root_files.select { |path| path.extname =~ GEM_SCRIPT_RE }
139
- end
140
-
141
- def extra_files
142
- gem_root_files.select { |path| path.relative_path_from(gem_root).to_posix =~ GEM_EXTRA_RE }
143
- end
144
-
145
- def resource_files
146
- files = gem_root_files.select { |path| path.relative_path_from(gem_root).to_posix !~ GEM_NON_FILE_RE }
147
- files << Pathname(gem_build_complete_path) if File.exist?(gem_build_complete_path)
148
- files
149
- end
150
-
151
- def find_gem_files(file_sets, features_from_gems)
152
- actual_files = file_sets.flat_map do |set|
153
- case set
154
- when :spec
155
- files.map { |file| Pathname(file) }
156
- when :loaded
157
- features_from_gems.select { |feature| feature.subpath?(gem_dir) }
158
- when :files
159
- resource_files
160
- when :extras
161
- extra_files
162
- when :scripts
163
- script_files
164
- else
165
- raise "Invalid file set: #{set}. Please specify a valid file set (:spec, :loaded, :files, :extras, :scripts)."
166
- end
167
- end
168
- actual_files.uniq
169
- actual_files
170
- end
171
- end
172
- end
1
+ # frozen_string_literal: true
2
+ require "rubygems"
3
+ require "pathname"
4
+ require_relative "refine_pathname"
5
+
6
+ module Ocran
7
+ module GemSpecQueryable
8
+ using RefinePathname
9
+
10
+ GEM_SCRIPT_RE = /\.rbw?$/
11
+ GEM_EXTRA_RE = %r{(
12
+ # Auxiliary files in the root of the gem
13
+ ^(\.\/)?(History|Install|Manifest|README|CHANGES|Licen[sc]e|Contributors|ChangeLog|BSD|GPL).*$ |
14
+ # Installation files in the root of the gem
15
+ ^(\.\/)?(Rakefile|setup.rb|extconf.rb)$ |
16
+ # Documentation/test directories in the root of the gem
17
+ ^(\.\/)?(doc|ext|examples|test|tests|benchmarks|spec)\/ |
18
+ # Directories anywhere
19
+ (^|\/)(\.autotest|\.svn|\.cvs|\.git)(\/|$) |
20
+ # Unlikely extensions
21
+ \.(rdoc|c|cpp|c\+\+|cxx|h|hxx|hpp|obj|o|a)$
22
+ )}xi
23
+ GEM_NON_FILE_RE = /(#{GEM_EXTRA_RE}|#{GEM_SCRIPT_RE})/
24
+
25
+ class << self
26
+ # find_gem_path method searches for the path of the gem containing the
27
+ # specified path. The 'path' argument is a file or directory path.
28
+ # It checks each gem's installation path in Gem.path to see if the
29
+ # specified path is a subpath. Returns the gem's path if found, or
30
+ # nil if not found.
31
+ def find_gem_path(path)
32
+ return unless defined?(Gem)
33
+
34
+ Gem.path.find { |gem_path| Pathname(path).subpath?(gem_path) }
35
+ end
36
+
37
+ # find_spec_file method searches for the path of the gemspec file of
38
+ # the gem containing the specified path. The 'path' argument is a file
39
+ # or directory path. It searches within the "gems" directory in each
40
+ # directory listed in Gem.path to check if the specified path is a
41
+ # subpath. If the gemspec file exists, it returns its path; otherwise,
42
+ # it returns nil.
43
+ def find_spec_file(path)
44
+ return unless defined?(Gem)
45
+
46
+ feature = Pathname(path)
47
+ Gem.path.each do |gem_path|
48
+ gems_dir = File.join(gem_path, "gems")
49
+ next unless feature.subpath?(gems_dir)
50
+
51
+ full_name = feature.relative_path_from(gems_dir).each_filename.first
52
+ spec_path = File.join(gem_path, "specifications", "#{full_name}.gemspec")
53
+ return spec_path if File.exist?(spec_path)
54
+ end
55
+ nil
56
+ end
57
+
58
+ # find_spec method searches and returns a Gem::Specification object
59
+ # based on the specified path. Internally, it uses find_spec_file to
60
+ # obtain the path to the gemspec file, and if that file exists, it
61
+ # calls Gem::Specification.load to load the gem's specifications.
62
+ # Returns the loaded Gem::Specification object, or nil if the gemspec
63
+ # file does not exist.
64
+ def find_spec(path)
65
+ return unless defined?(Gem)
66
+
67
+ spec_file = find_spec_file(path)
68
+ spec_file && Gem::Specification.load(spec_file)
69
+ end
70
+
71
+ def scanning_gemfile(gemfile_path)
72
+ # Ensure the necessary libraries are loaded to scan the Gemfile.
73
+ # This is particularly useful in custom-built Ruby environments or
74
+ # where certain libraries might be excluded.
75
+ %w[rubygems bundler].each do |lib|
76
+ require lib
77
+ rescue LoadError
78
+ raise "Couldn't scan Gemfile, unable to load #{lib}"
79
+ end
80
+
81
+ ENV["BUNDLE_GEMFILE"] = gemfile_path.to_s
82
+ # Bundler.load.specs includes the spec for Bundler itself
83
+ Bundler.load.specs.to_a
84
+ end
85
+
86
+ # Fall back to gem detection
87
+ def detect_gems_from(features, verbose: false)
88
+ features.inject([]) do |gems, feature|
89
+ if gems.any? { |spec| feature.subpath?(spec.gem_dir) }
90
+ # Skip if found in known Gem dir
91
+ elsif (spec = GemSpecQueryable.find_spec(feature))
92
+ gems << spec
93
+ else
94
+ puts "Failed to load gemspec for #{feature}" if verbose
95
+ end
96
+
97
+ gems
98
+ end
99
+ end
100
+
101
+ def gem_inclusion_set(spec_name, gem_options)
102
+ include = [:loaded, :files]
103
+ gem_options.each do |negate, option, list|
104
+ next unless list.nil? || list.include?(spec_name)
105
+
106
+ case option
107
+ when :minimal
108
+ include = [:loaded]
109
+ when :guess
110
+ include = [:loaded, :files]
111
+ when :all
112
+ include = [:scripts, :files]
113
+ when :full
114
+ include = [:scripts, :files, :extras]
115
+ when :spec
116
+ include = [:spec]
117
+ when :scripts, :files, :extras
118
+ if negate
119
+ include.delete(option)
120
+ else
121
+ include.push(option)
122
+ end
123
+ else
124
+ raise "Invalid Gem content detection option: #{option}"
125
+ end
126
+ end
127
+ include.uniq!
128
+ include
129
+ end
130
+ end
131
+
132
+ def gem_root = Pathname(gem_dir)
133
+
134
+ # Find the selected files
135
+ def gem_root_files = gem_root.find.select(&:file?)
136
+
137
+ def script_files
138
+ gem_root_files.select { |path| path.extname =~ GEM_SCRIPT_RE }
139
+ end
140
+
141
+ def extra_files
142
+ gem_root_files.select { |path| path.relative_path_from(gem_root).to_posix =~ GEM_EXTRA_RE }
143
+ end
144
+
145
+ def resource_files
146
+ files = gem_root_files.select { |path| path.relative_path_from(gem_root).to_posix !~ GEM_NON_FILE_RE }
147
+ files << Pathname(gem_build_complete_path) if File.exist?(gem_build_complete_path)
148
+ files
149
+ end
150
+
151
+ def find_gem_files(file_sets, features_from_gems)
152
+ actual_files = file_sets.flat_map do |set|
153
+ case set
154
+ when :spec
155
+ files.map { |file| Pathname(file) }
156
+ when :loaded
157
+ features_from_gems.select { |feature| feature.subpath?(gem_dir) }
158
+ when :files
159
+ resource_files
160
+ when :extras
161
+ extra_files
162
+ when :scripts
163
+ script_files
164
+ else
165
+ raise "Invalid file set: #{set}. Please specify a valid file set (:spec, :loaded, :files, :extras, :scripts)."
166
+ end
167
+ end
168
+ actual_files.uniq
169
+ actual_files
170
+ end
171
+ end
172
+ end
@@ -1,44 +1,57 @@
1
- require "rbconfig"
2
- require "pathname"
3
-
4
- module Ocran
5
- # Variables describing the host's build environment.
6
- module HostConfigHelper
7
- module_function
8
-
9
- def exec_prefix
10
- @exec_prefix ||= Pathname.new(RbConfig::CONFIG["exec_prefix"])
11
- end
12
-
13
- def sitelibdir
14
- @sitelibdir ||= Pathname.new(RbConfig::CONFIG["sitelibdir"])
15
- end
16
-
17
- def bindir
18
- @bindir ||= Pathname.new(RbConfig::CONFIG["bindir"])
19
- end
20
-
21
- def libruby_so
22
- @libruby_so ||= Pathname.new(RbConfig::CONFIG["LIBRUBY_SO"])
23
- end
24
-
25
- def exe_extname
26
- RbConfig::CONFIG["EXEEXT"] || ".exe"
27
- end
28
-
29
- def rubyw_exe
30
- @rubyw_exe ||= (RbConfig::CONFIG["rubyw_install_name"] || "rubyw") + exe_extname
31
- end
32
-
33
- def ruby_exe
34
- @ruby_exe ||= (RbConfig::CONFIG["ruby_install_name"] || "ruby") + exe_extname
35
- end
36
-
37
- def all_core_dir
38
- RbConfig::CONFIG
39
- .slice("rubylibdir", "sitelibdir", "vendorlibdir")
40
- .values
41
- .map { |path| Pathname.new(path) }
42
- end
43
- end
44
- end
1
+ require "rbconfig"
2
+ require "pathname"
3
+
4
+ module Ocran
5
+ # Variables describing the host's build environment.
6
+ module HostConfigHelper
7
+ module_function
8
+
9
+ def exec_prefix
10
+ @exec_prefix ||= Pathname.new(RbConfig::CONFIG["exec_prefix"])
11
+ end
12
+
13
+ def sitelibdir
14
+ @sitelibdir ||= Pathname.new(RbConfig::CONFIG["sitelibdir"])
15
+ end
16
+
17
+ def bindir
18
+ @bindir ||= Pathname.new(RbConfig::CONFIG["bindir"])
19
+ end
20
+
21
+ def libdir
22
+ @libdir ||= Pathname.new(RbConfig::CONFIG["libdir"])
23
+ end
24
+
25
+ def libruby_so
26
+ name = RbConfig::CONFIG["LIBRUBY_SO"]
27
+ return nil if name.nil? || name.empty?
28
+ @libruby_so ||= Pathname.new(name)
29
+ end
30
+
31
+ def libruby_aliases
32
+ aliases = RbConfig::CONFIG["LIBRUBY_ALIASES"]
33
+ return [] if aliases.nil? || aliases.empty?
34
+ aliases.split.map { |name| Pathname.new(name) }
35
+ end
36
+
37
+ def exe_extname
38
+ RbConfig::CONFIG["EXEEXT"] || ".exe"
39
+ end
40
+
41
+ def rubyw_exe
42
+ return nil unless Gem.win_platform?
43
+ @rubyw_exe ||= (RbConfig::CONFIG["rubyw_install_name"] || "rubyw") + exe_extname
44
+ end
45
+
46
+ def ruby_exe
47
+ @ruby_exe ||= (RbConfig::CONFIG["ruby_install_name"] || "ruby") + exe_extname
48
+ end
49
+
50
+ def all_core_dir
51
+ RbConfig::CONFIG
52
+ .slice("rubylibdir", "sitelibdir", "vendorlibdir")
53
+ .values
54
+ .map { |path| Pathname.new(path) }
55
+ end
56
+ end
57
+ end