diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index 298ec6420..4aa6c40b7 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -192,5 +192,5 @@ Style/MixinUsage: # AllowedMethods: respond_to_missing? Style/OptionalBooleanParameter: Exclude: - - 'lib/puppet/functions/to_json_pretty.rb' + - 'lib/puppet/functions/stdlib/to_json_pretty.rb' - 'lib/puppet_x/stdlib/toml_dumper.rb' diff --git a/lib/puppet/functions/stdlib/to_json_pretty.rb b/lib/puppet/functions/stdlib/to_json_pretty.rb new file mode 100644 index 000000000..6fc748575 --- /dev/null +++ b/lib/puppet/functions/stdlib/to_json_pretty.rb @@ -0,0 +1,74 @@ +# frozen_string_literal: true + +require 'json' + +# @summary +# Convert data structure and output to pretty JSON +# +# @example **Usage** +# * how to output pretty JSON to file +# file { '/tmp/my.json': +# ensure => file, +# content => stdlib::to_json_pretty($myhash), +# } +# +# * how to output pretty JSON skipping over keys with undef values +# file { '/tmp/my.json': +# ensure => file, +# content => stdlib::to_json_pretty({ +# param_one => 'value', +# param_two => undef, +# }, true), +# } +# +# * how to output pretty JSON using tabs for indentation +# file { '/tmp/my.json': +# ensure => file, +# content => stdlib::to_json_pretty({ +# param_one => 'value', +# param_two => { +# param_more => 42, +# }, +# }, nil, {indent => ' '}), +# } + +Puppet::Functions.create_function(:'stdlib::to_json_pretty') do + # @param data + # data structure which needs to be converted to pretty json + # @param skip_undef + # value `true` or `false` + # @param opts + # hash-map of settings passed to JSON.pretty_generate, see + # https://ruby-doc.org/stdlib-2.0.0/libdoc/json/rdoc/JSON.html#method-i-generate. + # Note that `max_nesting` doesn't take the value `false`; use `-1` instead. + # @return + # converted data to pretty json + dispatch :to_json_pretty do + param 'Variant[Hash, Array]', :data + optional_param 'Optional[Boolean]', :skip_undef + optional_param 'Struct[{ +indent => Optional[String], +space => Optional[String], +space_before => Optional[String], +object_nl => Optional[String], +array_nl => Optional[String], +allow_nan => Optional[Boolean], +max_nesting => Optional[Integer[-1,default]], +}]', :opts + end + + def to_json_pretty(data, skip_undef = false, opts = nil) + # It's not possible to make an abstract type that can be either a boolean + # false or an integer, so we use -1 as the falsey value + if opts + opts = opts.transform_keys(&:to_sym) + + opts[:max_nesting] = false if opts[:max_nesting] == -1 + end + + data = data.compact if skip_undef && (data.is_a?(Array) || Hash) + # Call ::JSON to ensure it references the JSON library from Ruby's standard library + # instead of a random JSON namespace that might be in scope due to user code. + JSON.pretty_generate(data, opts) << "\n" + end +end diff --git a/lib/puppet/functions/to_json_pretty.rb b/lib/puppet/functions/to_json_pretty.rb index bff40d14e..0616256f1 100644 --- a/lib/puppet/functions/to_json_pretty.rb +++ b/lib/puppet/functions/to_json_pretty.rb @@ -1,74 +1,14 @@ # frozen_string_literal: true -require 'json' - -# @summary -# Convert data structure and output to pretty JSON -# -# @example **Usage** -# * how to output pretty JSON to file -# file { '/tmp/my.json': -# ensure => file, -# content => to_json_pretty($myhash), -# } -# -# * how to output pretty JSON skipping over keys with undef values -# file { '/tmp/my.json': -# ensure => file, -# content => to_json_pretty({ -# param_one => 'value', -# param_two => undef, -# }, true), -# } -# -# * how to output pretty JSON using tabs for indentation -# file { '/tmp/my.json': -# ensure => file, -# content => to_json_pretty({ -# param_one => 'value', -# param_two => { -# param_more => 42, -# }, -# }, nil, {indent => ' '}), -# } +# THIS FILE WAS GENERATED BY `rake regenerate_unamespaced_shims` +# @summary DEPRECATED. Use the namespaced function [`stdlib::to_json_pretty`](#stdlibto_json_pretty) instead. Puppet::Functions.create_function(:to_json_pretty) do - # @param data - # data structure which needs to be converted to pretty json - # @param skip_undef - # value `true` or `false` - # @param opts - # hash-map of settings passed to JSON.pretty_generate, see - # https://ruby-doc.org/stdlib-2.0.0/libdoc/json/rdoc/JSON.html#method-i-generate. - # Note that `max_nesting` doesn't take the value `false`; use `-1` instead. - # @return - # converted data to pretty json - dispatch :to_json_pretty do - param 'Variant[Hash, Array]', :data - optional_param 'Optional[Boolean]', :skip_undef - optional_param 'Struct[{ -indent => Optional[String], -space => Optional[String], -space_before => Optional[String], -object_nl => Optional[String], -array_nl => Optional[String], -allow_nan => Optional[Boolean], -max_nesting => Optional[Integer[-1,default]], -}]', :opts + dispatch :deprecation_gen do + repeated_param 'Any', :args end - - def to_json_pretty(data, skip_undef = false, opts = nil) - # It's not possible to make an abstract type that can be either a boolean - # false or an integer, so we use -1 as the falsey value - if opts - opts = opts.transform_keys(&:to_sym) - - opts[:max_nesting] = false if opts[:max_nesting] == -1 - end - - data = data.compact if skip_undef && (data.is_a?(Array) || Hash) - # Call ::JSON to ensure it references the JSON library from Ruby's standard library - # instead of a random JSON namespace that might be in scope due to user code. - JSON.pretty_generate(data, opts) << "\n" + def deprecation_gen(*args) + call_function('deprecation', 'to_json_pretty', 'This function is deprecated, please use stdlib::to_json_pretty instead.') + call_function('stdlib::to_json_pretty', *args) end end diff --git a/spec/functions/to_json_pretty_spec.rb b/spec/functions/to_json_pretty_spec.rb index ed9b14bd9..f1a54e54b 100644 --- a/spec/functions/to_json_pretty_spec.rb +++ b/spec/functions/to_json_pretty_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' -describe 'to_json_pretty' do +describe 'stdlib::to_json_pretty' do it { is_expected.not_to be_nil } it { is_expected.to run.with_params([]).and_return("[\n\n]\n") } it { is_expected.to run.with_params(['one']).and_return("[\n \"one\"\n]\n") }