pdk 1.3.2 → 1.4.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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +63 -1
- data/lib/pdk/cli.rb +6 -0
- data/lib/pdk/cli/build.rb +76 -0
- data/lib/pdk/cli/convert.rb +11 -0
- data/lib/pdk/cli/module.rb +1 -0
- data/lib/pdk/cli/module/build.rb +14 -0
- data/lib/pdk/cli/new.rb +1 -0
- data/lib/pdk/cli/new/module.rb +6 -0
- data/lib/pdk/cli/new/provider.rb +27 -0
- data/lib/pdk/cli/update.rb +32 -0
- data/lib/pdk/cli/util.rb +1 -0
- data/lib/pdk/cli/util/option_normalizer.rb +0 -19
- data/lib/pdk/cli/util/option_validator.rb +4 -27
- data/lib/pdk/generate.rb +2 -1
- data/lib/pdk/generate/module.rb +63 -37
- data/lib/pdk/generate/provider.rb +80 -0
- data/lib/pdk/generate/puppet_object.rb +25 -6
- data/lib/pdk/module/build.rb +208 -0
- data/lib/pdk/module/convert.rb +81 -50
- data/lib/pdk/module/metadata.rb +13 -0
- data/lib/pdk/module/templatedir.rb +12 -8
- data/lib/pdk/module/update.rb +111 -0
- data/lib/pdk/module/update_manager.rb +27 -21
- data/lib/pdk/util.rb +13 -1
- data/lib/pdk/util/git.rb +15 -0
- data/lib/pdk/validate/puppet/puppet_syntax.rb +44 -25
- data/lib/pdk/version.rb +1 -1
- data/locales/pdk.pot +279 -95
- metadata +37 -2
@@ -0,0 +1,80 @@
|
|
1
|
+
require 'pdk/generate/puppet_object'
|
2
|
+
|
3
|
+
module PDK
|
4
|
+
module Generate
|
5
|
+
class Provider < PuppetObject
|
6
|
+
OBJECT_TYPE = :provider
|
7
|
+
|
8
|
+
# Prepares the data needed to render the new defined type template.
|
9
|
+
#
|
10
|
+
# @return [Hash{Symbol => Object}] a hash of information that will be
|
11
|
+
# provided to the defined type and defined type spec templates during
|
12
|
+
# rendering.
|
13
|
+
def template_data
|
14
|
+
data = {
|
15
|
+
name: object_name,
|
16
|
+
provider_class: Provider.class_name_from_object_name(object_name),
|
17
|
+
}
|
18
|
+
|
19
|
+
data
|
20
|
+
end
|
21
|
+
|
22
|
+
def raise_precondition_error(error)
|
23
|
+
raise PDK::CLI::ExitWithError, _('%{error}: Creating a provider needs some local configuration in your module.' \
|
24
|
+
' Please follow the docs at https://github.com/puppetlabs/puppet-resource_api#getting-started.') % { error: error }
|
25
|
+
end
|
26
|
+
|
27
|
+
def check_preconditions
|
28
|
+
super
|
29
|
+
# These preconditions can be removed once the pdk-templates are carrying the puppet-resource_api gem by default, and have switched
|
30
|
+
# the default mock_with value.
|
31
|
+
sync_path = PDK::Util.find_upwards('.sync.yml')
|
32
|
+
if sync_path.nil?
|
33
|
+
raise_precondition_error(_('.sync.yml not found'))
|
34
|
+
end
|
35
|
+
sync = YAML.load_file(sync_path)
|
36
|
+
if !sync.is_a? Hash
|
37
|
+
raise_precondition_error(_('.sync.yml contents is not a Hash'))
|
38
|
+
elsif !sync.key? 'Gemfile'
|
39
|
+
raise_precondition_error(_('Gemfile configuration not found'))
|
40
|
+
elsif !sync['Gemfile'].key? 'optional'
|
41
|
+
raise_precondition_error(_('Gemfile.optional configuration not found'))
|
42
|
+
elsif !sync['Gemfile']['optional'].key? ':development'
|
43
|
+
raise_precondition_error(_('Gemfile.optional.:development configuration not found'))
|
44
|
+
elsif sync['Gemfile']['optional'][':development'].none? { |g| g['gem'] == 'puppet-resource_api' }
|
45
|
+
raise_precondition_error(_('puppet-resource_api not found in the Gemfile config'))
|
46
|
+
elsif !sync.key? 'spec/spec_helper.rb'
|
47
|
+
raise_precondition_error(_('spec/spec_helper.rb configuration not found'))
|
48
|
+
elsif !sync['spec/spec_helper.rb'].key? 'mock_with'
|
49
|
+
raise_precondition_error(_('spec/spec_helper.rb.mock_with configuration not found'))
|
50
|
+
elsif !sync['spec/spec_helper.rb']['mock_with'] == ':rspec'
|
51
|
+
raise_precondition_error(_('spec/spec_helper.rb.mock_with not set to \':rspec\''))
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
# @return [String] the path where the new type will be written.
|
56
|
+
def target_object_path
|
57
|
+
@target_object_path ||= File.join(module_dir, 'lib', 'puppet', 'type', object_name) + '.rb'
|
58
|
+
end
|
59
|
+
|
60
|
+
# @return [String] the path where the new provider will be written.
|
61
|
+
def target_addon_path
|
62
|
+
@target_addon_path ||= File.join(module_dir, 'lib', 'puppet', 'provider', object_name, object_name) + '.rb'
|
63
|
+
end
|
64
|
+
|
65
|
+
# Calculates the path to the file where the tests for the new defined
|
66
|
+
# type will be written.
|
67
|
+
#
|
68
|
+
# @return [String] the path where the tests for the new defined type
|
69
|
+
# will be written.
|
70
|
+
def target_spec_path
|
71
|
+
@target_spec_path ||= File.join(module_dir, 'spec', 'unit', 'puppet', 'provider', object_name, object_name) + '_spec.rb'
|
72
|
+
end
|
73
|
+
|
74
|
+
# transform a object name into a ruby class name
|
75
|
+
def self.class_name_from_object_name(object_name)
|
76
|
+
object_name.to_s.split('_').map(&:capitalize).join
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
@@ -58,6 +58,14 @@ module PDK
|
|
58
58
|
raise NotImplementedError
|
59
59
|
end
|
60
60
|
|
61
|
+
# @abstract Subclass and implement {#target_addon_path}. Implementations
|
62
|
+
# of this method should return a String containing the destination path
|
63
|
+
# of the additional object file being generated.
|
64
|
+
# @return [String] returns nil if there is no additional object file
|
65
|
+
def target_addon_path
|
66
|
+
nil
|
67
|
+
end
|
68
|
+
|
61
69
|
# @abstract Subclass and implement {#target_spec_path}. Implementations
|
62
70
|
# of this method should return a String containing the destination path
|
63
71
|
# of the tests for the object being generated.
|
@@ -76,16 +84,14 @@ module PDK
|
|
76
84
|
self.class::OBJECT_TYPE
|
77
85
|
end
|
78
86
|
|
79
|
-
# Check that the target files do not
|
80
|
-
#
|
81
|
-
# point for the class.
|
87
|
+
# Check preconditions of this template group. By default this only makes sure that the target files do not
|
88
|
+
# already exist. Override this (and call super) to add your own preconditions.
|
82
89
|
#
|
83
90
|
# @raise [PDK::CLI::ExitWithError] if the target files already exist.
|
84
|
-
# @raise [PDK::CLI::FatalError] (see #render_file)
|
85
91
|
#
|
86
92
|
# @api public
|
87
|
-
def
|
88
|
-
[target_object_path, target_spec_path].compact.each do |target_file|
|
93
|
+
def check_preconditions
|
94
|
+
[target_object_path, target_addon_path, target_spec_path].compact.each do |target_file|
|
89
95
|
next unless File.exist?(target_file)
|
90
96
|
|
91
97
|
raise PDK::CLI::ExitWithError, _("Unable to generate %{object_type}; '%{file}' already exists.") % {
|
@@ -93,11 +99,24 @@ module PDK
|
|
93
99
|
object_type: object_type,
|
94
100
|
}
|
95
101
|
end
|
102
|
+
end
|
103
|
+
|
104
|
+
# Check that the templates can be rendered. Find an appropriate template
|
105
|
+
# and create the target files from the template. This is the main entry
|
106
|
+
# point for the class.
|
107
|
+
#
|
108
|
+
# @raise [PDK::CLI::ExitWithError] if the target files already exist.
|
109
|
+
# @raise [PDK::CLI::FatalError] (see #render_file)
|
110
|
+
#
|
111
|
+
# @api public
|
112
|
+
def run
|
113
|
+
check_preconditions
|
96
114
|
|
97
115
|
with_templates do |template_path, config_hash|
|
98
116
|
data = template_data.merge(configs: config_hash)
|
99
117
|
|
100
118
|
render_file(target_object_path, template_path[:object], data)
|
119
|
+
render_file(target_addon_path, template_path[:addon], data) if template_path[:addon]
|
101
120
|
render_file(target_spec_path, template_path[:spec], data) if template_path[:spec]
|
102
121
|
end
|
103
122
|
end
|
@@ -0,0 +1,208 @@
|
|
1
|
+
require 'fileutils'
|
2
|
+
require 'minitar'
|
3
|
+
require 'zlib'
|
4
|
+
require 'pathspec'
|
5
|
+
require 'find'
|
6
|
+
|
7
|
+
module PDK
|
8
|
+
module Module
|
9
|
+
class Build
|
10
|
+
def self.invoke(options = {})
|
11
|
+
new(options).build
|
12
|
+
end
|
13
|
+
|
14
|
+
attr_reader :module_dir
|
15
|
+
attr_reader :target_dir
|
16
|
+
|
17
|
+
def initialize(options = {})
|
18
|
+
@module_dir = File.expand_path(options[:module_dir] || Dir.pwd)
|
19
|
+
@target_dir = File.expand_path(options[:'target-dir'] || File.join(module_dir, 'pkg'))
|
20
|
+
end
|
21
|
+
|
22
|
+
# Read and parse the values from metadata.json for the module that is
|
23
|
+
# being built.
|
24
|
+
#
|
25
|
+
# @return [Hash{String => Object}] The hash of metadata values.
|
26
|
+
def metadata
|
27
|
+
@metadata ||= PDK::Module::Metadata.from_file(File.join(module_dir, 'metadata.json')).data
|
28
|
+
end
|
29
|
+
|
30
|
+
# Return the path where the built package file will be written to.
|
31
|
+
def package_file
|
32
|
+
@package_file ||= File.join(target_dir, "#{release_name}.tar.gz")
|
33
|
+
end
|
34
|
+
|
35
|
+
# Build a module package from a module directory.
|
36
|
+
#
|
37
|
+
# @return [String] The path to the built package file.
|
38
|
+
def build
|
39
|
+
create_build_dir
|
40
|
+
|
41
|
+
stage_module_in_build_dir
|
42
|
+
build_package
|
43
|
+
|
44
|
+
package_file
|
45
|
+
ensure
|
46
|
+
cleanup_build_dir
|
47
|
+
end
|
48
|
+
|
49
|
+
# Verify if there is an existing package in the target directory and prompts
|
50
|
+
# the user if they want to overwrite it.
|
51
|
+
def package_already_exists?
|
52
|
+
File.exist? package_file
|
53
|
+
end
|
54
|
+
|
55
|
+
# Check if the module is PDK Compatible. If not, then prompt the user if
|
56
|
+
# they want to run PDK Convert.
|
57
|
+
def module_pdk_compatible?
|
58
|
+
['pdk-version', 'template-url'].any? { |key| metadata.key?(key) }
|
59
|
+
end
|
60
|
+
|
61
|
+
# Return the path to the temporary build directory, which will be placed
|
62
|
+
# inside the target directory and match the release name (see #release_name).
|
63
|
+
def build_dir
|
64
|
+
@build_dir ||= File.join(target_dir, release_name)
|
65
|
+
end
|
66
|
+
|
67
|
+
# Create a temporary build directory where the files to be included in
|
68
|
+
# the package will be staged before building the tarball.
|
69
|
+
#
|
70
|
+
# If the directory already exists, remove it first.
|
71
|
+
def create_build_dir
|
72
|
+
cleanup_build_dir
|
73
|
+
|
74
|
+
FileUtils.mkdir_p(build_dir)
|
75
|
+
end
|
76
|
+
|
77
|
+
# Remove the temporary build directory and all its contents from disk.
|
78
|
+
#
|
79
|
+
# @return nil.
|
80
|
+
def cleanup_build_dir
|
81
|
+
FileUtils.rm_rf(build_dir, secure: true)
|
82
|
+
end
|
83
|
+
|
84
|
+
# Combine the module name and version into a Forge-compatible dash
|
85
|
+
# separated string.
|
86
|
+
#
|
87
|
+
# @return [String] The module name and version, joined by a dash.
|
88
|
+
def release_name
|
89
|
+
@release_name ||= [
|
90
|
+
metadata['name'],
|
91
|
+
metadata['version'],
|
92
|
+
].join('-')
|
93
|
+
end
|
94
|
+
|
95
|
+
# Iterate through all the files and directories in the module and stage
|
96
|
+
# them into the temporary build directory (unless ignored).
|
97
|
+
#
|
98
|
+
# @return nil
|
99
|
+
def stage_module_in_build_dir
|
100
|
+
Find.find(module_dir) do |path|
|
101
|
+
next if path == module_dir
|
102
|
+
|
103
|
+
ignored_path?(path) ? Find.prune : stage_path(path)
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
# Stage a file or directory from the module into the build directory.
|
108
|
+
#
|
109
|
+
# @param path [String] The path to the file or directory.
|
110
|
+
#
|
111
|
+
# @return nil.
|
112
|
+
def stage_path(path)
|
113
|
+
relative_path = Pathname.new(path).relative_path_from(Pathname.new(module_dir))
|
114
|
+
dest_path = File.join(build_dir, relative_path)
|
115
|
+
|
116
|
+
if File.directory?(path)
|
117
|
+
FileUtils.mkdir_p(dest_path, mode: File.stat(path).mode)
|
118
|
+
elsif File.symlink?(path)
|
119
|
+
warn_symlink(path)
|
120
|
+
else
|
121
|
+
FileUtils.cp(path, dest_path, preserve: true)
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
# Check if the given path matches one of the patterns listed in the
|
126
|
+
# ignore file.
|
127
|
+
#
|
128
|
+
# @param path [String] The path to be checked.
|
129
|
+
#
|
130
|
+
# @return [Boolean] true if the path matches and should be ignored.
|
131
|
+
def ignored_path?(path)
|
132
|
+
path = path.to_s + '/' if File.directory?(path)
|
133
|
+
|
134
|
+
!ignored_files.match_paths([path], module_dir).empty?
|
135
|
+
end
|
136
|
+
|
137
|
+
# Warn the user about a symlink that would have been included in the
|
138
|
+
# built package.
|
139
|
+
#
|
140
|
+
# @param path [String] The relative or absolute path to the symlink.
|
141
|
+
#
|
142
|
+
# @return nil.
|
143
|
+
def warn_symlink(path)
|
144
|
+
symlink_path = Pathname.new(path)
|
145
|
+
module_path = Pathname.new(module_dir)
|
146
|
+
|
147
|
+
PDK.logger.warn _('Symlinks in modules are not supported and will not be included in the package. Please investigate symlink %{from} -> %{to}.') % {
|
148
|
+
from: symlink_path.relative_path_from(module_path),
|
149
|
+
to: symlink_path.realpath.relative_path_from(module_path),
|
150
|
+
}
|
151
|
+
end
|
152
|
+
|
153
|
+
# Creates a gzip compressed tarball of the build directory.
|
154
|
+
#
|
155
|
+
# If the destination package already exists, it will be removed before
|
156
|
+
# creating the new tarball.
|
157
|
+
#
|
158
|
+
# @return nil.
|
159
|
+
def build_package
|
160
|
+
FileUtils.rm_f(package_file)
|
161
|
+
|
162
|
+
Dir.chdir(target_dir) do
|
163
|
+
Zlib::GzipWriter.open(package_file) do |package_fd|
|
164
|
+
Minitar.pack(release_name, package_fd)
|
165
|
+
end
|
166
|
+
end
|
167
|
+
end
|
168
|
+
|
169
|
+
# Select the most appropriate ignore file in the module directory.
|
170
|
+
#
|
171
|
+
# In order of preference, we first try `.pdkignore`, then `.pmtignore`
|
172
|
+
# and finally `.gitignore`.
|
173
|
+
#
|
174
|
+
# @return [String] The path to the file containing the patterns of file
|
175
|
+
# paths to ignore.
|
176
|
+
def ignore_file
|
177
|
+
@ignore_file ||= [
|
178
|
+
File.join(module_dir, '.pdkignore'),
|
179
|
+
File.join(module_dir, '.pmtignore'),
|
180
|
+
File.join(module_dir, '.gitignore'),
|
181
|
+
].find { |file| File.file?(file) && File.readable?(file) }
|
182
|
+
end
|
183
|
+
|
184
|
+
# Instantiate a new PathSpec class and populate it with the pattern(s) of
|
185
|
+
# files to be ignored.
|
186
|
+
#
|
187
|
+
# @return [PathSpec] The populated ignore path matcher.
|
188
|
+
def ignored_files
|
189
|
+
@ignored_files ||= if ignore_file.nil?
|
190
|
+
PathSpec.new
|
191
|
+
else
|
192
|
+
fd = File.open(ignore_file, 'rb:UTF-8')
|
193
|
+
data = fd.read
|
194
|
+
fd.close
|
195
|
+
|
196
|
+
PathSpec.new(data)
|
197
|
+
end
|
198
|
+
|
199
|
+
# Also ignore the target directory if it is in the module dir and not already ignored
|
200
|
+
if Find.find(@module_dir).include?(target_dir) && !@ignored_files.match(File.basename(target_dir) + '/')
|
201
|
+
@ignored_files = @ignored_files.add("\/#{File.basename(target_dir)}\/")
|
202
|
+
end
|
203
|
+
|
204
|
+
@ignored_files
|
205
|
+
end
|
206
|
+
end
|
207
|
+
end
|
208
|
+
end
|
data/lib/pdk/module/convert.rb
CHANGED
@@ -7,44 +7,30 @@ module PDK
|
|
7
7
|
module Module
|
8
8
|
class Convert
|
9
9
|
def self.invoke(options)
|
10
|
-
|
11
|
-
|
10
|
+
new(options).run
|
11
|
+
end
|
12
12
|
|
13
|
-
|
14
|
-
new_metadata = update_metadata('metadata.json', templates.metadata, options)
|
13
|
+
attr_reader :options
|
15
14
|
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
update_manager.modify_file('metadata.json', new_metadata)
|
20
|
-
else
|
21
|
-
update_manager.add_file('metadata.json', new_metadata)
|
22
|
-
end
|
15
|
+
def initialize(options = {})
|
16
|
+
@options = options
|
17
|
+
end
|
23
18
|
|
24
|
-
|
25
|
-
|
26
|
-
update_manager.modify_file(file_path, file_content)
|
27
|
-
else
|
28
|
-
update_manager.add_file(file_path, file_content)
|
29
|
-
end
|
30
|
-
end
|
31
|
-
end
|
19
|
+
def run
|
20
|
+
stage_changes!
|
32
21
|
|
33
22
|
unless update_manager.changes?
|
34
23
|
PDK::Report.default_target.puts(_('No changes required.'))
|
35
24
|
return
|
36
25
|
end
|
37
26
|
|
38
|
-
|
39
|
-
summary = get_summary(update_manager)
|
40
|
-
print_summary(summary)
|
27
|
+
print_summary
|
41
28
|
|
42
|
-
|
43
|
-
full_report(update_manager) unless update_manager.changes[:modified].empty?
|
29
|
+
full_report('convert_report.txt') unless update_manager.changes[:modified].empty?
|
44
30
|
|
45
|
-
return if
|
31
|
+
return if noop?
|
46
32
|
|
47
|
-
unless
|
33
|
+
unless force?
|
48
34
|
PDK.logger.info _(
|
49
35
|
'Module conversion is a potentially destructive action. ' \
|
50
36
|
'Ensure that you have committed your module to a version control ' \
|
@@ -54,21 +40,62 @@ module PDK
|
|
54
40
|
return unless continue
|
55
41
|
end
|
56
42
|
|
57
|
-
#
|
58
|
-
|
59
|
-
|
60
|
-
update_manager.
|
61
|
-
update_manager.remove_file(File.join('.bundle', 'config'))
|
43
|
+
# Remove these files straight away as these changes are not something that the user needs to review.
|
44
|
+
if needs_bundle_update?
|
45
|
+
update_manager.unlink_file('Gemfile.lock')
|
46
|
+
update_manager.unlink_file(File.join('.bundle', 'config'))
|
62
47
|
end
|
63
48
|
|
64
49
|
update_manager.sync_changes!
|
65
50
|
|
66
|
-
PDK::Util::Bundler.ensure_bundle! if
|
51
|
+
PDK::Util::Bundler.ensure_bundle! if needs_bundle_update?
|
52
|
+
|
53
|
+
print_result 'Convert completed'
|
54
|
+
end
|
55
|
+
|
56
|
+
def noop?
|
57
|
+
options[:noop]
|
58
|
+
end
|
59
|
+
|
60
|
+
def force?
|
61
|
+
options[:force]
|
62
|
+
end
|
63
|
+
|
64
|
+
def needs_bundle_update?
|
65
|
+
update_manager.changed?('Gemfile')
|
66
|
+
end
|
67
|
+
|
68
|
+
def stage_changes!
|
69
|
+
PDK::Module::TemplateDir.new(template_url, nil, false) do |templates|
|
70
|
+
new_metadata = update_metadata('metadata.json', templates.metadata)
|
71
|
+
|
72
|
+
if options[:noop] && new_metadata.nil?
|
73
|
+
update_manager.add_file('metadata.json', '')
|
74
|
+
elsif File.file?('metadata.json')
|
75
|
+
update_manager.modify_file('metadata.json', new_metadata)
|
76
|
+
else
|
77
|
+
update_manager.add_file('metadata.json', new_metadata)
|
78
|
+
end
|
79
|
+
|
80
|
+
templates.render do |file_path, file_content|
|
81
|
+
if File.exist? file_path
|
82
|
+
update_manager.modify_file(file_path, file_content)
|
83
|
+
else
|
84
|
+
update_manager.add_file(file_path, file_content)
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
def update_manager
|
91
|
+
@update_manager ||= PDK::Module::UpdateManager.new
|
92
|
+
end
|
67
93
|
|
68
|
-
|
94
|
+
def template_url
|
95
|
+
@template_url ||= options.fetch(:'template-url', PDK::Util.default_template_url)
|
69
96
|
end
|
70
97
|
|
71
|
-
def
|
98
|
+
def update_metadata(metadata_path, template_metadata)
|
72
99
|
if File.file?(metadata_path)
|
73
100
|
if File.readable?(metadata_path)
|
74
101
|
begin
|
@@ -79,12 +106,12 @@ module PDK
|
|
79
106
|
metadata = PDK::Generate::Module.prepare_metadata(options) unless options[:noop] # rubocop:disable Metrics/BlockNesting
|
80
107
|
end
|
81
108
|
else
|
82
|
-
raise PDK::CLI::ExitWithError, _('Unable to
|
109
|
+
raise PDK::CLI::ExitWithError, _('Unable to update module metadata; %{path} exists but it is not readable.') % {
|
83
110
|
path: metadata_path,
|
84
111
|
}
|
85
112
|
end
|
86
113
|
elsif File.exist?(metadata_path)
|
87
|
-
raise PDK::CLI::ExitWithError, _('Unable to
|
114
|
+
raise PDK::CLI::ExitWithError, _('Unable to update module metadata; %{path} exists but it is not a file.') % {
|
88
115
|
path: metadata_path,
|
89
116
|
}
|
90
117
|
else
|
@@ -102,14 +129,18 @@ module PDK
|
|
102
129
|
metadata.to_json
|
103
130
|
end
|
104
131
|
|
105
|
-
def
|
132
|
+
def summary
|
106
133
|
summary = {}
|
107
134
|
update_manager.changes.each do |category, update_category|
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
135
|
+
if update_category.respond_to?(:keys)
|
136
|
+
updated_files = update_category.keys
|
137
|
+
else
|
138
|
+
begin
|
139
|
+
updated_files = update_category.map { |file| file[:path] }
|
140
|
+
rescue TypeError
|
141
|
+
updated_files = update_category.to_a
|
142
|
+
end
|
143
|
+
end
|
113
144
|
|
114
145
|
summary[category] = updated_files
|
115
146
|
end
|
@@ -117,7 +148,7 @@ module PDK
|
|
117
148
|
summary
|
118
149
|
end
|
119
150
|
|
120
|
-
def
|
151
|
+
def print_summary
|
121
152
|
footer = false
|
122
153
|
|
123
154
|
summary.keys.each do |category|
|
@@ -131,23 +162,23 @@ module PDK
|
|
131
162
|
PDK::Report.default_target.puts(_("\n%{banner}") % { banner: generate_banner('', 40) }) if footer
|
132
163
|
end
|
133
164
|
|
134
|
-
def
|
135
|
-
PDK::Report.default_target.puts(_("\n%{banner}") % { banner: generate_banner(
|
165
|
+
def print_result(banner_text)
|
166
|
+
PDK::Report.default_target.puts(_("\n%{banner}") % { banner: generate_banner(banner_text, 40) })
|
136
167
|
summary_to_print = summary.map { |k, v| "#{v.length} files #{k}" unless v.empty? }.compact
|
137
168
|
PDK::Report.default_target.puts(_("\n%{summary}\n\n") % { summary: "#{summary_to_print.join(', ')}." })
|
138
169
|
end
|
139
170
|
|
140
|
-
def
|
141
|
-
File.open(
|
142
|
-
f.write("/*
|
171
|
+
def full_report(path)
|
172
|
+
File.open(path, 'w') do |f|
|
173
|
+
f.write("/* Report generated by PDK at #{Time.now} */")
|
143
174
|
update_manager.changes[:modified].each do |_, diff|
|
144
175
|
f.write("\n\n\n" + diff)
|
145
176
|
end
|
146
177
|
end
|
147
|
-
PDK::Report.default_target.puts(_("\nYou can find a report of differences in
|
178
|
+
PDK::Report.default_target.puts(_("\nYou can find a report of differences in %{path}.\n\n") % { path: path })
|
148
179
|
end
|
149
180
|
|
150
|
-
def
|
181
|
+
def generate_banner(text, width = 80)
|
151
182
|
padding = width - text.length
|
152
183
|
banner = ''
|
153
184
|
padding_char = '-'
|