Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Puppet module for outputting json in a sorted consistent way
#
# sorted_json.rb
# Puppet module for outputting json in a sorted consistent way. I use it for creating config files with puppet
require 'json'
def sorted_json(json)
if (json.kind_of? String)
return json.to_json
elsif (json.kind_of? Array)
arrayRet = []
json.each do |a|
arrayRet.push(sorted_json(a))
end
return "[" << arrayRet.join(',') << "]";
elsif (json.kind_of? Hash)
ret = []
json.keys.sort.each do |k|
ret.push(k.to_json << ":" << sorted_json(json[k]))
end
return "{" << ret.join(",") << "}";
end
raise Exception("Unable to handle object of type " + json.class)
end
module Puppet::Parser::Functions
newfunction(:sorted_json, :type => :rvalue, :doc => <<-EOS
This function takes data, outputs making sure the hash keys are sorted
*Examples:*
sorted_json({'key'=>'value'})
Would return: {'key':'value'}
EOS
) do |arguments|
raise(Puppet::ParseError, "sorted_json(): Wrong number of arguments " +
"given (#{arguments.size} for 1)") if arguments.size != 1
json = arguments[0]
return sorted_json(json)
end
end
# vim: set ts=2 sw=2 et :
@tmclaugh

This comment has been minimized.

Copy link

@tmclaugh tmclaugh commented Nov 7, 2013

Any license info for this function? I have an upcoming PR against electrical/puppet-lumberjack#9 where I use this and I'd like to redistribute this.

@davidcollom

This comment has been minimized.

Copy link

@davidcollom davidcollom commented Nov 18, 2013

I too would like to use this code within a module I've developed for Serf @ davidcollom/puppet-serf

@falzm

This comment has been minimized.

Copy link

@falzm falzm commented Jan 23, 2014

I forked and rewritten the function in a cleaner way to support all JSON types: https://gist.github.com/falzm/8575549

@jonhattan

This comment has been minimized.

Copy link

@jonhattan jonhattan commented Jul 28, 2014

Great func. Ideally it should be part of puppet stdlib.

@halkeye

This comment has been minimized.

Copy link
Owner Author

@halkeye halkeye commented Jan 12, 2015

oh wow, i never noticed these comments. Feel free to use it as you will

@aj-jester

This comment has been minimized.

Copy link

@aj-jester aj-jester commented Aug 22, 2015

I updated this puppet function to properly cast quoted numbers to integers because some services expect their port numbers to be unquoted: { "port": "80" } vs { "port": 80 }.

I also added support to generate pretty config with toggle-able indentation.

https://gist.github.com/aj-jester/e0078c38db9eb7c1ef45

@akozichev

This comment has been minimized.

Copy link

@akozichev akozichev commented Oct 23, 2015

I needed same thing for yaml, so I modified one of the above scripts for yaml syntax. No complex structures though, just enough to get me going.
https://github.com/akozichev/sorted_yaml/blob/master/sorted_yaml.rb

@Cinderhaze

This comment has been minimized.

Copy link

@Cinderhaze Cinderhaze commented May 18, 2016

+1 on a function like this being a part of stdlib. I see it duplicated across a bunch of modules. Also, It would be great if we could get an official version on this somewhere with a license file. I hate it when I get blocked by policy when I can't bring code in without a release version (Our policies won't allow for a commit sha as a version :/ )

@jcrsilva

This comment has been minimized.

Copy link

@jcrsilva jcrsilva commented Feb 23, 2017

+2 on stdlib

edit: and this is 4 years old, it'd be about time

@KlavsKlavsen

This comment has been minimized.

Copy link

@KlavsKlavsen KlavsKlavsen commented Jun 28, 2017

Simple puppet 4 edition

#
# LICENSE: https://gist.github.com/aj-jester/e0078c38db9eb7c1ef45
#
require 'json'

Puppet::Functions.create_function(:sorted_json) do
  dispatch :sorted_json do
    param 'Hash', :arg
  end

  def sorted_generate(obj)
    case obj
      when Fixnum, Float, TrueClass, FalseClass, NilClass
        return obj.to_json
      when String
        # Convert quoted integers (string) to int
        return (obj.match(/\A[-]?[0-9]+\z/) ? obj.to_i : obj).to_json
      when Array
        arrayRet = []
        obj.each do |a|
          arrayRet.push(sorted_generate(a))
        end
        return "[" << arrayRet.join(',') << "]";
      when Hash
        ret = []
        obj.keys.sort.each do |k|
          ret.push(k.to_json << ":" << sorted_generate(obj[k]))
        end
        return "{" << ret.join(",") << "}";
      else
        raise Exception("Unable to handle object of type <%s>" % obj.class.to_s)
    end
  end # end def

  def sorted_json(h)
    sorted_generate(h)
  end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment