mirror of
https://github.com/microsoft/regorus.git
synced 2026-08-05 02:16:11 +00:00
update ruby bindings (#200)
This commit is contained in:
3
bindings/ruby/Cargo.toml
Normal file
3
bindings/ruby/Cargo.toml
Normal file
@@ -0,0 +1,3 @@
|
||||
[workspace]
|
||||
members = ["ext/regorusrb"]
|
||||
resolver = "2"
|
||||
@@ -10,7 +10,7 @@ gemspec
|
||||
gem "minitest", "~> 5.16"
|
||||
gem "rake", "~> 13.0"
|
||||
gem "rake-compiler"
|
||||
gem "rb_sys", "~> 0.9.63"
|
||||
gem "rake-compiler-dock"
|
||||
gem "rubocop", "~> 1.62", require: false
|
||||
gem "rubocop-minitest", require: false
|
||||
gem "rubocop-rake", require: false
|
||||
|
||||
@@ -2,12 +2,13 @@ PATH
|
||||
remote: .
|
||||
specs:
|
||||
regorusrb (0.1.0)
|
||||
rb_sys (~> 0.9.91)
|
||||
|
||||
GEM
|
||||
remote: https://rubygems.org/
|
||||
specs:
|
||||
ast (2.4.2)
|
||||
json (2.7.1)
|
||||
json (2.7.2)
|
||||
language_server-protocol (3.17.0.3)
|
||||
minitest (5.22.3)
|
||||
parallel (1.24.0)
|
||||
@@ -16,13 +17,14 @@ GEM
|
||||
racc
|
||||
racc (1.7.3)
|
||||
rainbow (3.1.1)
|
||||
rake (13.1.0)
|
||||
rake (13.2.1)
|
||||
rake-compiler (1.2.7)
|
||||
rake
|
||||
rb_sys (0.9.90)
|
||||
rake-compiler-dock (1.4.0)
|
||||
rb_sys (0.9.91)
|
||||
regexp_parser (2.9.0)
|
||||
rexml (3.2.6)
|
||||
rubocop (1.62.1)
|
||||
rubocop (1.63.0)
|
||||
json (~> 2.3)
|
||||
language_server-protocol (>= 3.17.0)
|
||||
parallel (~> 1.10)
|
||||
@@ -51,7 +53,7 @@ DEPENDENCIES
|
||||
minitest (~> 5.16)
|
||||
rake (~> 13.0)
|
||||
rake-compiler
|
||||
rb_sys (~> 0.9.63)
|
||||
rake-compiler-dock
|
||||
regorusrb!
|
||||
rubocop (~> 1.62)
|
||||
rubocop-minitest
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
../../LICENSE
|
||||
21
bindings/ruby/LICENSE.txt
Normal file
21
bindings/ruby/LICENSE.txt
Normal file
@@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) Microsoft Corporation.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE
|
||||
@@ -10,14 +10,18 @@
|
||||
|
||||
Regorus can be used in Ruby by configuring bundler to build from the remote git source.
|
||||
|
||||
Use the bundler CLI to add the gem from remote git source:
|
||||
If using [Bundler](https://bundler.io/) to manage gems (recommended), edit your gemfile to include the following
|
||||
`
|
||||
bundle add regorus --git 'https://github.com/microsoft/regorus/tree/main/bindings/ruby'
|
||||
gem "regorusrb", git: "https://github.com/microsoft/regorus/", glob: "bindings/ruby/*.gemspec"
|
||||
`
|
||||
|
||||
or manually edit your gemfile to include the following
|
||||
or manually install checkout the source and build the gem
|
||||
|
||||
`
|
||||
gem "regorus", git: "https://github.com/microsoft/regorus/tree/main/bindings/ruby"
|
||||
git clone https://github.com/microsoft/regorus/
|
||||
cd regorus/bindings/ruby
|
||||
rake && rake build # should eventually output 'regorusrb 0.1.0 built to pkg/regorusrb-0.1.0.gem.'
|
||||
gem install --local ./pkg/regorusrb-0.1.0.gem
|
||||
`
|
||||
|
||||
It is not yet available in rubygems.
|
||||
|
||||
@@ -2,22 +2,28 @@
|
||||
|
||||
require "bundler/gem_tasks"
|
||||
require "minitest/test_task"
|
||||
require "rake/extensiontask"
|
||||
require "rubocop/rake_task"
|
||||
require "rb_sys/extensiontask"
|
||||
|
||||
Minitest::TestTask.create
|
||||
|
||||
require "rubocop/rake_task"
|
||||
|
||||
RuboCop::RakeTask.new
|
||||
|
||||
require "rb_sys/extensiontask"
|
||||
|
||||
desc "build the .gem file, including native extensions, according to the .gemspec"
|
||||
task build: :compile
|
||||
|
||||
GEMSPEC = Gem::Specification.load("regorusrb.gemspec")
|
||||
|
||||
RbSys::ExtensionTask.new("regorusrb", GEMSPEC) do |ext|
|
||||
ext.lib_dir = "lib/regorusrb"
|
||||
ext.lib_dir = "lib/regorus"
|
||||
ext.cross_compile = true
|
||||
ext.cross_platform = %w[x86-mingw32 x64-mingw-ucrt x64-mingw32 x86-linux x86_64-linux x86_64-darwin arm64-darwin]
|
||||
end
|
||||
|
||||
task default: %i[compile test rubocop]
|
||||
|
||||
desc "Build native extension for a given platform (i.e. rake 'native[x86_64-linux]')"
|
||||
task :native, [:platform] do |_t, platform:|
|
||||
sh "bundle", "exec", "rb-sys-dock", "--platform", platform, "--build"
|
||||
end
|
||||
|
||||
@@ -10,7 +10,7 @@ crate-type = ["cdylib"]
|
||||
path = "src/lib.rs"
|
||||
|
||||
[dependencies]
|
||||
magnus = { version = "0.6.2" }
|
||||
regorus = { path = "../../../.." }
|
||||
magnus = { version = "0.6.3" }
|
||||
regorus = { git = "https://github.com/microsoft/regorus" }
|
||||
serde_json = "1.0.115"
|
||||
serde_magnus = "0.8.1"
|
||||
|
||||
@@ -3,4 +3,6 @@
|
||||
require "mkmf"
|
||||
require "rb_sys/mkmf"
|
||||
|
||||
create_rust_makefile("regorusrb/regorusrb")
|
||||
create_rust_makefile("regorus/regorusrb") do |r|
|
||||
r.auto_install_rust_toolchain = true
|
||||
end
|
||||
|
||||
@@ -158,9 +158,9 @@ impl Engine {
|
||||
})
|
||||
}
|
||||
|
||||
fn eval_rule(&self, path: String) -> Result<Option<magnus::Value>, Error> {
|
||||
fn eval_rule(&self, query: String) -> Result<Option<magnus::Value>, Error> {
|
||||
let result =
|
||||
self.engine.borrow_mut().eval_rule(path).map_err(|e| {
|
||||
self.engine.borrow_mut().eval_rule(query).map_err(|e| {
|
||||
Error::new(runtime_error(), format!("Failed to evaluate rule: {}", e))
|
||||
})?;
|
||||
|
||||
@@ -176,6 +176,21 @@ impl Engine {
|
||||
}),
|
||||
}
|
||||
}
|
||||
|
||||
fn eval_bool_query(&self, query: String) -> Result<bool, Error> {
|
||||
self.engine
|
||||
.borrow_mut()
|
||||
.eval_bool_query(query, false)
|
||||
.map_err(|e| Error::new(runtime_error(), format!("Failed to evaluate query: {}", e)))
|
||||
}
|
||||
|
||||
fn eval_allow_query(&self, query: String) -> Result<bool, Error> {
|
||||
Ok(self.engine.borrow_mut().eval_allow_query(query, false))
|
||||
}
|
||||
|
||||
fn eval_deny_query(&self, query: String) -> Result<bool, Error> {
|
||||
Ok(self.engine.borrow_mut().eval_deny_query(query, false))
|
||||
}
|
||||
}
|
||||
|
||||
#[magnus::init]
|
||||
@@ -219,6 +234,8 @@ fn init(ruby: &Ruby) -> Result<(), Error> {
|
||||
engine_class.define_method("eval_query", method!(Engine::eval_query, 1))?;
|
||||
engine_class.define_method("eval_query_as_json", method!(Engine::eval_query_as_json, 1))?;
|
||||
engine_class.define_method("eval_rule", method!(Engine::eval_rule, 1))?;
|
||||
|
||||
engine_class.define_method("eval_bool_query", method!(Engine::eval_bool_query, 1))?;
|
||||
engine_class.define_method("eval_allow_query", method!(Engine::eval_allow_query, 1))?;
|
||||
engine_class.define_method("eval_deny_query", method!(Engine::eval_deny_query, 1))?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require_relative "regorus/version"
|
||||
require_relative "regorusrb/regorusrb"
|
||||
require_relative "regorus/regorusrb"
|
||||
|
||||
module Regorus
|
||||
class Engine; end
|
||||
|
||||
@@ -20,21 +20,11 @@ Gem::Specification.new do |spec|
|
||||
spec.metadata["changelog_uri"] = "#{spec.homepage}/blob/main/bindings/ruby/CHANGELOG.md"
|
||||
spec.metadata["rubygems_mfa_required"] = "true"
|
||||
|
||||
# Specify which files should be added to the gem when it is released.
|
||||
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.
|
||||
gemspec = File.basename(__FILE__)
|
||||
spec.files = IO.popen(%w[git ls-files -z], chdir: __dir__, err: IO::NULL) do |ls|
|
||||
ls.readlines("\x0", chomp: true).reject do |f|
|
||||
(f == gemspec) ||
|
||||
f.start_with?(*%w[bin/ test/ spec/ features/ .git .github appveyor Gemfile])
|
||||
end
|
||||
end
|
||||
|
||||
# Ensure Cargo.lock is included
|
||||
spec.files << "../../Cargo.lock" if File.exist?("../../Cargo.lock")
|
||||
spec.files = Dir["lib/*.rb", "lib/regorus/*.rb", "ext/**/*.{rs,rb,lock,toml}", "Cargo.{lock,toml}", "LICENSE.txt", "README.md"]
|
||||
|
||||
spec.bindir = "exe"
|
||||
spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) }
|
||||
spec.require_paths = ["lib"]
|
||||
spec.extensions = ["ext/regorusrb/Cargo.toml"]
|
||||
spec.extensions = ["ext/regorusrb/extconf.rb"]
|
||||
spec.add_dependency "rb_sys", "~> 0.9.91"
|
||||
end
|
||||
|
||||
@@ -119,6 +119,30 @@ class TestRegorus < Minitest::Test
|
||||
refute @engine.eval_rule("data.regorus_test.is_manager_bool")
|
||||
end
|
||||
|
||||
def test_eval_bool_query
|
||||
assert @engine.eval_bool_query("1 < 2")
|
||||
refute @engine.eval_bool_query("1 > 2")
|
||||
assert_raises(RuntimeError) { @engine.eval_bool_query("1 + 1") }
|
||||
assert_raises(RuntimeError) { @engine.eval_bool_query("true; true") }
|
||||
assert_raises(RuntimeError) { @engine.eval_bool_query("true; false; true") }
|
||||
end
|
||||
|
||||
def test_eval_allow_query
|
||||
assert @engine.eval_allow_query("1 < 2")
|
||||
refute @engine.eval_allow_query("1 > 2")
|
||||
refute @engine.eval_allow_query("1 + 1")
|
||||
refute @engine.eval_allow_query("true; true")
|
||||
refute @engine.eval_allow_query("true; false; true")
|
||||
end
|
||||
|
||||
def test_eval_deny_query
|
||||
assert @engine.eval_deny_query("1 < 2")
|
||||
refute @engine.eval_deny_query("1 > 2")
|
||||
assert @engine.eval_deny_query("1 + 1")
|
||||
assert @engine.eval_deny_query("true; true")
|
||||
assert @engine.eval_deny_query("true; false; true")
|
||||
end
|
||||
|
||||
def test_missing_rules_handling
|
||||
@engine.set_input(input_for(ALICE))
|
||||
assert_raises(RuntimeError) { @engine.eval_rule("data.regorus_test.not_a_rule") }
|
||||
|
||||
Reference in New Issue
Block a user