pdk 1.9.0 → 3.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 (163) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +744 -711
  3. data/README.md +23 -21
  4. data/lib/pdk/answer_file.rb +3 -112
  5. data/lib/pdk/bolt.rb +20 -0
  6. data/lib/pdk/cli/build.rb +51 -54
  7. data/lib/pdk/cli/bundle.rb +33 -29
  8. data/lib/pdk/cli/console.rb +148 -0
  9. data/lib/pdk/cli/convert.rb +46 -37
  10. data/lib/pdk/cli/env.rb +51 -0
  11. data/lib/pdk/cli/errors.rb +4 -3
  12. data/lib/pdk/cli/exec/command.rb +285 -0
  13. data/lib/pdk/cli/exec/interactive_command.rb +109 -0
  14. data/lib/pdk/cli/exec.rb +32 -201
  15. data/lib/pdk/cli/exec_group.rb +79 -43
  16. data/lib/pdk/cli/get/config.rb +26 -0
  17. data/lib/pdk/cli/get.rb +22 -0
  18. data/lib/pdk/cli/new/class.rb +20 -22
  19. data/lib/pdk/cli/new/defined_type.rb +21 -21
  20. data/lib/pdk/cli/new/fact.rb +27 -0
  21. data/lib/pdk/cli/new/function.rb +27 -0
  22. data/lib/pdk/cli/new/module.rb +40 -29
  23. data/lib/pdk/cli/new/provider.rb +18 -18
  24. data/lib/pdk/cli/new/task.rb +23 -22
  25. data/lib/pdk/cli/new/test.rb +52 -0
  26. data/lib/pdk/cli/new/transport.rb +27 -0
  27. data/lib/pdk/cli/new.rb +15 -9
  28. data/lib/pdk/cli/release/prep.rb +39 -0
  29. data/lib/pdk/cli/release/publish.rb +46 -0
  30. data/lib/pdk/cli/release.rb +185 -0
  31. data/lib/pdk/cli/remove/config.rb +83 -0
  32. data/lib/pdk/cli/remove.rb +22 -0
  33. data/lib/pdk/cli/set/config.rb +121 -0
  34. data/lib/pdk/cli/set.rb +22 -0
  35. data/lib/pdk/cli/test/unit.rb +71 -69
  36. data/lib/pdk/cli/test.rb +9 -8
  37. data/lib/pdk/cli/update.rb +38 -21
  38. data/lib/pdk/cli/util/command_redirector.rb +13 -3
  39. data/lib/pdk/cli/util/interview.rb +25 -9
  40. data/lib/pdk/cli/util/option_normalizer.rb +6 -6
  41. data/lib/pdk/cli/util/option_validator.rb +19 -9
  42. data/lib/pdk/cli/util/spinner.rb +13 -0
  43. data/lib/pdk/cli/util/update_manager_printer.rb +82 -0
  44. data/lib/pdk/cli/util.rb +105 -48
  45. data/lib/pdk/cli/validate.rb +96 -111
  46. data/lib/pdk/cli.rb +134 -87
  47. data/lib/pdk/config/errors.rb +5 -0
  48. data/lib/pdk/config/ini_file.rb +184 -0
  49. data/lib/pdk/config/ini_file_setting.rb +35 -0
  50. data/lib/pdk/config/json.rb +35 -0
  51. data/lib/pdk/config/json_schema_namespace.rb +137 -0
  52. data/lib/pdk/config/json_schema_setting.rb +51 -0
  53. data/lib/pdk/config/json_with_schema.rb +47 -0
  54. data/lib/pdk/config/namespace.rb +362 -0
  55. data/lib/pdk/config/setting.rb +134 -0
  56. data/lib/pdk/config/task_schema.json +116 -0
  57. data/lib/pdk/config/validator.rb +31 -0
  58. data/lib/pdk/config/yaml.rb +41 -0
  59. data/lib/pdk/config/yaml_with_schema.rb +51 -0
  60. data/lib/pdk/config.rb +304 -0
  61. data/lib/pdk/context/control_repo.rb +61 -0
  62. data/lib/pdk/context/module.rb +28 -0
  63. data/lib/pdk/context/none.rb +22 -0
  64. data/lib/pdk/context.rb +98 -0
  65. data/lib/pdk/control_repo.rb +89 -0
  66. data/lib/pdk/generate/defined_type.rb +27 -33
  67. data/lib/pdk/generate/fact.rb +26 -0
  68. data/lib/pdk/generate/function.rb +49 -0
  69. data/lib/pdk/generate/module.rb +160 -153
  70. data/lib/pdk/generate/provider.rb +16 -69
  71. data/lib/pdk/generate/puppet_class.rb +27 -32
  72. data/lib/pdk/generate/puppet_object.rb +100 -159
  73. data/lib/pdk/generate/task.rb +34 -51
  74. data/lib/pdk/generate/transport.rb +34 -0
  75. data/lib/pdk/generate.rb +21 -8
  76. data/lib/pdk/logger.rb +24 -6
  77. data/lib/pdk/module/build.rb +125 -37
  78. data/lib/pdk/module/convert.rb +146 -65
  79. data/lib/pdk/module/metadata.rb +72 -71
  80. data/lib/pdk/module/release.rb +255 -0
  81. data/lib/pdk/module/update.rb +48 -37
  82. data/lib/pdk/module/update_manager.rb +75 -39
  83. data/lib/pdk/module.rb +10 -2
  84. data/lib/pdk/monkey_patches.rb +268 -0
  85. data/lib/pdk/report/event.rb +36 -48
  86. data/lib/pdk/report.rb +35 -22
  87. data/lib/pdk/template/fetcher/git.rb +84 -0
  88. data/lib/pdk/template/fetcher/local.rb +29 -0
  89. data/lib/pdk/template/fetcher.rb +100 -0
  90. data/lib/pdk/template/renderer/v1/legacy_template_dir.rb +108 -0
  91. data/lib/pdk/template/renderer/v1/renderer.rb +131 -0
  92. data/lib/pdk/template/renderer/v1/template_file.rb +100 -0
  93. data/lib/pdk/template/renderer/v1.rb +25 -0
  94. data/lib/pdk/template/renderer.rb +97 -0
  95. data/lib/pdk/template/template_dir.rb +67 -0
  96. data/lib/pdk/template.rb +52 -0
  97. data/lib/pdk/tests/unit.rb +101 -51
  98. data/lib/pdk/util/bundler.rb +44 -42
  99. data/lib/pdk/util/changelog_generator.rb +138 -0
  100. data/lib/pdk/util/env.rb +48 -0
  101. data/lib/pdk/util/filesystem.rb +139 -2
  102. data/lib/pdk/util/git.rb +108 -8
  103. data/lib/pdk/util/json_finder.rb +86 -0
  104. data/lib/pdk/util/puppet_strings.rb +125 -0
  105. data/lib/pdk/util/puppet_version.rb +71 -87
  106. data/lib/pdk/util/ruby_version.rb +49 -25
  107. data/lib/pdk/util/template_uri.rb +283 -0
  108. data/lib/pdk/util/vendored_file.rb +34 -42
  109. data/lib/pdk/util/version.rb +11 -10
  110. data/lib/pdk/util/windows/api_types.rb +74 -44
  111. data/lib/pdk/util/windows/file.rb +31 -27
  112. data/lib/pdk/util/windows/process.rb +74 -0
  113. data/lib/pdk/util/windows/string.rb +19 -12
  114. data/lib/pdk/util/windows.rb +2 -0
  115. data/lib/pdk/util.rb +111 -124
  116. data/lib/pdk/validate/control_repo/control_repo_validator_group.rb +23 -0
  117. data/lib/pdk/validate/control_repo/environment_conf_validator.rb +98 -0
  118. data/lib/pdk/validate/external_command_validator.rb +213 -0
  119. data/lib/pdk/validate/internal_ruby_validator.rb +101 -0
  120. data/lib/pdk/validate/invokable_validator.rb +238 -0
  121. data/lib/pdk/validate/metadata/metadata_json_lint_validator.rb +84 -0
  122. data/lib/pdk/validate/metadata/metadata_syntax_validator.rb +76 -0
  123. data/lib/pdk/validate/metadata/metadata_validator_group.rb +20 -0
  124. data/lib/pdk/validate/puppet/puppet_epp_validator.rb +131 -0
  125. data/lib/pdk/validate/puppet/puppet_lint_validator.rb +66 -0
  126. data/lib/pdk/validate/puppet/puppet_plan_syntax_validator.rb +38 -0
  127. data/lib/pdk/validate/puppet/puppet_syntax_validator.rb +135 -0
  128. data/lib/pdk/validate/puppet/puppet_validator_group.rb +22 -0
  129. data/lib/pdk/validate/ruby/ruby_rubocop_validator.rb +79 -0
  130. data/lib/pdk/validate/ruby/ruby_validator_group.rb +19 -0
  131. data/lib/pdk/validate/tasks/tasks_metadata_lint_validator.rb +83 -0
  132. data/lib/pdk/validate/tasks/tasks_name_validator.rb +45 -0
  133. data/lib/pdk/validate/tasks/tasks_validator_group.rb +20 -0
  134. data/lib/pdk/validate/validator.rb +120 -0
  135. data/lib/pdk/validate/validator_group.rb +107 -0
  136. data/lib/pdk/validate/yaml/yaml_syntax_validator.rb +86 -0
  137. data/lib/pdk/validate/yaml/yaml_validator_group.rb +19 -0
  138. data/lib/pdk/validate.rb +86 -12
  139. data/lib/pdk/version.rb +2 -2
  140. data/lib/pdk.rb +60 -10
  141. metadata +138 -100
  142. data/lib/pdk/cli/module/build.rb +0 -14
  143. data/lib/pdk/cli/module/generate.rb +0 -45
  144. data/lib/pdk/cli/module.rb +0 -14
  145. data/lib/pdk/i18n.rb +0 -4
  146. data/lib/pdk/module/templatedir.rb +0 -321
  147. data/lib/pdk/template_file.rb +0 -95
  148. data/lib/pdk/validate/base_validator.rb +0 -215
  149. data/lib/pdk/validate/metadata/metadata_json_lint.rb +0 -86
  150. data/lib/pdk/validate/metadata/metadata_syntax.rb +0 -109
  151. data/lib/pdk/validate/metadata_validator.rb +0 -30
  152. data/lib/pdk/validate/puppet/puppet_lint.rb +0 -67
  153. data/lib/pdk/validate/puppet/puppet_syntax.rb +0 -112
  154. data/lib/pdk/validate/puppet_validator.rb +0 -30
  155. data/lib/pdk/validate/ruby/rubocop.rb +0 -77
  156. data/lib/pdk/validate/ruby_validator.rb +0 -29
  157. data/lib/pdk/validate/tasks/metadata_lint.rb +0 -126
  158. data/lib/pdk/validate/tasks/name.rb +0 -88
  159. data/lib/pdk/validate/tasks_validator.rb +0 -33
  160. data/lib/pdk/validate/yaml/syntax.rb +0 -109
  161. data/lib/pdk/validate/yaml_validator.rb +0 -31
  162. data/locales/config.yaml +0 -21
  163. data/locales/pdk.pot +0 -1291
@@ -1,87 +1,86 @@
1
- require 'json'
2
- require 'pdk/util/filesystem'
1
+ require 'pdk'
3
2
 
4
3
  module PDK
5
4
  module Module
6
5
  class Metadata
7
6
  attr_accessor :data
8
7
 
9
- include PDK::Util::Filesystem
10
-
11
8
  OPERATING_SYSTEMS = {
12
9
  'RedHat based Linux' => [
13
10
  {
14
- 'operatingsystem' => 'CentOS',
15
- 'operatingsystemrelease' => ['7'],
11
+ 'operatingsystem' => 'CentOS',
12
+ 'operatingsystemrelease' => ['7']
16
13
  },
17
14
  {
18
- 'operatingsystem' => 'OracleLinux',
19
- 'operatingsystemrelease' => ['7'],
15
+ 'operatingsystem' => 'OracleLinux',
16
+ 'operatingsystemrelease' => ['7']
20
17
  },
21
18
  {
22
- 'operatingsystem' => 'RedHat',
23
- 'operatingsystemrelease' => ['7'],
19
+ 'operatingsystem' => 'RedHat',
20
+ 'operatingsystemrelease' => ['8']
24
21
  },
25
22
  {
26
- 'operatingsystem' => 'Scientific',
27
- 'operatingsystemrelease' => ['7'],
28
- },
23
+ 'operatingsystem' => 'Scientific',
24
+ 'operatingsystemrelease' => ['7']
25
+ }
29
26
  ],
30
27
  'Debian based Linux' => [
31
28
  {
32
- 'operatingsystem' => 'Debian',
33
- 'operatingsystemrelease' => ['8'],
29
+ 'operatingsystem' => 'Debian',
30
+ 'operatingsystemrelease' => ['10']
34
31
  },
35
32
  {
36
- 'operatingsystem' => 'Ubuntu',
37
- 'operatingsystemrelease' => ['16.04'],
38
- },
33
+ 'operatingsystem' => 'Ubuntu',
34
+ 'operatingsystemrelease' => ['18.04']
35
+ }
39
36
  ],
40
37
  'Fedora' => {
41
- 'operatingsystem' => 'Fedora',
42
- 'operatingsystemrelease' => ['25'],
38
+ 'operatingsystem' => 'Fedora',
39
+ 'operatingsystemrelease' => ['29']
43
40
  },
44
41
  'OSX' => {
45
- 'operatingsystem' => 'Darwin',
46
- 'operatingsystemrelease' => ['16'],
42
+ 'operatingsystem' => 'Darwin',
43
+ 'operatingsystemrelease' => ['16']
47
44
  },
48
45
  'SLES' => {
49
- 'operatingsystem' => 'SLES',
50
- 'operatingsystemrelease' => ['12'],
46
+ 'operatingsystem' => 'SLES',
47
+ 'operatingsystemrelease' => ['15']
51
48
  },
52
49
  'Solaris' => {
53
- 'operatingsystem' => 'Solaris',
54
- 'operatingsystemrelease' => ['11'],
50
+ 'operatingsystem' => 'Solaris',
51
+ 'operatingsystemrelease' => ['11']
55
52
  },
56
53
  'Windows' => {
57
- 'operatingsystem' => 'windows',
58
- 'operatingsystemrelease' => ['2008 R2', '2012 R2', '10'],
54
+ 'operatingsystem' => 'windows',
55
+ 'operatingsystemrelease' => ['2019', '10']
59
56
  },
57
+ 'AIX' => {
58
+ 'operatingsystem' => 'AIX',
59
+ 'operatingsystemrelease' => ['6.1', '7.1', '7.2']
60
+ }
60
61
  }.freeze
61
62
 
62
63
  DEFAULT_OPERATING_SYSTEMS = [
63
64
  'RedHat based Linux',
64
65
  'Debian based Linux',
65
- 'Windows',
66
+ 'Windows'
66
67
  ].freeze
67
68
 
68
69
  DEFAULTS = {
69
- 'name' => nil,
70
- 'version' => '0.1.0',
71
- 'author' => nil,
72
- 'summary' => '',
73
- 'license' => 'Apache-2.0',
74
- 'source' => '',
75
- 'project_page' => nil,
76
- 'issues_url' => nil,
77
- 'dependencies' => [],
70
+ 'name' => nil,
71
+ 'version' => '0.1.0',
72
+ 'author' => nil,
73
+ 'summary' => '',
74
+ 'license' => 'Apache-2.0',
75
+ 'source' => '',
76
+ 'project_page' => nil,
77
+ 'issues_url' => nil,
78
+ 'dependencies' => [],
78
79
  'data_provider' => nil,
79
- 'operatingsystem_support' => DEFAULT_OPERATING_SYSTEMS.map { |os_name|
80
- OPERATING_SYSTEMS[os_name]
81
- }.flatten,
80
+ 'operatingsystem_support' => DEFAULT_OPERATING_SYSTEMS.dup,
82
81
  'requirements' => [
83
- { 'name' => 'puppet', 'version_requirement' => '>= 4.10.0 < 7.0.0' },
84
- ],
82
+ { 'name' => 'puppet', 'version_requirement' => '>= 7.24 < 9.0.0' }
83
+ ]
85
84
  }.freeze
86
85
 
87
86
  def initialize(params = {})
@@ -90,24 +89,21 @@ module PDK
90
89
  end
91
90
 
92
91
  def self.from_file(metadata_json_path)
93
- if metadata_json_path.nil?
94
- raise ArgumentError, _('Cannot read metadata from file: no path to file was given.')
95
- end
92
+ raise ArgumentError, 'Cannot read metadata from file: no path to file was given.' if metadata_json_path.nil?
96
93
 
97
- unless File.file?(metadata_json_path)
98
- raise ArgumentError, _("'%{file}' does not exist or is not a file.") % { file: metadata_json_path }
99
- end
94
+ raise ArgumentError, format("'%{file}' does not exist or is not a file.", file: metadata_json_path) unless PDK::Util::Filesystem.file?(metadata_json_path)
100
95
 
101
- unless File.readable?(metadata_json_path)
102
- raise ArgumentError, _("Unable to open '%{file}' for reading.") % { file: metadata_json_path }
103
- end
96
+ raise ArgumentError, format("Unable to open '%{file}' for reading.", file: metadata_json_path) unless PDK::Util::Filesystem.readable?(metadata_json_path)
104
97
 
98
+ require 'json'
105
99
  begin
106
- data = JSON.parse(File.read(metadata_json_path))
100
+ data = JSON.parse(PDK::Util::Filesystem.read_file(metadata_json_path))
107
101
  rescue JSON::JSONError => e
108
- raise ArgumentError, _('Invalid JSON in metadata.json: %{msg}') % { msg: e.message }
102
+ raise ArgumentError, format('Invalid JSON in metadata.json: %{msg}', msg: e.message)
109
103
  end
110
104
 
105
+ require 'pdk/util'
106
+ 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
111
107
  new(data)
112
108
  end
113
109
 
@@ -118,12 +114,14 @@ module PDK
118
114
  self
119
115
  end
120
116
 
121
- def to_json
117
+ def to_json(*_args)
118
+ require 'json'
119
+
122
120
  JSON.pretty_generate(@data.dup.delete_if { |_key, value| value.nil? })
123
121
  end
124
122
 
125
123
  def write!(path)
126
- write_file(path, to_json)
124
+ PDK::Util::Filesystem.write_file(path, to_json)
127
125
  end
128
126
 
129
127
  def forge_ready?
@@ -131,14 +129,16 @@ module PDK
131
129
  end
132
130
 
133
131
  def interview_for_forge!
132
+ require 'pdk/generate/module'
133
+
134
134
  PDK::Generate::Module.module_interview(self, only_ask: missing_fields)
135
135
  end
136
136
 
137
137
  def validate_puppet_version_requirement!
138
138
  msgs = {
139
- no_reqs: _('Module metadata does not contain any requirements.'),
140
- no_puppet_req: _('Module metadata does not contain a "puppet" requirement.'),
141
- no_puppet_ver: _('The "puppet" requirement in module metadata does not specify a "version_requirement".'),
139
+ no_reqs: 'Module metadata does not contain any requirements.',
140
+ no_puppet_req: 'Module metadata does not contain a "puppet" requirement.',
141
+ no_puppet_ver: 'The "puppet" requirement in module metadata does not specify a "version_requirement".'
142
142
  }
143
143
 
144
144
  raise ArgumentError, msgs[:no_reqs] unless @data.key?('requirements')
@@ -153,40 +153,41 @@ module PDK
153
153
  end
154
154
  end
155
155
 
156
- private
157
-
158
156
  def missing_fields
159
- fields = DEFAULTS.keys - %w[data_provider requirements dependencies]
157
+ fields = DEFAULTS.keys - ['data_provider', 'requirements', 'dependencies']
160
158
  fields.select { |key| @data[key].nil? || @data[key].empty? }
161
159
  end
162
160
 
161
+ private
162
+
163
163
  # Do basic validation and parsing of the name parameter.
164
164
  def process_name(data)
165
165
  validate_name(data['name'])
166
- author, _modname = data['name'].split(%r{[-/]}, 2)
166
+ author, modname = data['name'].split(%r{[-/]}, 2)
167
+ data['name'] = [author, modname].join('-')
167
168
 
168
169
  data['author'] ||= author if @data['author'] == DEFAULTS['author']
169
170
  end
170
171
 
171
172
  # Validates that the given module name is both namespaced and well-formed.
172
173
  def validate_name(name)
173
- return if name =~ %r{\A[a-z0-9]+[-\/][a-z][a-z0-9_]*\Z}i
174
+ return if %r{\A[a-z0-9]+[-/][a-z][a-z0-9_]*\Z}i.match?(name)
174
175
 
175
176
  namespace, modname = name.split(%r{[-/]}, 2)
176
177
  modname = :namespace_missing if namespace == ''
177
178
 
178
179
  err = case modname
179
180
  when nil, '', :namespace_missing
180
- _('Field must be a dash-separated user name and module name.')
181
- when %r{[^a-z0-9_]}i
182
- _('Module name must contain only alphanumeric or underscore characters.')
183
- when %r{^[^a-z]}i
184
- _('Module name must begin with a letter.')
181
+ 'Field must be a dash-separated user name and module name.'
182
+ when /[^a-z0-9_]/i
183
+ 'Module name must contain only alphanumeric or underscore characters.'
184
+ when /^[^a-z]/i
185
+ 'Module name must begin with a letter.'
185
186
  else
186
- _('Namespace must contain only alphanumeric characters.')
187
+ 'Namespace must contain only alphanumeric characters.'
187
188
  end
188
189
 
189
- raise ArgumentError, _("Invalid 'name' field in metadata.json: %{err}") % { err: err }
190
+ raise ArgumentError, format("Invalid 'name' field in metadata.json: %{err}", err: err)
190
191
  end
191
192
  end
192
193
  end
@@ -0,0 +1,255 @@
1
+ require 'pdk'
2
+ require 'uri'
3
+
4
+ module PDK
5
+ module Module
6
+ class Release
7
+ def self.invoke(module_path, options = {})
8
+ new(module_path, options).run
9
+ end
10
+
11
+ attr_reader :options, :module_path
12
+
13
+ def initialize(module_path, options = {})
14
+ @options = options
15
+
16
+ # TODO: Currently the release process can ONLY be run if the working directory IS the module root. However, in the future
17
+ # this WILL change, so we have the API arguments for it, but only accept `nil` for the first parameter
18
+ raise PDK::CLI::ExitWithError, 'Running the release process outside of the working directory is not supported' unless module_path.nil?
19
+
20
+ if module_path.nil?
21
+ module_path = PDK::Util.module_root
22
+ raise PDK::CLI::ExitWithError, 'The module release process requires a valid module path' if module_path.nil?
23
+ end
24
+ raise PDK::CLI::ExitWithError, format('%{module_path} is not a valid module', module_path: module_path) unless PDK::Util.in_module_root?(module_path)
25
+
26
+ @module_path = module_path
27
+ end
28
+
29
+ def run
30
+ # Pre-release checks
31
+ unless force?
32
+ raise PDK::CLI::ExitWithError, 'The module is not PDK compatible' if requires_pdk_compatibility? && !pdk_compatible?
33
+ raise PDK::CLI::ExitWithError, 'The module is not Forge compatible' if requires_forge_compatibility? && !forge_compatible?
34
+ end
35
+
36
+ # Note that these checks are duplicated in the run_publish method, however it's a much better
37
+ # experience to fail early, than going through the whole process, only to error at the end knowing full well
38
+ # it'll fail anyway.
39
+ validate_publish_options!
40
+
41
+ run_validations(options) unless skip_validation?
42
+
43
+ PDK.logger.info format('Releasing %{module_name} - from version %{module_version}', module_name: module_metadata.data['name'], module_version: module_metadata.data['version'])
44
+
45
+ PDK::Util::ChangelogGenerator.generate_changelog unless skip_changelog?
46
+
47
+ # Calculate the new module version
48
+ new_version = specified_version
49
+ new_version = PDK::Util::ChangelogGenerator.compute_next_version(module_metadata.data['version']) if new_version.nil? && !skip_changelog?
50
+ new_version = module_metadata.data['version'] if new_version.nil?
51
+
52
+ if new_version != module_metadata.data['version']
53
+ PDK.logger.info format('Updating version to %{module_version}', module_version: new_version)
54
+
55
+ # Set the new version in metadata file
56
+ module_metadata.data['version'] = new_version
57
+ write_module_metadata!
58
+
59
+ # Update the changelog with the correct version
60
+ PDK::Util::ChangelogGenerator.generate_changelog unless skip_changelog?
61
+
62
+ # Check if the versions match
63
+ latest_version = PDK::Util::ChangelogGenerator.latest_version
64
+ if !latest_version && (new_version != latest_version)
65
+ raise PDK::CLI::ExitWithError, format('%{new_version} does not match %{latest_version}', new_version: new_version, latest_version: latest_version)
66
+ end
67
+ end
68
+
69
+ run_documentation(options) unless skip_documentation?
70
+
71
+ run_dependency_checker(options) unless skip_dependency?
72
+
73
+ if skip_build?
74
+ # Even if we're skipping the build, we still need the name of the tarball
75
+ # Use the specified package path if set
76
+ package_file = specified_package if package_file.nil?
77
+ # Use the default as a last resort
78
+ package_file = default_package_filename if package_file.nil?
79
+ else
80
+ package_file = run_build(options)
81
+ end
82
+
83
+ run_publish(options.dup, package_file) unless skip_publish?
84
+ end
85
+
86
+ def module_metadata
87
+ @module_metada ||= PDK::Module::Metadata.from_file(File.join(module_path, 'metadata.json'))
88
+ end
89
+
90
+ def write_module_metadata!
91
+ module_metadata.write!(File.join(module_path, 'metadata.json'))
92
+ clear_cached_data
93
+ end
94
+
95
+ def default_package_filename
96
+ return @default_tarball_filename unless @default_tarball_filename.nil?
97
+
98
+ builder = PDK::Module::Build.new(module_dir: module_path)
99
+ @default_tarball_filename = builder.package_file
100
+ end
101
+
102
+ def run_validations(opts)
103
+ # TODO: Surely I can use a pre-existing class for this?
104
+ PDK::CLI::Util.validate_puppet_version_opts(opts)
105
+
106
+ PDK::CLI::Util.module_version_check
107
+
108
+ puppet_env = PDK::CLI::Util.puppet_from_opts_or_env(opts)
109
+ PDK::Util::PuppetVersion.fetch_puppet_dev if opts[:'puppet-dev']
110
+ PDK::Util::RubyVersion.use(puppet_env[:ruby_version])
111
+
112
+ PDK::Util::Bundler.ensure_bundle!(puppet_env[:gemset])
113
+
114
+ validator_exit_code, = PDK::Validate.invoke_validators_by_name(PDK.context, PDK::Validate.validator_names, false, options)
115
+ raise PDK::CLI::ExitWithError, 'An error occured during validation' unless validator_exit_code.zero?
116
+ end
117
+
118
+ def run_documentation(_opts)
119
+ PDK.logger.info 'Updating documentation using puppet strings'
120
+ docs_command = PDK::CLI::Exec::InteractiveCommand.new(PDK::CLI::Exec.bundle_bin, 'exec', 'puppet', 'strings', 'generate', '--format', 'markdown', '--out', 'REFERENCE.md')
121
+ docs_command.context = :module
122
+ result = docs_command.execute!
123
+ raise PDK::CLI::ExitWithError, format('An error occured generating the module documentation: %{stdout}', stdout: result[:stdout]) unless result[:exit_code].zero?
124
+ end
125
+
126
+ def run_dependency_checker(_opts)
127
+ # run dependency-checker and output dependent modules list
128
+ PDK.logger.info 'Running dependency checks'
129
+
130
+ dep_command = PDK::CLI::Exec::Command.new('dependency-checker', 'metadata.json')
131
+ dep_command.context = :module
132
+ result = dep_command.execute!
133
+
134
+ raise PDK::CLI::ExitWithError, format('An error occured checking the module dependencies: %{stdout}', stdout: result[:stdout]) unless result[:exit_code].zero?
135
+ end
136
+
137
+ # @return [String] Path to the built tarball
138
+ def run_build(opts)
139
+ PDK::Module::Build.invoke(opts.dup)
140
+ end
141
+
142
+ def run_publish(_opts, tarball_path)
143
+ validate_publish_options!
144
+ raise PDK::CLI::ExitWithError, format('Module tarball %{tarball_path} does not exist', tarball_path: tarball_path) unless PDK::Util::Filesystem.file?(tarball_path)
145
+
146
+ # TODO: Replace this code when the upload functionality is added to the forge ruby gem
147
+ require 'base64'
148
+ file_data = Base64.encode64(PDK::Util::Filesystem.read_file(tarball_path, open_args: 'rb'))
149
+
150
+ PDK.logger.info 'Uploading tarball to puppet forge...'
151
+ uri = URI(forge_upload_url)
152
+ require 'net/http'
153
+ request = Net::HTTP::Post.new(uri.path)
154
+ request['Authorization'] = "Bearer #{forge_token}"
155
+ request['Content-Type'] = 'application/json'
156
+ data = { file: file_data }
157
+
158
+ request.body = data.to_json
159
+
160
+ require 'openssl'
161
+ use_ssl = uri.instance_of?(URI::HTTPS)
162
+ response = Net::HTTP.start(uri.host, uri.port, use_ssl: use_ssl) do |http|
163
+ http.request(request)
164
+ end
165
+
166
+ raise PDK::CLI::ExitWithError, format('Error uploading to Puppet Forge: %{result}', result: response.body) unless response.is_a?(Net::HTTPSuccess)
167
+
168
+ PDK.logger.info 'Publish to Forge was successful'
169
+ end
170
+
171
+ def validate_publish_options!
172
+ return if skip_publish?
173
+ raise PDK::CLI::ExitWithError, 'Missing forge-upload-url option' unless forge_upload_url
174
+ raise PDK::CLI::ExitWithError, 'Missing forge-token option' unless forge_token
175
+ end
176
+
177
+ def force?
178
+ options[:force]
179
+ end
180
+
181
+ def skip_build?
182
+ options[:'skip-build']
183
+ end
184
+
185
+ def skip_changelog?
186
+ options[:'skip-changelog']
187
+ end
188
+
189
+ def skip_dependency?
190
+ options[:'skip-dependency']
191
+ end
192
+
193
+ def skip_documentation?
194
+ options[:'skip-documentation']
195
+ end
196
+
197
+ def skip_publish?
198
+ options[:'skip-publish']
199
+ end
200
+
201
+ def skip_validation?
202
+ options[:'skip-validation']
203
+ end
204
+
205
+ def specified_version
206
+ options[:version]
207
+ end
208
+
209
+ def specified_package
210
+ options[:file]
211
+ end
212
+
213
+ def forge_token
214
+ options[:'forge-token']
215
+ end
216
+
217
+ def forge_upload_url
218
+ options[:'forge-upload-url']
219
+ end
220
+
221
+ def requires_pdk_compatibility?
222
+ # Validation, Changelog and Dependency checks require the
223
+ # module to be PDK Compatible
224
+ !(skip_validation? && skip_changelog? && skip_dependency?)
225
+ end
226
+
227
+ def requires_forge_compatibility?
228
+ # Pushing to the for requires the metadata to be forge compatible
229
+ !skip_publish?
230
+ end
231
+
232
+ # :nocov:
233
+ # These are just convenience methods and are tested elsewhere
234
+ def forge_compatible?
235
+ module_metadata.forge_ready?
236
+ end
237
+
238
+ def pdk_compatible?
239
+ return @pdk_compatible unless @pdk_compatible.nil?
240
+
241
+ builder = PDK::Module::Build.new(module_dir: module_path)
242
+ @pdk_compatible = builder.module_pdk_compatible?
243
+ end
244
+ # :nocov:
245
+
246
+ private
247
+
248
+ def clear_cached_data
249
+ @module_metadata = nil
250
+ @pdk_compatible = nil
251
+ @default_tarball_filename = nil
252
+ end
253
+ end
254
+ end
255
+ end
@@ -1,21 +1,19 @@
1
- require 'pdk/module/convert'
1
+ require 'pdk'
2
2
 
3
3
  module PDK
4
4
  module Module
5
5
  class Update < Convert
6
- GIT_DESCRIBE_PATTERN = %r{\A(?<base>.+?)-(?<additional_commits>\d+)-g(?<sha>.+)\Z}
6
+ GIT_DESCRIBE_PATTERN = /\A(?<base>.+?)-(?<additional_commits>\d+)-g(?<sha>.+)\Z/.freeze
7
7
 
8
8
  def run
9
+ template_uri.uri_fragment = new_template_version
10
+
9
11
  stage_changes!
10
12
 
11
- if current_version == new_version
12
- PDK.logger.debug _('This module is already up to date with version %{version} of the template.') % {
13
- version: new_version,
14
- }
15
- end
13
+ PDK.logger.debug format('This module is already up to date with version %{version} of the template.', version: new_version) if current_version == new_version
16
14
 
17
15
  unless update_manager.changes?
18
- PDK::Report.default_target.puts(_('No changes required.'))
16
+ PDK::Report.default_target.puts('No changes required.')
19
17
  return
20
18
  end
21
19
 
@@ -27,31 +25,31 @@ module PDK
27
25
  return if noop?
28
26
 
29
27
  unless force?
30
- message = _('Do you want to continue and make these changes to your module?')
28
+ message = 'Do you want to continue and make these changes to your module?'
31
29
  return unless PDK::CLI::Util.prompt_for_yes(message)
32
30
  end
33
31
 
34
- # Remove these files straight away as these changes are not something that the user needs to review.
35
- if needs_bundle_update?
36
- update_manager.unlink_file('Gemfile.lock')
37
- update_manager.unlink_file(File.join('.bundle', 'config'))
38
- end
32
+ # Remove these files straight away as these changes are not something
33
+ # that the user needs to review.
34
+ update_manager.unlink_file('Gemfile.lock')
35
+ update_manager.unlink_file(File.join('.bundle', 'config'))
39
36
 
40
37
  update_manager.sync_changes!
41
38
 
42
- PDK::Util::Bundler.ensure_bundle! if needs_bundle_update?
39
+ require 'pdk/util/bundler'
40
+ PDK::Util::Bundler.ensure_bundle!
43
41
 
44
42
  print_result 'Update completed'
45
43
  end
46
44
 
47
45
  def module_metadata
48
- @module_metadata ||= PDK::Module::Metadata.from_file('metadata.json')
46
+ @module_metadata ||= PDK::Module::Metadata.from_file(File.join(module_dir, 'metadata.json'))
49
47
  rescue ArgumentError => e
50
48
  raise PDK::CLI::ExitWithError, e.message
51
49
  end
52
50
 
53
- def template_url
54
- @template_url ||= module_metadata.data['template-url']
51
+ def template_uri
52
+ @template_uri ||= PDK::Util::TemplateURI.new(module_metadata.data['template-url'])
55
53
  end
56
54
 
57
55
  def current_version
@@ -62,8 +60,30 @@ module PDK
62
60
  @new_version ||= fetch_remote_version(new_template_version)
63
61
  end
64
62
 
63
+ def new_template_version
64
+ return options[:'template-ref'] if options[:'template-ref']
65
+
66
+ if template_uri.default? && PDK::Util::Git.tag?(template_uri.bare_uri, template_uri.uri_fragment) && PDK::Util.package_install?
67
+ PDK::Util::TemplateURI.default_template_ref
68
+ else
69
+ template_uri.uri_fragment
70
+ end
71
+ end
72
+
73
+ def pinned_to_puppetlabs_template_tag?
74
+ return false unless template_uri.puppetlabs_template?
75
+ return false unless PDK::Util::Git.tag?(template_uri.bare_uri, template_uri.uri_fragment)
76
+ return false if latest_template?
77
+
78
+ template_uri.uri_fragment == new_template_version
79
+ end
80
+
65
81
  private
66
82
 
83
+ def latest_template?
84
+ [PDK::TEMPLATE_REF, 'master', 'main'].include?(template_uri.uri_fragment)
85
+ end
86
+
67
87
  def current_template_version
68
88
  @current_template_version ||= module_metadata.data['template-ref']
69
89
  end
@@ -73,38 +93,29 @@ module PDK
73
93
 
74
94
  return data if data.nil?
75
95
 
76
- if data[:base].start_with?('heads/')
77
- "#{data[:base].gsub(%r{^heads/}, '')}@#{data[:sha]}"
96
+ if %r{^(?:heads|remotes)/}.match?(data[:base])
97
+ "#{data[:base].gsub(%r{^(heads/|remotes/\w+?/)}, '')}@#{data[:sha]}"
78
98
  else
79
99
  data[:base]
80
100
  end
81
101
  end
82
102
 
83
- def new_template_version
84
- PDK::Util.default_template_ref
85
- end
86
-
87
- def fetch_remote_version(version)
88
- return version unless version.include?('/')
103
+ def fetch_remote_version(template_ref)
104
+ return template_ref unless current_template_version.is_a?(String)
105
+ return template_ref if template_ref == PDK::TEMPLATE_REF
89
106
 
90
- branch = version.partition('/').last
91
107
  sha_length = GIT_DESCRIBE_PATTERN.match(current_template_version)[:sha].length - 1
92
- "#{branch}@#{PDK::Util::Git.ls_remote(template_url, "refs/heads/#{branch}")[0..sha_length]}"
108
+ "#{template_ref}@#{PDK::Util::Git.ls_remote(template_uri.bare_uri, template_ref)[0..sha_length]}"
93
109
  end
94
110
 
95
111
  def update_message
96
- format_string = if template_url == PDK::Util.puppetlabs_template_url
97
- _('Updating %{module_name} using the default template, from %{current_version} to %{new_version}')
112
+ format_string = if template_uri.default?
113
+ 'Updating %{module_name} using the default template, from %{current_version} to %{new_version}'
98
114
  else
99
- _('Updating %{module_name} using the template at %{template_url}, from %{current_version} to %{new_version}')
115
+ 'Updating %{module_name} using the template at %{template_url}, from %{current_version} to %{new_version}'
100
116
  end
101
117
 
102
- format_string % {
103
- module_name: module_metadata.data['name'],
104
- template_url: template_url,
105
- current_version: current_version,
106
- new_version: new_version,
107
- }
118
+ format(format_string, module_name: module_metadata.data['name'], template_url: template_uri.bare_uri, current_version: current_version, new_version: new_version)
108
119
  end
109
120
  end
110
121
  end