pdk 2.3.0 → 2.4.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 (153) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +1329 -1321
  3. data/LICENSE +201 -201
  4. data/README.md +163 -163
  5. data/exe/pdk +10 -10
  6. data/lib/pdk/analytics/client/google_analytics.rb +143 -143
  7. data/lib/pdk/analytics/client/noop.rb +25 -25
  8. data/lib/pdk/analytics/util.rb +19 -19
  9. data/lib/pdk/analytics.rb +30 -30
  10. data/lib/pdk/answer_file.rb +12 -12
  11. data/lib/pdk/bolt.rb +19 -19
  12. data/lib/pdk/cli/build.rb +82 -82
  13. data/lib/pdk/cli/bundle.rb +48 -48
  14. data/lib/pdk/cli/config/get.rb +26 -26
  15. data/lib/pdk/cli/config.rb +22 -22
  16. data/lib/pdk/cli/console.rb +148 -148
  17. data/lib/pdk/cli/convert.rb +52 -52
  18. data/lib/pdk/cli/env.rb +52 -52
  19. data/lib/pdk/cli/errors.rb +25 -25
  20. data/lib/pdk/cli/exec/command.rb +293 -293
  21. data/lib/pdk/cli/exec/interactive_command.rb +114 -114
  22. data/lib/pdk/cli/exec.rb +84 -84
  23. data/lib/pdk/cli/exec_group.rb +104 -104
  24. data/lib/pdk/cli/get/config.rb +24 -24
  25. data/lib/pdk/cli/get.rb +20 -20
  26. data/lib/pdk/cli/module/build.rb +12 -12
  27. data/lib/pdk/cli/module/generate.rb +47 -47
  28. data/lib/pdk/cli/module.rb +14 -14
  29. data/lib/pdk/cli/new/class.rb +32 -32
  30. data/lib/pdk/cli/new/defined_type.rb +32 -32
  31. data/lib/pdk/cli/new/fact.rb +29 -29
  32. data/lib/pdk/cli/new/function.rb +29 -29
  33. data/lib/pdk/cli/new/module.rb +53 -53
  34. data/lib/pdk/cli/new/provider.rb +29 -29
  35. data/lib/pdk/cli/new/task.rb +34 -34
  36. data/lib/pdk/cli/new/test.rb +52 -52
  37. data/lib/pdk/cli/new/transport.rb +27 -27
  38. data/lib/pdk/cli/new.rb +21 -21
  39. data/lib/pdk/cli/release/prep.rb +39 -39
  40. data/lib/pdk/cli/release/publish.rb +50 -50
  41. data/lib/pdk/cli/release.rb +194 -194
  42. data/lib/pdk/cli/remove/config.rb +80 -80
  43. data/lib/pdk/cli/remove.rb +20 -20
  44. data/lib/pdk/cli/set/config.rb +119 -119
  45. data/lib/pdk/cli/set.rb +20 -20
  46. data/lib/pdk/cli/test/unit.rb +90 -90
  47. data/lib/pdk/cli/test.rb +11 -11
  48. data/lib/pdk/cli/update.rb +64 -64
  49. data/lib/pdk/cli/util/command_redirector.rb +27 -27
  50. data/lib/pdk/cli/util/interview.rb +72 -72
  51. data/lib/pdk/cli/util/option_normalizer.rb +55 -55
  52. data/lib/pdk/cli/util/option_validator.rb +68 -68
  53. data/lib/pdk/cli/util/spinner.rb +13 -13
  54. data/lib/pdk/cli/util/update_manager_printer.rb +82 -82
  55. data/lib/pdk/cli/util.rb +305 -305
  56. data/lib/pdk/cli/validate.rb +116 -116
  57. data/lib/pdk/cli.rb +175 -175
  58. data/lib/pdk/config/analytics_schema.json +26 -26
  59. data/lib/pdk/config/errors.rb +5 -5
  60. data/lib/pdk/config/ini_file.rb +183 -183
  61. data/lib/pdk/config/ini_file_setting.rb +39 -39
  62. data/lib/pdk/config/json.rb +34 -34
  63. data/lib/pdk/config/json_schema_namespace.rb +142 -142
  64. data/lib/pdk/config/json_schema_setting.rb +53 -53
  65. data/lib/pdk/config/json_with_schema.rb +49 -49
  66. data/lib/pdk/config/namespace.rb +354 -354
  67. data/lib/pdk/config/setting.rb +135 -135
  68. data/lib/pdk/config/validator.rb +31 -31
  69. data/lib/pdk/config/yaml.rb +46 -46
  70. data/lib/pdk/config/yaml_with_schema.rb +59 -59
  71. data/lib/pdk/config.rb +390 -390
  72. data/lib/pdk/context/control_repo.rb +60 -60
  73. data/lib/pdk/context/module.rb +28 -28
  74. data/lib/pdk/context/none.rb +22 -22
  75. data/lib/pdk/context.rb +99 -99
  76. data/lib/pdk/control_repo.rb +90 -90
  77. data/lib/pdk/generate/defined_type.rb +43 -43
  78. data/lib/pdk/generate/fact.rb +25 -25
  79. data/lib/pdk/generate/function.rb +48 -48
  80. data/lib/pdk/generate/module.rb +352 -352
  81. data/lib/pdk/generate/provider.rb +28 -28
  82. data/lib/pdk/generate/puppet_class.rb +43 -43
  83. data/lib/pdk/generate/puppet_object.rb +232 -232
  84. data/lib/pdk/generate/task.rb +68 -68
  85. data/lib/pdk/generate/transport.rb +33 -33
  86. data/lib/pdk/generate.rb +24 -24
  87. data/lib/pdk/i18n.rb +4 -4
  88. data/lib/pdk/logger.rb +45 -45
  89. data/lib/pdk/module/build.rb +322 -322
  90. data/lib/pdk/module/convert.rb +296 -296
  91. data/lib/pdk/module/metadata.rb +202 -202
  92. data/lib/pdk/module/release.rb +260 -260
  93. data/lib/pdk/module/update.rb +131 -131
  94. data/lib/pdk/module/update_manager.rb +227 -227
  95. data/lib/pdk/module.rb +30 -30
  96. data/lib/pdk/report/event.rb +370 -370
  97. data/lib/pdk/report.rb +121 -121
  98. data/lib/pdk/template/fetcher/git.rb +85 -85
  99. data/lib/pdk/template/fetcher/local.rb +28 -28
  100. data/lib/pdk/template/fetcher.rb +98 -98
  101. data/lib/pdk/template/renderer/v1/legacy_template_dir.rb +116 -116
  102. data/lib/pdk/template/renderer/v1/renderer.rb +132 -132
  103. data/lib/pdk/template/renderer/v1/template_file.rb +102 -102
  104. data/lib/pdk/template/renderer/v1.rb +25 -25
  105. data/lib/pdk/template/renderer.rb +96 -96
  106. data/lib/pdk/template/template_dir.rb +67 -67
  107. data/lib/pdk/template.rb +59 -59
  108. data/lib/pdk/tests/unit.rb +252 -252
  109. data/lib/pdk/util/bundler.rb +259 -259
  110. data/lib/pdk/util/changelog_generator.rb +137 -137
  111. data/lib/pdk/util/env.rb +47 -47
  112. data/lib/pdk/util/filesystem.rb +138 -138
  113. data/lib/pdk/util/git.rb +179 -179
  114. data/lib/pdk/util/json_finder.rb +85 -85
  115. data/lib/pdk/util/puppet_strings.rb +125 -125
  116. data/lib/pdk/util/puppet_version.rb +266 -266
  117. data/lib/pdk/util/ruby_version.rb +179 -179
  118. data/lib/pdk/util/template_uri.rb +295 -295
  119. data/lib/pdk/util/vendored_file.rb +93 -93
  120. data/lib/pdk/util/version.rb +43 -43
  121. data/lib/pdk/util/windows/api_types.rb +82 -82
  122. data/lib/pdk/util/windows/file.rb +36 -36
  123. data/lib/pdk/util/windows/process.rb +79 -79
  124. data/lib/pdk/util/windows/string.rb +16 -16
  125. data/lib/pdk/util/windows.rb +15 -15
  126. data/lib/pdk/util.rb +278 -277
  127. data/lib/pdk/validate/control_repo/control_repo_validator_group.rb +23 -23
  128. data/lib/pdk/validate/control_repo/environment_conf_validator.rb +98 -98
  129. data/lib/pdk/validate/external_command_validator.rb +208 -208
  130. data/lib/pdk/validate/internal_ruby_validator.rb +100 -100
  131. data/lib/pdk/validate/invokable_validator.rb +228 -228
  132. data/lib/pdk/validate/metadata/metadata_json_lint_validator.rb +86 -86
  133. data/lib/pdk/validate/metadata/metadata_syntax_validator.rb +78 -78
  134. data/lib/pdk/validate/metadata/metadata_validator_group.rb +20 -20
  135. data/lib/pdk/validate/puppet/puppet_epp_validator.rb +133 -133
  136. data/lib/pdk/validate/puppet/puppet_lint_validator.rb +66 -66
  137. data/lib/pdk/validate/puppet/puppet_syntax_validator.rb +137 -137
  138. data/lib/pdk/validate/puppet/puppet_validator_group.rb +21 -21
  139. data/lib/pdk/validate/ruby/ruby_rubocop_validator.rb +80 -80
  140. data/lib/pdk/validate/ruby/ruby_validator_group.rb +19 -19
  141. data/lib/pdk/validate/tasks/tasks_metadata_lint_validator.rb +88 -88
  142. data/lib/pdk/validate/tasks/tasks_name_validator.rb +50 -50
  143. data/lib/pdk/validate/tasks/tasks_validator_group.rb +20 -20
  144. data/lib/pdk/validate/validator.rb +118 -118
  145. data/lib/pdk/validate/validator_group.rb +104 -104
  146. data/lib/pdk/validate/yaml/yaml_syntax_validator.rb +95 -95
  147. data/lib/pdk/validate/yaml/yaml_validator_group.rb +19 -19
  148. data/lib/pdk/validate.rb +94 -94
  149. data/lib/pdk/version.rb +4 -4
  150. data/lib/pdk.rb +76 -76
  151. data/locales/config.yaml +21 -21
  152. data/locales/pdk.pot +2094 -2094
  153. metadata +5 -6
@@ -1,16 +1,16 @@
1
- require 'pdk/util/windows'
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 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')
14
- end
15
- module_function :wide_string
16
- end
1
+ require 'pdk/util/windows'
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 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')
14
+ end
15
+ module_function :wide_string
16
+ end
@@ -1,15 +1,15 @@
1
- module PDK
2
- module Util
3
- module Windows
4
- WIN32_FALSE = 0
5
- module File; end
6
-
7
- if Gem.win_platform?
8
- require 'pdk/util/windows/api_types'
9
- require 'pdk/util/windows/string'
10
- require 'pdk/util/windows/file'
11
- require 'pdk/util/windows/process'
12
- end
13
- end
14
- end
15
- end
1
+ module PDK
2
+ module Util
3
+ module Windows
4
+ WIN32_FALSE = 0
5
+ module File; end
6
+
7
+ if Gem.win_platform?
8
+ require 'pdk/util/windows/api_types'
9
+ require 'pdk/util/windows/string'
10
+ require 'pdk/util/windows/file'
11
+ require 'pdk/util/windows/process'
12
+ end
13
+ end
14
+ end
15
+ end
data/lib/pdk/util.rb CHANGED
@@ -1,277 +1,278 @@
1
- require 'pdk'
2
-
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.
6
- require 'pdk/util/windows'
7
-
8
- autoload :Pathname, 'pathname'
9
-
10
- module PDK
11
- module Util
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 = %w[
26
- manifests
27
- lib/puppet
28
- lib/puppet_x
29
- lib/facter
30
- tasks
31
- facts.d
32
- functions
33
- types
34
- ].freeze
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
-
46
- # Searches upwards from current working directory for the given target file.
47
- #
48
- # @param target [String] Name of file to search for.
49
- # @param start_dir [String] Directory to start searching from, defaults to Dir.pwd
50
- #
51
- # @return [String, nil] Fully qualified path to the given target file if found,
52
- # nil if the target file could not be found.
53
- def find_upwards(target, start_dir = nil)
54
- previous = nil
55
- current = PDK::Util::Filesystem.expand_path(start_dir || Dir.pwd)
56
-
57
- until !PDK::Util::Filesystem.directory?(current) || current == previous
58
- filename = File.join(current, target)
59
- return filename if PDK::Util::Filesystem.file?(filename)
60
- previous = current
61
- current = PDK::Util::Filesystem.expand_path('..', current)
62
- end
63
- end
64
- module_function :find_upwards
65
-
66
- # Generate a name for a temporary directory.
67
- #
68
- # @param base [String] A string to base the name generation off.
69
- #
70
- # @return [String] The temporary directory path.
71
- def make_tmpdir_name(base)
72
- require 'tmpdir'
73
-
74
- t = Time.now.strftime('%Y%m%d')
75
- name = "#{base}#{t}-#{Process.pid}-#{rand(0x100000000).to_s(36)}"
76
- File.join(Dir.tmpdir, name)
77
- end
78
- module_function :make_tmpdir_name
79
-
80
- # Return an expanded, absolute path
81
- #
82
- # @param path [String] Existing path that may not be canonical
83
- #
84
- # @return [String] Canonical path
85
- def canonical_path(path)
86
- if Gem.win_platform?
87
- unless PDK::Util::Filesystem.exist?(path)
88
- raise PDK::CLI::FatalError, _("Cannot resolve a full path to '%{path}', as it does not currently exist.") % { path: path }
89
- end
90
- PDK::Util::Windows::File.get_long_pathname(path)
91
- else
92
- PDK::Util::Filesystem.expand_path(path)
93
- end
94
- end
95
- module_function :canonical_path
96
-
97
- def package_install?
98
- require 'pdk/util/version'
99
-
100
- !PDK::Util::Version.version_file.nil?
101
- end
102
- module_function :package_install?
103
-
104
- def development_mode?
105
- require 'pdk/util/version'
106
-
107
- (!PDK::Util::Version.git_ref.nil? || PDK::VERSION.end_with?('.pre'))
108
- end
109
- module_function :development_mode?
110
-
111
- def gem_install?
112
- !(package_install? || development_mode?)
113
- end
114
- module_function :gem_install?
115
-
116
- def pdk_package_basedir
117
- raise PDK::CLI::FatalError, _('Package basedir requested for non-package install.') unless package_install?
118
- require 'pdk/util/version'
119
-
120
- File.dirname(PDK::Util::Version.version_file)
121
- end
122
- module_function :pdk_package_basedir
123
-
124
- def package_cachedir
125
- File.join(pdk_package_basedir, 'share', 'cache')
126
- end
127
- module_function :package_cachedir
128
-
129
- # Returns the fully qualified path to a per-user PDK cachedir.
130
- #
131
- # @return [String] Fully qualified path to per-user PDK cachedir.
132
- def cachedir
133
- if Gem.win_platform?
134
- File.join(PDK::Util::Env['LOCALAPPDATA'], 'PDK', 'cache')
135
- else
136
- File.join(Dir.home, '.pdk', 'cache')
137
- end
138
- end
139
- module_function :cachedir
140
-
141
- def configdir
142
- if Gem.win_platform?
143
- File.join(PDK::Util::Env['LOCALAPPDATA'], 'PDK')
144
- else
145
- File.join(PDK::Util::Env.fetch('XDG_CONFIG_HOME', File.join(Dir.home, '.config')), 'pdk')
146
- end
147
- end
148
- module_function :configdir
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
-
159
- # Returns path to the root of the module being worked on.
160
- #
161
- # @return [String, nil] Fully qualified base path to module, or nil if
162
- # the current working dir does not appear to be within a module.
163
- def module_root
164
- metadata_path = find_upwards('metadata.json')
165
- if metadata_path
166
- File.dirname(metadata_path)
167
- elsif in_module_root?
168
- Dir.pwd
169
- else
170
- nil
171
- end
172
- end
173
- module_function :module_root
174
-
175
- # The module's fixtures directory for spec testing
176
- # @return [String] - the path to the module's fixtures directory
177
- def module_fixtures_dir
178
- dir = module_root
179
- File.join(module_root, 'spec', 'fixtures') unless dir.nil?
180
- end
181
- module_function :module_fixtures_dir
182
-
183
- # Returns true or false depending on if any of the common directories in a module
184
- # are found in the specified directory. If a directory is not specified, the current
185
- # working directory is used.
186
- #
187
- # @return [boolean] True if any folders from MODULE_FOLDERS are found in the current dir,
188
- # false otherwise.
189
- def in_module_root?(path = Dir.pwd)
190
- PDK::Util::MODULE_FOLDERS.any? { |dir| PDK::Util::Filesystem.directory?(File.join(path, dir)) }
191
- end
192
- module_function :in_module_root?
193
-
194
- # Iterate through possible JSON documents until we find one that is valid.
195
- #
196
- # @param [String] text the text in which to find a JSON document
197
- # @return [Hash, nil] subset of text as Hash of first valid JSON found, or nil if no valid
198
- # JSON found in the text
199
- def find_first_json_in(text)
200
- find_all_json_in(text).first
201
- end
202
- module_function :find_first_json_in
203
-
204
- # Iterate through possible JSON documents for all valid JSON
205
- #
206
- # @param [String] text the text in which to find JSON document(s)
207
- # @return [Array<Hash>] subset of text as Array of all JSON object found, empty Array if none are found
208
- # JSON found in the text
209
- def find_all_json_in(text)
210
- PDK::Util::JSONFinder.new(text).objects
211
- end
212
- module_function :find_all_json_in
213
-
214
- # Returns the targets' paths relative to the working directory
215
- #
216
- # @return [Array<String>] The absolute or path to the target
217
- def targets_relative_to_pwd(targets)
218
- targets.map do |t|
219
- if Pathname.new(t).absolute?
220
- Pathname.new(t).relative_path_from(Pathname.pwd)
221
- else
222
- t
223
- end
224
- end
225
- end
226
- module_function :targets_relative_to_pwd
227
-
228
- # TO-DO: Refactor replacement of lib/pdk/module/build.rb:metadata to use this function instead
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)
231
- require 'pdk/module/metadata'
232
- module_path ||= module_root
233
- PDK::Module::Metadata.from_file(File.join(module_path, 'metadata.json')).data
234
- end
235
- module_function :module_metadata
236
-
237
- # TO-DO: Refactor replacement of lib/pdk/module/build.rb:module_pdk_compatible? to use this function instead
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) }
241
- end
242
- module_function :module_pdk_compatible?
243
-
244
- def module_pdk_version
245
- metadata = module_metadata
246
-
247
- if metadata.nil? || metadata.fetch('pdk-version', nil).nil?
248
- nil
249
- else
250
- metadata['pdk-version'].split.first
251
- end
252
- rescue ArgumentError => e
253
- PDK.logger.error(e)
254
- nil
255
- end
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
276
- end
277
- end
1
+ require 'pdk'
2
+
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.
6
+ require 'pdk/util/windows'
7
+
8
+ autoload :Pathname, 'pathname'
9
+
10
+ module PDK
11
+ module Util
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 = %w[
26
+ manifests
27
+ lib/puppet
28
+ lib/puppet_x
29
+ lib/facter
30
+ tasks
31
+ facts.d
32
+ functions
33
+ types
34
+ ].freeze
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
+
46
+ # Searches upwards from current working directory for the given target file.
47
+ #
48
+ # @param target [String] Name of file to search for.
49
+ # @param start_dir [String] Directory to start searching from, defaults to Dir.pwd
50
+ #
51
+ # @return [String, nil] Fully qualified path to the given target file if found,
52
+ # nil if the target file could not be found.
53
+ def find_upwards(target, start_dir = nil)
54
+ previous = nil
55
+ current = PDK::Util::Filesystem.expand_path(start_dir || Dir.pwd)
56
+
57
+ until !PDK::Util::Filesystem.directory?(current) || current == previous
58
+ filename = File.join(current, target)
59
+ return filename if PDK::Util::Filesystem.file?(filename)
60
+ previous = current
61
+ current = PDK::Util::Filesystem.expand_path('..', current)
62
+ end
63
+ end
64
+ module_function :find_upwards
65
+
66
+ # Generate a name for a temporary directory.
67
+ #
68
+ # @param base [String] A string to base the name generation off.
69
+ #
70
+ # @return [String] The temporary directory path.
71
+ def make_tmpdir_name(base)
72
+ require 'tmpdir'
73
+
74
+ t = Time.now.strftime('%Y%m%d')
75
+ name = "#{base}#{t}-#{Process.pid}-#{rand(0x100000000).to_s(36)}"
76
+ File.join(Dir.tmpdir, name)
77
+ end
78
+ module_function :make_tmpdir_name
79
+
80
+ # Return an expanded, absolute path
81
+ #
82
+ # @param path [String] Existing path that may not be canonical
83
+ #
84
+ # @return [String] Canonical path
85
+ def canonical_path(path)
86
+ if Gem.win_platform?
87
+ unless PDK::Util::Filesystem.exist?(path)
88
+ raise PDK::CLI::FatalError, _("Cannot resolve a full path to '%{path}', as it does not currently exist.") % { path: path }
89
+ end
90
+ PDK::Util::Windows::File.get_long_pathname(path)
91
+ else
92
+ PDK::Util::Filesystem.expand_path(path)
93
+ end
94
+ end
95
+ module_function :canonical_path
96
+
97
+ def package_install?
98
+ require 'pdk/util/version'
99
+
100
+ !PDK::Util::Version.version_file.nil?
101
+ end
102
+ module_function :package_install?
103
+
104
+ def development_mode?
105
+ require 'pdk/util/version'
106
+
107
+ (!PDK::Util::Version.git_ref.nil? || PDK::VERSION.end_with?('.pre'))
108
+ end
109
+ module_function :development_mode?
110
+
111
+ def gem_install?
112
+ !(package_install? || development_mode?)
113
+ end
114
+ module_function :gem_install?
115
+
116
+ def pdk_package_basedir
117
+ raise PDK::CLI::FatalError, _('Package basedir requested for non-package install.') unless package_install?
118
+ require 'pdk/util/version'
119
+
120
+ File.dirname(PDK::Util::Version.version_file)
121
+ end
122
+ module_function :pdk_package_basedir
123
+
124
+ def package_cachedir
125
+ File.join(pdk_package_basedir, 'share', 'cache')
126
+ end
127
+ module_function :package_cachedir
128
+
129
+ # Returns the fully qualified path to a per-user PDK cachedir.
130
+ #
131
+ # @return [String] Fully qualified path to per-user PDK cachedir.
132
+ def cachedir
133
+ if Gem.win_platform?
134
+ File.join(PDK::Util::Env['LOCALAPPDATA'], 'PDK', 'cache')
135
+ else
136
+ File.join(Dir.home, '.pdk', 'cache')
137
+ end
138
+ end
139
+ module_function :cachedir
140
+
141
+ def configdir
142
+ if Gem.win_platform?
143
+ File.join(PDK::Util::Env['LOCALAPPDATA'], 'PDK')
144
+ else
145
+ File.join(PDK::Util::Env.fetch('XDG_CONFIG_HOME', File.join(Dir.home, '.config')), 'pdk')
146
+ end
147
+ end
148
+ module_function :configdir
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
+
159
+ # Returns path to the root of the module being worked on.
160
+ #
161
+ # @return [String, nil] Fully qualified base path to module, or nil if
162
+ # the current working dir does not appear to be within a module.
163
+ def module_root
164
+ metadata_path = find_upwards('metadata.json')
165
+ if metadata_path
166
+ File.dirname(metadata_path)
167
+ elsif in_module_root?
168
+ Dir.pwd
169
+ else
170
+ nil
171
+ end
172
+ end
173
+ module_function :module_root
174
+
175
+ # The module's fixtures directory for spec testing
176
+ # @return [String] - the path to the module's fixtures directory
177
+ def module_fixtures_dir
178
+ dir = module_root
179
+ File.join(module_root, 'spec', 'fixtures') unless dir.nil?
180
+ end
181
+ module_function :module_fixtures_dir
182
+
183
+ # Returns true or false depending on if any of the common directories in a module
184
+ # are found in the specified directory. If a directory is not specified, the current
185
+ # working directory is used.
186
+ #
187
+ # @return [boolean] True if any folders from MODULE_FOLDERS are found in the current dir,
188
+ # false otherwise.
189
+ def in_module_root?(path = Dir.pwd)
190
+ PDK::Util::MODULE_FOLDERS.any? { |dir| PDK::Util::Filesystem.directory?(File.join(path, dir)) } ||
191
+ PDK::Util::Filesystem.file?(File.join(path, 'metadata.json'))
192
+ end
193
+ module_function :in_module_root?
194
+
195
+ # Iterate through possible JSON documents until we find one that is valid.
196
+ #
197
+ # @param [String] text the text in which to find a JSON document
198
+ # @return [Hash, nil] subset of text as Hash of first valid JSON found, or nil if no valid
199
+ # JSON found in the text
200
+ def find_first_json_in(text)
201
+ find_all_json_in(text).first
202
+ end
203
+ module_function :find_first_json_in
204
+
205
+ # Iterate through possible JSON documents for all valid JSON
206
+ #
207
+ # @param [String] text the text in which to find JSON document(s)
208
+ # @return [Array<Hash>] subset of text as Array of all JSON object found, empty Array if none are found
209
+ # JSON found in the text
210
+ def find_all_json_in(text)
211
+ PDK::Util::JSONFinder.new(text).objects
212
+ end
213
+ module_function :find_all_json_in
214
+
215
+ # Returns the targets' paths relative to the working directory
216
+ #
217
+ # @return [Array<String>] The absolute or path to the target
218
+ def targets_relative_to_pwd(targets)
219
+ targets.map do |t|
220
+ if Pathname.new(t).absolute?
221
+ Pathname.new(t).relative_path_from(Pathname.pwd)
222
+ else
223
+ t
224
+ end
225
+ end
226
+ end
227
+ module_function :targets_relative_to_pwd
228
+
229
+ # TO-DO: Refactor replacement of lib/pdk/module/build.rb:metadata to use this function instead
230
+ # @param module_path [String] The path to the root of the module. Default is determine the module root automatically
231
+ def module_metadata(module_path = nil)
232
+ require 'pdk/module/metadata'
233
+ module_path ||= module_root
234
+ PDK::Module::Metadata.from_file(File.join(module_path, 'metadata.json')).data
235
+ end
236
+ module_function :module_metadata
237
+
238
+ # TO-DO: Refactor replacement of lib/pdk/module/build.rb:module_pdk_compatible? to use this function instead
239
+ # @param module_path [String] The path to the root of the module. Default is determine the module root automatically
240
+ def module_pdk_compatible?(module_path = nil)
241
+ ['pdk-version', 'template-url'].any? { |key| module_metadata(module_path).key?(key) }
242
+ end
243
+ module_function :module_pdk_compatible?
244
+
245
+ def module_pdk_version
246
+ metadata = module_metadata
247
+
248
+ if metadata.nil? || metadata.fetch('pdk-version', nil).nil?
249
+ nil
250
+ else
251
+ metadata['pdk-version'].split.first
252
+ end
253
+ rescue ArgumentError => e
254
+ PDK.logger.error(e)
255
+ nil
256
+ end
257
+ module_function :module_pdk_version
258
+
259
+ # Does a deep copy instead of a shallow copy of an object.
260
+ #
261
+ # @param object [Object] The object to duplicate
262
+ #
263
+ # @return [Object] duplicate of the original object
264
+ # the current working dir does not appear to be within a module.
265
+ def deep_duplicate(object)
266
+ if object.is_a?(Array)
267
+ object.map { |item| deep_duplicate(item) }
268
+ elsif object.is_a?(Hash)
269
+ hash = object.dup
270
+ hash.each_pair { |key, value| hash[key] = deep_duplicate(value) }
271
+ hash
272
+ else
273
+ object
274
+ end
275
+ end
276
+ module_function :deep_duplicate
277
+ end
278
+ end