Skip to content

Commit

Permalink
Add functionality to purge Object pollution from plain Ruby pipelines
Browse files Browse the repository at this point in the history
- Set Ruby 3.1 as minimum version for the gem
  • Loading branch information
jaredcwhite committed Jul 19, 2024
1 parent eb9a1bd commit 9403bf1
Show file tree
Hide file tree
Showing 8 changed files with 44 additions and 4 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
ruby_version: [2.7.2, 3.0.0, 3.2.0]
ruby_version: [3.1.0, 3.2.0, 3.3.0]
continue-on-error: ${{ endsWith(matrix.ruby, 'head') || matrix.ruby == 'debug' }}
# Has to be top level to cache properly
env:
Expand Down
2 changes: 1 addition & 1 deletion .ruby-version
Original file line number Diff line number Diff line change
@@ -1 +1 @@
2.7.2
3.1.4
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
# Changelog

## 2.2.0

- Add functionality to purge certain `Object`-based method pollution which interferes with the workings of Serbea's `Pipeline` in pure Ruby.
- Ruby 3.1 is now the minimum required version.

## 2.1.0

- Remove Active Support as a dependency
Expand Down
4 changes: 4 additions & 0 deletions docs/src/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -392,3 +392,7 @@ Pipelines "inherit" their calling context by using Ruby's `binding` feature. Tha
Another interesting facet of Serbea pipelines is that they're forgiving by default. If a filter can't be found (either there's no method available to call the object itself nor is there a separate helper method), it will log a warning to STDERR and continue on. This is to make the syntax feel a bit more like HTML and CSS where you can make a mistake or encounter an unexpected error condition yet not crash the entire application.
If you do want to crash your entire application (😜), you can set the configuration option: `Serbea::Pipeline.raise_on_missing_filters = true`. This will raise a `Serbea::FilterMissing` error if a filter can't be found.
**Note:** if you find that a certain method doesn't work within a pipeline when writing plain Ruby, because that method has polluted the global `Object` set of instance methods, you can call `Serbea::Pipeline.polluted_method(:method_name_here)` to strip that off and allow filtering to work. It also accepts an array of symbols.
**Note:** if you find that a certain filter is being called as a method directly on the value object, rather than a defined filter method itself, you can add that method name to a deny list via `Serbea::Pipeline.deny_value_method(:method_name_here)`. It also accepts an array of symbols.
20 changes: 20 additions & 0 deletions lib/serbea/pipeline.rb
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,27 @@ def self.value_methods_denylist
@value_methods_denylist ||= Set.new
end

def self.purge_class_pollution
@pollution_purged ||= begin
polluted_methods_list.each do |name|
define_method name do |*args, **kwargs|
filter(name, *args, **kwargs)
end
end

true
end
end

def self.polluted_method(name)
polluted_methods_list.merge Array(name)
end
def self.polluted_methods_list
@polluted_methods_list ||= Set.new(%i(select to_json))
end

def initialize(binding, value)
self.class.purge_class_pollution
@binding = binding
@context = binding.receiver
@value = value
Expand Down
2 changes: 1 addition & 1 deletion lib/version.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
module Serbea
VERSION = "2.1.0"
VERSION = "2.2.0"
end
2 changes: 1 addition & 1 deletion serbea.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ Gem::Specification.new do |spec|
spec.homepage = "https://github.com/bridgetownrb/serbea"
spec.license = "MIT"

spec.required_ruby_version = ">= 2.7"
spec.required_ruby_version = ">= 3.1"

spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r!^(test|script|spec|features|docs|serbea-rails)/!) }
spec.require_paths = ["lib"]
Expand Down
11 changes: 11 additions & 0 deletions test/test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -246,6 +246,14 @@ def test_multiline(input_value)
end
end

def test_json_filter
pipe({a: 1, b: "2"}) do
select proc { _1 == :a }
to_h
to_json
end
end

def transform_this_way(input)
input.join("=")
end
Expand All @@ -267,4 +275,7 @@ def test_join(input, delimeter)
raise "Multi-line pipeline broken! #{pipeline_output}" unless
pipeline_output == "VAL A=123 !!"

pipeline_output = PipelineTemplateTest.new.test_json_filter
raise "Unpolluted pipeline methods not working! #{pipeline_output}" unless pipeline_output == '{"a":1}'

puts "\nYay! Tests passed."

0 comments on commit 9403bf1

Please sign in to comment.