pdk 3.0.1 → 3.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (48) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +37 -1
  3. data/lib/pdk/cli/build.rb +6 -5
  4. data/lib/pdk/cli/bundle.rb +0 -2
  5. data/lib/pdk/cli/console.rb +0 -2
  6. data/lib/pdk/cli/convert.rb +3 -3
  7. data/lib/pdk/cli/env.rb +0 -2
  8. data/lib/pdk/cli/exec/command.rb +0 -2
  9. data/lib/pdk/cli/new/class.rb +0 -2
  10. data/lib/pdk/cli/new/defined_type.rb +0 -2
  11. data/lib/pdk/cli/new/fact.rb +0 -2
  12. data/lib/pdk/cli/new/function.rb +0 -2
  13. data/lib/pdk/cli/new/module.rb +0 -2
  14. data/lib/pdk/cli/new/provider.rb +0 -2
  15. data/lib/pdk/cli/new/task.rb +0 -2
  16. data/lib/pdk/cli/new/test.rb +0 -2
  17. data/lib/pdk/cli/release/prep.rb +0 -2
  18. data/lib/pdk/cli/release/publish.rb +0 -2
  19. data/lib/pdk/cli/release.rb +0 -9
  20. data/lib/pdk/cli/test/unit.rb +0 -2
  21. data/lib/pdk/cli/update.rb +3 -3
  22. data/lib/pdk/cli/util.rb +0 -38
  23. data/lib/pdk/cli/validate.rb +0 -7
  24. data/lib/pdk/cli.rb +0 -2
  25. data/lib/pdk/config/namespace.rb +3 -3
  26. data/lib/pdk/config/setting.rb +3 -3
  27. data/lib/pdk/config.rb +0 -80
  28. data/lib/pdk/module/convert.rb +8 -3
  29. data/lib/pdk/module/metadata.rb +18 -10
  30. data/lib/pdk/module/release.rb +9 -6
  31. data/lib/pdk/module/update_manager.rb +29 -3
  32. data/lib/pdk/report/event.rb +1 -1
  33. data/lib/pdk/template/renderer/v1/legacy_template_dir.rb +10 -13
  34. data/lib/pdk/template/renderer/v1/renderer.rb +3 -1
  35. data/lib/pdk/template.rb +0 -3
  36. data/lib/pdk/tests/unit.rb +3 -3
  37. data/lib/pdk/util/filesystem.rb +10 -0
  38. data/lib/pdk/util.rb +1 -0
  39. data/lib/pdk/version.rb +2 -2
  40. data/lib/pdk.rb +0 -14
  41. metadata +63 -98
  42. data/lib/pdk/analytics/client/google_analytics.rb +0 -141
  43. data/lib/pdk/analytics/client/noop.rb +0 -25
  44. data/lib/pdk/analytics/util.rb +0 -18
  45. data/lib/pdk/analytics.rb +0 -30
  46. data/lib/pdk/config/analytics_schema.json +0 -26
  47. data/lib/pdk/module/build.rb +0 -302
  48. data/lib/pdk/monkey_patches.rb +0 -268
@@ -1,302 +0,0 @@
1
- require 'pdk'
2
-
3
- module PDK
4
- module Module
5
- class Build
6
- def self.invoke(options = {})
7
- new(options).build
8
- end
9
-
10
- attr_reader :module_dir, :target_dir
11
-
12
- def initialize(options = {})
13
- @module_dir = PDK::Util::Filesystem.expand_path(options[:module_dir] || Dir.pwd)
14
- @target_dir = PDK::Util::Filesystem.expand_path(options[:'target-dir'] || File.join(module_dir, 'pkg'))
15
- end
16
-
17
- # Read and parse the values from metadata.json for the module that is
18
- # being built.
19
- #
20
- # @return [Hash{String => Object}] The hash of metadata values.
21
- def metadata
22
- require 'pdk/module/metadata'
23
-
24
- @metadata ||= PDK::Module::Metadata.from_file(File.join(module_dir, 'metadata.json')).data
25
- end
26
-
27
- # Return the path where the built package file will be written to.
28
- def package_file
29
- @package_file ||= File.join(target_dir, "#{release_name}.tar.gz")
30
- end
31
-
32
- # Build a module package from a module directory.
33
- #
34
- # @return [String] The path to the built package file.
35
- def build
36
- create_build_dir
37
-
38
- stage_module_in_build_dir
39
- build_package
40
-
41
- package_file
42
- ensure
43
- cleanup_build_dir
44
- end
45
-
46
- # Verify if there is an existing package in the target directory and prompts
47
- # the user if they want to overwrite it.
48
- def package_already_exists?
49
- PDK::Util::Filesystem.exist?(package_file)
50
- end
51
-
52
- # Check if the module is PDK Compatible. If not, then prompt the user if
53
- # they want to run PDK Convert.
54
- def module_pdk_compatible?
55
- ['pdk-version', 'template-url'].any? { |key| metadata.key?(key) }
56
- end
57
-
58
- # Return the path to the temporary build directory, which will be placed
59
- # inside the target directory and match the release name (see #release_name).
60
- def build_dir
61
- @build_dir ||= File.join(target_dir, release_name)
62
- end
63
-
64
- # Create a temporary build directory where the files to be included in
65
- # the package will be staged before building the tarball.
66
- #
67
- # If the directory already exists, remove it first.
68
- def create_build_dir
69
- cleanup_build_dir
70
-
71
- PDK::Util::Filesystem.mkdir_p(build_dir)
72
- end
73
-
74
- # Remove the temporary build directory and all its contents from disk.
75
- #
76
- # @return nil.
77
- def cleanup_build_dir
78
- PDK::Util::Filesystem.rm_rf(build_dir, secure: true)
79
- end
80
-
81
- # Combine the module name and version into a Forge-compatible dash
82
- # separated string.
83
- #
84
- # @return [String] The module name and version, joined by a dash.
85
- def release_name
86
- @release_name ||= [
87
- metadata['name'],
88
- metadata['version']
89
- ].join('-')
90
- end
91
-
92
- # Iterate through all the files and directories in the module and stage
93
- # them into the temporary build directory (unless ignored).
94
- #
95
- # @return nil
96
- def stage_module_in_build_dir
97
- require 'find'
98
-
99
- Find.find(module_dir) do |path|
100
- next if path == module_dir
101
-
102
- ignored_path?(path) ? Find.prune : stage_path(path)
103
- end
104
- end
105
-
106
- # Stage a file or directory from the module into the build directory.
107
- #
108
- # @param path [String] The path to the file or directory.
109
- #
110
- # @return nil.
111
- def stage_path(path)
112
- require 'pathname'
113
-
114
- relative_path = Pathname.new(path).relative_path_from(Pathname.new(module_dir))
115
- dest_path = File.join(build_dir, relative_path)
116
-
117
- validate_path_encoding!(relative_path.to_path)
118
-
119
- if PDK::Util::Filesystem.directory?(path)
120
- PDK::Util::Filesystem.mkdir_p(dest_path, mode: PDK::Util::Filesystem.stat(path).mode)
121
- elsif PDK::Util::Filesystem.symlink?(path)
122
- warn_symlink(path)
123
- else
124
- validate_ustar_path!(relative_path.to_path)
125
- PDK::Util::Filesystem.cp(path, dest_path, preserve: true)
126
- end
127
- rescue ArgumentError => e
128
- raise PDK::CLI::ExitWithError, format('%{message} Rename the file or exclude it from the package ' \
129
- 'by adding it to the .pdkignore file in your module.', message: e.message)
130
- end
131
-
132
- # Check if the given path matches one of the patterns listed in the
133
- # ignore file.
134
- #
135
- # @param path [String] The path to be checked.
136
- #
137
- # @return [Boolean] true if the path matches and should be ignored.
138
- def ignored_path?(path)
139
- path = "#{path}/" if PDK::Util::Filesystem.directory?(path)
140
-
141
- !ignored_files.match_paths([path], module_dir).empty?
142
- end
143
-
144
- # Warn the user about a symlink that would have been included in the
145
- # built package.
146
- #
147
- # @param path [String] The relative or absolute path to the symlink.
148
- #
149
- # @return nil.
150
- def warn_symlink(path)
151
- require 'pathname'
152
-
153
- symlink_path = Pathname.new(path)
154
- module_path = Pathname.new(module_dir)
155
-
156
- PDK.logger.warn format('Symlinks in modules are not supported and will not be included in the package. Please investigate symlink %{from} -> %{to}.',
157
- from: symlink_path.relative_path_from(module_path), to: symlink_path.realpath.relative_path_from(module_path))
158
- end
159
-
160
- # Checks if the path length will fit into the POSIX.1-1998 (ustar) tar
161
- # header format.
162
- #
163
- # POSIX.1-2001 (which allows paths of infinite length) was adopted by GNU
164
- # tar in 2004 and is supported by minitar 0.7 and above. Unfortunately
165
- # much of the Puppet ecosystem still uses minitar 0.6.1.
166
- #
167
- # POSIX.1-1998 tar format does not allow for paths greater than 256 bytes,
168
- # or paths that can't be split into a prefix of 155 bytes (max) and
169
- # a suffix of 100 bytes (max).
170
- #
171
- # This logic was pretty much copied from the private method
172
- # {Archive::Tar::Minitar::Writer#split_name}.
173
- #
174
- # @param path [String] the relative path to be added to the tar file.
175
- #
176
- # @raise [ArgumentError] if the path is too long or could not be split.
177
- #
178
- # @return [nil]
179
- def validate_ustar_path!(path)
180
- raise ArgumentError, format("The path '%{path}' is longer than 256 bytes.", path: path) if path.bytesize > 256
181
-
182
- if path.bytesize <= 100
183
- prefix = ''
184
- else
185
- parts = path.split(File::SEPARATOR)
186
- newpath = parts.pop
187
- nxt = ''
188
-
189
- loop do
190
- nxt = parts.pop || ''
191
- break if newpath.bytesize + 1 + nxt.bytesize >= 100
192
-
193
- newpath = File.join(nxt, newpath)
194
- end
195
-
196
- prefix = File.join(*parts, nxt)
197
- path = newpath
198
- end
199
-
200
- return unless path.bytesize > 100 || prefix.bytesize > 155
201
-
202
- raise ArgumentError,
203
- format("'%{path}' could not be split at a directory separator into two " \
204
- 'parts, the first having a maximum length of 155 bytes and the ' \
205
- 'second having a maximum length of 100 bytes.', path: path)
206
- end
207
-
208
- # Checks if the path contains any non-ASCII characters.
209
- #
210
- # Java will throw an error when it encounters a path containing
211
- # characters that are not supported by the hosts locale. In order to
212
- # maximise compatibility we limit the paths to contain only ASCII
213
- # characters, which should be part of any locale character set.
214
- #
215
- # @param path [String] the relative path to be added to the tar file.
216
- #
217
- # @raise [ArgumentError] if the path contains non-ASCII characters.
218
- #
219
- # @return [nil]
220
- def validate_path_encoding!(path)
221
- return unless /[^\x00-\x7F]/.match?(path)
222
-
223
- raise ArgumentError, format("'%{path}' can only include ASCII characters in its path or " \
224
- 'filename in order to be compatible with a wide range of hosts.', path: path)
225
- end
226
-
227
- # Creates a gzip compressed tarball of the build directory.
228
- #
229
- # If the destination package already exists, it will be removed before
230
- # creating the new tarball.
231
- #
232
- # @return nil.
233
- def build_package
234
- require 'zlib'
235
- require 'minitar'
236
- require 'find'
237
-
238
- PDK::Util::Filesystem.rm_f(package_file)
239
-
240
- Dir.chdir(target_dir) do
241
- gz = Zlib::GzipWriter.new(File.open(package_file, 'wb')) # rubocop:disable PDK/FileOpen
242
- tar = Minitar::Output.new(gz)
243
- Find.find(release_name) do |entry|
244
- entry_meta = {
245
- name: entry
246
- }
247
-
248
- orig_mode = PDK::Util::Filesystem.stat(entry).mode
249
- min_mode = Minitar.dir?(entry) ? 0o755 : 0o644
250
-
251
- entry_meta[:mode] = orig_mode | min_mode
252
-
253
- PDK.logger.debug(format('Updated permissions of packaged \'%{entry}\' to %{new_mode}', entry: entry, new_mode: (entry_meta[:mode] & 0o7777).to_s(8))) if entry_meta[:mode] != orig_mode
254
-
255
- Minitar.pack_file(entry_meta, tar)
256
- end
257
- ensure
258
- tar.close
259
- end
260
- end
261
-
262
- # Select the most appropriate ignore file in the module directory.
263
- #
264
- # In order of preference, we first try `.pdkignore`, then `.pmtignore`
265
- # and finally `.gitignore`.
266
- #
267
- # @return [String] The path to the file containing the patterns of file
268
- # paths to ignore.
269
- def ignore_file
270
- @ignore_file ||= [
271
- File.join(module_dir, '.pdkignore'),
272
- File.join(module_dir, '.pmtignore'),
273
- File.join(module_dir, '.gitignore')
274
- ].find { |file| PDK::Util::Filesystem.file?(file) && PDK::Util::Filesystem.readable?(file) }
275
- end
276
-
277
- # Instantiate a new PathSpec class and populate it with the pattern(s) of
278
- # files to be ignored.
279
- #
280
- # @return [PathSpec] The populated ignore path matcher.
281
- def ignored_files
282
- require 'pdk/module'
283
- require 'pathspec'
284
-
285
- @ignored_files ||=
286
- begin
287
- ignored = if ignore_file.nil?
288
- PathSpec.new
289
- else
290
- PathSpec.new(PDK::Util::Filesystem.read_file(ignore_file, open_args: 'rb:UTF-8'))
291
- end
292
-
293
- ignored = ignored.add("/#{File.basename(target_dir)}/") if File.realdirpath(target_dir).start_with?(File.realdirpath(module_dir))
294
-
295
- PDK::Module::DEFAULT_IGNORED.each { |r| ignored.add(r) }
296
-
297
- ignored
298
- end
299
- end
300
- end
301
- end
302
- end
@@ -1,268 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module OS
4
- # Os detection: Are we on Windows?
5
- def self.windows?
6
- (/cygwin|mswin|mingw|bccwin|wince|emx/ =~ RUBY_PLATFORM) != nil
7
- end
8
- end
9
-
10
- # Patch childprocess so that it is Ruby 3 compliant.
11
- # This could be removed if the following PR is ever merged
12
- # and released:
13
- # https://github.com/enkessler/childprocess/pull/185
14
- module ChildProcess
15
- class << self
16
- def build(*args)
17
- case os
18
- when :macosx, :linux, :solaris, :bsd, :cygwin, :aix
19
- if posix_spawn?
20
- Unix::PosixSpawnProcess.new(*args)
21
- elsif jruby?
22
- JRuby::Process.new(*args)
23
- else
24
- Unix::ForkExecProcess.new(*args)
25
- end
26
- when :windows
27
- Windows::Process.new(*args)
28
- else
29
- raise Error, "unsupported platform #{platform_name.inspect}"
30
- end
31
- end
32
- end
33
-
34
- class AbstractProcess
35
- def initialize(*args)
36
- raise ArgumentError, "all arguments must be String: #{args.inspect}" unless args.all?(String)
37
-
38
- @args = args
39
- @started = false
40
- @exit_code = nil
41
- @io = nil
42
- @cwd = nil
43
- @detach = false
44
- @duplex = false
45
- @leader = false
46
- @environment = {}
47
- end
48
- end
49
-
50
- if OS.windows?
51
- module Windows
52
- module Lib
53
- extend FFI::Library
54
- def self.msvcrt_name
55
- RbConfig::CONFIG['RUBY_SO_NAME'][/msvc\w+/] || 'ucrtbase'
56
- end
57
-
58
- ffi_lib 'kernel32', msvcrt_name
59
- ffi_convention :stdcall
60
-
61
- # We have to redefine the function declarations so that they are available
62
- # with the patched ffi_lib.
63
- enum :wait_status, [
64
- :wait_object_0, 0, # rubocop:disable Naming/VariableNumber
65
- :wait_timeout, 0x102,
66
- :wait_abandoned, 0x80,
67
- :wait_failed, 0xFFFFFFFF
68
- ]
69
-
70
- #
71
- # BOOL WINAPI CreateProcess(
72
- # __in_opt LPCTSTR lpApplicationName,
73
- # __inout_opt LPTSTR lpCommandLine,
74
- # __in_opt LPSECURITY_ATTRIBUTES lpProcessAttributes,
75
- # __in_opt LPSECURITY_ATTRIBUTES lpThreadAttributes,
76
- # __in BOOL bInheritHandles,
77
- # __in DWORD dwCreationFlags,
78
- # __in_opt LPVOID lpEnvironment,
79
- # __in_opt LPCTSTR lpCurrentDirectory,
80
- # __in LPSTARTUPINFO lpStartupInfo,
81
- # __out LPPROCESS_INFORMATION lpProcessInformation
82
- # );
83
- #
84
-
85
- attach_function :create_process, :CreateProcessW, [
86
- :pointer,
87
- :buffer_inout,
88
- :pointer,
89
- :pointer,
90
- :bool,
91
- :ulong,
92
- :pointer,
93
- :pointer,
94
- :pointer,
95
- :pointer
96
- ], :bool
97
-
98
- #
99
- # DWORD WINAPI FormatMessage(
100
- # __in DWORD dwFlags,
101
- # __in_opt LPCVOID lpSource,
102
- # __in DWORD dwMessageId,
103
- # __in DWORD dwLanguageId,
104
- # __out LPTSTR lpBuffer,
105
- # __in DWORD nSize,
106
- # __in_opt va_list *Arguments
107
- # );
108
- #
109
-
110
- attach_function :format_message, :FormatMessageA, [
111
- :ulong,
112
- :pointer,
113
- :ulong,
114
- :ulong,
115
- :pointer,
116
- :ulong,
117
- :pointer
118
- ], :ulong
119
-
120
- attach_function :close_handle, :CloseHandle, [:pointer], :bool
121
-
122
- #
123
- # HANDLE WINAPI OpenProcess(
124
- # __in DWORD dwDesiredAccess,
125
- # __in BOOL bInheritHandle,
126
- # __in DWORD dwProcessId
127
- # );
128
- #
129
-
130
- attach_function :open_process, :OpenProcess, [:ulong, :bool, :ulong], :pointer
131
-
132
- #
133
- # HANDLE WINAPI CreateJobObject(
134
- # _In_opt_ LPSECURITY_ATTRIBUTES lpJobAttributes,
135
- # _In_opt_ LPCTSTR lpName
136
- # );
137
- #
138
-
139
- attach_function :create_job_object, :CreateJobObjectA, [:pointer, :pointer], :pointer
140
-
141
- #
142
- # BOOL WINAPI AssignProcessToJobObject(
143
- # _In_ HANDLE hJob,
144
- # _In_ HANDLE hProcess
145
- # );
146
-
147
- attach_function :assign_process_to_job_object, :AssignProcessToJobObject, [:pointer, :pointer], :bool
148
-
149
- #
150
- # BOOL WINAPI SetInformationJobObject(
151
- # _In_ HANDLE hJob,
152
- # _In_ JOBOBJECTINFOCLASS JobObjectInfoClass,
153
- # _In_ LPVOID lpJobObjectInfo,
154
- # _In_ DWORD cbJobObjectInfoLength
155
- # );
156
- #
157
-
158
- attach_function :set_information_job_object, :SetInformationJobObject, [:pointer, :int, :pointer, :ulong], :bool
159
-
160
- #
161
- #
162
- # DWORD WINAPI WaitForSingleObject(
163
- # __in HANDLE hHandle,
164
- # __in DWORD dwMilliseconds
165
- # );
166
- #
167
-
168
- attach_function :wait_for_single_object, :WaitForSingleObject, [:pointer, :ulong], :wait_status, blocking: true
169
-
170
- #
171
- # BOOL WINAPI GetExitCodeProcess(
172
- # __in HANDLE hProcess,
173
- # __out LPDWORD lpExitCode
174
- # );
175
- #
176
-
177
- attach_function :get_exit_code, :GetExitCodeProcess, [:pointer, :pointer], :bool
178
-
179
- #
180
- # BOOL WINAPI GenerateConsoleCtrlEvent(
181
- # __in DWORD dwCtrlEvent,
182
- # __in DWORD dwProcessGroupId
183
- # );
184
- #
185
-
186
- attach_function :generate_console_ctrl_event, :GenerateConsoleCtrlEvent, [:ulong, :ulong], :bool
187
-
188
- #
189
- # BOOL WINAPI TerminateProcess(
190
- # __in HANDLE hProcess,
191
- # __in UINT uExitCode
192
- # );
193
- #
194
-
195
- attach_function :terminate_process, :TerminateProcess, [:pointer, :uint], :bool
196
-
197
- #
198
- # intptr_t _get_osfhandle(
199
- # int fd
200
- # );
201
- #
202
-
203
- attach_function :get_osfhandle, :_get_osfhandle, [:int], :intptr_t
204
-
205
- #
206
- # int _open_osfhandle (
207
- # intptr_t osfhandle,
208
- # int flags
209
- # );
210
- #
211
-
212
- attach_function :open_osfhandle, :_open_osfhandle, [:pointer, :int], :int
213
-
214
- # BOOL WINAPI SetHandleInformation(
215
- # __in HANDLE hObject,
216
- # __in DWORD dwMask,
217
- # __in DWORD dwFlags
218
- # );
219
-
220
- attach_function :set_handle_information, :SetHandleInformation, [:pointer, :ulong, :ulong], :bool
221
-
222
- # BOOL WINAPI GetHandleInformation(
223
- # __in HANDLE hObject,
224
- # __out LPDWORD lpdwFlags
225
- # );
226
-
227
- attach_function :get_handle_information, :GetHandleInformation, [:pointer, :pointer], :bool
228
-
229
- # BOOL WINAPI CreatePipe(
230
- # __out PHANDLE hReadPipe,
231
- # __out PHANDLE hWritePipe,
232
- # __in_opt LPSECURITY_ATTRIBUTES lpPipeAttributes,
233
- # __in DWORD nSize
234
- # );
235
-
236
- attach_function :create_pipe, :CreatePipe, [:pointer, :pointer, :pointer, :ulong], :bool
237
-
238
- #
239
- # HANDLE WINAPI GetCurrentProcess(void);
240
- #
241
-
242
- attach_function :current_process, :GetCurrentProcess, [], :pointer
243
-
244
- #
245
- # BOOL WINAPI DuplicateHandle(
246
- # __in HANDLE hSourceProcessHandle,
247
- # __in HANDLE hSourceHandle,
248
- # __in HANDLE hTargetProcessHandle,
249
- # __out LPHANDLE lpTargetHandle,
250
- # __in DWORD dwDesiredAccess,
251
- # __in BOOL bInheritHandle,
252
- # __in DWORD dwOptions
253
- # );
254
- #
255
-
256
- attach_function :_duplicate_handle, :DuplicateHandle, [
257
- :pointer,
258
- :pointer,
259
- :pointer,
260
- :pointer,
261
- :ulong,
262
- :bool,
263
- :ulong
264
- ], :bool
265
- end
266
- end
267
- end
268
- end