pdk 1.9.0 → 3.2.0

Sign up to get free protection for your applications and to get access to all the features.
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