liquid_migrator.rb 2.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768
  1. module LiquidMigrator
  2. def self.convert_all_agent_options(agent)
  3. agent.options = self.convert_hash(agent.options, {:merge_path_attributes => true, :leading_dollarsign_is_jsonpath => true})
  4. agent.save!
  5. end
  6. def self.convert_hash(hash, options={})
  7. options = {:merge_path_attributes => false, :leading_dollarsign_is_jsonpath => false}.merge options
  8. keys_to_remove = []
  9. hash.tap do |hash|
  10. hash.each_pair do |key, value|
  11. case value.class.to_s
  12. when 'String', 'FalseClass', 'TrueClass'
  13. path_key = "#{key}_path"
  14. if options[:merge_path_attributes] && !hash[path_key].nil?
  15. # replace the value if the path is present
  16. value = hash[path_key] if hash[path_key].present?
  17. # in any case delete the path attibute
  18. keys_to_remove << path_key
  19. end
  20. hash[key] = LiquidMigrator.convert_string value, options[:leading_dollarsign_is_jsonpath]
  21. when 'ActiveSupport::HashWithIndifferentAccess'
  22. hash[key] = convert_hash(hash[key], options)
  23. when 'Array'
  24. hash[key] = hash[key].collect { |k| convert_string(k, options[:leading_dollarsign_is_jsonpath])}
  25. end
  26. end
  27. # remove the unneeded *_path attributes
  28. end.select { |k, v| !keys_to_remove.include? k }
  29. end
  30. def self.convert_string(string, leading_dollarsign_is_jsonpath=false)
  31. if string == true || string == false
  32. # there might be empty *_path attributes for boolean defaults
  33. string
  34. elsif string[0] == '$' && leading_dollarsign_is_jsonpath
  35. # in most cases a *_path attribute
  36. convert_json_path string
  37. else
  38. # migrate the old interpolation syntax to the new liquid based
  39. string.gsub(/<([^>]+)>/).each do
  40. match = $1
  41. if match =~ /\Aescape /
  42. # convert the old escape syntax to a liquid filter
  43. self.convert_json_path(match.gsub(/\Aescape /, '').strip, ' | uri_escape')
  44. else
  45. self.convert_json_path(match.strip)
  46. end
  47. end
  48. end
  49. end
  50. def self.convert_json_path(string, filter = "")
  51. check_path(string)
  52. if string.start_with? '$.'
  53. "{{#{string[2..-1]}#{filter}}}"
  54. else
  55. "{{#{string[1..-1]}#{filter}}}"
  56. end
  57. end
  58. def self.check_path(string)
  59. if string !~ /\A(\$\.?)?(\w+\.)*(\w+)\Z/
  60. raise "JSONPath '#{string}' is too complex, please check your migration."
  61. end
  62. end
  63. end