This is an automated email from the ASF dual-hosted git repository.
erickguan pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/opendal.git
The following commit(s) were added to refs/heads/main by this push:
new 74ebf547e fix(bindings/ruby): publish ruby binding gem (#6606)
74ebf547e is described below
commit 74ebf547e02c0d64e365ce65b644f69cc031ee50
Author: Erick Guan <[email protected]>
AuthorDate: Wed Oct 1 20:18:55 2025 +0200
fix(bindings/ruby): publish ruby binding gem (#6606)
* Fix path for the action patch file
* Fix rake release task override
* Fix release workflows
Fixes file paths to include core files
Fixes complilations
Fixes artifact downloads
Lock release tags
* Fix metadata's inspect
* Move middlewares to OpenDal::Middlware
* Fix tests in CI
* Push all native gems
* Update links in README
* Extend native build for more Rubies
* Version bump
---
.github/workflows/release_ruby.yml | 67 ++++++++++++++-----------
bindings/ruby/Cargo.toml | 7 +--
bindings/ruby/README.md | 6 +--
bindings/ruby/Rakefile | 71 +++++++++++++++++++++++----
bindings/ruby/core | 1 +
bindings/ruby/lib/opendal_ruby/metadata.rb | 2 +-
bindings/ruby/opendal.gemspec | 43 ++++++++++++----
bindings/ruby/src/lib.rs | 5 +-
bindings/ruby/src/metadata.rs | 2 +-
bindings/ruby/src/middlewares.rs | 33 ++++++++-----
bindings/ruby/test/blocking_op_test.rb | 2 +-
bindings/ruby/test/metadata_test.rb | 78 ++++++++++++++++++++++++++++++
bindings/ruby/test/middlewares_test.rb | 8 +--
13 files changed, 252 insertions(+), 73 deletions(-)
diff --git a/.github/workflows/release_ruby.yml
b/.github/workflows/release_ruby.yml
index aab851d09..25bdde914 100644
--- a/.github/workflows/release_ruby.yml
+++ b/.github/workflows/release_ruby.yml
@@ -20,7 +20,7 @@ name: Release Ruby Binding
on:
push:
tags:
- - 'v[0-9]+.[0-9]+.[0-9]+*' # Triggers on version tags (v0.54.0,
v0.54.0-rc.1, etc.)
+ - 'v[0-9]+.[0-9]+.[0-9]+-rc.[0-9]+' # Triggers on version tags (v0.54.0,
v0.54.0-rc.1, etc.)
pull_request:
branches:
- main
@@ -43,6 +43,8 @@ defaults:
jobs:
build:
runs-on: ubuntu-latest
+ outputs:
+ version: ${{ steps.summary.outputs.version }}
steps:
- name: Checkout repository
@@ -68,12 +70,21 @@ jobs:
retention-days: 30
- name: Log Build Summary
+ id: summary
run: |
+ # e.g. from `Cargo.toml` to released version:
+ # - 0.54.0 -> 0.54.0
+ # - 0.54.0-rc.1 -> 0.54.1.pre.rc.1
+ VERSION=$(bundle exec rake version)
+ echo "version=$VERSION" >> "$GITHUB_OUTPUT"
+
echo "## Ruby gem built successfully! 📦" >> "$GITHUB_STEP_SUMMARY"
echo "" >> "$GITHUB_STEP_SUMMARY"
echo "**Ref:** ${{ github.ref_name || github.ref }}" >>
"$GITHUB_STEP_SUMMARY"
- echo "**Version:** $(bundle exec rake version)" >>
"$GITHUB_STEP_SUMMARY"
+ echo "**Version:** $VERSION" >> "$GITHUB_STEP_SUMMARY"
+ # We maintain multiple build targets for native gems.
+ # We only provide best-effort support for native gems. We could withdraw the
support to these builds at any time.
build-native:
strategy:
fail-fast: false
@@ -82,17 +93,16 @@ jobs:
- os: ubuntu-latest
platform: x86_64-linux
rust_target: x86_64-unknown-linux-gnu
- - os: ubuntu-latest
+ - os: ubuntu-24.04-arm
platform: aarch64-linux
rust_target: aarch64-unknown-linux-gnu
- os: macos-latest
- platform: arm64-darwin
+ platform: arm64-darwin23
rust_target: aarch64-apple-darwin
- - os: macos-latest
- platform: x86_64-darwin
- rust_target: x86_64-apple-darwin
runs-on: ${{ matrix.os }}
+ continue-on-error: true
+
env:
RB_SYS_CARGO_TARGET: ${{ matrix.rust_target }}
@@ -110,28 +120,17 @@ jobs:
bundler-cache: true
working-directory: bindings/ruby # must repeat because GitHub
Actions will not use defaults.run
- - name: Linux cross deps
- if: runner.os == 'Linux' && matrix.platform == 'aarch64-linux'
- run: sudo apt-get update && sudo apt-get install -y
gcc-aarch64-linux-gnu
+ - name: Show available rake tasks
+ run: bundle exec rake --tasks
- - name: Build gem
- if: runner.os != 'Linux' || matrix.platform != 'aarch64-linux'
- run: bundle exec rake native gem
+ - name: Build native gem
+ run: bundle exec rake native:opendal:${{ matrix.platform }} gem
- # For Linux aarch64, tell Cargo which linker to use
- - name: Build aarch64-linux gem
- if: runner.os == 'Linux' && matrix.platform == 'aarch64-linux'
- run: |
- export
CARGO_TARGET_AARCH64_UNKNOWN_LINUX_GNU_LINKER=aarch64-linux-gnu-gcc
- bundle exec rake native gem
-
- - name: Collect gems
+ - name: Collect built gem
run: |
echo "Built gem file:"
ls -la pkg/
echo ""
- echo "Gem version:"
- bundle exec rake version
mkdir -p pkg_out
cp -r pkg/*.gem pkg_out/
@@ -144,9 +143,14 @@ jobs:
retention-days: 30
publish:
+ # allow:
+ # - standard tag releases
+ # - workflow_dispatch:
+ # - reattempt standard tag releases
+ # - pre-releases
if: >-
- (github.event_name == 'workflow_dispatch' && github.ref ==
'refs/heads/main') ||
- (github.event_name == 'push' && startsWith(github.ref, 'refs/tags/v') &&
!contains(github.ref, '-'))
+ startsWith(github.ref, 'refs/tags/v') ||
+ (github.event_name == 'workflow_dispatch' &&
contains(needs.build.outputs.version, 'rc'))
needs: [build, build-native]
runs-on: ubuntu-latest
@@ -162,12 +166,17 @@ jobs:
bundler-cache: true
working-directory: bindings/ruby
- - name: Download gem artifact
- if: github.event_name == 'push'
+ - name: Download gem artifacts
uses: actions/download-artifact@v4
with:
pattern: opendal-ruby-gem-*
path: bindings/ruby/pkg/
+ merge-multiple: true
+
+ - name: List downloaded artifacts
+ run: |
+ echo "Downloaded gems:"
+ ls -lh pkg/*.gem
# Adapted from rubygems/release-gem@v1. Changed:
# 1. publishing git tag
@@ -254,7 +263,7 @@ jobs:
- name: Release gem
run: bundle exec rake release
env:
- RUBYOPT: "${{ format('-r{0}/rubygems-attestation-patch.rb {1}',
github.action_path, env.RUBYOPT) || env.RUBYOPT }}"
+ RUBYOPT: "${{
format('-r{0}/bindings/ruby/rubygems-attestation-patch.rb {1}',
github.workspace, env.RUBYOPT) || env.RUBYOPT }}"
- name: Wait for release to propagate
run: gem exec rubygems-await pkg/*.gem
@@ -264,6 +273,8 @@ jobs:
echo "## Ruby binding released! 🚀" >> "$GITHUB_STEP_SUMMARY"
echo "" >> "$GITHUB_STEP_SUMMARY"
echo "**Version:** $(bundle exec rake version)" >>
"$GITHUB_STEP_SUMMARY"
+ echo "" >> "$GITHUB_STEP_SUMMARY"
+ echo "Check out the [RubyGems
page](https://rubygems.org/gems/opendal) for more details." >>
"$GITHUB_STEP_SUMMARY"
- name: Clean up credentials
if: always()
diff --git a/bindings/ruby/Cargo.toml b/bindings/ruby/Cargo.toml
index 46112650a..867355e24 100644
--- a/bindings/ruby/Cargo.toml
+++ b/bindings/ruby/Cargo.toml
@@ -25,7 +25,7 @@ homepage = "https://opendal.apache.org/"
license = "Apache-2.0"
repository = "https://github.com/apache/opendal"
rust-version = "1.82"
-version = "0.1.0"
+version = "0.1.6-rc.2" # updates this version to bump Rubygem version during
release process
[lib]
crate-type = ["cdylib"]
@@ -34,8 +34,9 @@ name = "opendal_ruby"
[dependencies]
magnus = { version = "0.8", features = ["bytes", "io"] }
-# this crate won't be published, we always use the local version
-opendal = { version = ">=0", path = "../../core", features = [
+# 1. this crate won't be published, we always use the local version
+# 2. we use the symbolink to allow released gem to find core's source files.
+opendal = { version = ">=0", path = "./core", features = [
"blocking",
"layers-throttle",
# These are default features before v0.46. TODO: change to optional features
diff --git a/bindings/ruby/README.md b/bindings/ruby/README.md
index 409679837..11376f4d5 100644
--- a/bindings/ruby/README.md
+++ b/bindings/ruby/README.md
@@ -1,9 +1,9 @@
# Apache OpenDALâ„¢ Ruby Binding
-
-
+[](https://rubygems.org/gems/opendal)
+[](https://rubygems.org/gems/opendal)
-OpenDAL's Ruby gem.
+OpenDAL's Ruby [gem](https://rubygems.org/gems/opendal).

diff --git a/bindings/ruby/Rakefile b/bindings/ruby/Rakefile
index 66c4b8d56..f21942d5b 100644
--- a/bindings/ruby/Rakefile
+++ b/bindings/ruby/Rakefile
@@ -19,26 +19,31 @@
require "bundler/gem_tasks"
require "rake/testtask"
-require "rake/extensiontask"
+require "rb_sys/extensiontask"
require "standard/rake"
GEMSPEC = Gem::Specification.load("opendal.gemspec")
CRATE_PACKAGE_NAME = "opendal-ruby"
-Rake::ExtensionTask.new(CRATE_PACKAGE_NAME, GEMSPEC) do |ext|
+RbSys::ExtensionTask.new(CRATE_PACKAGE_NAME, GEMSPEC) do |ext|
ext.name = "opendal_ruby"
ext.ext_dir = "."
ext.lib_dir = "lib/opendal_ruby"
ext.cross_compile = true
ext.cross_platform = %w[
- x64-mingw-ucrt
- x64-mingw32
x86_64-linux
arm64-linux
- x86_64-darwin
arm64-darwin
+ arm64-darwin23
]
+
+ # Override Ruby version requirement for native gems
+ # This prevents automatic constraint to the build Ruby version (e.g., >=
3.3, < 3.4.dev)
+ ext.cross_compiling do |gem_spec|
+ # keep in sync with opendal.gemspec
+ gem_spec.required_ruby_version = ">= 3.2", "< 3.5.dev"
+ end
end
Rake::Task[:test].prerequisites << :compile
@@ -80,17 +85,65 @@ namespace :doc do
end
task doc: "doc:default"
-task default: %i[clobber compile test standard]
+task default: %i[compile test standard]
+task purge: %i[clean clobber]
desc "report gem version"
task :version do
print GEMSPEC.version
end
-desc "Multi-arch release (overrides bundler)"
+desc "Resolve symlinks in core directory for gem packaging" # Read more in
`.release-ruby.yml`
+task :resolve_symlinks do
+ puts "Changing symlinks in core directory to actual files for packaging..."
+ Dir.chdir("core") do # a symbolic link to OpenDAL core for packaging
+ Dir.glob("**/*", File::FNM_DOTMATCH).each do |file|
+ next unless File.symlink?(file)
+
+ link_target = File.readlink(file)
+ resolved_path = File.expand_path(link_target, File.dirname(file))
+
+ if File.exist?(resolved_path)
+ puts "Resolving symlink: #{file} -> #{link_target}"
+ File.delete(file)
+ FileUtils.cp(resolved_path, file)
+ end
+ end
+ end
+end
+
+# Hook into build task to resolve symlinks first
+Rake::Task["build"].enhance([:resolve_symlinks]) if
Rake::Task.task_defined?("build")
+
+Rake::Task["release"].clear # clear the existing release task to allow override
+Rake::Task["release:rubygem_push"].clear if
Rake::Task.task_defined?("release:rubygem_push")
+
+# overrides bundler's default rake release task
+# we removed build and git tagging steps. Read more in `.release-ruby.yml`
+# read more
https://github.com/rubygems/rubygems/blob/master/bundler/lib/bundler/gem_helper.rb
+desc "Multi-arch release"
task release: [
- # we removed build and git tagging steps. Read more in `.release-ruby.yml`
- # read more
https://github.com/rubygems/rubygems/blob/master/bundler/lib/bundler/gem_helper.rb
"release:guard_clean",
"release:rubygem_push"
]
+
+namespace :release do
+ desc "Push all gems to RubyGems"
+ task :rubygem_push do
+ # Push all gem files (source + platform-specific) like Nokogiri does
+ # Bundler's built_gem_path only returns the last modified gem, so we glob
all gems instead
+ gem_files = Gem::Util.glob_files_in_dir("#{GEMSPEC.name}-*.gem",
"pkg").sort
+
+ if gem_files.empty?
+ abort "No gem files found in pkg/"
+ end
+
+ puts "Found #{gem_files.length} gem(s) to push:"
+ gem_files.each { |f| puts " - #{File.basename(f)}" }
+
+ gem_files.each do |gem_file|
+ puts "\nPushing #{File.basename(gem_file)}..."
+ sh "gem push #{gem_file}"
+ end
+ end
+end
diff --git a/bindings/ruby/core b/bindings/ruby/core
new file mode 120000
index 000000000..3d25ddeb2
--- /dev/null
+++ b/bindings/ruby/core
@@ -0,0 +1 @@
+../../core
\ No newline at end of file
diff --git a/bindings/ruby/lib/opendal_ruby/metadata.rb
b/bindings/ruby/lib/opendal_ruby/metadata.rb
index 8194f530d..51e7782a0 100644
--- a/bindings/ruby/lib/opendal_ruby/metadata.rb
+++ b/bindings/ruby/lib/opendal_ruby/metadata.rb
@@ -36,7 +36,7 @@ module OpenDal
def inspect
# Be concise to keep a few attributes
- "#<#{self.class.name} mode: #{entry_mode}, \
+ "#<#{self.class.name} mode: #{mode}, \
content_type: #{content_type}, \
content_length: #{content_length}>"
end
diff --git a/bindings/ruby/opendal.gemspec b/bindings/ruby/opendal.gemspec
index 672da127a..90d5c9ef1 100644
--- a/bindings/ruby/opendal.gemspec
+++ b/bindings/ruby/opendal.gemspec
@@ -41,21 +41,44 @@ Gem::Specification.new do |spec|
spec.homepage = "https://opendal.apache.org/"
spec.license = "Apache-2.0"
- spec.metadata["homepage_uri"] = spec.homepage
- spec.metadata["source_code_uri"] = "https://github.com/apache/opendal"
- spec.metadata["changelog_uri"] = "https://github.com/apache/opendal/releases"
- spec.metadata["rubygems_mfa_required"] = "true"
+ spec.metadata = {
+ "bug_tracker_uri" => "https://github.com/apache/opendal/issues",
+ "changelog_uri" => "https://github.com/apache/opendal/releases",
+ "documentation_uri" => "https://opendal.apache.org/docs/ruby/",
+ "homepage_uri" => spec.homepage,
+ "source_code_uri" => "https://github.com/apache/opendal",
+ "rubygems_mfa_required" => "true"
+ }
- # Specify which files should be added to the gem when it is released.
+ # Specify which files should be added to a source release gem when we
release OpenDAL Ruby gem.
# The `git ls-files -z` loads the files in the RubyGem that have been added
into git.
spec.files = Dir.chdir(__dir__) do
- `git ls-files -z`.split("\x0").reject do |f|
- (File.expand_path(f) == __FILE__) || f.start_with?(*%w[gems/ pkg/
target/ tmp/ .git])
+ git_files = `git ls-files -z`.split("\x0").reject do |f|
+ (File.expand_path(f) == __FILE__) || f.start_with?(*%w[gems/ pkg/
target/ tmp/ .git]) || f == "core"
end
+
+ # Include core directory files, excluding symlinks
+ core_files = Dir.chdir("./core") do
+ `git ls-files -z`.split("\x0").reject do |f|
+ File.symlink?(File.join("./core", f))
+ end.map { |f| "core/#{f}" }
+ end
+
+ # Resolve symlinks: copy actual files from their target locations
+ # This handles recursive symbol link cases. e.g., core/CHANGELOG.md ->
../CHANGELOG.md
+ symlink_targets = Dir.chdir("./core") do
+ `git ls-files -z`.split("\x0").select do |f|
+ File.symlink?(File.join("./core", f))
+ end.filter_map do |f|
+ link_target = File.readlink(File.join("./core", f))
+ resolved_path = File.expand_path(link_target, File.join(__dir__,
"core"))
+ File.exist?(resolved_path) ? "core/#{f}" : nil
+ end
+ end
+
+ git_files + core_files + symlink_targets
end
- spec.bindir = "exe"
- spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) }
spec.require_paths = ["lib"]
spec.extensions = ["./extconf.rb"]
@@ -64,6 +87,8 @@ Gem::Specification.new do |spec|
# use a Ruby version which:
# - supports Rubygems with the ability of compilation of Rust gem
# - not end of life
+ #
+ # keep in sync with `Rakefile`.
spec.required_ruby_version = ">= 3.2"
# intentionally skipping rb_sys gem because newer Rubygems will be present
diff --git a/bindings/ruby/src/lib.rs b/bindings/ruby/src/lib.rs
index f1783c54a..8bf2e8939 100644
--- a/bindings/ruby/src/lib.rs
+++ b/bindings/ruby/src/lib.rs
@@ -19,6 +19,7 @@ use std::sync::LazyLock;
use magnus::function;
use magnus::Error;
+use magnus::Module;
use magnus::Ruby;
// We will use `ocore::` to represents opendal rust core functionalities.
@@ -54,7 +55,9 @@ fn init(ruby: &Ruby) -> Result<(), Error> {
let _ = io::include(ruby, &gem_module);
let _ = lister::include(ruby, &gem_module);
let _ = operator_info::include(ruby, &gem_module);
- let _ = middlewares::include(ruby, &gem_module);
+
+ let middleware_module = gem_module.define_module("Middleware")?;
+ let _ = middlewares::include(ruby, &middleware_module);
Ok(())
}
diff --git a/bindings/ruby/src/metadata.rs b/bindings/ruby/src/metadata.rs
index ef07d5c73..451bc0885 100644
--- a/bindings/ruby/src/metadata.rs
+++ b/bindings/ruby/src/metadata.rs
@@ -30,7 +30,7 @@ use magnus::RModule;
use crate::*;
/// @yard
-/// Metadata about the file.
+/// Metadata about an object.
#[magnus::wrap(class = "OpenDal::Metadata", free_immediately, size)]
pub struct Metadata(ocore::Metadata);
diff --git a/bindings/ruby/src/middlewares.rs b/bindings/ruby/src/middlewares.rs
index e6f194db7..71a74f272 100644
--- a/bindings/ruby/src/middlewares.rs
+++ b/bindings/ruby/src/middlewares.rs
@@ -64,7 +64,7 @@ where
/// Adds retry for temporary failed operations.
///
/// See [`opendal::layers::RetryLayer`] for more information.
-#[magnus::wrap(class = "OpenDal::RetryMiddleware")]
+#[magnus::wrap(class = "OpenDal::Middleware::Retry")]
struct RetryMiddleware(Arc<Mutex<ocore::layers::RetryLayer>>);
impl RetryMiddleware {
@@ -73,7 +73,7 @@ impl RetryMiddleware {
}
fn apply_to(ruby: &Ruby, rb_self: &Self, operator: &Operator) ->
Result<Operator, Error> {
- apply_layer(ruby, &rb_self.0, operator, "RetryMiddleware")
+ apply_layer(ruby, &rb_self.0, operator, "OpenDal::Middleware::Retry")
}
}
@@ -81,7 +81,7 @@ impl RetryMiddleware {
/// Adds concurrent request limit.
///
/// See [`opendal::layers::ConcurrentLimitLayer`] for more information.
-#[magnus::wrap(class = "OpenDal::ConcurrentLimitMiddleware")]
+#[magnus::wrap(class = "OpenDal::Middleware::ConcurrentLimit")]
struct
ConcurrentLimitMiddleware(Arc<Mutex<ocore::layers::ConcurrentLimitLayer>>);
impl ConcurrentLimitMiddleware {
@@ -92,7 +92,12 @@ impl ConcurrentLimitMiddleware {
}
fn apply_to(ruby: &Ruby, rb_self: &Self, operator: &Operator) ->
Result<Operator, Error> {
- apply_layer(ruby, &rb_self.0, operator, "ConcurrentLimitMiddleware")
+ apply_layer(
+ ruby,
+ &rb_self.0,
+ operator,
+ "OpenDal::Middleware::ConcurrentLimit",
+ )
}
}
@@ -100,7 +105,7 @@ impl ConcurrentLimitMiddleware {
/// Adds a bandwidth rate limiter to the underlying services.
///
/// See [`opendal::layers::ThrottleLayer`] for more information.
-#[magnus::wrap(class = "OpenDal::ThrottleMiddleware")]
+#[magnus::wrap(class = "OpenDal::Middleware::Throttle")]
struct ThrottleMiddleware(Arc<Mutex<ocore::layers::ThrottleLayer>>);
impl ThrottleMiddleware {
@@ -111,7 +116,7 @@ impl ThrottleMiddleware {
}
fn apply_to(ruby: &Ruby, rb_self: &Self, operator: &Operator) ->
Result<Operator, Error> {
- apply_layer(ruby, &rb_self.0, operator, "ConcurrentLimitMiddleware")
+ apply_layer(ruby, &rb_self.0, operator,
"OpenDal::Middleware::Throttle")
}
}
@@ -128,7 +133,7 @@ fn parse_duration(ruby: &Ruby, val: f64) ->
Result<Duration, Error> {
/// Adds timeout for every operation to avoid slow or unexpected hang
operations.
///
/// See [`opendal::layers::TimeoutLayer`] for more information.
-#[magnus::wrap(class = "OpenDal::TimeoutMiddleware")]
+#[magnus::wrap(class = "OpenDal::Middleware::Timeout")]
struct TimeoutMiddleware(Arc<Mutex<ocore::layers::TimeoutLayer>>);
impl TimeoutMiddleware {
@@ -140,26 +145,28 @@ impl TimeoutMiddleware {
}
fn apply_to(ruby: &Ruby, rb_self: &Self, operator: &Operator) ->
Result<Operator, Error> {
- apply_layer(ruby, &rb_self.0, operator, "TimeoutMiddleware")
+ apply_layer(ruby, &rb_self.0, operator, "OpenDal::Middleware::Timeout")
}
}
-pub fn include(ruby: &Ruby, gem_module: &RModule) -> Result<(), Error> {
- let retry = gem_module.define_class("RetryMiddleware",
ruby.class_object())?;
+pub fn include(ruby: &Ruby, middleware_module: &RModule) -> Result<(), Error> {
+ middleware_module.define_class("Retry", ruby.class_object())?;
+
+ let retry = middleware_module.define_class("Retry", ruby.class_object())?;
retry.define_singleton_method("new", function!(RetryMiddleware::new, 0))?;
retry.define_method("apply_to", method!(RetryMiddleware::apply_to, 1))?;
let concurrent_limit =
- gem_module.define_class("ConcurrentLimitMiddleware",
ruby.class_object())?;
+ middleware_module.define_class("ConcurrentLimit",
ruby.class_object())?;
concurrent_limit
.define_singleton_method("new",
function!(ConcurrentLimitMiddleware::new, 1))?;
concurrent_limit.define_method("apply_to",
method!(ConcurrentLimitMiddleware::apply_to, 1))?;
- let throttle_middleware = gem_module.define_class("ThrottleMiddleware",
ruby.class_object())?;
+ let throttle_middleware = middleware_module.define_class("Throttle",
ruby.class_object())?;
throttle_middleware.define_singleton_method("new",
function!(ThrottleMiddleware::new, 2))?;
throttle_middleware.define_method("apply_to",
method!(ThrottleMiddleware::apply_to, 1))?;
- let timeout_middleware = gem_module.define_class("TimeoutMiddleware",
ruby.class_object())?;
+ let timeout_middleware = middleware_module.define_class("Timeout",
ruby.class_object())?;
timeout_middleware.define_singleton_method("new",
function!(TimeoutMiddleware::new, 2))?;
timeout_middleware.define_method("apply_to",
method!(TimeoutMiddleware::apply_to, 1))?;
diff --git a/bindings/ruby/test/blocking_op_test.rb
b/bindings/ruby/test/blocking_op_test.rb
index 846dd9acd..079669241 100644
--- a/bindings/ruby/test/blocking_op_test.rb
+++ b/bindings/ruby/test/blocking_op_test.rb
@@ -105,7 +105,7 @@ class OpenDalTest < ActiveSupport::TestCase
end
test "middleware applies a middleware" do
- @op.middleware(OpenDal::RetryMiddleware.new)
+ @op.middleware(OpenDal::Middleware::Retry.new)
assert @op.is_a?(OpenDal::Operator)
end
diff --git a/bindings/ruby/test/metadata_test.rb
b/bindings/ruby/test/metadata_test.rb
new file mode 100644
index 000000000..59a8c4c29
--- /dev/null
+++ b/bindings/ruby/test/metadata_test.rb
@@ -0,0 +1,78 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+# frozen_string_literal: true
+
+require "test_helper"
+
+class MetadataTest < ActiveSupport::TestCase
+ setup do
+ @op = OpenDal::Operator.new("memory", {})
+ @op.write("/file", "OpenDAL Ruby is ready.")
+ end
+
+ test "returns metadata" do
+ metadata = @op.stat("file")
+
+ assert_nothing_raised do
+ metadata.inspect
+ end
+ end
+
+ test "#file? works" do
+ metadata = @op.stat("file")
+
+ assert metadata.file?
+ end
+
+ test "#dir? works" do
+ metadata = @op.stat("/")
+ assert metadata.dir?
+
+ assert [email protected]("file").dir?
+ end
+
+ test "#mode works" do
+ metadata = @op.stat("file")
+ assert_equal OpenDal::Metadata::FILE, metadata.mode
+ end
+
+ test "#content_disposition works" do
+ metadata = @op.stat("file")
+ assert_nil metadata.content_disposition
+ end
+
+ test "#content_length works" do
+ metadata = @op.stat("file")
+ assert_equal 22, metadata.content_length
+ end
+
+ test "#content_md5 works" do
+ metadata = @op.stat("file")
+ assert_nil metadata.content_md5
+ end
+
+ test "#content_type works" do
+ metadata = @op.stat("file")
+ assert_nil metadata.content_type
+ end
+
+ test "#etag works" do
+ metadata = @op.stat("file")
+ assert_nil metadata.etag
+ end
+end
diff --git a/bindings/ruby/test/middlewares_test.rb
b/bindings/ruby/test/middlewares_test.rb
index 8ab90748a..25fed3c9c 100644
--- a/bindings/ruby/test/middlewares_test.rb
+++ b/bindings/ruby/test/middlewares_test.rb
@@ -22,25 +22,25 @@ require "test_helper"
class MiddlewaresTest < ActiveSupport::TestCase
test "builds a retry middleware" do
assert_nothing_raised do
- OpenDal::RetryMiddleware.new
+ OpenDal::Middleware::Retry.new
end
end
test "builds a concurrent limit middleware" do
assert_nothing_raised do
- OpenDal::ConcurrentLimitMiddleware.new(10)
+ OpenDal::Middleware::ConcurrentLimit.new(10)
end
end
test "builds a throttle middleware" do
assert_nothing_raised do
- OpenDal::ThrottleMiddleware.new(100, 10)
+ OpenDal::Middleware::Throttle.new(100, 10)
end
end
test "builds a timeout middleware" do
assert_nothing_raised do
- OpenDal::TimeoutMiddleware.new(1.23, 1.0)
+ OpenDal::Middleware::Timeout.new(1.23, 1.0)
end
end
end