pdk 1.9.0 → 3.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (163) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +744 -711
  3. data/README.md +23 -21
  4. data/lib/pdk/answer_file.rb +3 -112
  5. data/lib/pdk/bolt.rb +20 -0
  6. data/lib/pdk/cli/build.rb +51 -54
  7. data/lib/pdk/cli/bundle.rb +33 -29
  8. data/lib/pdk/cli/console.rb +148 -0
  9. data/lib/pdk/cli/convert.rb +46 -37
  10. data/lib/pdk/cli/env.rb +51 -0
  11. data/lib/pdk/cli/errors.rb +4 -3
  12. data/lib/pdk/cli/exec/command.rb +285 -0
  13. data/lib/pdk/cli/exec/interactive_command.rb +109 -0
  14. data/lib/pdk/cli/exec.rb +32 -201
  15. data/lib/pdk/cli/exec_group.rb +79 -43
  16. data/lib/pdk/cli/get/config.rb +26 -0
  17. data/lib/pdk/cli/get.rb +22 -0
  18. data/lib/pdk/cli/new/class.rb +20 -22
  19. data/lib/pdk/cli/new/defined_type.rb +21 -21
  20. data/lib/pdk/cli/new/fact.rb +27 -0
  21. data/lib/pdk/cli/new/function.rb +27 -0
  22. data/lib/pdk/cli/new/module.rb +40 -29
  23. data/lib/pdk/cli/new/provider.rb +18 -18
  24. data/lib/pdk/cli/new/task.rb +23 -22
  25. data/lib/pdk/cli/new/test.rb +52 -0
  26. data/lib/pdk/cli/new/transport.rb +27 -0
  27. data/lib/pdk/cli/new.rb +15 -9
  28. data/lib/pdk/cli/release/prep.rb +39 -0
  29. data/lib/pdk/cli/release/publish.rb +46 -0
  30. data/lib/pdk/cli/release.rb +185 -0
  31. data/lib/pdk/cli/remove/config.rb +83 -0
  32. data/lib/pdk/cli/remove.rb +22 -0
  33. data/lib/pdk/cli/set/config.rb +121 -0
  34. data/lib/pdk/cli/set.rb +22 -0
  35. data/lib/pdk/cli/test/unit.rb +71 -69
  36. data/lib/pdk/cli/test.rb +9 -8
  37. data/lib/pdk/cli/update.rb +38 -21
  38. data/lib/pdk/cli/util/command_redirector.rb +13 -3
  39. data/lib/pdk/cli/util/interview.rb +25 -9
  40. data/lib/pdk/cli/util/option_normalizer.rb +6 -6
  41. data/lib/pdk/cli/util/option_validator.rb +19 -9
  42. data/lib/pdk/cli/util/spinner.rb +13 -0
  43. data/lib/pdk/cli/util/update_manager_printer.rb +82 -0
  44. data/lib/pdk/cli/util.rb +105 -48
  45. data/lib/pdk/cli/validate.rb +96 -111
  46. data/lib/pdk/cli.rb +134 -87
  47. data/lib/pdk/config/errors.rb +5 -0
  48. data/lib/pdk/config/ini_file.rb +184 -0
  49. data/lib/pdk/config/ini_file_setting.rb +35 -0
  50. data/lib/pdk/config/json.rb +35 -0
  51. data/lib/pdk/config/json_schema_namespace.rb +137 -0
  52. data/lib/pdk/config/json_schema_setting.rb +51 -0
  53. data/lib/pdk/config/json_with_schema.rb +47 -0
  54. data/lib/pdk/config/namespace.rb +362 -0
  55. data/lib/pdk/config/setting.rb +134 -0
  56. data/lib/pdk/config/task_schema.json +116 -0
  57. data/lib/pdk/config/validator.rb +31 -0
  58. data/lib/pdk/config/yaml.rb +41 -0
  59. data/lib/pdk/config/yaml_with_schema.rb +51 -0
  60. data/lib/pdk/config.rb +304 -0
  61. data/lib/pdk/context/control_repo.rb +61 -0
  62. data/lib/pdk/context/module.rb +28 -0
  63. data/lib/pdk/context/none.rb +22 -0
  64. data/lib/pdk/context.rb +98 -0
  65. data/lib/pdk/control_repo.rb +89 -0
  66. data/lib/pdk/generate/defined_type.rb +27 -33
  67. data/lib/pdk/generate/fact.rb +26 -0
  68. data/lib/pdk/generate/function.rb +49 -0
  69. data/lib/pdk/generate/module.rb +160 -153
  70. data/lib/pdk/generate/provider.rb +16 -69
  71. data/lib/pdk/generate/puppet_class.rb +27 -32
  72. data/lib/pdk/generate/puppet_object.rb +100 -159
  73. data/lib/pdk/generate/task.rb +34 -51
  74. data/lib/pdk/generate/transport.rb +34 -0
  75. data/lib/pdk/generate.rb +21 -8
  76. data/lib/pdk/logger.rb +24 -6
  77. data/lib/pdk/module/build.rb +125 -37
  78. data/lib/pdk/module/convert.rb +146 -65
  79. data/lib/pdk/module/metadata.rb +72 -71
  80. data/lib/pdk/module/release.rb +255 -0
  81. data/lib/pdk/module/update.rb +48 -37
  82. data/lib/pdk/module/update_manager.rb +75 -39
  83. data/lib/pdk/module.rb +10 -2
  84. data/lib/pdk/monkey_patches.rb +268 -0
  85. data/lib/pdk/report/event.rb +36 -48
  86. data/lib/pdk/report.rb +35 -22
  87. data/lib/pdk/template/fetcher/git.rb +84 -0
  88. data/lib/pdk/template/fetcher/local.rb +29 -0
  89. data/lib/pdk/template/fetcher.rb +100 -0
  90. data/lib/pdk/template/renderer/v1/legacy_template_dir.rb +108 -0
  91. data/lib/pdk/template/renderer/v1/renderer.rb +131 -0
  92. data/lib/pdk/template/renderer/v1/template_file.rb +100 -0
  93. data/lib/pdk/template/renderer/v1.rb +25 -0
  94. data/lib/pdk/template/renderer.rb +97 -0
  95. data/lib/pdk/template/template_dir.rb +67 -0
  96. data/lib/pdk/template.rb +52 -0
  97. data/lib/pdk/tests/unit.rb +101 -51
  98. data/lib/pdk/util/bundler.rb +44 -42
  99. data/lib/pdk/util/changelog_generator.rb +138 -0
  100. data/lib/pdk/util/env.rb +48 -0
  101. data/lib/pdk/util/filesystem.rb +139 -2
  102. data/lib/pdk/util/git.rb +108 -8
  103. data/lib/pdk/util/json_finder.rb +86 -0
  104. data/lib/pdk/util/puppet_strings.rb +125 -0
  105. data/lib/pdk/util/puppet_version.rb +71 -87
  106. data/lib/pdk/util/ruby_version.rb +49 -25
  107. data/lib/pdk/util/template_uri.rb +283 -0
  108. data/lib/pdk/util/vendored_file.rb +34 -42
  109. data/lib/pdk/util/version.rb +11 -10
  110. data/lib/pdk/util/windows/api_types.rb +74 -44
  111. data/lib/pdk/util/windows/file.rb +31 -27
  112. data/lib/pdk/util/windows/process.rb +74 -0
  113. data/lib/pdk/util/windows/string.rb +19 -12
  114. data/lib/pdk/util/windows.rb +2 -0
  115. data/lib/pdk/util.rb +111 -124
  116. data/lib/pdk/validate/control_repo/control_repo_validator_group.rb +23 -0
  117. data/lib/pdk/validate/control_repo/environment_conf_validator.rb +98 -0
  118. data/lib/pdk/validate/external_command_validator.rb +213 -0
  119. data/lib/pdk/validate/internal_ruby_validator.rb +101 -0
  120. data/lib/pdk/validate/invokable_validator.rb +238 -0
  121. data/lib/pdk/validate/metadata/metadata_json_lint_validator.rb +84 -0
  122. data/lib/pdk/validate/metadata/metadata_syntax_validator.rb +76 -0
  123. data/lib/pdk/validate/metadata/metadata_validator_group.rb +20 -0
  124. data/lib/pdk/validate/puppet/puppet_epp_validator.rb +131 -0
  125. data/lib/pdk/validate/puppet/puppet_lint_validator.rb +66 -0
  126. data/lib/pdk/validate/puppet/puppet_plan_syntax_validator.rb +38 -0
  127. data/lib/pdk/validate/puppet/puppet_syntax_validator.rb +135 -0
  128. data/lib/pdk/validate/puppet/puppet_validator_group.rb +22 -0
  129. data/lib/pdk/validate/ruby/ruby_rubocop_validator.rb +79 -0
  130. data/lib/pdk/validate/ruby/ruby_validator_group.rb +19 -0
  131. data/lib/pdk/validate/tasks/tasks_metadata_lint_validator.rb +83 -0
  132. data/lib/pdk/validate/tasks/tasks_name_validator.rb +45 -0
  133. data/lib/pdk/validate/tasks/tasks_validator_group.rb +20 -0
  134. data/lib/pdk/validate/validator.rb +120 -0
  135. data/lib/pdk/validate/validator_group.rb +107 -0
  136. data/lib/pdk/validate/yaml/yaml_syntax_validator.rb +86 -0
  137. data/lib/pdk/validate/yaml/yaml_validator_group.rb +19 -0
  138. data/lib/pdk/validate.rb +86 -12
  139. data/lib/pdk/version.rb +2 -2
  140. data/lib/pdk.rb +60 -10
  141. metadata +138 -100
  142. data/lib/pdk/cli/module/build.rb +0 -14
  143. data/lib/pdk/cli/module/generate.rb +0 -45
  144. data/lib/pdk/cli/module.rb +0 -14
  145. data/lib/pdk/i18n.rb +0 -4
  146. data/lib/pdk/module/templatedir.rb +0 -321
  147. data/lib/pdk/template_file.rb +0 -95
  148. data/lib/pdk/validate/base_validator.rb +0 -215
  149. data/lib/pdk/validate/metadata/metadata_json_lint.rb +0 -86
  150. data/lib/pdk/validate/metadata/metadata_syntax.rb +0 -109
  151. data/lib/pdk/validate/metadata_validator.rb +0 -30
  152. data/lib/pdk/validate/puppet/puppet_lint.rb +0 -67
  153. data/lib/pdk/validate/puppet/puppet_syntax.rb +0 -112
  154. data/lib/pdk/validate/puppet_validator.rb +0 -30
  155. data/lib/pdk/validate/ruby/rubocop.rb +0 -77
  156. data/lib/pdk/validate/ruby_validator.rb +0 -29
  157. data/lib/pdk/validate/tasks/metadata_lint.rb +0 -126
  158. data/lib/pdk/validate/tasks/name.rb +0 -88
  159. data/lib/pdk/validate/tasks_validator.rb +0 -33
  160. data/lib/pdk/validate/yaml/syntax.rb +0 -109
  161. data/lib/pdk/validate/yaml_validator.rb +0 -31
  162. data/locales/config.yaml +0 -21
  163. data/locales/pdk.pot +0 -1291
@@ -0,0 +1,74 @@
1
+ require 'pdk/util/windows'
2
+
3
+ module PDK
4
+ module Util
5
+ module Windows
6
+ module Process
7
+ require 'ffi'
8
+ extend PDK::Util::Windows::String
9
+ extend FFI::Library
10
+
11
+ def environment_hash
12
+ env_ptr = GetEnvironmentStringsW()
13
+
14
+ contains_unicode_replacement = lambda do |string|
15
+ return false unless string.include?("\uFFFD")
16
+
17
+ PDK.logger.warning "Discarding environment variable #{string} which contains invalid bytes"
18
+ true
19
+ end
20
+
21
+ # pass :invalid => :replace to the Ruby String#encode to use replacement
22
+ # characters
23
+ pairs = env_ptr.read_arbitrary_wide_string_up_to(65_534, :double_null, invalid: :replace)
24
+ .split(?\x00)
25
+ .reject { |env_str| env_str.nil? || env_str.empty? || env_str[0] == '=' }
26
+ .reject { |env_str| contains_unicode_replacement.call(env_str) }
27
+ .map { |env_pair| env_pair.split('=', 2) }
28
+ pairs.to_h
29
+ ensure
30
+ PDK.logger.debug 'FreeEnvironmentStringsW memory leak' if env_ptr && !env_ptr.null? && (FreeEnvironmentStringsW(env_ptr) == PDK::Util::Windows::WIN32_FALSE)
31
+ end
32
+ module_function :environment_hash
33
+
34
+ def set_environment_variable(name, val)
35
+ raise ArgumentError, 'Environment variable name must not be nil or empty' if name.nil? || name.empty?
36
+
37
+ FFI::MemoryPointer.from_string_to_wide_string(name) do |name_ptr|
38
+ if val.nil?
39
+ raise format('Failed to remove environment variable: %{name}', name: name) if SetEnvironmentVariableW(name_ptr, FFI::MemoryPointer::NULL) == PDK::Util::Windows::WIN32_FALSE
40
+ else
41
+ FFI::MemoryPointer.from_string_to_wide_string(val) do |val_ptr|
42
+ raise format('Failed to set environment variaible: %{name}', name: name) if SetEnvironmentVariableW(name_ptr, val_ptr) == PDK::Util::Windows::WIN32_FALSE
43
+ end
44
+ end
45
+ end
46
+ end
47
+ module_function :set_environment_variable
48
+
49
+ ffi_convention :stdcall
50
+
51
+ # https://msdn.microsoft.com/en-us/library/windows/desktop/ms683187(v=vs.85).aspx
52
+ # LPTCH GetEnvironmentStrings(void);
53
+ ffi_lib :kernel32
54
+ attach_function_private :GetEnvironmentStringsW, [], :pointer
55
+
56
+ # https://msdn.microsoft.com/en-us/library/windows/desktop/ms683151(v=vs.85).aspx
57
+ # BOOL FreeEnvironmentStrings(
58
+ # _In_ LPTCH lpszEnvironmentBlock
59
+ # );
60
+ ffi_lib :kernel32
61
+ attach_function_private :FreeEnvironmentStringsW, [:pointer], :win32_bool
62
+
63
+ # https://msdn.microsoft.com/en-us/library/windows/desktop/ms686206(v=vs.85).aspx
64
+ # BOOL WINAPI SetEnvironmentVariableW(
65
+ # _In_ LPCTSTR lpName,
66
+ # _In_opt_ LPCTSTR lpValue
67
+ # );
68
+ ffi_lib :kernel32
69
+ attach_function_private :SetEnvironmentVariableW, [:lpcwstr, :lpcwstr],
70
+ :win32_bool
71
+ end
72
+ end
73
+ end
74
+ end
@@ -1,16 +1,23 @@
1
1
  require 'pdk/util/windows'
2
2
 
3
- module PDK::Util::Windows::String
4
- def wide_string(str)
5
- # if given a nil string, assume caller wants to pass a nil pointer to win32
6
- return nil if str.nil?
7
- # ruby (< 2.1) does not respect multibyte terminators, so it is possible
8
- # for a string to contain a single trailing null byte, followed by garbage
9
- # causing buffer overruns.
10
- #
11
- # See http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?revision=41920&view=revision
12
- newstr = str + "\0".encode(str.encoding)
13
- newstr.encode!('UTF-16LE')
3
+ module PDK
4
+ module Util
5
+ module Windows
6
+ module String
7
+ def wide_string(str)
8
+ # if given a nil string, assume caller wants to pass a nil pointer to win32
9
+ return if str.nil?
10
+
11
+ # ruby (< 2.1) does not respect multibyte terminators, so it is possible
12
+ # for a string to contain a single trailing null byte, followed by garbage
13
+ # causing buffer overruns.
14
+ #
15
+ # See http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?revision=41920&view=revision
16
+ newstr = str + "\0".encode(str.encoding)
17
+ newstr.encode!('UTF-16LE')
18
+ end
19
+ module_function :wide_string
20
+ end
21
+ end
14
22
  end
15
- module_function :wide_string
16
23
  end
@@ -1,12 +1,14 @@
1
1
  module PDK
2
2
  module Util
3
3
  module Windows
4
+ WIN32_FALSE = 0
4
5
  module File; end
5
6
 
6
7
  if Gem.win_platform?
7
8
  require 'pdk/util/windows/api_types'
8
9
  require 'pdk/util/windows/string'
9
10
  require 'pdk/util/windows/file'
11
+ require 'pdk/util/windows/process'
10
12
  end
11
13
  end
12
14
  end
data/lib/pdk/util.rb CHANGED
@@ -1,21 +1,38 @@
1
- require 'tmpdir'
2
- require 'tempfile'
1
+ require 'pdk'
3
2
 
4
- require 'pdk/util/version'
3
+ # PDK::Util::Windows can not be lazy loaded because it conditionally requires
4
+ # other files on Windows only. This can probably be fixed up with a later
5
+ # refactoring.
5
6
  require 'pdk/util/windows'
6
- require 'pdk/util/vendored_file'
7
- require 'pdk/util/filesystem'
7
+
8
+ autoload :Pathname, 'pathname'
8
9
 
9
10
  module PDK
10
11
  module Util
11
- MODULE_FOLDERS = %w[
12
- manifests
13
- lib
14
- tasks
15
- facts.d
16
- functions
17
- types
18
- ].freeze
12
+ autoload :Bundler, 'pdk/util/bundler'
13
+ autoload :ChangelogGenerator, 'pdk/util/changelog_generator'
14
+ autoload :Env, 'pdk/util/env'
15
+ autoload :Filesystem, 'pdk/util/filesystem'
16
+ autoload :Git, 'pdk/util/git'
17
+ autoload :JSONFinder, 'pdk/util/json_finder'
18
+ autoload :PuppetStrings, 'pdk/util/puppet_strings'
19
+ autoload :PuppetVersion, 'pdk/util/puppet_version'
20
+ autoload :RubyVersion, 'pdk/util/ruby_version'
21
+ autoload :TemplateURI, 'pdk/util/template_uri'
22
+ autoload :VendoredFile, 'pdk/util/vendored_file'
23
+ autoload :Version, 'pdk/util/version'
24
+
25
+ MODULE_FOLDERS = ['manifests', 'lib/puppet', 'lib/puppet_x', 'lib/facter', 'tasks', 'facts.d', 'functions', 'types'].freeze
26
+
27
+ # :nocov:
28
+ # This method just wraps core Ruby functionality and
29
+ # can be ignored for code coverage
30
+
31
+ # Calls Kernel.exit with an exitcode
32
+ def exit_process(exit_code)
33
+ exit exit_code
34
+ end
35
+ # :nocov:
19
36
 
20
37
  # Searches upwards from current working directory for the given target file.
21
38
  #
@@ -26,13 +43,14 @@ module PDK
26
43
  # nil if the target file could not be found.
27
44
  def find_upwards(target, start_dir = nil)
28
45
  previous = nil
29
- current = File.expand_path(start_dir || Dir.pwd)
46
+ current = PDK::Util::Filesystem.expand_path(start_dir || Dir.pwd)
30
47
 
31
- until !File.directory?(current) || current == previous
48
+ until !PDK::Util::Filesystem.directory?(current) || current == previous
32
49
  filename = File.join(current, target)
33
- return filename if File.file?(filename)
50
+ return filename if PDK::Util::Filesystem.file?(filename)
51
+
34
52
  previous = current
35
- current = File.expand_path('..', current)
53
+ current = PDK::Util::Filesystem.expand_path('..', current)
36
54
  end
37
55
  end
38
56
  module_function :find_upwards
@@ -43,6 +61,8 @@ module PDK
43
61
  #
44
62
  # @return [String] The temporary directory path.
45
63
  def make_tmpdir_name(base)
64
+ require 'tmpdir'
65
+
46
66
  t = Time.now.strftime('%Y%m%d')
47
67
  name = "#{base}#{t}-#{Process.pid}-#{rand(0x100000000).to_s(36)}"
48
68
  File.join(Dir.tmpdir, name)
@@ -56,23 +76,26 @@ module PDK
56
76
  # @return [String] Canonical path
57
77
  def canonical_path(path)
58
78
  if Gem.win_platform?
59
- unless File.exist?(path)
60
- raise PDK::CLI::FatalError, _("Cannot resolve a full path to '%{path}', as it does not currently exist.") % { path: path }
61
- end
79
+ raise PDK::CLI::FatalError, format("Cannot resolve a full path to '%{path}', as it does not currently exist.", path: path) unless PDK::Util::Filesystem.exist?(path)
80
+
62
81
  PDK::Util::Windows::File.get_long_pathname(path)
63
82
  else
64
- File.expand_path(path)
83
+ PDK::Util::Filesystem.expand_path(path)
65
84
  end
66
85
  end
67
86
  module_function :canonical_path
68
87
 
69
88
  def package_install?
89
+ require 'pdk/util/version'
90
+
70
91
  !PDK::Util::Version.version_file.nil?
71
92
  end
72
93
  module_function :package_install?
73
94
 
74
95
  def development_mode?
75
- (!PDK::Util::Version.git_ref.nil? || PDK::VERSION.end_with?('.pre'))
96
+ require 'pdk/util/version'
97
+
98
+ !PDK::Util::Version.git_ref.nil? || PDK::VERSION.end_with?('.pre')
76
99
  end
77
100
  module_function :development_mode?
78
101
 
@@ -82,7 +105,9 @@ module PDK
82
105
  module_function :gem_install?
83
106
 
84
107
  def pdk_package_basedir
85
- raise PDK::CLI::FatalError, _('Package basedir requested for non-package install.') unless package_install?
108
+ raise PDK::CLI::FatalError, 'Package basedir requested for non-package install.' unless package_install?
109
+
110
+ require 'pdk/util/version'
86
111
 
87
112
  File.dirname(PDK::Util::Version.version_file)
88
113
  end
@@ -98,13 +123,32 @@ module PDK
98
123
  # @return [String] Fully qualified path to per-user PDK cachedir.
99
124
  def cachedir
100
125
  if Gem.win_platform?
101
- File.join(ENV['LOCALAPPDATA'], 'PDK', 'cache')
126
+ File.join(PDK::Util::Env['LOCALAPPDATA'], 'PDK', 'cache')
102
127
  else
103
128
  File.join(Dir.home, '.pdk', 'cache')
104
129
  end
105
130
  end
106
131
  module_function :cachedir
107
132
 
133
+ def configdir
134
+ if Gem.win_platform?
135
+ File.join(PDK::Util::Env['LOCALAPPDATA'], 'PDK')
136
+ else
137
+ File.join(PDK::Util::Env.fetch('XDG_CONFIG_HOME', File.join(Dir.home, '.config')), 'pdk')
138
+ end
139
+ end
140
+ module_function :configdir
141
+
142
+ def system_configdir
143
+ return @system_configdir unless @system_configdir.nil?
144
+ return @system_configdir = File.join(File::SEPARATOR, 'opt', 'puppetlabs', 'pdk', 'config') unless Gem.win_platform?
145
+
146
+ return @system_configdir = File.join(PDK::Util::Env['ProgramData'], 'PuppetLabs', 'PDK') unless PDK::Util::Env['ProgramData'].nil?
147
+
148
+ @system_configdir = File.join(PDK::Util::Env['AllUsersProfile'], 'PuppetLabs', 'PDK')
149
+ end
150
+ module_function :system_configdir
151
+
108
152
  # Returns path to the root of the module being worked on.
109
153
  #
110
154
  # @return [String, nil] Fully qualified base path to module, or nil if
@@ -115,19 +159,27 @@ module PDK
115
159
  File.dirname(metadata_path)
116
160
  elsif in_module_root?
117
161
  Dir.pwd
118
- else
119
- nil
120
162
  end
121
163
  end
122
164
  module_function :module_root
123
165
 
166
+ # The module's fixtures directory for spec testing
167
+ # @return [String] - the path to the module's fixtures directory
168
+ def module_fixtures_dir
169
+ dir = module_root
170
+ File.join(module_root, 'spec', 'fixtures') unless dir.nil?
171
+ end
172
+ module_function :module_fixtures_dir
173
+
124
174
  # Returns true or false depending on if any of the common directories in a module
125
- # are found in the current directory
175
+ # are found in the specified directory. If a directory is not specified, the current
176
+ # working directory is used.
126
177
  #
127
178
  # @return [boolean] True if any folders from MODULE_FOLDERS are found in the current dir,
128
179
  # false otherwise.
129
- def in_module_root?
130
- PDK::Util::MODULE_FOLDERS.any? { |dir| File.directory?(dir) }
180
+ def in_module_root?(path = Dir.pwd)
181
+ PDK::Util::MODULE_FOLDERS.any? { |dir| PDK::Util::Filesystem.directory?(File.join(path, dir)) } ||
182
+ PDK::Util::Filesystem.file?(File.join(path, 'metadata.json'))
131
183
  end
132
184
  module_function :in_module_root?
133
185
 
@@ -137,7 +189,7 @@ module PDK
137
189
  # @return [Hash, nil] subset of text as Hash of first valid JSON found, or nil if no valid
138
190
  # JSON found in the text
139
191
  def find_first_json_in(text)
140
- find_valid_json_in(text)
192
+ find_all_json_in(text).first
141
193
  end
142
194
  module_function :find_first_json_in
143
195
 
@@ -147,42 +199,10 @@ module PDK
147
199
  # @return [Array<Hash>] subset of text as Array of all JSON object found, empty Array if none are found
148
200
  # JSON found in the text
149
201
  def find_all_json_in(text)
150
- find_valid_json_in(text, break_on_first: false)
202
+ PDK::Util::JSONFinder.new(text).objects
151
203
  end
152
204
  module_function :find_all_json_in
153
205
 
154
- # Iterate through possible JSON documents until we find one that is valid.
155
- #
156
- # @param [String] text the text in which to find a JSON document
157
- # @param [Hash] opts options
158
- # @option opts [Boolean] :break_on_first Whether or not to break after valid JSON is found, defaults to true
159
- #
160
- # @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
161
- # JSON found in the text
162
- #
163
- # @private
164
- def find_valid_json_in(text, opts = {})
165
- break_on_first = opts.key?(:break_on_first) ? opts[:break_on_first] : true
166
-
167
- json_result = break_on_first ? nil : []
168
-
169
- text.scan(%r{\{(?:[^{}]|(?:\g<0>))*\}}x) do |str|
170
- begin
171
- if break_on_first
172
- json_result = JSON.parse(str)
173
- break
174
- else
175
- json_result.push(JSON.parse(str))
176
- end
177
- rescue JSON::ParserError
178
- next
179
- end
180
- end
181
-
182
- json_result
183
- end
184
- module_function :find_valid_json_in
185
-
186
206
  # Returns the targets' paths relative to the working directory
187
207
  #
188
208
  # @return [Array<String>] The absolute or path to the target
@@ -197,72 +217,19 @@ module PDK
197
217
  end
198
218
  module_function :targets_relative_to_pwd
199
219
 
200
- def default_template_url
201
- answer_file_url = PDK.answers['template-url']
202
-
203
- return puppetlabs_template_url if answer_file_url.nil?
204
-
205
- # Ignore answer file template-url if the value is the old or new default.
206
- return puppetlabs_template_url if answer_file_url == 'https://github.com/puppetlabs/pdk-module-template'
207
- return puppetlabs_template_url if answer_file_url == puppetlabs_template_url
208
-
209
- if File.directory?(answer_file_url)
210
- # Instantiating a new TemplateDir object pointing to the directory
211
- # will cause the directory contents to be validated, raising
212
- # ArgumentError if it does not appear to be a valid template.
213
- PDK::Module::TemplateDir.new(answer_file_url) {}
214
- return answer_file_url
215
- end
216
-
217
- raise ArgumentError unless PDK::Util::Git.repo?(answer_file_url)
218
-
219
- answer_file_url
220
- rescue ArgumentError
221
- PDK.logger.warn(
222
- _("Unable to access the previously used template '%{template}', using the default template instead.") % {
223
- template: answer_file_url,
224
- },
225
- )
226
- PDK.answers.update!('template-url' => nil)
227
- return puppetlabs_template_url
228
- end
229
- module_function :default_template_url
230
-
231
- def puppetlabs_template_url
232
- if package_install?
233
- 'file://' + File.join(package_cachedir, 'pdk-templates.git')
234
- else
235
- 'https://github.com/puppetlabs/pdk-templates'
236
- end
237
- end
238
- module_function :puppetlabs_template_url
239
-
240
- def default_template_ref
241
- # TODO: This should respect a --template-ref option if we add that
242
- return 'origin/master' if default_template_url != puppetlabs_template_url
243
-
244
- puppetlabs_template_ref
245
- end
246
- module_function :default_template_ref
247
-
248
- def puppetlabs_template_ref
249
- if PDK::Util.development_mode?
250
- 'origin/master'
251
- else
252
- PDK::TEMPLATE_REF
253
- end
254
- end
255
- module_function :puppetlabs_template_ref
256
-
257
220
  # TO-DO: Refactor replacement of lib/pdk/module/build.rb:metadata to use this function instead
258
- def module_metadata
259
- PDK::Module::Metadata.from_file(File.join(module_root, 'metadata.json')).data
221
+ # @param module_path [String] The path to the root of the module. Default is determine the module root automatically
222
+ def module_metadata(module_path = nil)
223
+ require 'pdk/module/metadata'
224
+ module_path ||= module_root
225
+ PDK::Module::Metadata.from_file(File.join(module_path, 'metadata.json')).data
260
226
  end
261
227
  module_function :module_metadata
262
228
 
263
229
  # TO-DO: Refactor replacement of lib/pdk/module/build.rb:module_pdk_compatible? to use this function instead
264
- def module_pdk_compatible?
265
- ['pdk-version', 'template-url'].any? { |key| module_metadata.key?(key) }
230
+ # @param module_path [String] The path to the root of the module. Default is determine the module root automatically
231
+ def module_pdk_compatible?(module_path = nil)
232
+ ['pdk-version', 'template-url'].any? { |key| module_metadata(module_path).key?(key) }
266
233
  end
267
234
  module_function :module_pdk_compatible?
268
235
 
@@ -279,5 +246,25 @@ module PDK
279
246
  nil
280
247
  end
281
248
  module_function :module_pdk_version
249
+
250
+ # Does a deep copy instead of a shallow copy of an object.
251
+ #
252
+ # @param object [Object] The object to duplicate
253
+ #
254
+ # @return [Object] duplicate of the original object
255
+ # the current working dir does not appear to be within a module.
256
+ def deep_duplicate(object)
257
+ case object
258
+ when Array
259
+ object.map { |item| deep_duplicate(item) }
260
+ when Hash
261
+ hash = object.dup
262
+ hash.each_pair { |key, value| hash[key] = deep_duplicate(value) }
263
+ hash
264
+ else
265
+ object
266
+ end
267
+ end
268
+ module_function :deep_duplicate
282
269
  end
283
270
  end
@@ -0,0 +1,23 @@
1
+ require 'pdk'
2
+
3
+ module PDK
4
+ module Validate
5
+ module ControlRepo
6
+ class ControlRepoValidatorGroup < ValidatorGroup
7
+ def name
8
+ 'control-repo'
9
+ end
10
+
11
+ def valid_in_context?
12
+ context.is_a?(PDK::Context::ControlRepo)
13
+ end
14
+
15
+ def validators
16
+ [
17
+ EnvironmentConfValidator
18
+ ].freeze
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,98 @@
1
+ require 'pdk'
2
+
3
+ module PDK
4
+ module Validate
5
+ module ControlRepo
6
+ class EnvironmentConfValidator < InternalRubyValidator
7
+ ALLOWED_SETTINGS = ['modulepath', 'manifest', 'config_version', 'environment_timeout'].freeze
8
+
9
+ def name
10
+ 'environment-conf'
11
+ end
12
+
13
+ def valid_in_context?
14
+ context.is_a?(PDK::Context::ControlRepo)
15
+ end
16
+
17
+ def pattern
18
+ ['environment.conf']
19
+ end
20
+
21
+ def spinner_text
22
+ format('Checking Puppet Environment settings (%{patterns}).', patterns: pattern.join(' '))
23
+ end
24
+
25
+ def validate_target(report, target)
26
+ unless PDK::Util::Filesystem.readable?(target)
27
+ report.add_event(
28
+ file: target,
29
+ source: name,
30
+ state: :failure,
31
+ severity: 'error',
32
+ message: 'Could not be read.'
33
+ )
34
+ return 1
35
+ end
36
+
37
+ is_valid = true
38
+ begin
39
+ env_conf = PDK::ControlRepo.environment_conf_as_config(target)
40
+
41
+ env_conf.resolve.each do |setting_name, setting_value|
42
+ # Remove the 'environment.' setting_name prefix
43
+ setting_name = setting_name.slice(12..-1)
44
+ next if ALLOWED_SETTINGS.include?(setting_name)
45
+
46
+ # A hash indicates that the ini file has a section in it.
47
+ message = if setting_value.is_a?(Hash)
48
+ format("Invalid section '%{name}'", name: setting_name)
49
+ else
50
+ format("Invalid setting '%{name}'", name: setting_name)
51
+ end
52
+
53
+ report.add_event(
54
+ file: target,
55
+ source: name,
56
+ state: :failure,
57
+ severity: 'error',
58
+ message: message
59
+ )
60
+ is_valid = false
61
+ end
62
+
63
+ timeout = env_conf.fetch('environment_timeout', nil)
64
+ unless timeout.nil? || timeout == '0' || timeout == 'unlimited'
65
+ report.add_event(
66
+ file: target,
67
+ source: name,
68
+ state: :failure,
69
+ severity: 'error',
70
+ message: format("environment_timeout is set to '%{timeout}' but should be 0, 'unlimited' or not set.", timeout: timeout)
71
+ )
72
+ is_valid = false
73
+ end
74
+
75
+ return 1 unless is_valid
76
+
77
+ report.add_event(
78
+ file: target,
79
+ source: name,
80
+ state: :passed,
81
+ severity: 'ok'
82
+ )
83
+ 0
84
+ rescue StandardError => e
85
+ report.add_event(
86
+ file: target,
87
+ source: name,
88
+ state: :failure,
89
+ severity: 'error',
90
+ message: e.message
91
+ )
92
+ 1
93
+ end
94
+ end
95
+ end
96
+ end
97
+ end
98
+ end