pdk 1.14.0 → 1.14.1

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 (87) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +31 -0
  3. data/lib/pdk.rb +63 -8
  4. data/lib/pdk/analytics.rb +14 -28
  5. data/lib/pdk/analytics/client/google_analytics.rb +2 -0
  6. data/lib/pdk/analytics/client/noop.rb +2 -0
  7. data/lib/pdk/analytics/util.rb +2 -0
  8. data/lib/pdk/answer_file.rb +2 -21
  9. data/lib/pdk/cli.rb +25 -13
  10. data/lib/pdk/cli/errors.rb +2 -0
  11. data/lib/pdk/cli/exec.rb +5 -0
  12. data/lib/pdk/cli/exec/command.rb +10 -6
  13. data/lib/pdk/cli/exec/interactive_command.rb +1 -1
  14. data/lib/pdk/cli/exec_group.rb +2 -0
  15. data/lib/pdk/cli/module/generate.rb +1 -1
  16. data/lib/pdk/cli/new/module.rb +8 -1
  17. data/lib/pdk/cli/new/test.rb +0 -1
  18. data/lib/pdk/cli/test/unit.rb +0 -3
  19. data/lib/pdk/cli/util.rb +24 -13
  20. data/lib/pdk/cli/util/command_redirector.rb +3 -2
  21. data/lib/pdk/cli/util/interview.rb +2 -1
  22. data/lib/pdk/cli/util/option_normalizer.rb +2 -0
  23. data/lib/pdk/cli/util/option_validator.rb +2 -0
  24. data/lib/pdk/cli/validate.rb +0 -1
  25. data/lib/pdk/config.rb +19 -13
  26. data/lib/pdk/config/json.rb +1 -1
  27. data/lib/pdk/config/json_schema_namespace.rb +3 -4
  28. data/lib/pdk/config/json_schema_setting.rb +1 -1
  29. data/lib/pdk/config/json_with_schema.rb +1 -2
  30. data/lib/pdk/config/namespace.rb +2 -0
  31. data/lib/pdk/config/setting.rb +2 -0
  32. data/lib/pdk/config/validator.rb +31 -0
  33. data/lib/pdk/config/yaml.rb +1 -2
  34. data/lib/pdk/config/yaml_with_schema.rb +1 -1
  35. data/lib/pdk/generate.rb +19 -13
  36. data/lib/pdk/generate/defined_type.rb +1 -1
  37. data/lib/pdk/generate/module.rb +1 -1
  38. data/lib/pdk/generate/provider.rb +2 -2
  39. data/lib/pdk/generate/puppet_class.rb +1 -1
  40. data/lib/pdk/generate/puppet_object.rb +2 -0
  41. data/lib/pdk/generate/task.rb +1 -1
  42. data/lib/pdk/generate/transport.rb +1 -1
  43. data/lib/pdk/logger.rb +1 -4
  44. data/lib/pdk/module.rb +7 -0
  45. data/lib/pdk/module/build.rb +2 -0
  46. data/lib/pdk/module/convert.rb +2 -0
  47. data/lib/pdk/module/metadata.rb +2 -1
  48. data/lib/pdk/module/templatedir.rb +2 -0
  49. data/lib/pdk/module/update.rb +1 -1
  50. data/lib/pdk/module/update_manager.rb +2 -0
  51. data/lib/pdk/report.rb +3 -1
  52. data/lib/pdk/report/event.rb +2 -0
  53. data/lib/pdk/template_file.rb +1 -0
  54. data/lib/pdk/tests/unit.rb +8 -3
  55. data/lib/pdk/util.rb +25 -7
  56. data/lib/pdk/util/bundler.rb +2 -0
  57. data/lib/pdk/util/env.rb +30 -0
  58. data/lib/pdk/util/filesystem.rb +4 -1
  59. data/lib/pdk/util/git.rb +3 -1
  60. data/lib/pdk/util/puppet_strings.rb +4 -2
  61. data/lib/pdk/util/puppet_version.rb +11 -1
  62. data/lib/pdk/util/ruby_version.rb +1 -0
  63. data/lib/pdk/util/template_uri.rb +2 -0
  64. data/lib/pdk/util/vendored_file.rb +2 -0
  65. data/lib/pdk/util/version.rb +2 -0
  66. data/lib/pdk/util/windows.rb +1 -0
  67. data/lib/pdk/util/windows/api_types.rb +32 -0
  68. data/lib/pdk/util/windows/process.rb +79 -0
  69. data/lib/pdk/validate.rb +24 -5
  70. data/lib/pdk/validate/base_validator.rb +2 -0
  71. data/lib/pdk/validate/metadata/metadata_json_lint.rb +1 -1
  72. data/lib/pdk/validate/metadata/metadata_syntax.rb +1 -1
  73. data/lib/pdk/validate/metadata_validator.rb +1 -3
  74. data/lib/pdk/validate/puppet/puppet_epp.rb +2 -2
  75. data/lib/pdk/validate/puppet/puppet_lint.rb +1 -1
  76. data/lib/pdk/validate/puppet/puppet_syntax.rb +2 -2
  77. data/lib/pdk/validate/puppet_validator.rb +1 -4
  78. data/lib/pdk/validate/ruby/rubocop.rb +1 -1
  79. data/lib/pdk/validate/ruby_validator.rb +1 -2
  80. data/lib/pdk/validate/tasks/metadata_lint.rb +1 -1
  81. data/lib/pdk/validate/tasks/name.rb +1 -1
  82. data/lib/pdk/validate/tasks_validator.rb +1 -3
  83. data/lib/pdk/validate/yaml/syntax.rb +1 -1
  84. data/lib/pdk/validate/yaml_validator.rb +1 -2
  85. data/lib/pdk/version.rb +1 -1
  86. data/locales/pdk.pot +243 -207
  87. metadata +7 -4
@@ -1,3 +1,5 @@
1
+ require 'pdk'
2
+
1
3
  module PDK
2
4
  module Module
3
5
  class Build
@@ -1,3 +1,5 @@
1
+ require 'pdk'
2
+
1
3
  module PDK
2
4
  module Module
3
5
  class Convert
@@ -1,4 +1,4 @@
1
- require 'pdk/util/filesystem'
1
+ require 'pdk'
2
2
 
3
3
  module PDK
4
4
  module Module
@@ -108,6 +108,7 @@ module PDK
108
108
  raise ArgumentError, _('Invalid JSON in metadata.json: %{msg}') % { msg: e.message }
109
109
  end
110
110
 
111
+ require 'pdk/util'
111
112
  data['template-url'] = PDK::Util::TemplateURI.default_template_uri.metadata_format if PDK::Util.package_install? && data['template-url'] == PDK::Util::TemplateURI::PACKAGED_TEMPLATE_KEYWORD
112
113
  new(data)
113
114
  end
@@ -1,3 +1,5 @@
1
+ require 'pdk'
2
+
1
3
  module PDK
2
4
  module Module
3
5
  class TemplateDir
@@ -1,4 +1,4 @@
1
- require 'pdk/module/convert'
1
+ require 'pdk'
2
2
 
3
3
  module PDK
4
4
  module Module
@@ -1,3 +1,5 @@
1
+ require 'pdk'
2
+
1
3
  module PDK
2
4
  module Module
3
5
  class UpdateManager
@@ -1,7 +1,9 @@
1
- require 'pdk/report/event'
1
+ require 'pdk'
2
2
 
3
3
  module PDK
4
4
  class Report
5
+ autoload :Event, 'pdk/report/event'
6
+
5
7
  # @return [Array<String>] the list of supported report formats.
6
8
  def self.formats
7
9
  @report_formats ||= %w[junit text].freeze
@@ -1,3 +1,5 @@
1
+ require 'pdk'
2
+
1
3
  module PDK
2
4
  class Report
3
5
  class Event
@@ -1,4 +1,5 @@
1
1
  require 'ostruct'
2
+ require 'pdk'
2
3
 
3
4
  module PDK
4
5
  class TemplateFile < OpenStruct
@@ -1,3 +1,5 @@
1
+ require 'pdk'
2
+
1
3
  module PDK
2
4
  module Test
3
5
  class Unit
@@ -38,9 +40,7 @@ module PDK
38
40
 
39
41
  command = PDK::CLI::Exec::InteractiveCommand.new(*cmd_with_args(task)).tap do |c|
40
42
  c.context = :module
41
- c.environment = environment.reject do |key, _|
42
- key == 'CI_SPEC_OPTIONS'
43
- end
43
+ c.environment = environment
44
44
  end
45
45
 
46
46
  command.execute!
@@ -95,6 +95,11 @@ module PDK
95
95
  spinner_msg = options[:parallel] ? _('Running unit tests in parallel.') : _('Running unit tests.')
96
96
 
97
97
  if options[:interactive]
98
+ environment['CI_SPEC_OPTIONS'] = if options[:verbose]
99
+ '--format documentation'
100
+ else
101
+ '--format progress'
102
+ end
98
103
  result = interactive_rake(cmd(tests, options), environment)
99
104
  return result[:exit_code]
100
105
  end
@@ -1,13 +1,30 @@
1
+ require 'pdk'
2
+
1
3
  # PDK::Util::Windows can not be lazy loaded because it conditionally requires
2
4
  # other files on Windows only. This can probably be fixed up with a later
3
5
  # refactoring.
4
6
  require 'pdk/util/windows'
5
7
 
8
+ autoload :Pathname, 'pathname'
9
+
6
10
  module PDK
7
11
  module Util
12
+ autoload :Bundler, 'pdk/util/bundler'
13
+ autoload :Env, 'pdk/util/env'
14
+ autoload :Filesystem, 'pdk/util/filesystem'
15
+ autoload :Git, 'pdk/util/git'
16
+ autoload :PuppetStrings, 'pdk/util/puppet_strings'
17
+ autoload :PuppetVersion, 'pdk/util/puppet_version'
18
+ autoload :RubyVersion, 'pdk/util/ruby_version'
19
+ autoload :TemplateURI, 'pdk/util/template_uri'
20
+ autoload :VendoredFile, 'pdk/util/vendored_file'
21
+ autoload :Version, 'pdk/util/version'
22
+
8
23
  MODULE_FOLDERS = %w[
9
24
  manifests
10
- lib
25
+ lib/puppet
26
+ lib/puppet_x
27
+ lib/facter
11
28
  tasks
12
29
  facts.d
13
30
  functions
@@ -102,7 +119,7 @@ module PDK
102
119
  # @return [String] Fully qualified path to per-user PDK cachedir.
103
120
  def cachedir
104
121
  if Gem.win_platform?
105
- File.join(ENV['LOCALAPPDATA'], 'PDK', 'cache')
122
+ File.join(PDK::Util::Env['LOCALAPPDATA'], 'PDK', 'cache')
106
123
  else
107
124
  File.join(Dir.home, '.pdk', 'cache')
108
125
  end
@@ -111,9 +128,9 @@ module PDK
111
128
 
112
129
  def configdir
113
130
  if Gem.win_platform?
114
- File.join(ENV['LOCALAPPDATA'], 'PDK')
131
+ File.join(PDK::Util::Env['LOCALAPPDATA'], 'PDK')
115
132
  else
116
- File.join(ENV.fetch('XDG_CONFIG_HOME', File.join(Dir.home, '.config')), 'pdk')
133
+ File.join(PDK::Util::Env.fetch('XDG_CONFIG_HOME', File.join(Dir.home, '.config')), 'pdk')
117
134
  end
118
135
  end
119
136
  module_function :configdir
@@ -143,12 +160,13 @@ module PDK
143
160
  module_function :module_fixtures_dir
144
161
 
145
162
  # Returns true or false depending on if any of the common directories in a module
146
- # are found in the current directory
163
+ # are found in the specified directory. If a directory is not specified, the current
164
+ # working directory is used.
147
165
  #
148
166
  # @return [boolean] True if any folders from MODULE_FOLDERS are found in the current dir,
149
167
  # false otherwise.
150
- def in_module_root?
151
- PDK::Util::MODULE_FOLDERS.any? { |dir| File.directory?(dir) }
168
+ def in_module_root?(path = Dir.pwd)
169
+ PDK::Util::MODULE_FOLDERS.any? { |dir| PDK::Util::Filesystem.directory?(File.join(path, dir)) }
152
170
  end
153
171
  module_function :in_module_root?
154
172
 
@@ -1,3 +1,5 @@
1
+ require 'pdk'
2
+
1
3
  module PDK
2
4
  module Util
3
5
  module Bundler
@@ -0,0 +1,30 @@
1
+ require 'pdk'
2
+ require 'forwardable'
3
+
4
+ module PDK
5
+ module Util
6
+ class Env
7
+ class << self
8
+ extend Forwardable
9
+
10
+ def_delegators :env_hash, :[], :key?, :fetch, :select, :reject
11
+
12
+ def []=(key, value)
13
+ if Gem.win_platform?
14
+ PDK::Util::Windows::Process.set_environment_variable(key, value)
15
+ else
16
+ ENV[key] = value
17
+ end
18
+ end
19
+
20
+ def env_hash
21
+ if Gem.win_platform?
22
+ PDK::Util::Windows::Process.environment_hash
23
+ else
24
+ ENV
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
@@ -1,8 +1,11 @@
1
+ require 'pdk'
2
+
1
3
  module PDK
2
4
  module Util
3
5
  module Filesystem
4
6
  def write_file(path, content)
5
- raise ArgumentError unless path.is_a?(String) || path.respond_to?(:to_path)
7
+ raise ArgumentError, _('content must be a String') unless content.is_a?(String)
8
+ raise ArgumentError, _('path must be a String or Pathname') unless path.is_a?(String) || path.respond_to?(:to_path)
6
9
 
7
10
  # Harmonize newlines across platforms.
8
11
  content = content.encode(universal_newline: true)
@@ -1,3 +1,5 @@
1
+ require 'pdk'
2
+
1
3
  module PDK
2
4
  module Util
3
5
  class GitError < StandardError
@@ -108,7 +110,7 @@ module PDK
108
110
  }
109
111
  end
110
112
 
111
- matching_refs = output[:stdout].split("\n").map { |r| r.split("\t") }
113
+ matching_refs = output[:stdout].split(%r{\r?\n}).map { |r| r.split("\t") }
112
114
  matching_ref = matching_refs.find { |_sha, remote_ref| remote_ref == "refs/tags/#{ref}" || remote_ref == "refs/remotes/origin/#{ref}" || remote_ref == "refs/heads/#{ref}" }
113
115
  raise PDK::CLI::ExitWithError, _('Unable to find a branch or tag named "%{ref}" in %{repo}') % { ref: ref, repo: repo } if matching_ref.nil?
114
116
  matching_ref.first
@@ -1,3 +1,5 @@
1
+ require 'pdk'
2
+
1
3
  module PDK
2
4
  module Util
3
5
  module PuppetStrings
@@ -89,7 +91,7 @@ module PDK
89
91
  def self.all_objects
90
92
  require 'pdk/generate'
91
93
 
92
- generators = PDK::Generate::GENERATORS.select do |gen|
94
+ generators = PDK::Generate.generators.select do |gen|
93
95
  gen.respond_to?(:puppet_strings_type) && !gen.puppet_strings_type.nil?
94
96
  end
95
97
 
@@ -114,7 +116,7 @@ module PDK
114
116
  def self.find_generator(type)
115
117
  require 'pdk/generate'
116
118
 
117
- PDK::Generate::GENERATORS.find do |gen|
119
+ PDK::Generate.generators.find do |gen|
118
120
  gen.respond_to?(:puppet_strings_type) && gen.puppet_strings_type == type
119
121
  end
120
122
  end
@@ -1,3 +1,5 @@
1
+ require 'pdk'
2
+
1
3
  module PDK
2
4
  module Util
3
5
  class PuppetVersion
@@ -42,7 +44,13 @@ module PDK
42
44
  latest
43
45
  end
44
46
 
45
- def fetch_puppet_dev
47
+ def puppet_dev_fetched?
48
+ !@puppet_dev_fetched.nil?
49
+ end
50
+
51
+ def fetch_puppet_dev(options = {})
52
+ return if options[:run] == :once && puppet_dev_fetched?
53
+
46
54
  require 'pdk/util/git'
47
55
  require 'fileutils'
48
56
 
@@ -74,6 +82,8 @@ module PDK
74
82
 
75
83
  # Reset local repo to latest
76
84
  reset_result = PDK::Util::Git.git('-C', puppet_dev_path, 'reset', '--hard', 'origin/master')
85
+
86
+ @puppet_dev_fetched = true
77
87
  return if reset_result[:exit_code].zero?
78
88
 
79
89
  PDK.logger.error reset_result[:stdout]
@@ -1,3 +1,4 @@
1
+ require 'pdk'
1
2
  require 'forwardable'
2
3
 
3
4
  module PDK
@@ -1,3 +1,5 @@
1
+ require 'pdk'
2
+
1
3
  module PDK
2
4
  module Util
3
5
  class TemplateURI
@@ -1,3 +1,5 @@
1
+ require 'pdk'
2
+
1
3
  module PDK
2
4
  module Util
3
5
  class VendoredFile
@@ -1,3 +1,5 @@
1
+ require 'pdk'
2
+
1
3
  module PDK
2
4
  module Util
3
5
  module Version
@@ -8,6 +8,7 @@ module PDK
8
8
  require 'pdk/util/windows/api_types'
9
9
  require 'pdk/util/windows/string'
10
10
  require 'pdk/util/windows/file'
11
+ require 'pdk/util/windows/process'
11
12
  end
12
13
  end
13
14
  end
@@ -2,6 +2,13 @@ require 'ffi'
2
2
  require 'pdk/util/windows/string'
3
3
 
4
4
  module PDK::Util::Windows::APITypes
5
+ module ::FFI::Library
6
+ def attach_function_private(*args)
7
+ attach_function(*args)
8
+ private args[0]
9
+ end
10
+ end
11
+
5
12
  class ::FFI::Pointer
6
13
  def self.from_string_to_wide_string(str, &_block)
7
14
  str = PDK::Util::Windows::String.wide_string(str)
@@ -28,6 +35,26 @@ module PDK::Util::Windows::APITypes
28
35
  }
29
36
  raise
30
37
  end
38
+
39
+ def read_arbitrary_wide_string_up_to(max_char_length = 512, null_terminator = :single_null, encode_options = {})
40
+ unless [:single_null, :double_null].include?(null_terminator)
41
+ raise ArgumentError, _(
42
+ 'Unable to read wide strings with %{null_terminator} terminal nulls',
43
+ ) % { null_terminator: null_terminator }
44
+ end
45
+
46
+ terminator_width = (null_terminator == :single_null) ? 1 : 2
47
+ reader_method = (null_terminator == :single_null) ? :get_uint16 : :get_uint32
48
+
49
+ # Look for the null_terminator; if found, read up to that null
50
+ # (exclusive)
51
+ (0...max_char_length - terminator_width).each do |i|
52
+ return read_wide_string(i, Encoding::UTF_8, encode_options) if send(reader_method, (i * 2)).zero?
53
+ end
54
+
55
+ # String is longer than the max, read just up to the max
56
+ read_wide_string(max_char_length, Encoding::UTF_8, encode_options)
57
+ end
31
58
  end
32
59
 
33
60
  # FFI Types
@@ -47,4 +74,9 @@ module PDK::Util::Windows::APITypes
47
74
  # 8 bits per byte
48
75
  FFI.typedef :uchar, :byte
49
76
  FFI.typedef :uint16, :wchar
77
+
78
+ # FFI bool can be only 1 byte at times,
79
+ # Win32 BOOL is a signed int, and is always 4 bytes, even on x64
80
+ # https://blogs.msdn.com/b/oldnewthing/archive/2011/03/28/10146459.aspx
81
+ FFI.typedef :int32, :win32_bool
50
82
  end
@@ -0,0 +1,79 @@
1
+ require 'pdk/util/windows'
2
+
3
+ module PDK::Util::Windows::Process
4
+ require 'ffi'
5
+ extend PDK::Util::Windows::String
6
+ extend FFI::Library
7
+
8
+ def environment_hash
9
+ env_ptr = GetEnvironmentStringsW()
10
+
11
+ contains_unicode_replacement = ->(string) do
12
+ return false unless string.include?("\uFFFD")
13
+
14
+ PDK.logger.warning _(
15
+ 'Discarding environment variable %{string} which contains invalid ' \
16
+ 'bytes',
17
+ ) % { string: string }
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
+ Hash[pairs]
29
+ ensure
30
+ if env_ptr && !env_ptr.null?
31
+ if FreeEnvironmentStringsW(env_ptr) == PDK::Util::Windows::WIN32_FALSE
32
+ PDK.logger.debug _('FreeEnvironmentStringsW memory leak')
33
+ end
34
+ end
35
+ end
36
+ module_function :environment_hash
37
+
38
+ def set_environment_variable(name, val)
39
+ raise ArgumentError, _('Environment variable name must not be nil or empty') if name.nil? || name.empty?
40
+
41
+ FFI::MemoryPointer.from_string_to_wide_string(name) do |name_ptr|
42
+ if val.nil?
43
+ if SetEnvironmentVariableW(name_ptr, FFI::MemoryPointer::NULL) == PDK::Util::Windows::WIN32_FALSE
44
+ raise _('Failed to remove environment variable: %{name}') % { name: name }
45
+ end
46
+ else
47
+ FFI::MemoryPointer.from_string_to_wide_string(val) do |val_ptr|
48
+ if SetEnvironmentVariableW(name_ptr, val_ptr) == PDK::Util::Windows::WIN32_FALSE
49
+ raise _('Failed to set environment variaible: %{name}') % { name: name }
50
+ end
51
+ end
52
+ end
53
+ end
54
+ end
55
+ module_function :set_environment_variable
56
+
57
+ ffi_convention :stdcall
58
+
59
+ # https://msdn.microsoft.com/en-us/library/windows/desktop/ms683187(v=vs.85).aspx
60
+ # LPTCH GetEnvironmentStrings(void);
61
+ ffi_lib :kernel32
62
+ attach_function_private :GetEnvironmentStringsW, [], :pointer
63
+
64
+ # https://msdn.microsoft.com/en-us/library/windows/desktop/ms683151(v=vs.85).aspx
65
+ # BOOL FreeEnvironmentStrings(
66
+ # _In_ LPTCH lpszEnvironmentBlock
67
+ # );
68
+ ffi_lib :kernel32
69
+ attach_function_private :FreeEnvironmentStringsW, [:pointer], :win32_bool
70
+
71
+ # https://msdn.microsoft.com/en-us/library/windows/desktop/ms686206(v=vs.85).aspx
72
+ # BOOL WINAPI SetEnvironmentVariableW(
73
+ # _In_ LPCTSTR lpName,
74
+ # _In_opt_ LPCTSTR lpValue
75
+ # );
76
+ ffi_lib :kernel32
77
+ attach_function_private :SetEnvironmentVariableW, [:lpcwstr, :lpcwstr],
78
+ :win32_bool
79
+ end