ocran 1.4.0 → 1.4.2

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: bda746979fe3d0906ec129a11cc4b6d2bc7233f8d11eea4e3f4fb8f2aac9f8a4
4
- data.tar.gz: dfa8ef139ec3ea69e984de479d90cfb00268d29abba79b609dbe7915d0002fe6
3
+ metadata.gz: ff520e4a8036bbcec4c8a1e56c96c89297cf43a88dd868d77ae5f4aadac7865c
4
+ data.tar.gz: 7735500efac55f60da13cf8c854bb6f80967b091b8baad310889073c7b8093eb
5
5
  SHA512:
6
- metadata.gz: 60aab3f5becf047750ff2efcd5b9c05ecce6493d1e9f77f576dfc94f0864110ee881b91456404367b99912967e2c4cef596558c75cfcfa66aeb48a4308b63e91
7
- data.tar.gz: cde421042a8d660dfb16d7fae20c7217d63cdaf5f701777115da1a2535af311580a6a9483609229d5faf326718d76edd1856b207a20f3df52b7b9f20565494af
6
+ metadata.gz: 7f360b8ea6dd7f87887a9afaa31e1053d0208588f91e24f6ccb224e6e17afe5ca4f2c7558b99907caaea540097b62c14aa3e2fd0cd89ada4615b54da316c883f
7
+ data.tar.gz: 5586f5255f2d966c12a23bbe934d1743b0b2f12158307dee2c94dbaa7b3731a08c31f019a378740280da2895d6a216c750da47b84f5fe30143bfc3d5d755bafe
data/CHANGELOG.txt CHANGED
@@ -1,3 +1,11 @@
1
+ === 1.4.2
2
+ - Auto-bundle OpenSSL and all its transitive dependencies (openssl.rb, digest.so, etc.) when net/http is loaded but no HTTPS request was made during the dependency scan. OpenSSL is now required inside the OCRAN build process so every file it pulls in appears in the bundled executable.
3
+ - Add companion DLL scan on windows: when a native extension (.so) within the Ruby installation is loaded, all DLLs in the same directory are proactively included. This ensures libssl-3-x64.dll, libcrypto-3-x64.dll, libwinpthread-1.dll, and libyaml-0-2.dll are bundled even when no HTTPS connection is made during the build scan.
4
+ - Add `return if defined?(Ocran)` guards to test fixtures that have runtime-only side effects (file writes, Dir.chdir, file existence checks, network requests) to prevent them from running during the dependency scan, so we can check if the dependencies are included correctly.
5
+
6
+ === 1.4.1
7
+ - Fix kernel_require.rb packed at wrong path when rubygems-update is installed (e.g. via asdf on Linux/macOS). kernel_require.rb is now located relative to the actually-loaded rubygems.rb from $LOADED_FEATURES, falling back to rubylibdir for standard Ruby installations.
8
+
1
9
  === 1.4.0
2
10
  - Add Linux support: build and run self-extracting ELF executables on Linux. The stub compiles and runs natively on Linux using POSIX APIs.
3
11
  - Add macOS support: build and run self-extracting Mach-O executables on macOS.
data/README.md CHANGED
@@ -115,10 +115,11 @@ Same as `--output-dir`, but packages the result into a zip file. Requires
115
115
  ### Options:
116
116
 
117
117
  ocran --help
118
+ ocran -h
118
119
 
119
120
  #### General options:
120
121
 
121
- * `--help`: Display available command-line options.
122
+ * `--help`, `-h`: Display available command-line options.
122
123
  * `--quiet`: Suppress all output during the build process.
123
124
  * `--verbose`: Provide detailed output during the build process.
124
125
  * `--version`: Display the OCRAN version number and exit.
@@ -222,6 +223,23 @@ On Windows, run the batch file:
222
223
  * OCRAN-built executables correctly handle multibyte paths (e.g. Japanese, emoji) on Windows 10 1903+.
223
224
  * When using the executable from the console, run `chcp 65001` first to switch to UTF-8 on windows.
224
225
 
226
+ ## Limitations
227
+
228
+ ### No cross-platform building
229
+
230
+ OCRAN is not a cross-compiler. The executable or directory it produces bundles
231
+ the Ruby interpreter from the machine where OCRAN is run, so you must **run
232
+ OCRAN on the same platform (and architecture) as the intended target**:
233
+
234
+ * To produce a Windows `.exe`, run OCRAN on Windows.
235
+ * To produce a Linux binary, run OCRAN on Linux.
236
+ * To produce a macOS app bundle, run OCRAN on macOS.
237
+
238
+ There is no support for building a Windows `.exe` from a Linux or macOS host,
239
+ or vice versa. If you need builds for multiple platforms, run OCRAN in CI on
240
+ each target platform separately (e.g., a Windows runner for `.exe` builds and
241
+ a Linux runner for Linux builds).
242
+
225
243
  ## Requirements
226
244
 
227
245
  * Ruby 3.2+
@@ -100,12 +100,25 @@ module Ocran
100
100
  # Since https://github.com/rubygems/rubygems/commit/cad4cf16cf8fcc637d9da643ef97cf0be2ed63cb
101
101
  # rubygems/core_ext/kernel_require.rb is loaded via IO.read+eval rather than require,
102
102
  # so it never appears in $LOADED_FEATURES and must be added manually.
103
- # Use RbConfig::CONFIG["rubylibdir"] directly so the path is always correct,
104
- # regardless of Ruby version or platform path separator conventions.
103
+ # We check multiple candidate locations because the layout varies by Ruby setup:
104
+ # - Standard Ruby (including RubyInstaller on Windows): rubygems.rb lives in rubylibdir
105
+ # - Ruby with rubygems-update (e.g. asdf on Linux/macOS): rubygems.rb lives in site_ruby
106
+ # kernel_require.rb must be packed alongside the rubygems.rb that was actually loaded,
107
+ # because rubygems.rb uses require_relative to load it.
105
108
  kernel_require_rel = "rubygems/core_ext/kernel_require.rb"
106
109
  unless features.any? { |f| f.to_posix.end_with?(kernel_require_rel) }
107
- kernel_require_path = Pathname(RbConfig::CONFIG["rubylibdir"]) / kernel_require_rel
108
- features.push(kernel_require_path) if kernel_require_path.exist?
110
+ # Prefer the location alongside the actually-loaded rubygems.rb, fall back to rubylibdir
111
+ rubygems_feature = features.find { |f| f.to_posix.end_with?("/rubygems.rb") }
112
+ candidate_dirs = []
113
+ candidate_dirs << rubygems_feature.dirname if rubygems_feature
114
+ candidate_dirs << Pathname(RbConfig::CONFIG["rubylibdir"])
115
+ candidate_dirs.each do |base_dir|
116
+ kernel_require_path = base_dir / kernel_require_rel
117
+ if kernel_require_path.exist?
118
+ features.push(kernel_require_path)
119
+ break
120
+ end
121
+ end
109
122
  end
110
123
 
111
124
  # Convert all relative paths to absolute paths before building.
@@ -131,6 +144,24 @@ module Ocran
131
144
  # Store the currently loaded files
132
145
  features = normalized_features
133
146
 
147
+ # If net/http was loaded but openssl wasn't (it is only required lazily
148
+ # at the point of an actual HTTPS connection), require it now inside the
149
+ # OCRAN build process so that every transitive dependency — openssl.rb,
150
+ # digest.so, and any other files pulled in by the extension — appears in
151
+ # $LOADED_FEATURES and gets bundled alongside the application.
152
+ openssl_so = Pathname(RbConfig::CONFIG["archdir"]) / "openssl.so"
153
+ if openssl_so.exist? &&
154
+ features.any? { |f| f.to_posix.end_with?("/net/http.rb") } &&
155
+ features.none? { |f| f == openssl_so }
156
+ say "Auto-loading openssl (net/http loaded but openssl not yet required)"
157
+ before = $LOADED_FEATURES.dup
158
+ require "openssl"
159
+ ($LOADED_FEATURES - before).each do |f|
160
+ path = Pathname(f).cleanpath
161
+ features << path if path.absolute?
162
+ end
163
+ end
164
+
134
165
  say "Building #{@option.output_executable}"
135
166
  require_relative "build_helper"
136
167
  builder.extend(BuildHelper)
@@ -172,6 +203,22 @@ module Ocran
172
203
  builder.copy_to_bin(dll, dll.basename)
173
204
  end
174
205
  end
206
+
207
+ # Proactively include companion DLLs for loaded native extensions.
208
+ # Native extensions (.so) may depend on DLLs in the same archdir
209
+ # directory (e.g., libssl-3-x64.dll alongside openssl.so) that are
210
+ # loaded lazily on first use. Scanning .so directories ensures those
211
+ # DLLs are bundled even when the extension is required but not
212
+ # exercised during the OCRAN dependency scan.
213
+ features.select { |f| f.extname?(".so") && f.subpath?(exec_prefix) }
214
+ .map(&:dirname).uniq
215
+ .each do |dir|
216
+ dir.each_child do |path|
217
+ next unless path.file? && path.extname?(".dll")
218
+ say "Adding companion DLL #{path}"
219
+ builder.duplicate_to_exec_prefix(path)
220
+ end
221
+ end
175
222
  end
176
223
 
177
224
  # Windows-only: Add external manifest and builtin DLLs
data/lib/ocran/option.rb CHANGED
@@ -46,7 +46,7 @@ ocran [options] script.rb
46
46
 
47
47
  Ocran options:
48
48
 
49
- --help Display this information.
49
+ --help, -h Display this information.
50
50
  --quiet Suppress output while building executable.
51
51
  --verbose Show extra output while building executable.
52
52
  --version Display version number and exit.
@@ -179,7 +179,7 @@ EOF
179
179
  when /\A--(no-)?gem-(\w+)(?:=(.*))?$/
180
180
  negate, group, list = $1, $2, $3
181
181
  @options[:gem_options] << [negate, group.to_sym, list&.split(",")] if group
182
- when "--help", /\A--./
182
+ when "--help", "-h", /\A--./
183
183
  puts usage
184
184
  raise SystemExit
185
185
  else
data/lib/ocran/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Ocran
4
- VERSION = "1.4.0"
4
+ VERSION = "1.4.2"
5
5
  end
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.4.0
4
+ version: 1.4.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andi Idogawa