Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 5 additions & 2 deletions bindings/ruby/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,11 @@ name = "opendal_ruby"

[dependencies]
magnus = { version = "0.8", features = ["bytes", "io"] }
# 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.
# 1. we don't use published core but a local copy
# 2. for a source release, this path must be the local "./core".
# we set it via rake copy_core. Read more in:
# - Rakefile
# - opendal.gemspec
opendal = { version = ">=0", path = "../../core", features = [
"blocking",
"layers-throttle",
Expand Down
39 changes: 29 additions & 10 deletions bindings/ruby/Rakefile
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,33 @@ require "standard/rake"
GEMSPEC = Gem::Specification.load("opendal.gemspec")
CRATE_PACKAGE_NAME = "opendal-ruby"

desc "Copy core files for compilation"
task :copy_core do
core_dir = "../../core"
distributed_core_dir = "core"

puts "Copying core files from #{core_dir} to #{distributed_core_dir}..."
FileUtils.rm_rf(distributed_core_dir, secure: true)
system("cp", "-Lr", core_dir, distributed_core_dir) # resolves symbolic links to a copy

# Verify core files were copied
core_files_count = `git -C #{File.expand_path(core_dir, __dir__)} ls-files -z`.split("\x0").length
puts "Copied #{core_files_count} files from core directory"

# Patch Cargo.toml for source distribution
# When core files are copied locally, update Cargo.toml to reference the local copy
if File.directory?(distributed_core_dir)
cargo_toml = File.read("Cargo.toml")

# Only patch if we haven't already and we're using the relative path
if cargo_toml.include?('path = "../../core"')
puts "Patching Cargo.toml to use local core directory..."
cargo_toml.gsub!('path = "../../core"', 'path = "core"')
File.write("Cargo.toml", cargo_toml)
end
end
end

RbSys::ExtensionTask.new(CRATE_PACKAGE_NAME, GEMSPEC) do |ext|
ext.name = "opendal_ruby"
ext.ext_dir = "."
Expand Down Expand Up @@ -93,16 +120,8 @@ task :version do
print GEMSPEC.version
end

desc "Copy the core directory for gem packaging" # Read more in `./.github/workflows/release-ruby.yml`
task :copy_core do
puts "Copy the core directory for packaging..."
src = "../../core"
dst = "./core"
`cp -RL #{src} #{dst}`
end

# Hook into build task to copy the core directory first
Rake::Task["build"].enhance([:copy_core]) if Rake::Task.task_defined?("build")
# Ensure core files are copied before compilation and packaging
Rake::Task["build"].enhance(["copy_core"]) 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")
Expand Down
44 changes: 20 additions & 24 deletions bindings/ruby/opendal.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,8 @@ require "json"
Gem::Specification.new do |spec|
spec.name = "opendal"
# RubyGems integrates and expects `cargo`.
# Read more about [Gem::Ext::CargoBuilder](https://github.com/rubygems/rubygems/blob/v3.5.23/lib/rubygems/ext/cargo_builder.rb)
# Read more about
# [Gem::Ext::CargoBuilder](https://github.com/rubygems/rubygems/blob/v3.5.23/lib/rubygems/ext/cargo_builder.rb)
#
# OpenDAL relies on "version" in `Cargo.toml` for the release process. You can read this gem spec with:
# `bundle exec ruby -e 'puts Gem::Specification.load("opendal.gemspec")'`
Expand Down Expand Up @@ -54,40 +55,35 @@ Gem::Specification.new do |spec|
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.
spec.files = Dir.chdir(__dir__) do
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"
f.start_with?(*%w[gems/ pkg/ target/ tmp/ .git])
end

# Copy core directory
src = "../../core"
dst = "./core"
`cp -RL #{src} #{dst}`
# When building release package, include core directory files for rake build
core_dir = "../../core"
distributed_core_dir = "core"

# 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
if Dir.exist?(distributed_core_dir)
# Core files should already be copied by the Rakefile's copy_core task
core_files = `git -C #{File.expand_path(core_dir, __dir__)} ls-files -z`
.split("\x0")
.filter_map do |f|
full_path = "#{distributed_core_dir}/#{f}"
full_path if File.exist?(full_path)
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
git_files + core_files
else
git_files
end

git_files + core_files + symlink_targets
end

spec.require_paths = ["lib"]

spec.extensions = ["./extconf.rb"]

# Exclude non-Ruby files from RDoc to prevent parsing errors
spec.rdoc_options = ["--exclude", "Cargo\\..*", "--exclude", "core/", "--exclude", "\\.rs$"]

spec.requirements = ["Rust >= 1.85"]
# use a Ruby version which:
# - supports Rubygems with the ability of compilation of Rust gem
Expand Down
Loading