pdk 1.14.1 → 1.18.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (128) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +155 -2
  3. data/lib/pdk.rb +28 -19
  4. data/lib/pdk/answer_file.rb +2 -95
  5. data/lib/pdk/bolt.rb +19 -0
  6. data/lib/pdk/cli.rb +4 -5
  7. data/lib/pdk/cli/bundle.rb +5 -1
  8. data/lib/pdk/cli/config.rb +3 -1
  9. data/lib/pdk/cli/config/get.rb +3 -1
  10. data/lib/pdk/cli/console.rb +1 -1
  11. data/lib/pdk/cli/convert.rb +16 -10
  12. data/lib/pdk/cli/exec.rb +2 -1
  13. data/lib/pdk/cli/exec/command.rb +45 -4
  14. data/lib/pdk/cli/exec_group.rb +78 -43
  15. data/lib/pdk/cli/get.rb +20 -0
  16. data/lib/pdk/cli/get/config.rb +24 -0
  17. data/lib/pdk/cli/module/build.rb +1 -1
  18. data/lib/pdk/cli/module/generate.rb +1 -1
  19. data/lib/pdk/cli/new/class.rb +2 -2
  20. data/lib/pdk/cli/new/defined_type.rb +2 -2
  21. data/lib/pdk/cli/new/provider.rb +2 -2
  22. data/lib/pdk/cli/new/task.rb +2 -2
  23. data/lib/pdk/cli/new/test.rb +2 -2
  24. data/lib/pdk/cli/new/transport.rb +2 -2
  25. data/lib/pdk/cli/release.rb +192 -0
  26. data/lib/pdk/cli/release/prep.rb +39 -0
  27. data/lib/pdk/cli/release/publish.rb +40 -0
  28. data/lib/pdk/cli/remove.rb +20 -0
  29. data/lib/pdk/cli/remove/config.rb +80 -0
  30. data/lib/pdk/cli/set.rb +20 -0
  31. data/lib/pdk/cli/set/config.rb +119 -0
  32. data/lib/pdk/cli/update.rb +18 -8
  33. data/lib/pdk/cli/util.rb +7 -3
  34. data/lib/pdk/cli/util/update_manager_printer.rb +82 -0
  35. data/lib/pdk/cli/validate.rb +26 -44
  36. data/lib/pdk/config.rb +265 -8
  37. data/lib/pdk/config/ini_file.rb +183 -0
  38. data/lib/pdk/config/ini_file_setting.rb +39 -0
  39. data/lib/pdk/config/namespace.rb +26 -6
  40. data/lib/pdk/config/setting.rb +3 -2
  41. data/lib/pdk/context.rb +99 -0
  42. data/lib/pdk/context/control_repo.rb +60 -0
  43. data/lib/pdk/context/module.rb +28 -0
  44. data/lib/pdk/context/none.rb +22 -0
  45. data/lib/pdk/control_repo.rb +90 -0
  46. data/lib/pdk/generate.rb +1 -0
  47. data/lib/pdk/generate/defined_type.rb +25 -32
  48. data/lib/pdk/generate/module.rb +42 -35
  49. data/lib/pdk/generate/provider.rb +16 -65
  50. data/lib/pdk/generate/puppet_class.rb +25 -31
  51. data/lib/pdk/generate/puppet_object.rb +84 -189
  52. data/lib/pdk/generate/resource_api_object.rb +55 -0
  53. data/lib/pdk/generate/task.rb +28 -46
  54. data/lib/pdk/generate/transport.rb +21 -75
  55. data/lib/pdk/module.rb +1 -1
  56. data/lib/pdk/module/build.rb +38 -25
  57. data/lib/pdk/module/convert.rb +61 -42
  58. data/lib/pdk/module/metadata.rb +1 -3
  59. data/lib/pdk/module/release.rb +254 -0
  60. data/lib/pdk/module/update.rb +24 -16
  61. data/lib/pdk/module/update_manager.rb +8 -1
  62. data/lib/pdk/report.rb +18 -12
  63. data/lib/pdk/report/event.rb +6 -3
  64. data/lib/pdk/template.rb +59 -0
  65. data/lib/pdk/template/fetcher.rb +98 -0
  66. data/lib/pdk/template/fetcher/git.rb +85 -0
  67. data/lib/pdk/template/fetcher/local.rb +28 -0
  68. data/lib/pdk/template/renderer.rb +96 -0
  69. data/lib/pdk/template/renderer/v1.rb +25 -0
  70. data/lib/pdk/template/renderer/v1/legacy_template_dir.rb +116 -0
  71. data/lib/pdk/template/renderer/v1/renderer.rb +132 -0
  72. data/lib/pdk/template/renderer/v1/template_file.rb +102 -0
  73. data/lib/pdk/template/template_dir.rb +67 -0
  74. data/lib/pdk/tests/unit.rb +5 -0
  75. data/lib/pdk/util.rb +55 -45
  76. data/lib/pdk/util/bundler.rb +9 -9
  77. data/lib/pdk/util/changelog_generator.rb +120 -0
  78. data/lib/pdk/util/env.rb +28 -11
  79. data/lib/pdk/util/filesystem.rb +62 -2
  80. data/lib/pdk/util/git.rb +60 -8
  81. data/lib/pdk/util/json_finder.rb +84 -0
  82. data/lib/pdk/util/puppet_strings.rb +3 -3
  83. data/lib/pdk/util/puppet_version.rb +4 -5
  84. data/lib/pdk/util/ruby_version.rb +9 -6
  85. data/lib/pdk/util/template_uri.rb +60 -48
  86. data/lib/pdk/util/version.rb +4 -4
  87. data/lib/pdk/validate.rb +79 -25
  88. data/lib/pdk/validate/control_repo/control_repo_validator_group.rb +23 -0
  89. data/lib/pdk/validate/control_repo/environment_conf_validator.rb +98 -0
  90. data/lib/pdk/validate/external_command_validator.rb +208 -0
  91. data/lib/pdk/validate/internal_ruby_validator.rb +100 -0
  92. data/lib/pdk/validate/invokable_validator.rb +215 -0
  93. data/lib/pdk/validate/metadata/metadata_json_lint_validator.rb +86 -0
  94. data/lib/pdk/validate/metadata/metadata_syntax_validator.rb +78 -0
  95. data/lib/pdk/validate/metadata/metadata_validator_group.rb +20 -0
  96. data/lib/pdk/validate/puppet/puppet_epp_validator.rb +133 -0
  97. data/lib/pdk/validate/puppet/puppet_lint_validator.rb +66 -0
  98. data/lib/pdk/validate/puppet/puppet_syntax_validator.rb +137 -0
  99. data/lib/pdk/validate/puppet/puppet_validator_group.rb +21 -0
  100. data/lib/pdk/validate/ruby/ruby_rubocop_validator.rb +80 -0
  101. data/lib/pdk/validate/ruby/ruby_validator_group.rb +19 -0
  102. data/lib/pdk/validate/tasks/tasks_metadata_lint_validator.rb +88 -0
  103. data/lib/pdk/validate/tasks/tasks_name_validator.rb +50 -0
  104. data/lib/pdk/validate/tasks/tasks_validator_group.rb +20 -0
  105. data/lib/pdk/validate/validator.rb +118 -0
  106. data/lib/pdk/validate/validator_group.rb +104 -0
  107. data/lib/pdk/validate/yaml/yaml_syntax_validator.rb +95 -0
  108. data/lib/pdk/validate/yaml/yaml_validator_group.rb +19 -0
  109. data/lib/pdk/version.rb +1 -1
  110. data/locales/pdk.pot +755 -319
  111. metadata +66 -24
  112. data/lib/pdk/module/templatedir.rb +0 -391
  113. data/lib/pdk/template_file.rb +0 -96
  114. data/lib/pdk/validate/base_validator.rb +0 -215
  115. data/lib/pdk/validate/metadata/metadata_json_lint.rb +0 -82
  116. data/lib/pdk/validate/metadata/metadata_syntax.rb +0 -111
  117. data/lib/pdk/validate/metadata_validator.rb +0 -26
  118. data/lib/pdk/validate/puppet/puppet_epp.rb +0 -137
  119. data/lib/pdk/validate/puppet/puppet_lint.rb +0 -64
  120. data/lib/pdk/validate/puppet/puppet_syntax.rb +0 -137
  121. data/lib/pdk/validate/puppet_validator.rb +0 -26
  122. data/lib/pdk/validate/ruby/rubocop.rb +0 -72
  123. data/lib/pdk/validate/ruby_validator.rb +0 -26
  124. data/lib/pdk/validate/tasks/metadata_lint.rb +0 -130
  125. data/lib/pdk/validate/tasks/name.rb +0 -90
  126. data/lib/pdk/validate/tasks_validator.rb +0 -29
  127. data/lib/pdk/validate/yaml/syntax.rb +0 -125
  128. data/lib/pdk/validate/yaml_validator.rb +0 -28
@@ -0,0 +1,132 @@
1
+ require 'pdk'
2
+ require 'pdk/template/renderer'
3
+
4
+ module PDK
5
+ module Template
6
+ module Renderer
7
+ module V1
8
+ class Renderer < PDK::Template::Renderer::AbstractRenderer
9
+ # @see PDK::Template::Renderer::AbstractRenderer.render
10
+ def render(template_type, _name, options = {})
11
+ render_module(options) { |*args| yield(*args) } if template_type == PDK::Template::MODULE_TEMPLATE_TYPE
12
+ end
13
+
14
+ # @see PDK::Template::Renderer::AbstractRenderer.has_single_item?
15
+ def has_single_item?(item_path) # rubocop:disable Naming/PredicateName
16
+ PDK::Util::Filesystem.exist?(single_item_path(item_path))
17
+ end
18
+
19
+ # @see PDK::Template::Renderer::AbstractRenderer.render_single_item
20
+ def render_single_item(relative_file_path, template_data_hash)
21
+ template_file = single_item_path(relative_file_path)
22
+ return nil unless PDK::Util::Filesystem.file?(template_file) && PDK::Util::Filesystem.readable?(template_file)
23
+
24
+ PDK.logger.debug(_("Rendering '%{template}'...") % { template: template_file })
25
+ new_template_file(template_file, template_data_hash).render
26
+ end
27
+
28
+ # Returns the full path for a single item
29
+ #
30
+ # @param item_path [String] The path of the single item to render
31
+ # @return [String]
32
+ # @api private
33
+ #:nocov:
34
+ def single_item_path(item_path)
35
+ File.join(template_root, 'object_templates', item_path)
36
+ end
37
+ #:nocov:
38
+
39
+ # Helper method used during testing
40
+ #:nocov:
41
+ # @api private
42
+ def new_template_file(template_file, template_data_hash)
43
+ TemplateFile.new(template_file, template_data_hash)
44
+ end
45
+ #:nocov:
46
+
47
+ # Helper method used during testing
48
+ #:nocov:
49
+ # @api private
50
+ def new_legacy_template_dir(context, uri, path, module_metadata = {})
51
+ LegacyTemplateDir.new(context, uri, path, module_metadata)
52
+ end
53
+ #:nocov:
54
+
55
+ # Renders a new module
56
+ #
57
+ # @param options [Hash{Object => Object}] A list of options to pass through to the renderer. See PDK::Template::TemplateDir helper methods for other options
58
+ # @see #render
59
+ # @api private
60
+ #:nocov: This is tested in acceptance and packaging tests
61
+ def render_module(options = {})
62
+ require 'pdk/template/renderer/v1/template_file'
63
+
64
+ moduleroot_dir = File.join(template_root, 'moduleroot')
65
+ moduleroot_init = File.join(template_root, 'moduleroot_init')
66
+
67
+ dirs = [moduleroot_dir]
68
+ dirs << moduleroot_init if options[:include_first_time]
69
+
70
+ legacy_template_dir = new_legacy_template_dir(context, template_uri, template_root, options[:module_metadata] || {})
71
+
72
+ files_in_template(dirs).each do |template_file, template_loc|
73
+ template_file = template_file.to_s
74
+ PDK.logger.debug(_("Rendering '%{template}'...") % { template: template_file })
75
+ dest_path = template_file.sub(%r{\.erb\Z}, '')
76
+ config = legacy_template_dir.config_for(dest_path)
77
+
78
+ dest_status = if template_loc.start_with?(moduleroot_init)
79
+ :init
80
+ else
81
+ :manage
82
+ end
83
+
84
+ if config['unmanaged']
85
+ dest_status = :unmanage
86
+ elsif config['delete']
87
+ dest_status = :delete
88
+ else
89
+ begin
90
+ dest_content = new_template_file(File.join(template_loc, template_file), configs: config, template_dir: legacy_template_dir).render
91
+ rescue => error
92
+ error_msg = _(
93
+ "Failed to render template '%{template}'\n" \
94
+ '%{exception}: %{message}',
95
+ ) % { template: template_file, exception: error.class, message: error.message }
96
+ raise PDK::CLI::FatalError, error_msg
97
+ end
98
+ end
99
+
100
+ yield dest_path, dest_content, dest_status
101
+ end
102
+ end
103
+ #:nocov:
104
+
105
+ # Returns all files in the given template directories
106
+ #
107
+ # @param dirs [Array[String]] Directories to search in
108
+ # @param glob_suffix [Array[String]] File glob to use when searching for files. Defaults to ['**', '*']
109
+ #
110
+ # @return [Hash{String => String}] Key is the template file relative path and the value is the absolute path to the template directory
111
+ # @api private
112
+ def files_in_template(dirs, glob_suffix = ['**', '*'])
113
+ temp_paths = []
114
+ dirlocs = []
115
+ dirs.each do |dir|
116
+ raise ArgumentError, _("The directory '%{dir}' doesn't exist") % { dir: dir } unless PDK::Util::Filesystem.directory?(dir)
117
+ temp_paths += PDK::Util::Filesystem.glob(File.join(dir, *glob_suffix), File::FNM_DOTMATCH).select do |template_path|
118
+ if PDK::Util::Filesystem.file?(template_path) && !PDK::Util::Filesystem.symlink?(template_path)
119
+ dirlocs << dir
120
+ end
121
+ end
122
+ temp_paths.map do |template_path|
123
+ template_path.sub!(%r{\A#{Regexp.escape(dir)}#{Regexp.escape(File::SEPARATOR)}}, '')
124
+ end
125
+ end
126
+ Hash[temp_paths.zip dirlocs]
127
+ end
128
+ end
129
+ end
130
+ end
131
+ end
132
+ end
@@ -0,0 +1,102 @@
1
+ require 'pdk'
2
+ require 'ostruct'
3
+
4
+ module PDK
5
+ module Template
6
+ module Renderer
7
+ module V1
8
+ class TemplateFile < OpenStruct
9
+ # Initialises the TemplateFile object with the path to the template file
10
+ # and the data to be used when rendering the template.
11
+ #
12
+ # @param template_file [String] The path on disk to the template file.
13
+ # @param data [Hash{Symbol => Object}] The data that should be provided to
14
+ # the template when rendering.
15
+ # @option data [Object] :configs The value of this key will be provided to
16
+ # the template as an instance variable `@configs` in order to maintain
17
+ # compatibility with modulesync.
18
+ #
19
+ # @api public
20
+ def initialize(template_file, data = {})
21
+ @template_file = template_file
22
+
23
+ if data.key?(:configs)
24
+ @configs = data[:configs]
25
+ end
26
+
27
+ super(data)
28
+ end
29
+
30
+ # Renders the template by calling the appropriate engine based on the file
31
+ # extension.
32
+ #
33
+ # If the template has an `.erb` extension, the content of the template
34
+ # file will be treated as an ERB template. All other extensions are treated
35
+ # as plain text.
36
+ #
37
+ # @return [String] The rendered template
38
+ #
39
+ # @raise (see #template_content)
40
+ #
41
+ # @api public
42
+ def render
43
+ case File.extname(@template_file)
44
+ when '.erb'
45
+ render_erb
46
+ else
47
+ render_plain
48
+ end
49
+ end
50
+
51
+ def config_for(path)
52
+ return unless respond_to?(:template_dir)
53
+
54
+ template_dir.config_for(path)
55
+ end
56
+
57
+ private
58
+
59
+ # Reads the content of the template file into memory.
60
+ #
61
+ # @return [String] The content of the template file.
62
+ #
63
+ # @raise [ArgumentError] If the template file does not exist or can not be
64
+ # read.
65
+ #
66
+ # @api private
67
+ def template_content
68
+ if PDK::Util::Filesystem.file?(@template_file) && PDK::Util::Filesystem.readable?(@template_file)
69
+ return PDK::Util::Filesystem.read_file(@template_file)
70
+ end
71
+
72
+ raise ArgumentError, _("'%{template}' is not a readable file") % { template: @template_file }
73
+ end
74
+
75
+ # Renders the content of the template file as an ERB template.
76
+ #
77
+ # @return [String] The rendered template.
78
+ #
79
+ # @raise (see #template_content)
80
+ #
81
+ # @api private
82
+ def render_erb
83
+ renderer = ERB.new(template_content, nil, '-')
84
+ renderer.filename = @template_file
85
+ renderer.result(binding)
86
+ end
87
+
88
+ # Renders the content of the template file as plain text.
89
+ #
90
+ # @return [String] The rendered template.
91
+ #
92
+ # @raise (see #template_content)
93
+ #
94
+ # @api private
95
+ def render_plain
96
+ template_content
97
+ end
98
+ end
99
+ end
100
+ end
101
+ end
102
+ end
@@ -0,0 +1,67 @@
1
+ require 'pdk'
2
+ require 'forwardable'
3
+
4
+ module PDK
5
+ module Template
6
+ # A helper class representing an already fetched template on disk, with an appropriate renderer instance.
7
+ # @see PDK::Template.with
8
+ class TemplateDir
9
+ # Creates an instance of TemplateDir object
10
+ # @see TemplateDir.new
11
+ def self.instance(uri, path, context, renderer = nil)
12
+ new(uri, path, context, renderer)
13
+ end
14
+
15
+ extend Forwardable
16
+
17
+ # Helper methods for rendering
18
+ def_delegators :@renderer, :render, :render_single_item, :has_single_item?
19
+
20
+ # @return [PDK::Util::TemplateURI] The URI which points to the source location of the Template
21
+ attr_accessor :uri
22
+
23
+ # @return [String] The path to where the template exists on disk
24
+ attr_accessor :path
25
+
26
+ # @return [Hash{String => String}] A hash of information about the template
27
+ attr_accessor :metadata
28
+
29
+ # @param template_uri [PDK::Util::TemplateUri] A URI which points to the source location of the Template
30
+ # @param path [String] The path to where the template exists on disk
31
+ # @param context [PDK::Context] The context in which the redering will occur in
32
+ # @param renderer [PDK::Template::Renderer::AbstractRenderer] The an instance of a rendering class. If nil, a renderer will be created that's appropriate for the template and context
33
+ def initialize(uri, path, context, renderer = nil)
34
+ @uri = uri
35
+ @path = path
36
+ @metadata = {}
37
+
38
+ @renderer = renderer.nil? ? Renderer.instance(uri, path, context) : renderer
39
+ raise _('Could not find a compatible template renderer for %{path}') % { path: path } if @renderer.nil?
40
+ end
41
+
42
+ # Later additions may include Control Repo rendering, for example
43
+ #
44
+ # def render_control_repo(name, options = {})
45
+ # render(CONTROL_REPO_TEMPLATE_TYPE, name, options.merge(include_first_time: false)) { |*args| yield(*args) }
46
+ # end
47
+ #
48
+ # def render_new_control_repo(name, repo_metadata = {}, options = {})
49
+ # render(CONTROL_REPO_TEMPLATE_TYPE, name, options.merge(include_first_time: true, control_repo_metadata: repo_metadata)) { |*args| yield(*args) }
50
+ # end
51
+ #:nocov: These are just helper methods and are tested elsewhere.
52
+
53
+ # Render an existing module
54
+ # @see PDK::Template::Renderer::AbstractRenderer.render
55
+ def render_module(module_name, options = {})
56
+ @renderer.render(MODULE_TEMPLATE_TYPE, module_name, options.merge(include_first_time: false)) { |*args| yield(*args) }
57
+ end
58
+
59
+ # Render a new module
60
+ # @see PDK::Template::Renderer::AbstractRenderer.render
61
+ def render_new_module(module_name, module_metadata = {}, options = {})
62
+ @renderer.render(MODULE_TEMPLATE_TYPE, module_name, options.merge(include_first_time: true, module_metadata: module_metadata)) { |*args| yield(*args) }
63
+ end
64
+ #:nocov:
65
+ end
66
+ end
67
+ end
@@ -89,6 +89,11 @@ module PDK
89
89
  setup
90
90
 
91
91
  tests = options[:tests]
92
+ # Due to how rake handles paths in the command line options, any backslashed path (Windows platforms) needs to be converted
93
+ # to forward slash. We can't use File.expand_path as the files aren't guaranteed to be on-disk
94
+ #
95
+ # Ref - https://github.com/puppetlabs/pdk/issues/828
96
+ tests = tests.tr('\\', '/') unless tests.nil?
92
97
 
93
98
  environment = { 'CI_SPEC_OPTIONS' => '--format j' }
94
99
  environment['PUPPET_GEM_VERSION'] = options[:puppet] if options[:puppet]
@@ -10,9 +10,11 @@ autoload :Pathname, 'pathname'
10
10
  module PDK
11
11
  module Util
12
12
  autoload :Bundler, 'pdk/util/bundler'
13
+ autoload :ChangelogGenerator, 'pdk/util/changelog_generator'
13
14
  autoload :Env, 'pdk/util/env'
14
15
  autoload :Filesystem, 'pdk/util/filesystem'
15
16
  autoload :Git, 'pdk/util/git'
17
+ autoload :JSONFinder, 'pdk/util/json_finder'
16
18
  autoload :PuppetStrings, 'pdk/util/puppet_strings'
17
19
  autoload :PuppetVersion, 'pdk/util/puppet_version'
18
20
  autoload :RubyVersion, 'pdk/util/ruby_version'
@@ -31,6 +33,16 @@ module PDK
31
33
  types
32
34
  ].freeze
33
35
 
36
+ #:nocov:
37
+ # This method just wraps core Ruby functionality and
38
+ # can be ignored for code coverage
39
+
40
+ # Calls Kernel.exit with an exitcode
41
+ def exit_process(exit_code)
42
+ exit exit_code
43
+ end
44
+ #:nocov:
45
+
34
46
  # Searches upwards from current working directory for the given target file.
35
47
  #
36
48
  # @param target [String] Name of file to search for.
@@ -40,13 +52,13 @@ module PDK
40
52
  # nil if the target file could not be found.
41
53
  def find_upwards(target, start_dir = nil)
42
54
  previous = nil
43
- current = File.expand_path(start_dir || Dir.pwd)
55
+ current = PDK::Util::Filesystem.expand_path(start_dir || Dir.pwd)
44
56
 
45
- until !File.directory?(current) || current == previous
57
+ until !PDK::Util::Filesystem.directory?(current) || current == previous
46
58
  filename = File.join(current, target)
47
- return filename if File.file?(filename)
59
+ return filename if PDK::Util::Filesystem.file?(filename)
48
60
  previous = current
49
- current = File.expand_path('..', current)
61
+ current = PDK::Util::Filesystem.expand_path('..', current)
50
62
  end
51
63
  end
52
64
  module_function :find_upwards
@@ -72,12 +84,12 @@ module PDK
72
84
  # @return [String] Canonical path
73
85
  def canonical_path(path)
74
86
  if Gem.win_platform?
75
- unless File.exist?(path)
87
+ unless PDK::Util::Filesystem.exist?(path)
76
88
  raise PDK::CLI::FatalError, _("Cannot resolve a full path to '%{path}', as it does not currently exist.") % { path: path }
77
89
  end
78
90
  PDK::Util::Windows::File.get_long_pathname(path)
79
91
  else
80
- File.expand_path(path)
92
+ PDK::Util::Filesystem.expand_path(path)
81
93
  end
82
94
  end
83
95
  module_function :canonical_path
@@ -135,6 +147,15 @@ module PDK
135
147
  end
136
148
  module_function :configdir
137
149
 
150
+ def system_configdir
151
+ return @system_configdir unless @system_configdir.nil?
152
+ return @system_configdir = File.join(File::SEPARATOR, 'opt', 'puppetlabs', 'pdk', 'config') unless Gem.win_platform?
153
+
154
+ return @system_configdir = File.join(PDK::Util::Env['ProgramData'], 'PuppetLabs', 'PDK') unless PDK::Util::Env['ProgramData'].nil?
155
+ @system_configdir = File.join(PDK::Util::Env['AllUsersProfile'], 'PuppetLabs', 'PDK')
156
+ end
157
+ module_function :system_configdir
158
+
138
159
  # Returns path to the root of the module being worked on.
139
160
  #
140
161
  # @return [String, nil] Fully qualified base path to module, or nil if
@@ -176,7 +197,7 @@ module PDK
176
197
  # @return [Hash, nil] subset of text as Hash of first valid JSON found, or nil if no valid
177
198
  # JSON found in the text
178
199
  def find_first_json_in(text)
179
- find_valid_json_in(text)
200
+ find_all_json_in(text).first
180
201
  end
181
202
  module_function :find_first_json_in
182
203
 
@@ -186,42 +207,10 @@ module PDK
186
207
  # @return [Array<Hash>] subset of text as Array of all JSON object found, empty Array if none are found
187
208
  # JSON found in the text
188
209
  def find_all_json_in(text)
189
- find_valid_json_in(text, break_on_first: false)
210
+ PDK::Util::JSONFinder.new(text).objects
190
211
  end
191
212
  module_function :find_all_json_in
192
213
 
193
- # Iterate through possible JSON documents until we find one that is valid.
194
- #
195
- # @param [String] text the text in which to find a JSON document
196
- # @param [Hash] opts options
197
- # @option opts [Boolean] :break_on_first Whether or not to break after valid JSON is found, defaults to true
198
- #
199
- # @return [Hash, Array<Hash>, nil] subset of text as Hash of first valid JSON found, array of all valid JSON found, or nil if no valid
200
- # JSON found in the text
201
- #
202
- # @private
203
- def find_valid_json_in(text, opts = {})
204
- break_on_first = opts.key?(:break_on_first) ? opts[:break_on_first] : true
205
-
206
- json_result = break_on_first ? nil : []
207
-
208
- text.scan(%r{\{(?:[^{}]|(?:\g<0>))*\}}x) do |str|
209
- begin
210
- if break_on_first
211
- json_result = JSON.parse(str)
212
- break
213
- else
214
- json_result.push(JSON.parse(str))
215
- end
216
- rescue JSON::ParserError
217
- next
218
- end
219
- end
220
-
221
- json_result
222
- end
223
- module_function :find_valid_json_in
224
-
225
214
  # Returns the targets' paths relative to the working directory
226
215
  #
227
216
  # @return [Array<String>] The absolute or path to the target
@@ -237,16 +226,18 @@ module PDK
237
226
  module_function :targets_relative_to_pwd
238
227
 
239
228
  # TO-DO: Refactor replacement of lib/pdk/module/build.rb:metadata to use this function instead
240
- def module_metadata
229
+ # @param module_path [String] The path to the root of the module. Default is determine the module root automatically
230
+ def module_metadata(module_path = nil)
241
231
  require 'pdk/module/metadata'
242
-
243
- PDK::Module::Metadata.from_file(File.join(module_root, 'metadata.json')).data
232
+ module_path ||= module_root
233
+ PDK::Module::Metadata.from_file(File.join(module_path, 'metadata.json')).data
244
234
  end
245
235
  module_function :module_metadata
246
236
 
247
237
  # TO-DO: Refactor replacement of lib/pdk/module/build.rb:module_pdk_compatible? to use this function instead
248
- def module_pdk_compatible?
249
- ['pdk-version', 'template-url'].any? { |key| module_metadata.key?(key) }
238
+ # @param module_path [String] The path to the root of the module. Default is determine the module root automatically
239
+ def module_pdk_compatible?(module_path = nil)
240
+ ['pdk-version', 'template-url'].any? { |key| module_metadata(module_path).key?(key) }
250
241
  end
251
242
  module_function :module_pdk_compatible?
252
243
 
@@ -263,5 +254,24 @@ module PDK
263
254
  nil
264
255
  end
265
256
  module_function :module_pdk_version
257
+
258
+ # Does a deep copy instead of a shallow copy of an object.
259
+ #
260
+ # @param object [Object] The object to duplicate
261
+ #
262
+ # @return [Object] duplicate of the original object
263
+ # the current working dir does not appear to be within a module.
264
+ def deep_duplicate(object)
265
+ if object.is_a?(Array)
266
+ object.map { |item| deep_duplicate(item) }
267
+ elsif object.is_a?(Hash)
268
+ hash = object.dup
269
+ hash.each_pair { |key, value| hash[key] = deep_duplicate(value) }
270
+ hash
271
+ else
272
+ object
273
+ end
274
+ end
275
+ module_function :deep_duplicate
266
276
  end
267
277
  end