pdk 1.14.0 → 1.14.1

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