omnizip 0.4.6 → 0.4.8

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: 7dc6e02021b3915af5f65944e4d734bd3f95a5624b2a01c30100b6bbc36d5856
4
- data.tar.gz: 998838c2bd3df94ced6617b9d199a0f2eab552e332d285bdc6819860fef50324
3
+ metadata.gz: 58a7dba25317b98c16b22362275b4dc813c37346359a98b6797bb51cf2c05a04
4
+ data.tar.gz: 7db43532ecbb62cd66a7daac98daf0da9b13fc1076b843b592020c1c69d679e5
5
5
  SHA512:
6
- metadata.gz: f02b277ef180e076b5e0deb3847ed4cdf3f2a83abf829095779cdbfbdbc811891c8d9db9e000fb071c1d3bc164bd3cf4f031b8e19207b7d6e48232a21bf573dc
7
- data.tar.gz: 4d20378f2973be45cc1cb691894b9c54916c1f5546d45a64a5143feaf8cabf0e053d8d604b8f30b6534d123ad12084021d9815b82945f78f5bfacd64f4daef96
6
+ metadata.gz: ec0c3490a5b88ff20b9f03404d14da7a40ee4d9ab2e432737ad7e2e497ddaeac33be3a670fbcb9c66ede17ca393fab38e3c9ca12b8948705a12544f990577762
7
+ data.tar.gz: 2aa7b51d4127e8495a8d6e862862942aedbc9d139907d7fef2d3502b3914cbf861599a889928784b773e187eb3a00d3ed0a2ee9bebe6ed7a84506fdd96727771
data/.rubocop_todo.yml CHANGED
@@ -138,6 +138,8 @@ Metrics/AbcSize:
138
138
  # AllowedMethods: refine
139
139
  Metrics/BlockLength:
140
140
  Max: 81
141
+ Exclude:
142
+ - "lib/tasks/platform_gems.rake"
141
143
 
142
144
  # Offense count: 5
143
145
  # Configuration parameters: CountBlocks, CountModifierForms.
data/CHANGELOG.md CHANGED
@@ -7,6 +7,37 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ### Added
11
+ - Archive-level tier for every handler: tar, cpio, iso, xar, 7z and
12
+ rar3/4/5 (with `password:` passthrough) route list(names) and
13
+ read_entry through the cdylib's whole-archive surface, falling back
14
+ to the Ruby readers on any Rust error or a missing library. rpm
15
+ rides the tier for read_entry once the dylib is ≥ 0.21.111 (which
16
+ strips the cpio `./` prefix so its entry names match the Ruby
17
+ handler's); rpm list and OLE stay pure-Ruby — OLE is a pinned model
18
+ divergence (Ruby lists top-level entries, Rust flattens the storage
19
+ tree), documented in the capability matrix and pinned by the new
20
+ cross-implementation differential spec.
21
+
22
+ ### Added
23
+ - Prebuilt-binary distribution (parsanol model): platform gems
24
+ (x86_64/aarch64/arm Linux glibc+musl, arm64/x86_64 macOS,
25
+ x64/aarch64-mingw-ucrt, x64-mingw32) now vendor the prebuilt
26
+ `omnizip-ffi` cdylib — `gem install omnizip` gives Rust
27
+ acceleration with zero compilation on those platforms. The plain
28
+ `ruby` gem and every platform without a binary (JRuby,
29
+ TruffleRuby, anything else) stay fully functional on the pure-Ruby
30
+ core. The cdylibs are cross-built by omnizip-rs's release-binary
31
+ workflow and attached to each `omnizip-ffi-v*` release;
32
+ `rake platform_gems:build` packages them and `gem-build.yml`
33
+ smoke-tests each installed gem (tier active + pure-Ruby path with
34
+ `OMNIZIP_NO_RUST=1`).
35
+ - `OMNIZIP_NO_RUST=1` kill switch forces the pure-Ruby core
36
+ everywhere; `Library.resolve_path` (public now) prefers the
37
+ vendored cdylib over dev checkouts; `Library.dylib_version`
38
+ reports the Rust release a loaded cdylib was built from
39
+ (`ozip_version`, new in omnizip-rs 0.21.109).
40
+
10
41
  ### Fixed
11
42
  - PPMd works for the first time: the pure-Ruby ppmd7 core cannot
12
43
  decode its own output (root-only decoder, 100-symbol cap — proven)
data/README.adoc CHANGED
@@ -28,6 +28,28 @@ It provides both a command-line interface and a programmatic Ruby API, making it
28
28
 
29
29
  See link:readme-docs/compression-algorithms.adoc[Compression Algorithms Guide] for detailed information.
30
30
 
31
+ ==== Rust Acceleration (prebuilt, zero compilation)
32
+
33
+ Where the platform gem exists, `gem install omnizip` ships a prebuilt
34
+ `omnizip-ffi` cdylib and the codec + archive tiers route through it
35
+ automatically — no Rust toolchain, no compilation:
36
+
37
+ * x86_64-linux, aarch64-linux, arm-linux (glibc and musl)
38
+ * arm64-darwin, x86_64-darwin
39
+ * x64-mingw-ucrt, aarch64-mingw-ucrt, x64-mingw32
40
+
41
+ Everywhere else — including JRuby/TruffleRuby and any platform without
42
+ a binary — the gem stays fully functional on its pure-Ruby core (the
43
+ acceleration is strictly optional). Three escape hatches:
44
+
45
+ * `OMNIZIP_NO_RUST=1` — force the pure-Ruby core everywhere.
46
+ * `OMNIZIP_FFI_DYLIB=/path/to/libomnizip_ffi` — load a specific build.
47
+ * `rake rust:build` — build and vendor the cdylib yourself from a
48
+ checkout (developers).
49
+
50
+ Any Rust-side failure also falls back to the Ruby core mid-operation,
51
+ so `auto` mode is never worse than pure Ruby.
52
+
31
53
  ==== SDK-Compatible LZMA Mode (v0.2.0)
32
54
 
33
55
  Omnizip now provides SDK-compatible LZMA encoding and decoding for full XZ/LZMA tool compatibility.
@@ -20,6 +20,11 @@ module Omnizip
20
20
  end
21
21
 
22
22
  def list(path, details: false, **_)
23
+ unless details
24
+ tier_names = Omnizip::Backends.archive_entry_names(path)
25
+ return tier_names if tier_names
26
+ end
27
+
23
28
  entries = Omnizip::Formats::Cpio.list(path)
24
29
  if details
25
30
  entries.map do |e|
@@ -32,6 +37,9 @@ module Omnizip
32
37
  end
33
38
 
34
39
  def read_entry(path, entry_name, **_)
40
+ tier = Omnizip::Backends.archive_read_entry(path, entry_name)
41
+ return tier unless tier.nil?
42
+
35
43
  entry = Omnizip::Formats::Cpio.list(path)
36
44
  .find { |e| e.name == entry_name }
37
45
  unless entry
@@ -20,6 +20,11 @@ module Omnizip
20
20
  end
21
21
 
22
22
  def list(path, details: false, **_)
23
+ unless details
24
+ tier_names = Omnizip::Backends.archive_entry_names(path)
25
+ return tier_names if tier_names
26
+ end
27
+
23
28
  entries = Omnizip::Formats::Iso.list(path)
24
29
  if details
25
30
  entries.map do |e|
@@ -32,6 +37,9 @@ module Omnizip
32
37
  end
33
38
 
34
39
  def read_entry(path, entry_name, **_)
40
+ tier = Omnizip::Backends.archive_read_entry(path, entry_name)
41
+ return tier unless tier.nil?
42
+
35
43
  entry = Omnizip::Formats::Iso.list(path)
36
44
  .find { |e| e.full_path == entry_name }
37
45
  unless entry
@@ -29,6 +29,11 @@ module Omnizip
29
29
  end
30
30
 
31
31
  def list(path, details: false, **_)
32
+ unless details
33
+ tier_names = Omnizip::Backends.archive_entry_names(path)
34
+ return tier_names if tier_names
35
+ end
36
+
32
37
  reader = Omnizip::Formats::Rar::Reader.new(path).open
33
38
  entries = reader.list_files
34
39
  if details
@@ -43,6 +48,9 @@ module Omnizip
43
48
  end
44
49
 
45
50
  def read_entry(path, entry_name, password: nil, **_)
51
+ tier = Omnizip::Backends.archive_read_entry(path, entry_name, password: password)
52
+ return tier unless tier.nil?
53
+
46
54
  Dir.mktmpdir("omnizip-rar-entry") do |dir|
47
55
  dest = File.join(dir, "entry")
48
56
  Omnizip::Formats::Rar::Decompressor.extract_entry(
@@ -29,6 +29,9 @@ module Omnizip
29
29
  end
30
30
 
31
31
  def read_entry(path, entry_name, **_)
32
+ tier = Omnizip::Backends.archive_read_entry(path, entry_name)
33
+ return tier unless tier.nil?
34
+
32
35
  Dir.mktmpdir("omnizip-rpm-entry") do |dir|
33
36
  Omnizip::Formats::Rpm.extract(path, dir)
34
37
  dest = File.join(dir, entry_name)
@@ -25,6 +25,11 @@ module Omnizip
25
25
  end
26
26
 
27
27
  def list(path, details: false, **options)
28
+ unless details
29
+ tier_names = Omnizip::Backends.archive_entry_names(path, password: options[:password])
30
+ return tier_names if tier_names
31
+ end
32
+
28
33
  with_reader(path, options) do |reader|
29
34
  entries = reader.list_files
30
35
  if details
@@ -40,6 +45,9 @@ module Omnizip
40
45
  end
41
46
 
42
47
  def read_entry(path, entry_name, **options)
48
+ tier = Omnizip::Backends.archive_read_entry(path, entry_name, password: options[:password])
49
+ return tier unless tier.nil?
50
+
43
51
  with_reader(path, options) do |reader|
44
52
  entry = reader.list_files.find { |e| e.name == entry_name }
45
53
  raise Errno::ENOENT, "Entry not found: #{entry_name}" unless entry
@@ -22,6 +22,11 @@ module Omnizip
22
22
  end
23
23
 
24
24
  def list(path, details: false, **_)
25
+ unless details
26
+ tier_names = Omnizip::Backends.archive_entry_names(path)
27
+ return tier_names if tier_names
28
+ end
29
+
25
30
  entries = Omnizip::Formats::Tar.list(path)
26
31
  if details
27
32
  entries.map do |entry|
@@ -58,7 +63,10 @@ module Omnizip
58
63
  end
59
64
  end
60
65
 
61
- def read_entry(path, entry_name)
66
+ def read_entry(path, entry_name, **_)
67
+ tier = Omnizip::Backends.archive_read_entry(path, entry_name)
68
+ return tier unless tier.nil?
69
+
62
70
  data = nil
63
71
  Omnizip::Formats::Tar.open(path) do |reader|
64
72
  entry = reader.entries.find { |e| e.name == entry_name }
@@ -21,6 +21,11 @@ module Omnizip
21
21
  end
22
22
 
23
23
  def list(path, details: false, **_)
24
+ unless details
25
+ tier_names = Omnizip::Backends.archive_entry_names(path)
26
+ return tier_names if tier_names
27
+ end
28
+
24
29
  entries = Omnizip::Formats::Xar.list(path)
25
30
  if details
26
31
  entries.map do |e|
@@ -33,6 +38,9 @@ module Omnizip
33
38
  end
34
39
 
35
40
  def read_entry(path, entry_name, **_)
41
+ tier = Omnizip::Backends.archive_read_entry(path, entry_name)
42
+ return tier unless tier.nil?
43
+
36
44
  Dir.mktmpdir("omnizip-xar-entry") do |dir|
37
45
  Omnizip::Formats::Xar.extract(path, dir)
38
46
  dest = File.join(dir, entry_name)
@@ -96,15 +96,18 @@ module Omnizip
96
96
 
97
97
  # Whole-archive tier helpers: nil means "Rust unavailable or
98
98
  # entry not found — caller falls back to the Ruby reader".
99
- def archive_entry_names(path)
100
- Omnizip::Implementations::Rust::Archive.open(File.binread(path)) { |a| return a.entry_names }
99
+ # Encrypted formats (rar, 7z) pass password:.
100
+ def archive_entry_names(path, password: nil)
101
+ Omnizip::Implementations::Rust::Archive.open(File.binread(path), password: password) do |a|
102
+ return a.entry_names
103
+ end
101
104
  rescue Omnizip::Implementations::Rust::Archive::LibraryMissing, Omnizip::Implementations::Rust::Error, StandardError
102
105
  nil
103
106
  end
104
107
 
105
108
  # rubocop:disable-next Lint/ReturnInVoidContext
106
- def archive_read_entry(path, entry_name)
107
- Omnizip::Implementations::Rust::Archive.open(File.binread(path)) do |a|
109
+ def archive_read_entry(path, entry_name, password: nil)
110
+ Omnizip::Implementations::Rust::Archive.open(File.binread(path), password: password) do |a|
108
111
  idx = a.entry_names.index(entry_name)
109
112
  return nil if idx.nil?
110
113
 
@@ -76,30 +76,47 @@ module Omnizip
76
76
  }
77
77
  end
78
78
 
79
- private
80
-
81
- def open
82
- path = resolve_path
83
- return nil if path.nil?
84
-
85
- handle = Fiddle.dlopen(path.to_s)
86
- funcs = function_table.each_with_object({}) do |(key, (name, args, ret)), h|
87
- h[key] = Fiddle::Function.new(handle[name], args, ret)
88
- end
89
- new(funcs, handle)
90
- rescue StandardError => e # includes Fiddle::DLError
91
- warn "omnizip: rust backend unavailable (#{e.message}); using pure Ruby" if ENV["OMNIZIP_BACKEND"] == "rust"
79
+ # The Rust release the loaded cdylib was built from (e.g.
80
+ # "0.21.108"), read through the ozip_version symbol — the
81
+ # platform-gem smoke gate asserts it matches. nil when the
82
+ # library is absent or predates the symbol.
83
+ def dylib_version
84
+ handle = instance&.instance_handle
85
+ return nil if handle.nil?
86
+
87
+ func = Fiddle::Function.new(handle["ozip_version"], [], Fiddle::TYPE_VOIDP)
88
+ ptr = func.call
89
+ ptr.null? ? nil : ptr.to_s
90
+ rescue StandardError
92
91
  nil
93
92
  end
94
93
 
95
- def resolve_path
94
+ # Resolve the cdylib path. Precedence:
95
+ #
96
+ # 1. OMNIZIP_NO_RUST=1 — hard kill switch (always nil, so
97
+ # the pure-Ruby core handles everything; also the smoke
98
+ # gate for "works without Rust").
99
+ # 2. OMNIZIP_FFI_DYLIB — explicit path (developer override).
100
+ # 3. vendor/ — the prebuilt cdylib. Platform gems ship it
101
+ # here and `rake rust:build` writes here; rubygems
102
+ # already matched the platform at install time, so no
103
+ # runtime architecture probing is needed and the wrong
104
+ # arch cannot be picked.
105
+ # 4. ext/ (legacy location).
106
+ # 5. A sibling omnizip-rs checkout.
107
+ #
108
+ # `dirs` overrides 3-5 (spec seam: staged candidate paths).
109
+ def resolve_path(dirs = nil)
110
+ return nil if ENV.fetch("OMNIZIP_NO_RUST", nil) == "1"
111
+
96
112
  explicit = ENV.fetch("OMNIZIP_FFI_DYLIB", nil)
97
113
  return Pathname.new(explicit) if explicit && File.file?(explicit)
98
114
 
99
- candidates = [
115
+ candidates = dirs || [
116
+ Pathname.new(__dir__).join("../../../../vendor"),
100
117
  Pathname.new(__dir__).join("../../../../ext/libomnizip_ffi"),
101
- sibling_checkout,
102
- ].compact.flatten
118
+ *sibling_checkout,
119
+ ]
103
120
 
104
121
  %w[.dylib .so .dll].each do |ext|
105
122
  candidates.each do |dir|
@@ -110,6 +127,22 @@ module Omnizip
110
127
  nil
111
128
  end
112
129
 
130
+ private
131
+
132
+ def open
133
+ path = resolve_path
134
+ return nil if path.nil?
135
+
136
+ handle = Fiddle.dlopen(path.to_s)
137
+ funcs = function_table.each_with_object({}) do |(key, (name, args, ret)), h|
138
+ h[key] = Fiddle::Function.new(handle[name], args, ret)
139
+ end
140
+ new(funcs, handle)
141
+ rescue StandardError => e # includes Fiddle::DLError
142
+ warn "omnizip: rust backend unavailable (#{e.message}); using pure Ruby" if ENV["OMNIZIP_BACKEND"] == "rust"
143
+ nil
144
+ end
145
+
113
146
  # A sibling omnizip-rs checkout: ../omnizip-rs relative to
114
147
  # this gem's repository root.
115
148
  def sibling_checkout
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Omnizip
4
- VERSION = "0.4.6"
4
+ VERSION = "0.4.8"
5
5
  end
@@ -0,0 +1,147 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Build per-platform gems that vendor a prebuilt omnizip-ffi cdylib,
4
+ # so `gem install omnizip` gives Rust acceleration with zero
5
+ # compilation (parsanol distribution model, adopted 2026-09-21).
6
+ #
7
+ # # after downloading the release-binary artifacts:
8
+ # gh release download omnizip-ffi-v0.21.108 -R omnizip/omnizip-rs \
9
+ # -p 'libomnizip_ffi-*.tar.gz' -D artifacts
10
+ # bundle exec rake platform_gems:build DIR=artifacts
11
+ #
12
+ # Each target tarball maps to one rubygems platform; the built gems
13
+ # land in pkg/. The plain `ruby` platform gem keeps shipping without
14
+ # a binary (pure-Ruby core; OMNIZIP_NO_RUST=1 disables the tier).
15
+
16
+ # rust target → rubygems platform (keep in sync with
17
+ # omnizip-rs .github/workflows/release-binary.yml)
18
+ PLATFORM_GEM_TARGETS = {
19
+ "x86_64-unknown-linux-gnu" => "x86_64-linux",
20
+ "aarch64-unknown-linux-gnu" => "aarch64-linux",
21
+ "arm-unknown-linux-gnueabihf" => "arm-linux",
22
+ "x86_64-unknown-linux-musl" => "x86_64-linux-musl",
23
+ "aarch64-unknown-linux-musl" => "aarch64-linux-musl",
24
+ "arm-unknown-linux-musleabihf" => "arm-linux-musl",
25
+ "aarch64-apple-darwin" => "arm64-darwin",
26
+ "x86_64-apple-darwin" => "x86_64-darwin",
27
+ "x86_64-pc-windows-msvc" => "x64-mingw-ucrt",
28
+ "aarch64-pc-windows-msvc" => "aarch64-mingw-ucrt",
29
+ "x86_64-pc-windows-gnu" => "x64-mingw32",
30
+ }.freeze
31
+
32
+ namespace :platform_gems do
33
+ desc "Build one platform gem: TARGET=<rust target> DYLIB=<cdylib path>"
34
+ task :one do
35
+ target = ENV.fetch("TARGET") { abort "TARGET=<rust target> required" }
36
+ dylib = ENV.fetch("DYLIB") { abort "DYLIB=<cdylib path> required" }
37
+ platform = PLATFORM_GEM_TARGETS[target] or abort "unknown target #{target} (see lib/tasks/platform_gems.rake)"
38
+ out = build_platform_gem(platform, dylib)
39
+ puts "built: #{out}"
40
+ end
41
+
42
+ desc "Build platform gems for every tarball in DIR=libomnizip_ffi-<target>.tar.gz"
43
+ task :build do
44
+ dir = ENV.fetch("DIR") { abort "DIR=<artifacts dir> required" }
45
+ # Snapshot the pristine file list once. Gem::Specification.load
46
+ # caches by path and returns the SAME object on every call, so a
47
+ # per-call load + files += would leak the previous platform's
48
+ # cdylib into the next gem.
49
+ gem_root = File.expand_path("../..", __dir__)
50
+ base_spec = Gem::Specification.load(File.join(gem_root, "omnizip.gemspec"))
51
+ abort "omnizip.gemspec failed to load" unless base_spec
52
+ base_files = base_spec.files.select { |rel| File.file?(File.join(gem_root, rel)) }.freeze
53
+
54
+ Dir.glob(File.join(dir, "libomnizip_ffi-*.tar.gz")).each do |tarball|
55
+ target = File.basename(tarball, ".tar.gz").delete_prefix("libomnizip_ffi-")
56
+ platform = PLATFORM_GEM_TARGETS[target] or abort "no rubygems platform mapping for #{target}"
57
+ require "tmpdir"
58
+ Dir.mktmpdir do |tmp|
59
+ binary = extract_binary(tarball, tmp)
60
+ out = build_platform_gem(platform, binary, base_files)
61
+ puts "built: #{out} (#{File.size(out)} bytes)"
62
+ end
63
+ end
64
+ end
65
+
66
+ desc "Push every already-built platform gem under pkg/ to rubygems (idempotent)"
67
+ task :release do
68
+ require "rake"
69
+ require "rubygems/package"
70
+ gem_root = File.expand_path("../..", __dir__)
71
+ pkg = File.join(gem_root, "pkg")
72
+ gems = Dir.glob(File.join(pkg, "omnizip-*.gem"))
73
+ abort "no platform gems under #{pkg} — run platform_gems:build first" if gems.empty?
74
+
75
+ # Pushes only what's already built in pkg/. Invoked by the
76
+ # platform-gem push job, which dispatches the trusted
77
+ # release.yml with next_version=skip + release_command override
78
+ # so the cimas reusable workflow authenticates via the
79
+ # already-trusted OIDC configuration and runs this task verbatim.
80
+ #
81
+ # Idempotent against re-push of an already-published version
82
+ # (cimas reusable handles "already been pushed" via the
83
+ # gem-idempotent-push-guard action).
84
+ gems.each do |path|
85
+ puts "pushing #{File.basename(path)}"
86
+ run_gem_push(path)
87
+ end
88
+ end
89
+
90
+ def extract_binary(tarball, tmp)
91
+ system("tar", "-xzf", tarball, "-C", tmp) or abort "tar failed for #{tarball}"
92
+ Dir.glob(File.join(tmp, "*")).first or abort "empty tarball #{tarball}"
93
+ end
94
+
95
+ def run_gem_push(path)
96
+ require "rubygems/command/push_command"
97
+ cmd = Gem::Command::PushCommand.new
98
+ cmd.invoke("push", path)
99
+ rescue StandardError => e
100
+ raise if !/already been pushed|Repushing of gem versions is not allowed/i.match?(e.message)
101
+
102
+ warn "skip (already published): #{File.basename(path)}"
103
+ end
104
+
105
+ # Stage the tracked gem files plus the vendored cdylib, flip the
106
+ # gemspec platform, and build. `base_files` is the pristine
107
+ # gemspec file list (frozen); we ASSIGN a fresh list every call
108
+ # rather than mutating via +=, because Gem::Specification.load
109
+ # hands back a cached object.
110
+ def build_platform_gem(platform, dylib, base_files = nil)
111
+ require "fileutils"
112
+ require "rubygems/package"
113
+ require "tmpdir"
114
+
115
+ gem_root = File.expand_path("../..", __dir__)
116
+ spec = Gem::Specification.load(File.join(gem_root, "omnizip.gemspec"))
117
+ abort "omnizip.gemspec failed to load" unless spec
118
+ base_files ||= spec.files.select { |rel| File.file?(File.join(gem_root, rel)) }
119
+
120
+ Dir.mktmpdir do |tmp|
121
+ stage = File.join(tmp, "stage")
122
+ base_files.each do |rel|
123
+ dst = File.join(stage, rel)
124
+ FileUtils.mkdir_p(File.dirname(dst))
125
+ FileUtils.cp(File.join(gem_root, rel), dst)
126
+ end
127
+
128
+ vendored = "vendor/libomnizip_ffi#{File.extname(dylib)}"
129
+ FileUtils.mkdir_p(File.join(stage, "vendor"))
130
+ FileUtils.cp(dylib, File.join(stage, vendored))
131
+ abort "staged cdylib missing: #{vendored}" unless File.file?(File.join(stage, vendored))
132
+
133
+ spec.platform = Gem::Platform.new(platform)
134
+ spec.files = base_files + [vendored]
135
+ spec.test_files = []
136
+
137
+ Dir.chdir(stage) do
138
+ Gem::Package.build(spec)
139
+ end
140
+ built = Dir.glob(File.join(stage, "omnizip-*.gem")).first or
141
+ abort "gem build produced nothing for #{platform}"
142
+ FileUtils.mkdir_p(File.join(gem_root, "pkg"))
143
+ FileUtils.mv(built, File.join(gem_root, "pkg", File.basename(built)))
144
+ File.join(gem_root, "pkg", File.basename(built))
145
+ end
146
+ end
147
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: omnizip
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.6
4
+ version: 0.4.8
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ribose Inc.
@@ -724,6 +724,7 @@ files:
724
724
  - lib/omnizip/zip/input_stream.rb
725
725
  - lib/omnizip/zip/output_stream.rb
726
726
  - lib/tasks/msi_test_files.rake
727
+ - lib/tasks/platform_gems.rake
727
728
  - lib/tasks/rust_backend.rake
728
729
  - readme-docs/advanced-features.adoc
729
730
  - readme-docs/api-usage.adoc