pdk 0.1.0 → 0.2.0

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