lib/kumogata/post_processing.rb in kumogata-0.3.11 vs lib/kumogata/post_processing.rb in kumogata-0.3.12
- old
+ new
@@ -16,25 +16,30 @@
return unless _post
options = _post[:options] || {}
@command_options.merge(options)
+ outputs = template['Outputs'] || {}
+
_post.fetch(:commands).each do |name, attrs|
unless attrs.kind_of?(Hash) and attrs['command']
raise "Invalid post processing: #{name} => #{attrs.inspect}"
end
timing = [(attrs['after'] || TRIGGER_TIMING)].flatten.map {|i| i.to_sym }
+ command = attrs['command']
+
validate_timing(name, timing)
+ validate_command_template(name, command, outputs)
@commands[name] = {
:after => timing,
- :command => attrs['command'],
+ :command => command,
}
if (ssh = attrs['ssh'])
- validate_ssh(name, ssh)
+ validate_ssh(name, ssh, outputs)
@commands[name][:ssh] = ssh
end
end
end
@@ -68,11 +73,11 @@
raise "Unknown post processing timing: #{name} => #{timing.inspect}"
end
end
end
- def validate_ssh(name, ssh)
+ def validate_ssh(name, ssh, outputs)
host, user, options = ssh.values_at('host', 'user', 'options')
unless host and user
raise "`host` and `user` is required for post processing ssh: #{name}"
end
@@ -86,10 +91,12 @@
ssh['host'] = "<%= #{host_key} #{host_value.to_s.inspect} %>"
else
ssh['host'] = host.to_s
end
+ validate_command_template(name, ssh['host'], outputs)
+
if user.kind_of?(Hash)
if user.keys != ['Key']
raise "Invalid post processing ssh user: #{name} => #{user.inspect}"
end
@@ -97,10 +104,12 @@
ssh['user'] = "<%= #{user_key} #{user_value.to_s.inspect} %>"
else
ssh['user'] = user.to_s
end
+ validate_command_template(name, ssh['user'], outputs)
+
if options and not options.kind_of?(Hash)
raise "Invalid post processing ssh options: #{name} => #{options.inspect}"
end
end
@@ -168,9 +177,32 @@
end
def run_shell_command(command, outputs)
command = evaluate_command_template(command, outputs)
Open3.capture3(command)
+ end
+
+ def validate_command_template(name, command, outputs)
+ command = command.undent if @command_options[:undent]
+ trim_mode = @command_options[:trim_mode]
+ expected_outputs = Set.new
+
+ scope = Object.new
+ scope.instance_variable_set(:@__expected_outputs__, expected_outputs)
+
+ scope.instance_eval(<<-EOS)
+ def Key(name)
+ @__expected_outputs__ << name
+ end
+
+ ERB.new(#{command.inspect}, nil, #{trim_mode.inspect}).result(binding)
+ EOS
+
+ expected_outputs.each do |key|
+ unless outputs.keys.include?(key)
+ raise "Unknown output: #{name} => #{key.inspect}"
+ end
+ end
end
def evaluate_command_template(command, outputs)
command = command.undent if @command_options[:undent]
trim_mode = @command_options[:trim_mode]