pdk 0.1.0 → 0.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 (51) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +50 -0
  3. data/README.md +3 -9
  4. data/exe/pdk +1 -1
  5. data/lib/pdk.rb +5 -4
  6. data/lib/pdk/cli.rb +62 -59
  7. data/lib/pdk/cli/errors.rb +1 -1
  8. data/lib/pdk/cli/exec.rb +154 -29
  9. data/lib/pdk/cli/input.rb +2 -2
  10. data/lib/pdk/cli/new.rb +12 -27
  11. data/lib/pdk/cli/new/class.rb +28 -41
  12. data/lib/pdk/cli/new/module.rb +30 -41
  13. data/lib/pdk/cli/test.rb +9 -20
  14. data/lib/pdk/cli/test/unit.rb +38 -0
  15. data/lib/pdk/cli/util/option_normalizer.rb +45 -19
  16. data/lib/pdk/cli/util/option_validator.rb +24 -20
  17. data/lib/pdk/cli/validate.rb +65 -65
  18. data/lib/pdk/generate.rb +5 -0
  19. data/lib/pdk/generators/module.rb +37 -33
  20. data/lib/pdk/generators/puppet_class.rb +1 -1
  21. data/lib/pdk/generators/puppet_object.rb +19 -20
  22. data/lib/pdk/logger.rb +1 -1
  23. data/lib/pdk/module/metadata.rb +35 -18
  24. data/lib/pdk/module/templatedir.rb +40 -33
  25. data/lib/pdk/report.rb +76 -19
  26. data/lib/pdk/report/event.rb +276 -0
  27. data/lib/pdk/template_file.rb +8 -6
  28. data/lib/pdk/tests/unit.rb +8 -3
  29. data/lib/pdk/util.rb +65 -0
  30. data/lib/pdk/util/bundler.rb +167 -0
  31. data/lib/pdk/util/version.rb +34 -0
  32. data/lib/pdk/validate.rb +3 -4
  33. data/lib/pdk/validators/base_validator.rb +60 -4
  34. data/lib/pdk/validators/metadata.rb +29 -0
  35. data/lib/pdk/validators/puppet/puppet_lint.rb +47 -0
  36. data/lib/pdk/validators/puppet/puppet_parser.rb +34 -0
  37. data/lib/pdk/validators/puppet_validator.rb +30 -0
  38. data/lib/pdk/validators/ruby/rubocop.rb +59 -0
  39. data/lib/pdk/validators/ruby_validator.rb +29 -0
  40. data/lib/pdk/version.rb +1 -1
  41. data/lib/puppet/util/windows.rb +14 -0
  42. data/lib/puppet/util/windows/api_types.rb +278 -0
  43. data/lib/puppet/util/windows/file.rb +488 -0
  44. data/lib/puppet/util/windows/string.rb +16 -0
  45. data/locales/de/pdk.po +263 -78
  46. data/locales/pdk.pot +224 -65
  47. metadata +60 -8
  48. data/lib/pdk/cli/tests/unit.rb +0 -52
  49. data/lib/pdk/validators/puppet_lint.rb +0 -17
  50. data/lib/pdk/validators/puppet_parser.rb +0 -17
  51. data/lib/pdk/validators/ruby_lint.rb +0 -17
@@ -0,0 +1,47 @@
1
+ require 'pdk'
2
+ require 'pdk/util'
3
+ require 'pdk/cli/exec'
4
+ require 'pdk/validators/base_validator'
5
+
6
+ module PDK
7
+ module Validate
8
+ class PuppetLint < BaseValidator
9
+ def self.name
10
+ 'puppet-lint'
11
+ end
12
+
13
+ def self.cmd
14
+ 'puppet-lint'
15
+ end
16
+
17
+ def self.pattern
18
+ '**/*.pp'
19
+ end
20
+
21
+ def self.spinner_text
22
+ _('Checking Puppet manifest style')
23
+ end
24
+
25
+ def self.parse_options(_options, targets)
26
+ cmd_options = ['--json']
27
+
28
+ cmd_options.concat(targets)
29
+ end
30
+
31
+ def self.parse_output(report, json_data)
32
+ json_data.each do |offense|
33
+ report.add_event(
34
+ file: offense['path'],
35
+ source: 'puppet-lint',
36
+ line: offense['line'],
37
+ column: offense['column'],
38
+ message: offense['message'],
39
+ test: offense['check'],
40
+ severity: offense['kind'],
41
+ state: :failure,
42
+ )
43
+ end
44
+ end
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,34 @@
1
+ require 'pdk'
2
+ require 'pdk/cli/exec'
3
+ require 'pdk/validators/base_validator'
4
+
5
+ module PDK
6
+ module Validate
7
+ class PuppetParser < BaseValidator
8
+ def self.name
9
+ 'puppet-parser'
10
+ end
11
+
12
+ def self.cmd
13
+ 'puppet'
14
+ end
15
+
16
+ def self.pattern
17
+ '**/**.pp'
18
+ end
19
+
20
+ def self.spinner_text
21
+ _('Checking Puppet manifest syntax')
22
+ end
23
+
24
+ def self.parse_options(_options, targets)
25
+ %w[parser validate].concat(targets)
26
+ end
27
+
28
+ def self.parse_output(_report, _json_data)
29
+ # TODO: handle outputs
30
+ # report.add_event(result.merge(state: :passed, severity: :ok))
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,30 @@
1
+ require 'pdk'
2
+ require 'pdk/cli/exec'
3
+ require 'pdk/validators/base_validator'
4
+ require 'pdk/validators/puppet/puppet_lint'
5
+ require 'pdk/validators/puppet/puppet_parser'
6
+
7
+ module PDK
8
+ module Validate
9
+ class PuppetValidator < BaseValidator
10
+ def self.name
11
+ 'puppet'
12
+ end
13
+
14
+ def self.puppet_validators
15
+ [PuppetLint, PuppetParser]
16
+ end
17
+
18
+ def self.invoke(report, options = {})
19
+ exit_code = 0
20
+
21
+ puppet_validators.each do |validator|
22
+ exit_code = validator.invoke(report, options)
23
+ break if exit_code != 0
24
+ end
25
+
26
+ exit_code
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,59 @@
1
+ require 'pdk'
2
+ require 'pdk/cli/exec'
3
+ require 'pdk/util'
4
+ require 'pdk/util/bundler'
5
+ require 'pdk/validators/base_validator'
6
+ require 'pdk/validators/ruby_validator'
7
+
8
+ module PDK
9
+ module Validate
10
+ class Rubocop < BaseValidator
11
+ def self.name
12
+ 'rubocop'
13
+ end
14
+
15
+ def self.cmd
16
+ 'rubocop'
17
+ end
18
+
19
+ def self.spinner_text
20
+ _('Checking Ruby code style')
21
+ end
22
+
23
+ def self.parse_options(_options, targets)
24
+ cmd_options = ['--format', 'json']
25
+
26
+ cmd_options.concat(targets)
27
+ end
28
+
29
+ def self.parse_output(report, json_data)
30
+ return unless json_data.key?('files')
31
+
32
+ json_data['files'].each do |file_info|
33
+ next unless file_info.key?('offenses')
34
+ result = {
35
+ file: file_info['path'],
36
+ source: 'rubocop',
37
+ }
38
+
39
+ if file_info['offenses'].empty?
40
+ report.add_event(result.merge(state: :passed, severity: :ok))
41
+ else
42
+ file_info['offenses'].each do |offense|
43
+ report.add_event(
44
+ result.merge(
45
+ line: offense['location']['line'],
46
+ column: offense['location']['column'],
47
+ message: offense['message'],
48
+ severity: offense['severity'],
49
+ test: offense['cop_name'],
50
+ state: :failure,
51
+ ),
52
+ )
53
+ end
54
+ end
55
+ end
56
+ end
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,29 @@
1
+ require 'pdk'
2
+ require 'pdk/cli/exec'
3
+ require 'pdk/validators/base_validator'
4
+ require 'pdk/validators/ruby/rubocop'
5
+
6
+ module PDK
7
+ module Validate
8
+ class RubyValidator < BaseValidator
9
+ def self.name
10
+ 'ruby'
11
+ end
12
+
13
+ def self.ruby_validators
14
+ [Rubocop]
15
+ end
16
+
17
+ def self.invoke(report, options = {})
18
+ exit_code = 0
19
+
20
+ ruby_validators.each do |validator|
21
+ exit_code = validator.invoke(report, options)
22
+ break if exit_code != 0
23
+ end
24
+
25
+ exit_code
26
+ end
27
+ end
28
+ end
29
+ end
data/lib/pdk/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module PDK
2
- VERSION = '0.1.0'.freeze
2
+ VERSION = '0.2.0'.freeze
3
3
  end
@@ -0,0 +1,14 @@
1
+ module Puppet
2
+ module Util
3
+ module Windows
4
+ module File; end
5
+
6
+ if Gem.win_platform?
7
+ # these reference platform specific gems
8
+ require 'puppet/util/windows/api_types'
9
+ require 'puppet/util/windows/string'
10
+ require 'puppet/util/windows/file'
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,278 @@
1
+ require 'ffi'
2
+ require 'puppet/util/windows/string'
3
+
4
+ module Puppet::Util::Windows::APITypes
5
+ module ::FFI
6
+ WIN32_FALSE = 0
7
+
8
+ # standard Win32 error codes
9
+ ERROR_SUCCESS = 0
10
+ end
11
+
12
+ module ::FFI::Library
13
+ # Wrapper method for attach_function + private
14
+ def attach_function_private(*args)
15
+ attach_function(*args)
16
+ private args[0]
17
+ end
18
+ end
19
+
20
+ class ::FFI::Pointer
21
+ NULL_HANDLE = 0
22
+
23
+ def self.from_string_to_wide_string(str, &block)
24
+ str = Puppet::Util::Windows::String.wide_string(str)
25
+ FFI::MemoryPointer.new(:byte, str.bytesize) do |ptr|
26
+ # uchar here is synonymous with byte
27
+ ptr.put_array_of_uchar(0, str.bytes.to_a)
28
+
29
+ yield ptr
30
+ end
31
+
32
+ # ptr has already had free called, so nothing to return
33
+ nil
34
+ end
35
+
36
+ def read_win32_bool
37
+ # BOOL is always a 32-bit integer in Win32
38
+ # some Win32 APIs return 1 for true, while others are non-0
39
+ read_int32 != FFI::WIN32_FALSE
40
+ end
41
+
42
+ alias_method :read_dword, :read_uint32
43
+ alias_method :read_win32_ulong, :read_uint32
44
+ alias_method :read_qword, :read_uint64
45
+
46
+ alias_method :read_hresult, :read_int32
47
+
48
+ def read_handle
49
+ type_size == 4 ? read_uint32 : read_uint64
50
+ end
51
+
52
+ alias_method :read_wchar, :read_uint16
53
+ alias_method :read_word, :read_uint16
54
+ alias_method :read_array_of_wchar, :read_array_of_uint16
55
+
56
+ def read_wide_string(char_length, dst_encoding = Encoding::UTF_8)
57
+ # char_length is number of wide chars (typically excluding NULLs), *not* bytes
58
+ str = get_bytes(0, char_length * 2).force_encoding('UTF-16LE')
59
+ str.encode(dst_encoding)
60
+ end
61
+
62
+ # @param max_char_length [Integer] Maximum number of wide chars to return (typically excluding NULLs), *not* bytes
63
+ # @param null_terminator [Symbol] Number of number of null wchar characters, *not* bytes, that determine the end of the string
64
+ # null_terminator = :single_null, then the terminating sequence is two bytes of zero. This is UNIT16 = 0
65
+ # null_terminator = :double_null, then the terminating sequence is four bytes of zero. This is UNIT32 = 0
66
+ def read_arbitrary_wide_string_up_to(max_char_length = 512, null_terminator = :single_null)
67
+ if null_terminator != :single_null && null_terminator != :double_null
68
+ raise _("Unable to read wide strings with %{null_terminator} terminal nulls") % { null_terminator: null_terminator }
69
+ end
70
+
71
+ terminator_width = null_terminator == :single_null ? 1 : 2
72
+ reader_method = null_terminator == :single_null ? :get_uint16 : :get_uint32
73
+
74
+ # Look for a null terminating characters; if found, read up to that null (exclusive)
75
+ (0...max_char_length - terminator_width).each do |i|
76
+ return read_wide_string(i) if send(reader_method, (i * 2)) == 0
77
+ end
78
+
79
+ # String is longer than the max; read just to the max
80
+ read_wide_string(max_char_length)
81
+ end
82
+
83
+ def read_win32_local_pointer(&block)
84
+ ptr = nil
85
+ begin
86
+ ptr = read_pointer
87
+ yield ptr
88
+ ensure
89
+ if ptr && ! ptr.null?
90
+ if FFI::WIN32::LocalFree(ptr.address) != FFI::Pointer::NULL_HANDLE
91
+ Puppet.debug "LocalFree memory leak"
92
+ end
93
+ end
94
+ end
95
+
96
+ # ptr has already had LocalFree called, so nothing to return
97
+ nil
98
+ end
99
+
100
+ def read_com_memory_pointer(&block)
101
+ ptr = nil
102
+ begin
103
+ ptr = read_pointer
104
+ yield ptr
105
+ ensure
106
+ FFI::WIN32::CoTaskMemFree(ptr) if ptr && ! ptr.null?
107
+ end
108
+
109
+ # ptr has already had CoTaskMemFree called, so nothing to return
110
+ nil
111
+ end
112
+
113
+
114
+ alias_method :write_dword, :write_uint32
115
+ alias_method :write_word, :write_uint16
116
+ end
117
+
118
+ # FFI Types
119
+ # https://github.com/ffi/ffi/wiki/Types
120
+
121
+ # Windows - Common Data Types
122
+ # https://msdn.microsoft.com/en-us/library/cc230309.aspx
123
+
124
+ # Windows Data Types
125
+ # https://msdn.microsoft.com/en-us/library/windows/desktop/aa383751(v=vs.85).aspx
126
+
127
+ FFI.typedef :uint16, :word
128
+ FFI.typedef :uint32, :dword
129
+ # uintptr_t is defined in an FFI conf as platform specific, either
130
+ # ulong_long on x64 or just ulong on x86
131
+ FFI.typedef :uintptr_t, :handle
132
+ FFI.typedef :uintptr_t, :hwnd
133
+
134
+ # buffer_inout is similar to pointer (platform specific), but optimized for buffers
135
+ FFI.typedef :buffer_inout, :lpwstr
136
+ # buffer_in is similar to pointer (platform specific), but optimized for CONST read only buffers
137
+ FFI.typedef :buffer_in, :lpcwstr
138
+ FFI.typedef :buffer_in, :lpcolestr
139
+
140
+ # string is also similar to pointer, but should be used for const char *
141
+ # NOTE that this is not wide, useful only for A suffixed functions
142
+ FFI.typedef :string, :lpcstr
143
+
144
+ # pointer in FFI is platform specific
145
+ # NOTE: for API calls with reserved lpvoid parameters, pass a FFI::Pointer::NULL
146
+ FFI.typedef :pointer, :lpcvoid
147
+ FFI.typedef :pointer, :lpvoid
148
+ FFI.typedef :pointer, :lpword
149
+ FFI.typedef :pointer, :lpbyte
150
+ FFI.typedef :pointer, :lpdword
151
+ FFI.typedef :pointer, :pdword
152
+ FFI.typedef :pointer, :phandle
153
+ FFI.typedef :pointer, :ulong_ptr
154
+ FFI.typedef :pointer, :pbool
155
+ FFI.typedef :pointer, :lpunknown
156
+
157
+ # any time LONG / ULONG is in a win32 API definition DO NOT USE platform specific width
158
+ # which is what FFI uses by default
159
+ # instead create new aliases for these very special cases
160
+ # NOTE: not a good idea to redefine FFI :ulong since other typedefs may rely on it
161
+ FFI.typedef :uint32, :win32_ulong
162
+ FFI.typedef :int32, :win32_long
163
+ # FFI bool can be only 1 byte at times,
164
+ # Win32 BOOL is a signed int, and is always 4 bytes, even on x64
165
+ # https://blogs.msdn.com/b/oldnewthing/archive/2011/03/28/10146459.aspx
166
+ FFI.typedef :int32, :win32_bool
167
+
168
+ # BOOLEAN (unlike BOOL) is a BYTE - typedef unsigned char BYTE;
169
+ FFI.typedef :uchar, :boolean
170
+
171
+ # Same as a LONG, a 32-bit signed integer
172
+ FFI.typedef :int32, :hresult
173
+
174
+ # NOTE: FFI already defines (u)short as a 16-bit (un)signed like this:
175
+ # FFI.typedef :uint16, :ushort
176
+ # FFI.typedef :int16, :short
177
+
178
+ # 8 bits per byte
179
+ FFI.typedef :uchar, :byte
180
+ FFI.typedef :uint16, :wchar
181
+
182
+ module ::FFI::WIN32
183
+ extend ::FFI::Library
184
+
185
+ # https://msdn.microsoft.com/en-us/library/windows/desktop/aa373931(v=vs.85).aspx
186
+ # typedef struct _GUID {
187
+ # DWORD Data1;
188
+ # WORD Data2;
189
+ # WORD Data3;
190
+ # BYTE Data4[8];
191
+ # } GUID;
192
+ class GUID < FFI::Struct
193
+ layout :Data1, :dword,
194
+ :Data2, :word,
195
+ :Data3, :word,
196
+ :Data4, [:byte, 8]
197
+
198
+ def self.[](s)
199
+ raise _('Bad GUID format.') unless s =~ /^[0-9a-f]{8}-([0-9a-f]{4}-){3}[0-9a-f]{12}$/i
200
+
201
+ new.tap do |guid|
202
+ guid[:Data1] = s[0, 8].to_i(16)
203
+ guid[:Data2] = s[9, 4].to_i(16)
204
+ guid[:Data3] = s[14, 4].to_i(16)
205
+ guid[:Data4][0] = s[19, 2].to_i(16)
206
+ guid[:Data4][1] = s[21, 2].to_i(16)
207
+ s[24, 12].split('').each_slice(2).with_index do |a, i|
208
+ guid[:Data4][i + 2] = a.join('').to_i(16)
209
+ end
210
+ end
211
+ end
212
+
213
+ def ==(other) Windows.memcmp(other, self, size) == 0 end
214
+ end
215
+
216
+ # https://msdn.microsoft.com/en-us/library/windows/desktop/ms724950(v=vs.85).aspx
217
+ # typedef struct _SYSTEMTIME {
218
+ # WORD wYear;
219
+ # WORD wMonth;
220
+ # WORD wDayOfWeek;
221
+ # WORD wDay;
222
+ # WORD wHour;
223
+ # WORD wMinute;
224
+ # WORD wSecond;
225
+ # WORD wMilliseconds;
226
+ # } SYSTEMTIME, *PSYSTEMTIME;
227
+ class SYSTEMTIME < FFI::Struct
228
+ layout :wYear, :word,
229
+ :wMonth, :word,
230
+ :wDayOfWeek, :word,
231
+ :wDay, :word,
232
+ :wHour, :word,
233
+ :wMinute, :word,
234
+ :wSecond, :word,
235
+ :wMilliseconds, :word
236
+
237
+ def to_local_time
238
+ Time.local(self[:wYear], self[:wMonth], self[:wDay],
239
+ self[:wHour], self[:wMinute], self[:wSecond], self[:wMilliseconds] * 1000)
240
+ end
241
+ end
242
+
243
+ # https://msdn.microsoft.com/en-us/library/windows/desktop/ms724284(v=vs.85).aspx
244
+ # Contains a 64-bit value representing the number of 100-nanosecond
245
+ # intervals since January 1, 1601 (UTC).
246
+ # typedef struct _FILETIME {
247
+ # DWORD dwLowDateTime;
248
+ # DWORD dwHighDateTime;
249
+ # } FILETIME, *PFILETIME;
250
+ class FILETIME < FFI::Struct
251
+ layout :dwLowDateTime, :dword,
252
+ :dwHighDateTime, :dword
253
+ end
254
+
255
+ ffi_convention :stdcall
256
+
257
+ # https://msdn.microsoft.com/en-us/library/windows/desktop/aa366730(v=vs.85).aspx
258
+ # HLOCAL WINAPI LocalFree(
259
+ # _In_ HLOCAL hMem
260
+ # );
261
+ ffi_lib :kernel32
262
+ attach_function :LocalFree, [:handle], :handle
263
+
264
+ # https://msdn.microsoft.com/en-us/library/windows/desktop/ms724211(v=vs.85).aspx
265
+ # BOOL WINAPI CloseHandle(
266
+ # _In_ HANDLE hObject
267
+ # );
268
+ ffi_lib :kernel32
269
+ attach_function_private :CloseHandle, [:handle], :win32_bool
270
+
271
+ # https://msdn.microsoft.com/en-us/library/windows/desktop/ms680722(v=vs.85).aspx
272
+ # void CoTaskMemFree(
273
+ # _In_opt_ LPVOID pv
274
+ # );
275
+ ffi_lib :ole32
276
+ attach_function :CoTaskMemFree, [:lpvoid], :void
277
+ end
278
+ end