pdk 1.14.1 → 1.18.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (128) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +155 -2
  3. data/lib/pdk.rb +28 -19
  4. data/lib/pdk/answer_file.rb +2 -95
  5. data/lib/pdk/bolt.rb +19 -0
  6. data/lib/pdk/cli.rb +4 -5
  7. data/lib/pdk/cli/bundle.rb +5 -1
  8. data/lib/pdk/cli/config.rb +3 -1
  9. data/lib/pdk/cli/config/get.rb +3 -1
  10. data/lib/pdk/cli/console.rb +1 -1
  11. data/lib/pdk/cli/convert.rb +16 -10
  12. data/lib/pdk/cli/exec.rb +2 -1
  13. data/lib/pdk/cli/exec/command.rb +45 -4
  14. data/lib/pdk/cli/exec_group.rb +78 -43
  15. data/lib/pdk/cli/get.rb +20 -0
  16. data/lib/pdk/cli/get/config.rb +24 -0
  17. data/lib/pdk/cli/module/build.rb +1 -1
  18. data/lib/pdk/cli/module/generate.rb +1 -1
  19. data/lib/pdk/cli/new/class.rb +2 -2
  20. data/lib/pdk/cli/new/defined_type.rb +2 -2
  21. data/lib/pdk/cli/new/provider.rb +2 -2
  22. data/lib/pdk/cli/new/task.rb +2 -2
  23. data/lib/pdk/cli/new/test.rb +2 -2
  24. data/lib/pdk/cli/new/transport.rb +2 -2
  25. data/lib/pdk/cli/release.rb +192 -0
  26. data/lib/pdk/cli/release/prep.rb +39 -0
  27. data/lib/pdk/cli/release/publish.rb +40 -0
  28. data/lib/pdk/cli/remove.rb +20 -0
  29. data/lib/pdk/cli/remove/config.rb +80 -0
  30. data/lib/pdk/cli/set.rb +20 -0
  31. data/lib/pdk/cli/set/config.rb +119 -0
  32. data/lib/pdk/cli/update.rb +18 -8
  33. data/lib/pdk/cli/util.rb +7 -3
  34. data/lib/pdk/cli/util/update_manager_printer.rb +82 -0
  35. data/lib/pdk/cli/validate.rb +26 -44
  36. data/lib/pdk/config.rb +265 -8
  37. data/lib/pdk/config/ini_file.rb +183 -0
  38. data/lib/pdk/config/ini_file_setting.rb +39 -0
  39. data/lib/pdk/config/namespace.rb +26 -6
  40. data/lib/pdk/config/setting.rb +3 -2
  41. data/lib/pdk/context.rb +99 -0
  42. data/lib/pdk/context/control_repo.rb +60 -0
  43. data/lib/pdk/context/module.rb +28 -0
  44. data/lib/pdk/context/none.rb +22 -0
  45. data/lib/pdk/control_repo.rb +90 -0
  46. data/lib/pdk/generate.rb +1 -0
  47. data/lib/pdk/generate/defined_type.rb +25 -32
  48. data/lib/pdk/generate/module.rb +42 -35
  49. data/lib/pdk/generate/provider.rb +16 -65
  50. data/lib/pdk/generate/puppet_class.rb +25 -31
  51. data/lib/pdk/generate/puppet_object.rb +84 -189
  52. data/lib/pdk/generate/resource_api_object.rb +55 -0
  53. data/lib/pdk/generate/task.rb +28 -46
  54. data/lib/pdk/generate/transport.rb +21 -75
  55. data/lib/pdk/module.rb +1 -1
  56. data/lib/pdk/module/build.rb +38 -25
  57. data/lib/pdk/module/convert.rb +61 -42
  58. data/lib/pdk/module/metadata.rb +1 -3
  59. data/lib/pdk/module/release.rb +254 -0
  60. data/lib/pdk/module/update.rb +24 -16
  61. data/lib/pdk/module/update_manager.rb +8 -1
  62. data/lib/pdk/report.rb +18 -12
  63. data/lib/pdk/report/event.rb +6 -3
  64. data/lib/pdk/template.rb +59 -0
  65. data/lib/pdk/template/fetcher.rb +98 -0
  66. data/lib/pdk/template/fetcher/git.rb +85 -0
  67. data/lib/pdk/template/fetcher/local.rb +28 -0
  68. data/lib/pdk/template/renderer.rb +96 -0
  69. data/lib/pdk/template/renderer/v1.rb +25 -0
  70. data/lib/pdk/template/renderer/v1/legacy_template_dir.rb +116 -0
  71. data/lib/pdk/template/renderer/v1/renderer.rb +132 -0
  72. data/lib/pdk/template/renderer/v1/template_file.rb +102 -0
  73. data/lib/pdk/template/template_dir.rb +67 -0
  74. data/lib/pdk/tests/unit.rb +5 -0
  75. data/lib/pdk/util.rb +55 -45
  76. data/lib/pdk/util/bundler.rb +9 -9
  77. data/lib/pdk/util/changelog_generator.rb +120 -0
  78. data/lib/pdk/util/env.rb +28 -11
  79. data/lib/pdk/util/filesystem.rb +62 -2
  80. data/lib/pdk/util/git.rb +60 -8
  81. data/lib/pdk/util/json_finder.rb +84 -0
  82. data/lib/pdk/util/puppet_strings.rb +3 -3
  83. data/lib/pdk/util/puppet_version.rb +4 -5
  84. data/lib/pdk/util/ruby_version.rb +9 -6
  85. data/lib/pdk/util/template_uri.rb +60 -48
  86. data/lib/pdk/util/version.rb +4 -4
  87. data/lib/pdk/validate.rb +79 -25
  88. data/lib/pdk/validate/control_repo/control_repo_validator_group.rb +23 -0
  89. data/lib/pdk/validate/control_repo/environment_conf_validator.rb +98 -0
  90. data/lib/pdk/validate/external_command_validator.rb +208 -0
  91. data/lib/pdk/validate/internal_ruby_validator.rb +100 -0
  92. data/lib/pdk/validate/invokable_validator.rb +215 -0
  93. data/lib/pdk/validate/metadata/metadata_json_lint_validator.rb +86 -0
  94. data/lib/pdk/validate/metadata/metadata_syntax_validator.rb +78 -0
  95. data/lib/pdk/validate/metadata/metadata_validator_group.rb +20 -0
  96. data/lib/pdk/validate/puppet/puppet_epp_validator.rb +133 -0
  97. data/lib/pdk/validate/puppet/puppet_lint_validator.rb +66 -0
  98. data/lib/pdk/validate/puppet/puppet_syntax_validator.rb +137 -0
  99. data/lib/pdk/validate/puppet/puppet_validator_group.rb +21 -0
  100. data/lib/pdk/validate/ruby/ruby_rubocop_validator.rb +80 -0
  101. data/lib/pdk/validate/ruby/ruby_validator_group.rb +19 -0
  102. data/lib/pdk/validate/tasks/tasks_metadata_lint_validator.rb +88 -0
  103. data/lib/pdk/validate/tasks/tasks_name_validator.rb +50 -0
  104. data/lib/pdk/validate/tasks/tasks_validator_group.rb +20 -0
  105. data/lib/pdk/validate/validator.rb +118 -0
  106. data/lib/pdk/validate/validator_group.rb +104 -0
  107. data/lib/pdk/validate/yaml/yaml_syntax_validator.rb +95 -0
  108. data/lib/pdk/validate/yaml/yaml_validator_group.rb +19 -0
  109. data/lib/pdk/version.rb +1 -1
  110. data/locales/pdk.pot +755 -319
  111. metadata +66 -24
  112. data/lib/pdk/module/templatedir.rb +0 -391
  113. data/lib/pdk/template_file.rb +0 -96
  114. data/lib/pdk/validate/base_validator.rb +0 -215
  115. data/lib/pdk/validate/metadata/metadata_json_lint.rb +0 -82
  116. data/lib/pdk/validate/metadata/metadata_syntax.rb +0 -111
  117. data/lib/pdk/validate/metadata_validator.rb +0 -26
  118. data/lib/pdk/validate/puppet/puppet_epp.rb +0 -137
  119. data/lib/pdk/validate/puppet/puppet_lint.rb +0 -64
  120. data/lib/pdk/validate/puppet/puppet_syntax.rb +0 -137
  121. data/lib/pdk/validate/puppet_validator.rb +0 -26
  122. data/lib/pdk/validate/ruby/rubocop.rb +0 -72
  123. data/lib/pdk/validate/ruby_validator.rb +0 -26
  124. data/lib/pdk/validate/tasks/metadata_lint.rb +0 -130
  125. data/lib/pdk/validate/tasks/name.rb +0 -90
  126. data/lib/pdk/validate/tasks_validator.rb +0 -29
  127. data/lib/pdk/validate/yaml/syntax.rb +0 -125
  128. data/lib/pdk/validate/yaml_validator.rb +0 -28
@@ -5,8 +5,6 @@ module PDK
5
5
  class Metadata
6
6
  attr_accessor :data
7
7
 
8
- include PDK::Util::Filesystem
9
-
10
8
  OPERATING_SYSTEMS = {
11
9
  'RedHat based Linux' => [
12
10
  {
@@ -127,7 +125,7 @@ module PDK
127
125
  end
128
126
 
129
127
  def write!(path)
130
- write_file(path, to_json)
128
+ PDK::Util::Filesystem.write_file(path, to_json)
131
129
  end
132
130
 
133
131
  def forge_ready?
@@ -0,0 +1,254 @@
1
+ require 'pdk'
2
+
3
+ module PDK
4
+ module Module
5
+ class Release
6
+ def self.invoke(module_path, options = {})
7
+ new(module_path, options).run
8
+ end
9
+
10
+ attr_reader :options
11
+
12
+ attr_reader :module_path
13
+
14
+ def initialize(module_path, options = {})
15
+ @options = options
16
+
17
+ # TODO: Currently the release process can ONLY be run if the working directory IS the module root. However, in the future
18
+ # this WILL change, so we have the API arguments for it, but only accept `nil` for the first parameter
19
+ raise PDK::CLI::ExitWithError, _('Running the release process outside of the working directory is not supported') unless module_path.nil?
20
+
21
+ if module_path.nil?
22
+ module_path = PDK::Util.module_root
23
+ raise PDK::CLI::ExitWithError, _('The module release process requires a valid module path') % { module_path: module_path } if module_path.nil?
24
+ end
25
+ raise PDK::CLI::ExitWithError, _('%{module_path} is not a valid module') % { module_path: module_path } unless PDK::Util.in_module_root?(module_path)
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 _('Releasing %{module_name} - from version %{module_version}') % {
44
+ module_name: module_metadata.data['name'],
45
+ module_version: module_metadata.data['version'],
46
+ }
47
+
48
+ PDK::Util::ChangelogGenerator.generate_changelog unless skip_changelog?
49
+
50
+ # Calculate the new module version
51
+ new_version = specified_version
52
+ if new_version.nil? && !skip_changelog?
53
+ new_version = PDK::Util::ChangelogGenerator.compute_next_version(module_metadata.data['version'])
54
+ end
55
+ new_version = module_metadata.data['version'] if new_version.nil?
56
+
57
+ if new_version != module_metadata.data['version']
58
+ PDK.logger.info _('Updating version to %{module_version}') % {
59
+ module_version: new_version,
60
+ }
61
+
62
+ # Set the new version in metadata file
63
+ module_metadata.data['version'] = new_version
64
+ write_module_metadata!
65
+
66
+ # Update the changelog with the correct version
67
+ PDK::Util::ChangelogGenerator.generate_changelog unless skip_changelog?
68
+ end
69
+
70
+ run_documentation(options) unless skip_documentation?
71
+
72
+ run_dependency_checker(options) unless skip_dependency?
73
+
74
+ if skip_build?
75
+ # Even if we're skipping the build, we still need the name of the tarball
76
+ # Use the specified package path if set
77
+ package_file = specified_package if package_file.nil?
78
+ # Use the default as a last resort
79
+ package_file = default_package_filename if package_file.nil?
80
+ else
81
+ package_file = run_build(options)
82
+ end
83
+
84
+ run_publish(options.dup, package_file) unless skip_publish?
85
+ end
86
+
87
+ def module_metadata
88
+ @module_metada ||= PDK::Module::Metadata.from_file(File.join(module_path, 'metadata.json'))
89
+ end
90
+
91
+ def write_module_metadata!
92
+ module_metadata.write!(File.join(module_path, 'metadata.json'))
93
+ clear_cached_data
94
+ end
95
+
96
+ def default_package_filename
97
+ return @default_tarball_filename unless @default_tarball_filename.nil?
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, _('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, _('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, _('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.class == 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, _('Error uploading to Puppet Forge: %{result}') % { result: response } unless response.is_a?(Net::HTTPSuccess)
167
+ PDK.logger.info _('Publish to Forge was successful')
168
+ end
169
+
170
+ def validate_publish_options!
171
+ return if skip_publish?
172
+ raise PDK::CLI::ExitWithError, _('Missing forge-upload-url option') unless forge_upload_url
173
+ raise PDK::CLI::ExitWithError, _('Missing forge-token option') unless forge_token
174
+ end
175
+
176
+ def force?
177
+ options[:force]
178
+ end
179
+
180
+ def skip_build?
181
+ options[:'skip-build']
182
+ end
183
+
184
+ def skip_changelog?
185
+ options[:'skip-changelog']
186
+ end
187
+
188
+ def skip_dependency?
189
+ options[:'skip-dependency']
190
+ end
191
+
192
+ def skip_documentation?
193
+ options[:'skip-documentation']
194
+ end
195
+
196
+ def skip_publish?
197
+ options[:'skip-publish']
198
+ end
199
+
200
+ def skip_validation?
201
+ options[:'skip-validation']
202
+ end
203
+
204
+ def specified_version
205
+ options[:version]
206
+ end
207
+
208
+ def specified_package
209
+ options[:file]
210
+ end
211
+
212
+ def forge_token
213
+ options[:'forge-token']
214
+ end
215
+
216
+ def forge_upload_url
217
+ options[:'forge-upload-url']
218
+ end
219
+
220
+ def requires_pdk_compatibility?
221
+ # Validation, Changelog and Dependency checks require the
222
+ # module to be PDK Compatible
223
+ !(skip_validation? && skip_changelog? && skip_dependency?)
224
+ end
225
+
226
+ def requires_forge_compatibility?
227
+ # Pushing to the for requires the metadata to be forge compatible
228
+ !skip_publish?
229
+ end
230
+
231
+ #:nocov:
232
+ # These are just convenience methods and are tested elsewhere
233
+ def forge_compatible?
234
+ module_metadata.forge_ready?
235
+ end
236
+
237
+ def pdk_compatible?
238
+ return @pdk_compatible unless @pdk_compatible.nil?
239
+
240
+ builder = PDK::Module::Build.new(module_dir: module_path)
241
+ @pdk_compatible = builder.module_pdk_compatible?
242
+ end
243
+ #:nocov:
244
+
245
+ private
246
+
247
+ def clear_cached_data
248
+ @module_metadata = nil
249
+ @pdk_compatible = nil
250
+ @default_tarball_filename = nil
251
+ end
252
+ end
253
+ end
254
+ end
@@ -6,7 +6,7 @@ module PDK
6
6
  GIT_DESCRIBE_PATTERN = %r{\A(?<base>.+?)-(?<additional_commits>\d+)-g(?<sha>.+)\Z}
7
7
 
8
8
  def run
9
- template_uri.git_ref = new_template_version
9
+ template_uri.uri_fragment = new_template_version
10
10
 
11
11
  stage_changes!
12
12
 
@@ -33,25 +33,21 @@ module PDK
33
33
  return unless PDK::CLI::Util.prompt_for_yes(message)
34
34
  end
35
35
 
36
- # Remove these files straight away as these changes are not something that the user needs to review.
37
- if needs_bundle_update?
38
- update_manager.unlink_file('Gemfile.lock')
39
- update_manager.unlink_file(File.join('.bundle', 'config'))
40
- end
36
+ # Remove these files straight away as these changes are not something
37
+ # that the user needs to review.
38
+ update_manager.unlink_file('Gemfile.lock')
39
+ update_manager.unlink_file(File.join('.bundle', 'config'))
41
40
 
42
41
  update_manager.sync_changes!
43
42
 
44
- if needs_bundle_update?
45
- require 'pdk/util/bundler'
46
-
47
- PDK::Util::Bundler.ensure_bundle!
48
- end
43
+ require 'pdk/util/bundler'
44
+ PDK::Util::Bundler.ensure_bundle!
49
45
 
50
46
  print_result 'Update completed'
51
47
  end
52
48
 
53
49
  def module_metadata
54
- @module_metadata ||= PDK::Module::Metadata.from_file('metadata.json')
50
+ @module_metadata ||= PDK::Module::Metadata.from_file(File.join(module_dir, 'metadata.json'))
55
51
  rescue ArgumentError => e
56
52
  raise PDK::CLI::ExitWithError, e.message
57
53
  end
@@ -71,15 +67,27 @@ module PDK
71
67
  def new_template_version
72
68
  return options[:'template-ref'] if options[:'template-ref']
73
69
 
74
- if template_uri.default? && template_uri.ref_is_tag? && PDK::Util.package_install?
70
+ if template_uri.default? && PDK::Util::Git.tag?(template_uri.bare_uri, template_uri.uri_fragment) && PDK::Util.package_install?
75
71
  PDK::Util::TemplateURI.default_template_ref
76
72
  else
77
- template_uri.git_ref
73
+ template_uri.uri_fragment
78
74
  end
79
75
  end
80
76
 
77
+ def pinned_to_puppetlabs_template_tag?
78
+ return false unless template_uri.puppetlabs_template?
79
+ return false unless PDK::Util::Git.tag?(template_uri.bare_uri, template_uri.uri_fragment)
80
+ return false if latest_template?
81
+
82
+ template_uri.uri_fragment == new_template_version
83
+ end
84
+
81
85
  private
82
86
 
87
+ def latest_template?
88
+ [PDK::TEMPLATE_REF, 'master'].include?(template_uri.uri_fragment)
89
+ end
90
+
83
91
  def current_template_version
84
92
  @current_template_version ||= module_metadata.data['template-ref']
85
93
  end
@@ -101,7 +109,7 @@ module PDK
101
109
  return template_ref if template_ref == PDK::TEMPLATE_REF
102
110
 
103
111
  sha_length = GIT_DESCRIBE_PATTERN.match(current_template_version)[:sha].length - 1
104
- "#{template_ref}@#{PDK::Util::Git.ls_remote(template_uri.git_remote, template_ref)[0..sha_length]}"
112
+ "#{template_ref}@#{PDK::Util::Git.ls_remote(template_uri.bare_uri, template_ref)[0..sha_length]}"
105
113
  end
106
114
 
107
115
  def update_message
@@ -113,7 +121,7 @@ module PDK
113
121
 
114
122
  format_string % {
115
123
  module_name: module_metadata.data['name'],
116
- template_url: template_uri.git_remote,
124
+ template_url: template_uri.bare_uri,
117
125
  current_version: current_version,
118
126
  new_version: new_version,
119
127
  }
@@ -75,6 +75,13 @@ module PDK
75
75
  changes[:modified].key?(path)
76
76
  end
77
77
 
78
+ def clear!
79
+ @modified_files.clear
80
+ @added_files.clear
81
+ @removed_files.clear
82
+ nil
83
+ end
84
+
78
85
  # Apply any pending changes stored in the UpdateManager to the module.
79
86
  #
80
87
  # @raise (see #calculate_diffs)
@@ -186,7 +193,7 @@ module PDK
186
193
 
187
194
  require 'diff/lcs/hunk'
188
195
 
189
- file_mtime = File.stat(path).mtime.localtime.strftime('%Y-%m-%d %H:%M:%S.%N %z')
196
+ file_mtime = PDK::Util::Filesystem.stat(path).mtime.localtime.strftime('%Y-%m-%d %H:%M:%S.%N %z')
190
197
  now = Time.now.localtime.strftime('%Y-%m-%d %H:%M:%S.%N %z')
191
198
 
192
199
  output << "--- #{path}\t#{file_mtime}"
@@ -51,9 +51,6 @@ module PDK
51
51
  require 'time'
52
52
  require 'socket'
53
53
 
54
- # Open a File Object for IO if target is a string containing a filename or path
55
- target = File.open(target, 'w') if target.is_a? String
56
-
57
54
  document = REXML::Document.new
58
55
  document << REXML::XMLDecl.new
59
56
  testsuites = REXML::Element.new('testsuites')
@@ -81,9 +78,14 @@ module PDK
81
78
  end
82
79
 
83
80
  document.elements << testsuites
84
- document.write(target, 2)
85
- ensure
86
- target.close if target.is_a? File
81
+ report = ''
82
+ document.write(report, 2)
83
+
84
+ if target.is_a?(String)
85
+ PDK::Util::Filesystem.write_file(target, report)
86
+ else
87
+ target << report
88
+ end
87
89
  end
88
90
 
89
91
  # Renders the report as plain text.
@@ -94,22 +96,26 @@ module PDK
94
96
  # @param target [#write] an IO object that the report will be written to.
95
97
  # Defaults to PDK::Report.default_target.
96
98
  def write_text(target = self.class.default_target)
97
- # Open a File Object for IO if target is a string containing a filename or path
98
- target = File.open(target, 'w') if target.is_a? String
99
99
  coverage_report = nil
100
+ report = []
100
101
 
101
102
  events.each do |_tool, tool_events|
102
103
  tool_events.each do |event|
103
104
  if event.rspec_puppet_coverage?
104
105
  coverage_report = event.to_text
105
106
  else
106
- target.puts(event.to_text) unless event.pass?
107
+ report << event.to_text unless event.pass?
107
108
  end
108
109
  end
109
110
  end
110
- ensure
111
- target.puts "\n#{coverage_report}" if coverage_report
112
- target.close if target.is_a? File
111
+
112
+ report << "\n#{coverage_report}" if coverage_report
113
+
114
+ if target.is_a?(String)
115
+ PDK::Util::Filesystem.write_file(target, report.join("\n"))
116
+ else
117
+ target << report.join("\n")
118
+ end
113
119
  end
114
120
  end
115
121
  end
@@ -98,7 +98,7 @@ module PDK
98
98
  # results.
99
99
  def rspec_puppet_coverage?
100
100
  @rspec_puppet_coverage_pattern ||= File.join('**', 'lib', 'rspec-puppet', 'coverage.rb')
101
- source == 'rspec' && File.fnmatch?(@rspec_puppet_coverage_pattern, File.expand_path(file))
101
+ source == 'rspec' && PDK::Util::Filesystem.fnmatch?(@rspec_puppet_coverage_pattern, PDK::Util::Filesystem.expand_path(file))
102
102
  end
103
103
 
104
104
  # Renders the event in a clang style text format.
@@ -346,10 +346,13 @@ module PDK
346
346
  def context_lines(max_num_lines = 5)
347
347
  return if file.nil? || line.nil?
348
348
 
349
- file_path = [file, File.join(PDK::Util.module_root, file)].find { |r| File.file?(r) }
349
+ file_path = [file, File.join(PDK::Util.module_root, file)].find do |path|
350
+ PDK::Util::Filesystem.file?(path)
351
+ end
352
+
350
353
  return if file_path.nil?
351
354
 
352
- file_content = File.read(file_path).split("\n")
355
+ file_content = PDK::Util::Filesystem.read_file(file_path).split("\n")
353
356
  delta = (max_num_lines - 1) / 2
354
357
  min = [0, (line - 1) - delta].max
355
358
  max = [(line - 1) + delta, file_content.length].min