lib/itamae/recipe.rb in itamae-1.12.0 vs lib/itamae/recipe.rb in itamae-1.12.1

- old
+ new

@@ -51,11 +51,11 @@ ::File.dirname(@path) end def load(vars = {}) context = EvalContext.new(self, vars) - context.instance_eval(File.read(path), path, 1) + InstanceEval.new(File.read(path), path, 1, context: context).call end def run show_banner @@ -148,9 +148,28 @@ def run_command(*args) runner.backend.run_command(*args) end end + + class InstanceEval + def initialize(src, path, lineno, context:) + # Using instance_eval + eval to allow top-level class/module definition without `::`. + # To pass args without introducing any local/instance variables, this code is also eval-ed. + @code = <<-RUBY + @context.instance_eval do + eval(#{src.dump}, nil, #{path.dump}, #{lineno}) + end + RUBY + @context = context + end + + # This method has no local variables to avoid spilling them to recipes. + def call + eval(@code) + end + end + private_constant :InstanceEval class RecipeFromDefinition < Recipe attr_accessor :definition def load(vars = {})