Skip to content
12 changes: 11 additions & 1 deletion .github/workflows/ruby.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,23 @@ jobs:
strategy:
matrix:
os: [ubuntu-latest, macos-latest]
ruby: [ '2.6', '2.7', '3.0', '3.1', '3.2', '3.3', '3.4', head]
ruby: ['2.6', '2.7', '3.0', '3.1', '3.2', '3.3', '3.4', '4.0', head]
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v6
- name: Setup Image
if: matrix.os == 'ubuntu-latest'
run: |
sudo apt-get update && sudo apt-get install -y libpcap-dev
- uses: ruby/setup-ruby@v1
with:
ruby-version: ${{ matrix.ruby }}
- uses: actions/setup-go@v6
with:
go-version-file: go.mod
- name: Run Go erbrenderer tests
run: go test ./templatescompiler/erbrenderer/...
continue-on-error: ${{ matrix.ruby == 'head' }}
- run: bundle install
working-directory: templatescompiler/erbrenderer/
- run: bundle exec rake
Expand Down
2 changes: 1 addition & 1 deletion deployment/instance/state/builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -225,7 +225,7 @@ func (b *builder) renderJobTemplates(

func (b *builder) defaultAddress(networkRefs []NetworkRef, agentState agentclient.AgentState) (string, error) {

if (networkRefs == nil) || (len(networkRefs) == 0) {
if len(networkRefs) == 0 {
return "", errors.New("Must specify network") //nolint:staticcheck
}

Expand Down
4 changes: 3 additions & 1 deletion templatescompiler/erbrenderer/.gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,3 @@
Gemfile.lock
.bundle/
vendor/bundle/
Gemfile.lock
57 changes: 46 additions & 11 deletions templatescompiler/erbrenderer/erb_renderer.rb
Original file line number Diff line number Diff line change
@@ -1,10 +1,45 @@
# Based on common/properties/template_evaluation_context.rb
require "rubygems"
require "ostruct"
require "json"
require "erb"
require "yaml"

# Simple struct-like class to replace OpenStruct dependency
# OpenStruct is being removed from Ruby standard library in Ruby 3.5+
class PropertyStruct
def initialize(hash = {})
@table = {}
hash.each do |key, value|
@table[key.to_sym] = wrap_value(value)
end
end

def method_missing(method_name, *args)
if method_name.to_s.end_with?("=")
@table[method_name.to_s.chomp("=").to_sym] = wrap_value(args.first)
else
@table[method_name.to_sym]
end
end

def respond_to_missing?(method_name, _include_private = false)
@table.key?(method_name.to_sym) || method_name.to_s.end_with?("=")
end

private

def wrap_value(value)
case value
when Hash
PropertyStruct.new(value)
when Array
value.map { |item| wrap_value(item) }
else
value
end
end
end

class Hash
def recursive_merge!(other)
merge!(other) do |_, old_value, new_value|
Expand All @@ -19,9 +54,7 @@ def recursive_merge!(other)
end

class TemplateEvaluationContext
attr_reader :name, :index
attr_reader :properties, :raw_properties
attr_reader :spec
attr_reader :name, :index, :properties, :raw_properties, :spec

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

return args[1] if args.length == 2

raise UnknownProperty.new(names)
end

def if_p(*names)
values = names.map do |name|
value = lookup_property(@raw_properties, name)
return ActiveElseBlock.new(self) if value.nil?

value
end

yield(*values)
InactiveElseBlock.new
end

def if_link(name)
def if_link(_name)
false
end

Expand Down Expand Up @@ -98,10 +133,10 @@ def copy_property(dst, src, name, default = nil)
def openstruct(object)
case object
when Hash
mapped = object.each_with_object({}) { |(k, v), h|
mapped = object.each_with_object({}) do |(k, v), h|
h[k] = openstruct(v)
}
OpenStruct.new(mapped)
end
PropertyStruct.new(mapped)
when Array
object.map { |item| openstruct(item) }
else
Expand Down Expand Up @@ -148,13 +183,13 @@ class InactiveElseBlock
def else
end

def else_if_p(*names)
def else_if_p(*_names)
InactiveElseBlock.new
end
end
end

# todo do not use JSON in releases
# TODO: do not use JSON in releases
class << JSON
alias_method :dump_array_or_hash, :dump

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

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

Expand Down
Loading