Skip to content

Commit c5619f3

Browse files
authored
Merge pull request #709 from rubionic/rubionic/fix-ostruct-dependency-issue-229
fix: remove ostruct dependency for Ruby 3.5+ compatibility
2 parents 3cdd183 + e728312 commit c5619f3

File tree

5 files changed

+1358
-13
lines changed

5 files changed

+1358
-13
lines changed

.github/workflows/ruby.yml

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,23 @@ jobs:
66
strategy:
77
matrix:
88
os: [ubuntu-latest, macos-latest]
9-
ruby: [ '2.6', '2.7', '3.0', '3.1', '3.2', '3.3', '3.4', head]
9+
ruby: ['2.6', '2.7', '3.0', '3.1', '3.2', '3.3', '3.4', '4.0', head]
1010
runs-on: ${{ matrix.os }}
1111
steps:
1212
- uses: actions/checkout@v6
13+
- name: Setup Image
14+
if: matrix.os == 'ubuntu-latest'
15+
run: |
16+
sudo apt-get update && sudo apt-get install -y libpcap-dev
1317
- uses: ruby/setup-ruby@v1
1418
with:
1519
ruby-version: ${{ matrix.ruby }}
20+
- uses: actions/setup-go@v6
21+
with:
22+
go-version-file: go.mod
23+
- name: Run Go erbrenderer tests
24+
run: go test ./templatescompiler/erbrenderer/...
25+
continue-on-error: ${{ matrix.ruby == 'head' }}
1626
- run: bundle install
1727
working-directory: templatescompiler/erbrenderer/
1828
- run: bundle exec rake
Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,3 @@
1-
Gemfile.lock
1+
.bundle/
2+
vendor/bundle/
3+
Gemfile.lock

templatescompiler/erbrenderer/erb_renderer.rb

Lines changed: 46 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,45 @@
11
# Based on common/properties/template_evaluation_context.rb
22
require "rubygems"
3-
require "ostruct"
43
require "json"
54
require "erb"
65
require "yaml"
76

7+
# Simple struct-like class to replace OpenStruct dependency
8+
# OpenStruct is being removed from Ruby standard library in Ruby 3.5+
9+
class PropertyStruct
10+
def initialize(hash = {})
11+
@table = {}
12+
hash.each do |key, value|
13+
@table[key.to_sym] = wrap_value(value)
14+
end
15+
end
16+
17+
def method_missing(method_name, *args)
18+
if method_name.to_s.end_with?("=")
19+
@table[method_name.to_s.chomp("=").to_sym] = wrap_value(args.first)
20+
else
21+
@table[method_name.to_sym]
22+
end
23+
end
24+
25+
def respond_to_missing?(method_name, _include_private = false)
26+
@table.key?(method_name.to_sym) || method_name.to_s.end_with?("=")
27+
end
28+
29+
private
30+
31+
def wrap_value(value)
32+
case value
33+
when Hash
34+
PropertyStruct.new(value)
35+
when Array
36+
value.map { |item| wrap_value(item) }
37+
else
38+
value
39+
end
40+
end
41+
end
42+
843
class Hash
944
def recursive_merge!(other)
1045
merge!(other) do |_, old_value, new_value|
@@ -19,9 +54,7 @@ def recursive_merge!(other)
1954
end
2055

2156
class TemplateEvaluationContext
22-
attr_reader :name, :index
23-
attr_reader :properties, :raw_properties
24-
attr_reader :spec
57+
attr_reader :name, :index, :properties, :raw_properties, :spec
2558

2659
def initialize(spec)
2760
@name = spec["job"]["name"] if spec["job"].is_a?(Hash)
@@ -56,21 +89,23 @@ def p(*args)
5689
end
5790

5891
return args[1] if args.length == 2
92+
5993
raise UnknownProperty.new(names)
6094
end
6195

6296
def if_p(*names)
6397
values = names.map do |name|
6498
value = lookup_property(@raw_properties, name)
6599
return ActiveElseBlock.new(self) if value.nil?
100+
66101
value
67102
end
68103

69104
yield(*values)
70105
InactiveElseBlock.new
71106
end
72107

73-
def if_link(name)
108+
def if_link(_name)
74109
false
75110
end
76111

@@ -98,10 +133,10 @@ def copy_property(dst, src, name, default = nil)
98133
def openstruct(object)
99134
case object
100135
when Hash
101-
mapped = object.each_with_object({}) { |(k, v), h|
136+
mapped = object.each_with_object({}) do |(k, v), h|
102137
h[k] = openstruct(v)
103-
}
104-
OpenStruct.new(mapped)
138+
end
139+
PropertyStruct.new(mapped)
105140
when Array
106141
object.map { |item| openstruct(item) }
107142
else
@@ -148,13 +183,13 @@ class InactiveElseBlock
148183
def else
149184
end
150185

151-
def else_if_p(*names)
186+
def else_if_p(*_names)
152187
InactiveElseBlock.new
153188
end
154189
end
155190
end
156191

157-
# todo do not use JSON in releases
192+
# TODO: do not use JSON in releases
158193
class << JSON
159194
alias_method :dump_array_or_hash, :dump
160195

@@ -177,7 +212,7 @@ def render(src_path, dst_path)
177212
erb = ERB.new(File.read(src_path), trim_mode: "-")
178213
erb.filename = src_path
179214

180-
# Note: JSON.load_file was added in v2.3.1: https://github.com/ruby/json/blob/v2.3.1/lib/json/common.rb#L286
215+
# NOTE: JSON.load_file was added in v2.3.1: https://github.com/ruby/json/blob/v2.3.1/lib/json/common.rb#L286
181216
context_hash = JSON.parse(File.read(@json_context_path))
182217
template_evaluation_context = TemplateEvaluationContext.new(context_hash)
183218

0 commit comments

Comments
 (0)