pdk 2.3.0 → 2.4.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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +1329 -1321
- data/LICENSE +201 -201
- data/README.md +163 -163
- data/exe/pdk +10 -10
- data/lib/pdk/analytics/client/google_analytics.rb +143 -143
- data/lib/pdk/analytics/client/noop.rb +25 -25
- data/lib/pdk/analytics/util.rb +19 -19
- data/lib/pdk/analytics.rb +30 -30
- data/lib/pdk/answer_file.rb +12 -12
- data/lib/pdk/bolt.rb +19 -19
- data/lib/pdk/cli/build.rb +82 -82
- data/lib/pdk/cli/bundle.rb +48 -48
- data/lib/pdk/cli/config/get.rb +26 -26
- data/lib/pdk/cli/config.rb +22 -22
- data/lib/pdk/cli/console.rb +148 -148
- data/lib/pdk/cli/convert.rb +52 -52
- data/lib/pdk/cli/env.rb +52 -52
- data/lib/pdk/cli/errors.rb +25 -25
- data/lib/pdk/cli/exec/command.rb +293 -293
- data/lib/pdk/cli/exec/interactive_command.rb +114 -114
- data/lib/pdk/cli/exec.rb +84 -84
- data/lib/pdk/cli/exec_group.rb +104 -104
- data/lib/pdk/cli/get/config.rb +24 -24
- data/lib/pdk/cli/get.rb +20 -20
- data/lib/pdk/cli/module/build.rb +12 -12
- data/lib/pdk/cli/module/generate.rb +47 -47
- data/lib/pdk/cli/module.rb +14 -14
- data/lib/pdk/cli/new/class.rb +32 -32
- data/lib/pdk/cli/new/defined_type.rb +32 -32
- data/lib/pdk/cli/new/fact.rb +29 -29
- data/lib/pdk/cli/new/function.rb +29 -29
- data/lib/pdk/cli/new/module.rb +53 -53
- data/lib/pdk/cli/new/provider.rb +29 -29
- data/lib/pdk/cli/new/task.rb +34 -34
- data/lib/pdk/cli/new/test.rb +52 -52
- data/lib/pdk/cli/new/transport.rb +27 -27
- data/lib/pdk/cli/new.rb +21 -21
- data/lib/pdk/cli/release/prep.rb +39 -39
- data/lib/pdk/cli/release/publish.rb +50 -50
- data/lib/pdk/cli/release.rb +194 -194
- data/lib/pdk/cli/remove/config.rb +80 -80
- data/lib/pdk/cli/remove.rb +20 -20
- data/lib/pdk/cli/set/config.rb +119 -119
- data/lib/pdk/cli/set.rb +20 -20
- data/lib/pdk/cli/test/unit.rb +90 -90
- data/lib/pdk/cli/test.rb +11 -11
- data/lib/pdk/cli/update.rb +64 -64
- data/lib/pdk/cli/util/command_redirector.rb +27 -27
- data/lib/pdk/cli/util/interview.rb +72 -72
- data/lib/pdk/cli/util/option_normalizer.rb +55 -55
- data/lib/pdk/cli/util/option_validator.rb +68 -68
- data/lib/pdk/cli/util/spinner.rb +13 -13
- data/lib/pdk/cli/util/update_manager_printer.rb +82 -82
- data/lib/pdk/cli/util.rb +305 -305
- data/lib/pdk/cli/validate.rb +116 -116
- data/lib/pdk/cli.rb +175 -175
- data/lib/pdk/config/analytics_schema.json +26 -26
- data/lib/pdk/config/errors.rb +5 -5
- data/lib/pdk/config/ini_file.rb +183 -183
- data/lib/pdk/config/ini_file_setting.rb +39 -39
- data/lib/pdk/config/json.rb +34 -34
- data/lib/pdk/config/json_schema_namespace.rb +142 -142
- data/lib/pdk/config/json_schema_setting.rb +53 -53
- data/lib/pdk/config/json_with_schema.rb +49 -49
- data/lib/pdk/config/namespace.rb +354 -354
- data/lib/pdk/config/setting.rb +135 -135
- data/lib/pdk/config/validator.rb +31 -31
- data/lib/pdk/config/yaml.rb +46 -46
- data/lib/pdk/config/yaml_with_schema.rb +59 -59
- data/lib/pdk/config.rb +390 -390
- data/lib/pdk/context/control_repo.rb +60 -60
- data/lib/pdk/context/module.rb +28 -28
- data/lib/pdk/context/none.rb +22 -22
- data/lib/pdk/context.rb +99 -99
- data/lib/pdk/control_repo.rb +90 -90
- data/lib/pdk/generate/defined_type.rb +43 -43
- data/lib/pdk/generate/fact.rb +25 -25
- data/lib/pdk/generate/function.rb +48 -48
- data/lib/pdk/generate/module.rb +352 -352
- data/lib/pdk/generate/provider.rb +28 -28
- data/lib/pdk/generate/puppet_class.rb +43 -43
- data/lib/pdk/generate/puppet_object.rb +232 -232
- data/lib/pdk/generate/task.rb +68 -68
- data/lib/pdk/generate/transport.rb +33 -33
- data/lib/pdk/generate.rb +24 -24
- data/lib/pdk/i18n.rb +4 -4
- data/lib/pdk/logger.rb +45 -45
- data/lib/pdk/module/build.rb +322 -322
- data/lib/pdk/module/convert.rb +296 -296
- data/lib/pdk/module/metadata.rb +202 -202
- data/lib/pdk/module/release.rb +260 -260
- data/lib/pdk/module/update.rb +131 -131
- data/lib/pdk/module/update_manager.rb +227 -227
- data/lib/pdk/module.rb +30 -30
- data/lib/pdk/report/event.rb +370 -370
- data/lib/pdk/report.rb +121 -121
- data/lib/pdk/template/fetcher/git.rb +85 -85
- data/lib/pdk/template/fetcher/local.rb +28 -28
- data/lib/pdk/template/fetcher.rb +98 -98
- data/lib/pdk/template/renderer/v1/legacy_template_dir.rb +116 -116
- data/lib/pdk/template/renderer/v1/renderer.rb +132 -132
- data/lib/pdk/template/renderer/v1/template_file.rb +102 -102
- data/lib/pdk/template/renderer/v1.rb +25 -25
- data/lib/pdk/template/renderer.rb +96 -96
- data/lib/pdk/template/template_dir.rb +67 -67
- data/lib/pdk/template.rb +59 -59
- data/lib/pdk/tests/unit.rb +252 -252
- data/lib/pdk/util/bundler.rb +259 -259
- data/lib/pdk/util/changelog_generator.rb +137 -137
- data/lib/pdk/util/env.rb +47 -47
- data/lib/pdk/util/filesystem.rb +138 -138
- data/lib/pdk/util/git.rb +179 -179
- data/lib/pdk/util/json_finder.rb +85 -85
- data/lib/pdk/util/puppet_strings.rb +125 -125
- data/lib/pdk/util/puppet_version.rb +266 -266
- data/lib/pdk/util/ruby_version.rb +179 -179
- data/lib/pdk/util/template_uri.rb +295 -295
- data/lib/pdk/util/vendored_file.rb +93 -93
- data/lib/pdk/util/version.rb +43 -43
- data/lib/pdk/util/windows/api_types.rb +82 -82
- data/lib/pdk/util/windows/file.rb +36 -36
- data/lib/pdk/util/windows/process.rb +79 -79
- data/lib/pdk/util/windows/string.rb +16 -16
- data/lib/pdk/util/windows.rb +15 -15
- data/lib/pdk/util.rb +278 -277
- data/lib/pdk/validate/control_repo/control_repo_validator_group.rb +23 -23
- data/lib/pdk/validate/control_repo/environment_conf_validator.rb +98 -98
- data/lib/pdk/validate/external_command_validator.rb +208 -208
- data/lib/pdk/validate/internal_ruby_validator.rb +100 -100
- data/lib/pdk/validate/invokable_validator.rb +228 -228
- data/lib/pdk/validate/metadata/metadata_json_lint_validator.rb +86 -86
- data/lib/pdk/validate/metadata/metadata_syntax_validator.rb +78 -78
- data/lib/pdk/validate/metadata/metadata_validator_group.rb +20 -20
- data/lib/pdk/validate/puppet/puppet_epp_validator.rb +133 -133
- data/lib/pdk/validate/puppet/puppet_lint_validator.rb +66 -66
- data/lib/pdk/validate/puppet/puppet_syntax_validator.rb +137 -137
- data/lib/pdk/validate/puppet/puppet_validator_group.rb +21 -21
- data/lib/pdk/validate/ruby/ruby_rubocop_validator.rb +80 -80
- data/lib/pdk/validate/ruby/ruby_validator_group.rb +19 -19
- data/lib/pdk/validate/tasks/tasks_metadata_lint_validator.rb +88 -88
- data/lib/pdk/validate/tasks/tasks_name_validator.rb +50 -50
- data/lib/pdk/validate/tasks/tasks_validator_group.rb +20 -20
- data/lib/pdk/validate/validator.rb +118 -118
- data/lib/pdk/validate/validator_group.rb +104 -104
- data/lib/pdk/validate/yaml/yaml_syntax_validator.rb +95 -95
- data/lib/pdk/validate/yaml/yaml_validator_group.rb +19 -19
- data/lib/pdk/validate.rb +94 -94
- data/lib/pdk/version.rb +4 -4
- data/lib/pdk.rb +76 -76
- data/locales/config.yaml +21 -21
- data/locales/pdk.pot +2094 -2094
- metadata +5 -6
|
@@ -1,28 +1,28 @@
|
|
|
1
|
-
require 'pdk'
|
|
2
|
-
|
|
3
|
-
module PDK
|
|
4
|
-
module Generate
|
|
5
|
-
class Provider < PuppetObject
|
|
6
|
-
def friendly_name
|
|
7
|
-
'Resource API Provider'.freeze
|
|
8
|
-
end
|
|
9
|
-
|
|
10
|
-
def template_files
|
|
11
|
-
files = {
|
|
12
|
-
'provider_spec.erb' => File.join('spec', 'unit', 'puppet', 'provider', object_name, object_name) + '_spec.rb',
|
|
13
|
-
'provider_type_spec.erb' => File.join('spec', 'unit', 'puppet', 'type', object_name) + '_spec.rb',
|
|
14
|
-
}
|
|
15
|
-
return files if spec_only?
|
|
16
|
-
files.merge(
|
|
17
|
-
'provider.erb' => File.join('lib', 'puppet', 'provider', object_name, object_name) + '.rb',
|
|
18
|
-
'provider_type.erb' => File.join('lib', 'puppet', 'type', object_name) + '.rb',
|
|
19
|
-
)
|
|
20
|
-
end
|
|
21
|
-
|
|
22
|
-
def template_data
|
|
23
|
-
{ name: object_name,
|
|
24
|
-
provider_class: class_name_from_object_name(object_name) }
|
|
25
|
-
end
|
|
26
|
-
end
|
|
27
|
-
end
|
|
28
|
-
end
|
|
1
|
+
require 'pdk'
|
|
2
|
+
|
|
3
|
+
module PDK
|
|
4
|
+
module Generate
|
|
5
|
+
class Provider < PuppetObject
|
|
6
|
+
def friendly_name
|
|
7
|
+
'Resource API Provider'.freeze
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def template_files
|
|
11
|
+
files = {
|
|
12
|
+
'provider_spec.erb' => File.join('spec', 'unit', 'puppet', 'provider', object_name, object_name) + '_spec.rb',
|
|
13
|
+
'provider_type_spec.erb' => File.join('spec', 'unit', 'puppet', 'type', object_name) + '_spec.rb',
|
|
14
|
+
}
|
|
15
|
+
return files if spec_only?
|
|
16
|
+
files.merge(
|
|
17
|
+
'provider.erb' => File.join('lib', 'puppet', 'provider', object_name, object_name) + '.rb',
|
|
18
|
+
'provider_type.erb' => File.join('lib', 'puppet', 'type', object_name) + '.rb',
|
|
19
|
+
)
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def template_data
|
|
23
|
+
{ name: object_name,
|
|
24
|
+
provider_class: class_name_from_object_name(object_name) }
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
@@ -1,43 +1,43 @@
|
|
|
1
|
-
require 'pdk'
|
|
2
|
-
|
|
3
|
-
module PDK
|
|
4
|
-
module Generate
|
|
5
|
-
class PuppetClass < PuppetObject
|
|
6
|
-
PUPPET_STRINGS_TYPE = 'puppet_classes'.freeze
|
|
7
|
-
|
|
8
|
-
def initialize(*_args)
|
|
9
|
-
super
|
|
10
|
-
object_name_parts = @object_name.split('::')
|
|
11
|
-
|
|
12
|
-
@object_name = if object_name_parts.first == module_name
|
|
13
|
-
object_name
|
|
14
|
-
else
|
|
15
|
-
[module_name, object_name].join('::')
|
|
16
|
-
end
|
|
17
|
-
end
|
|
18
|
-
|
|
19
|
-
def friendly_name
|
|
20
|
-
'Puppet Class'.freeze
|
|
21
|
-
end
|
|
22
|
-
|
|
23
|
-
def template_files
|
|
24
|
-
# Calculate the class tests name
|
|
25
|
-
class_name_parts = object_name.split('::')
|
|
26
|
-
# Drop the module name if the object name contains multiple parts
|
|
27
|
-
class_name_parts.delete_at(0) if class_name_parts.length > 1
|
|
28
|
-
files = { 'class_spec.erb' => File.join('spec', 'classes', *class_name_parts) + '_spec.rb' }
|
|
29
|
-
return files if spec_only?
|
|
30
|
-
|
|
31
|
-
class_name_parts = object_name.split('::')[1..-1]
|
|
32
|
-
class_name_parts << 'init' if class_name_parts.empty?
|
|
33
|
-
files['class.erb'] = File.join('manifests', *class_name_parts) + '.pp'
|
|
34
|
-
|
|
35
|
-
files
|
|
36
|
-
end
|
|
37
|
-
|
|
38
|
-
def template_data
|
|
39
|
-
{ name: object_name }
|
|
40
|
-
end
|
|
41
|
-
end
|
|
42
|
-
end
|
|
43
|
-
end
|
|
1
|
+
require 'pdk'
|
|
2
|
+
|
|
3
|
+
module PDK
|
|
4
|
+
module Generate
|
|
5
|
+
class PuppetClass < PuppetObject
|
|
6
|
+
PUPPET_STRINGS_TYPE = 'puppet_classes'.freeze
|
|
7
|
+
|
|
8
|
+
def initialize(*_args)
|
|
9
|
+
super
|
|
10
|
+
object_name_parts = @object_name.split('::')
|
|
11
|
+
|
|
12
|
+
@object_name = if object_name_parts.first == module_name
|
|
13
|
+
object_name
|
|
14
|
+
else
|
|
15
|
+
[module_name, object_name].join('::')
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def friendly_name
|
|
20
|
+
'Puppet Class'.freeze
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def template_files
|
|
24
|
+
# Calculate the class tests name
|
|
25
|
+
class_name_parts = object_name.split('::')
|
|
26
|
+
# Drop the module name if the object name contains multiple parts
|
|
27
|
+
class_name_parts.delete_at(0) if class_name_parts.length > 1
|
|
28
|
+
files = { 'class_spec.erb' => File.join('spec', 'classes', *class_name_parts) + '_spec.rb' }
|
|
29
|
+
return files if spec_only?
|
|
30
|
+
|
|
31
|
+
class_name_parts = object_name.split('::')[1..-1]
|
|
32
|
+
class_name_parts << 'init' if class_name_parts.empty?
|
|
33
|
+
files['class.erb'] = File.join('manifests', *class_name_parts) + '.pp'
|
|
34
|
+
|
|
35
|
+
files
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def template_data
|
|
39
|
+
{ name: object_name }
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
|
@@ -1,232 +1,232 @@
|
|
|
1
|
-
require 'pdk'
|
|
2
|
-
|
|
3
|
-
module PDK
|
|
4
|
-
module Generate
|
|
5
|
-
class PuppetObject
|
|
6
|
-
attr_reader :context
|
|
7
|
-
attr_reader :object_name
|
|
8
|
-
attr_reader :options
|
|
9
|
-
|
|
10
|
-
# Initialises the PDK::Generate::PuppetObject object.
|
|
11
|
-
#
|
|
12
|
-
# In general, this object should never be instantiated directly. Instead,
|
|
13
|
-
# one of the subclasses should be used e.g. PDK::Generate::Klass.
|
|
14
|
-
#
|
|
15
|
-
# New subclasses generally only need to inherit this class, set the
|
|
16
|
-
# OBJECT_TYPE constant and implement the {#template_data},
|
|
17
|
-
# {#target_object_path} and {#target_spec_path} methods.
|
|
18
|
-
#
|
|
19
|
-
# @param module_dir [String] The path to the root of module that the
|
|
20
|
-
# will contain the object.
|
|
21
|
-
# @param object_name [String] The name of the object.
|
|
22
|
-
# @param options [Hash{Symbol => Object}]
|
|
23
|
-
def initialize(context, object_name, options)
|
|
24
|
-
raise ArgumentError, _('Expected PDK::Context::AbstractContext but got \'%{klass}\' for context') % { klass: context.class } unless context.is_a?(PDK::Context::AbstractContext)
|
|
25
|
-
@context = context
|
|
26
|
-
@options = options
|
|
27
|
-
@object_name = object_name
|
|
28
|
-
end
|
|
29
|
-
|
|
30
|
-
# Whether the generator should only return test (spec) files
|
|
31
|
-
# @return [Boolean]
|
|
32
|
-
def spec_only?
|
|
33
|
-
@options[:spec_only]
|
|
34
|
-
end
|
|
35
|
-
|
|
36
|
-
# Subclass and implement {#friendly_name} to provide a nice name to show users in CLI
|
|
37
|
-
# @abstract
|
|
38
|
-
# @return String
|
|
39
|
-
def friendly_name
|
|
40
|
-
raise NotImplementedError
|
|
41
|
-
end
|
|
42
|
-
|
|
43
|
-
# Subclass and implement {#template_files} to provide the template files to
|
|
44
|
-
# render. Implementations of this method should return a Hash!{String => String}.
|
|
45
|
-
# @abstract
|
|
46
|
-
# @return Hash{String => String} Hash key is the source template file and the Hash value is
|
|
47
|
-
# the relative destination path
|
|
48
|
-
def template_files
|
|
49
|
-
raise NotImplementedError
|
|
50
|
-
end
|
|
51
|
-
|
|
52
|
-
# Subclass and implement {#template_data} to provide data to the templates during rendering.
|
|
53
|
-
# @abstract
|
|
54
|
-
# @return Hash{Symbol => Object}
|
|
55
|
-
def template_data
|
|
56
|
-
raise NotImplementedError
|
|
57
|
-
end
|
|
58
|
-
|
|
59
|
-
# Raises an error if any pre-conditions are not met
|
|
60
|
-
#
|
|
61
|
-
# @return [void]
|
|
62
|
-
# @abstract
|
|
63
|
-
def check_preconditions
|
|
64
|
-
raise ArgumentError, _('Expected a module context but got %{context_name}') % { context_name: context.display_name } unless context.is_a?(PDK::Context::Module)
|
|
65
|
-
end
|
|
66
|
-
|
|
67
|
-
# Check the preconditions of this template group, behaving as a predicate rather than raising an exception.
|
|
68
|
-
#
|
|
69
|
-
# @return [Boolean] true if the generator is safe to run, otherwise false.
|
|
70
|
-
def can_run?
|
|
71
|
-
check_preconditions
|
|
72
|
-
true
|
|
73
|
-
rescue StandardError
|
|
74
|
-
false
|
|
75
|
-
end
|
|
76
|
-
|
|
77
|
-
# Creates an instance of an update manager
|
|
78
|
-
# @api private
|
|
79
|
-
def update_manager_instance
|
|
80
|
-
require 'pdk/module/update_manager'
|
|
81
|
-
PDK::Module::UpdateManager.new
|
|
82
|
-
end
|
|
83
|
-
|
|
84
|
-
# Stages and then executes the changes for the templates to be rendereed.
|
|
85
|
-
# This is the main entry point for the class.
|
|
86
|
-
#
|
|
87
|
-
# @see #stage_changes
|
|
88
|
-
# @return [PDK::Module::UpdateManager] The update manager which implemented the changes
|
|
89
|
-
# @api public
|
|
90
|
-
def run(update_manager = update_manager_instance)
|
|
91
|
-
stage_changes(update_manager).sync_changes!
|
|
92
|
-
update_manager
|
|
93
|
-
end
|
|
94
|
-
|
|
95
|
-
# Check that the templates can be rendered. Find an appropriate template
|
|
96
|
-
# and stages the target files from the template. This is the main entry
|
|
97
|
-
# point for the class.
|
|
98
|
-
#
|
|
99
|
-
# @raise [PDK::CLI::ExitWithError] if the target files already exist.
|
|
100
|
-
# @raise [PDK::CLI::FatalError] (see #render_file)
|
|
101
|
-
# @return [PDK::Module::UpdateManager] The update manager with the staged changes
|
|
102
|
-
# @api public
|
|
103
|
-
def stage_changes(update_manager)
|
|
104
|
-
check_preconditions
|
|
105
|
-
|
|
106
|
-
with_templates do |template_dir|
|
|
107
|
-
template_files.each do |source_file, relative_dest_path|
|
|
108
|
-
new_content = template_dir.render_single_item(source_file, template_data)
|
|
109
|
-
next if new_content.nil?
|
|
110
|
-
|
|
111
|
-
stage_change(relative_dest_path, new_content, update_manager)
|
|
112
|
-
end
|
|
113
|
-
end
|
|
114
|
-
non_template_files.each { |relative_dest_path, content| stage_change(relative_dest_path, content, update_manager) }
|
|
115
|
-
|
|
116
|
-
update_manager
|
|
117
|
-
end
|
|
118
|
-
|
|
119
|
-
# Stages a single file into the Update Manager.
|
|
120
|
-
# @return [void]
|
|
121
|
-
# @api private
|
|
122
|
-
def stage_change(relative_dest_path, content, update_manager)
|
|
123
|
-
absolute_file_path = File.join(context.root_path, relative_dest_path)
|
|
124
|
-
if PDK::Util::Filesystem.exist?(absolute_file_path)
|
|
125
|
-
raise PDK::CLI::ExitWithError, _("Unable to generate %{object_type}; '%{file}' already exists.") % {
|
|
126
|
-
file: absolute_file_path,
|
|
127
|
-
object_type: spec_only? ? 'unit test' : friendly_name,
|
|
128
|
-
}
|
|
129
|
-
end
|
|
130
|
-
update_manager.add_file(absolute_file_path, content)
|
|
131
|
-
end
|
|
132
|
-
|
|
133
|
-
# A subclass may wish to stage files into the Update Manager, but the content is not templated. Subclasses
|
|
134
|
-
# can override this method to stage arbitrary files
|
|
135
|
-
#
|
|
136
|
-
# @api private
|
|
137
|
-
# @return [Hash{String => String}] A Hash with the relative file path as the key and the new file content as the value.
|
|
138
|
-
# @abstract
|
|
139
|
-
def non_template_files
|
|
140
|
-
{}
|
|
141
|
-
end
|
|
142
|
-
|
|
143
|
-
# Search the possible template directories in order of preference to find
|
|
144
|
-
# a template that can be used to render a new object of the specified
|
|
145
|
-
# type.
|
|
146
|
-
#
|
|
147
|
-
# @yieldparam template_paths [Hash{Symbol => String}] :object contains
|
|
148
|
-
# the path on disk to the template file for the object, :spec contains
|
|
149
|
-
# the path on disk to the template file for the tests for the object
|
|
150
|
-
# (if it exists).
|
|
151
|
-
# @yieldparam config_hash [Hash{Object => Object}] the contents of the
|
|
152
|
-
# :global key in the config_defaults.yml file.
|
|
153
|
-
#
|
|
154
|
-
# @raise [PDK::CLI::FatalError] if no suitable template could be found.
|
|
155
|
-
#
|
|
156
|
-
# @api private
|
|
157
|
-
def with_templates
|
|
158
|
-
require 'pdk/logger'
|
|
159
|
-
require 'pdk/util/template_uri'
|
|
160
|
-
|
|
161
|
-
templates.each do |template|
|
|
162
|
-
if template[:uri].nil?
|
|
163
|
-
PDK.logger.debug(_('No %{dir_type} template found; trying next template directory.') % { dir_type: template[:type] })
|
|
164
|
-
next
|
|
165
|
-
end
|
|
166
|
-
|
|
167
|
-
PDK::Template.with(PDK::Util::TemplateURI.new(template[:uri]), context) do |template_dir|
|
|
168
|
-
if template_files.any? { |source_file, _| template_dir.has_single_item?(source_file) }
|
|
169
|
-
yield template_dir
|
|
170
|
-
# TODO: refactor to a search-and-execute form instead
|
|
171
|
-
return # work is done # rubocop:disable Lint/NonLocalExitFromIterator
|
|
172
|
-
elsif template[:allow_fallback]
|
|
173
|
-
PDK.logger.debug(_('Unable to find a %{type} template in %{url}; trying next template directory.') % { type: friendly_name, url: template[:uri] })
|
|
174
|
-
else
|
|
175
|
-
raise PDK::CLI::FatalError, _('Unable to find the %{type} template in %{url}.') % { type: friendly_name, url: template[:uri] }
|
|
176
|
-
end
|
|
177
|
-
end
|
|
178
|
-
end
|
|
179
|
-
rescue ArgumentError => e
|
|
180
|
-
raise PDK::CLI::ExitWithError, e
|
|
181
|
-
end
|
|
182
|
-
|
|
183
|
-
# Provides the possible template directory locations in the order in
|
|
184
|
-
# which they should be searched for a valid template.
|
|
185
|
-
#
|
|
186
|
-
# If a template-url has been specified on in the options hash (e.g. from
|
|
187
|
-
# a CLI parameter), then this template directory will be checked first
|
|
188
|
-
# and we do not fall back to the next possible template directory.
|
|
189
|
-
#
|
|
190
|
-
# If we have not been provided a specific template directory to use, we
|
|
191
|
-
# try the template specified in the module metadata (as set during
|
|
192
|
-
# PDK::Generate::Module) and fall back to the default template if
|
|
193
|
-
# necessary.
|
|
194
|
-
#
|
|
195
|
-
# @return [Array<Hash{Symbol => Object}>] an array of hashes. Each hash
|
|
196
|
-
# contains 3 keys: :type contains a String that describes the template
|
|
197
|
-
# directory, :url contains a String with the URL to the template
|
|
198
|
-
# directory, and :allow_fallback contains a Boolean that specifies if
|
|
199
|
-
# the lookup process should proceed to the next template directory if
|
|
200
|
-
# the template file is not in this template directory.
|
|
201
|
-
#
|
|
202
|
-
# @api private
|
|
203
|
-
def templates
|
|
204
|
-
require 'pdk/util/template_uri'
|
|
205
|
-
|
|
206
|
-
@templates ||= PDK::Util::TemplateURI.templates(@options)
|
|
207
|
-
end
|
|
208
|
-
|
|
209
|
-
# Retrieves the name of the module (without the forge username) from the
|
|
210
|
-
# module metadata.
|
|
211
|
-
#
|
|
212
|
-
# @return [String] The name of the module.
|
|
213
|
-
#
|
|
214
|
-
# @api private
|
|
215
|
-
def module_name
|
|
216
|
-
return nil unless context.is_a?(PDK::Context::Module)
|
|
217
|
-
|
|
218
|
-
require 'pdk/util'
|
|
219
|
-
@module_name ||= PDK::Util.module_metadata(context.root_path)['name'].rpartition('-').last
|
|
220
|
-
rescue ArgumentError => e
|
|
221
|
-
raise PDK::CLI::FatalError, e
|
|
222
|
-
end
|
|
223
|
-
|
|
224
|
-
private
|
|
225
|
-
|
|
226
|
-
# Transform an object name into a ruby class name
|
|
227
|
-
def class_name_from_object_name(object_name)
|
|
228
|
-
object_name.to_s.split('_').map(&:capitalize).join
|
|
229
|
-
end
|
|
230
|
-
end
|
|
231
|
-
end
|
|
232
|
-
end
|
|
1
|
+
require 'pdk'
|
|
2
|
+
|
|
3
|
+
module PDK
|
|
4
|
+
module Generate
|
|
5
|
+
class PuppetObject
|
|
6
|
+
attr_reader :context
|
|
7
|
+
attr_reader :object_name
|
|
8
|
+
attr_reader :options
|
|
9
|
+
|
|
10
|
+
# Initialises the PDK::Generate::PuppetObject object.
|
|
11
|
+
#
|
|
12
|
+
# In general, this object should never be instantiated directly. Instead,
|
|
13
|
+
# one of the subclasses should be used e.g. PDK::Generate::Klass.
|
|
14
|
+
#
|
|
15
|
+
# New subclasses generally only need to inherit this class, set the
|
|
16
|
+
# OBJECT_TYPE constant and implement the {#template_data},
|
|
17
|
+
# {#target_object_path} and {#target_spec_path} methods.
|
|
18
|
+
#
|
|
19
|
+
# @param module_dir [String] The path to the root of module that the
|
|
20
|
+
# will contain the object.
|
|
21
|
+
# @param object_name [String] The name of the object.
|
|
22
|
+
# @param options [Hash{Symbol => Object}]
|
|
23
|
+
def initialize(context, object_name, options)
|
|
24
|
+
raise ArgumentError, _('Expected PDK::Context::AbstractContext but got \'%{klass}\' for context') % { klass: context.class } unless context.is_a?(PDK::Context::AbstractContext)
|
|
25
|
+
@context = context
|
|
26
|
+
@options = options
|
|
27
|
+
@object_name = object_name
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
# Whether the generator should only return test (spec) files
|
|
31
|
+
# @return [Boolean]
|
|
32
|
+
def spec_only?
|
|
33
|
+
@options[:spec_only]
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
# Subclass and implement {#friendly_name} to provide a nice name to show users in CLI
|
|
37
|
+
# @abstract
|
|
38
|
+
# @return String
|
|
39
|
+
def friendly_name
|
|
40
|
+
raise NotImplementedError
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
# Subclass and implement {#template_files} to provide the template files to
|
|
44
|
+
# render. Implementations of this method should return a Hash!{String => String}.
|
|
45
|
+
# @abstract
|
|
46
|
+
# @return Hash{String => String} Hash key is the source template file and the Hash value is
|
|
47
|
+
# the relative destination path
|
|
48
|
+
def template_files
|
|
49
|
+
raise NotImplementedError
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
# Subclass and implement {#template_data} to provide data to the templates during rendering.
|
|
53
|
+
# @abstract
|
|
54
|
+
# @return Hash{Symbol => Object}
|
|
55
|
+
def template_data
|
|
56
|
+
raise NotImplementedError
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
# Raises an error if any pre-conditions are not met
|
|
60
|
+
#
|
|
61
|
+
# @return [void]
|
|
62
|
+
# @abstract
|
|
63
|
+
def check_preconditions
|
|
64
|
+
raise ArgumentError, _('Expected a module context but got %{context_name}') % { context_name: context.display_name } unless context.is_a?(PDK::Context::Module)
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
# Check the preconditions of this template group, behaving as a predicate rather than raising an exception.
|
|
68
|
+
#
|
|
69
|
+
# @return [Boolean] true if the generator is safe to run, otherwise false.
|
|
70
|
+
def can_run?
|
|
71
|
+
check_preconditions
|
|
72
|
+
true
|
|
73
|
+
rescue StandardError
|
|
74
|
+
false
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
# Creates an instance of an update manager
|
|
78
|
+
# @api private
|
|
79
|
+
def update_manager_instance
|
|
80
|
+
require 'pdk/module/update_manager'
|
|
81
|
+
PDK::Module::UpdateManager.new
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
# Stages and then executes the changes for the templates to be rendereed.
|
|
85
|
+
# This is the main entry point for the class.
|
|
86
|
+
#
|
|
87
|
+
# @see #stage_changes
|
|
88
|
+
# @return [PDK::Module::UpdateManager] The update manager which implemented the changes
|
|
89
|
+
# @api public
|
|
90
|
+
def run(update_manager = update_manager_instance)
|
|
91
|
+
stage_changes(update_manager).sync_changes!
|
|
92
|
+
update_manager
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
# Check that the templates can be rendered. Find an appropriate template
|
|
96
|
+
# and stages the target files from the template. This is the main entry
|
|
97
|
+
# point for the class.
|
|
98
|
+
#
|
|
99
|
+
# @raise [PDK::CLI::ExitWithError] if the target files already exist.
|
|
100
|
+
# @raise [PDK::CLI::FatalError] (see #render_file)
|
|
101
|
+
# @return [PDK::Module::UpdateManager] The update manager with the staged changes
|
|
102
|
+
# @api public
|
|
103
|
+
def stage_changes(update_manager)
|
|
104
|
+
check_preconditions
|
|
105
|
+
|
|
106
|
+
with_templates do |template_dir|
|
|
107
|
+
template_files.each do |source_file, relative_dest_path|
|
|
108
|
+
new_content = template_dir.render_single_item(source_file, template_data)
|
|
109
|
+
next if new_content.nil?
|
|
110
|
+
|
|
111
|
+
stage_change(relative_dest_path, new_content, update_manager)
|
|
112
|
+
end
|
|
113
|
+
end
|
|
114
|
+
non_template_files.each { |relative_dest_path, content| stage_change(relative_dest_path, content, update_manager) }
|
|
115
|
+
|
|
116
|
+
update_manager
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
# Stages a single file into the Update Manager.
|
|
120
|
+
# @return [void]
|
|
121
|
+
# @api private
|
|
122
|
+
def stage_change(relative_dest_path, content, update_manager)
|
|
123
|
+
absolute_file_path = File.join(context.root_path, relative_dest_path)
|
|
124
|
+
if PDK::Util::Filesystem.exist?(absolute_file_path)
|
|
125
|
+
raise PDK::CLI::ExitWithError, _("Unable to generate %{object_type}; '%{file}' already exists.") % {
|
|
126
|
+
file: absolute_file_path,
|
|
127
|
+
object_type: spec_only? ? 'unit test' : friendly_name,
|
|
128
|
+
}
|
|
129
|
+
end
|
|
130
|
+
update_manager.add_file(absolute_file_path, content)
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
# A subclass may wish to stage files into the Update Manager, but the content is not templated. Subclasses
|
|
134
|
+
# can override this method to stage arbitrary files
|
|
135
|
+
#
|
|
136
|
+
# @api private
|
|
137
|
+
# @return [Hash{String => String}] A Hash with the relative file path as the key and the new file content as the value.
|
|
138
|
+
# @abstract
|
|
139
|
+
def non_template_files
|
|
140
|
+
{}
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
# Search the possible template directories in order of preference to find
|
|
144
|
+
# a template that can be used to render a new object of the specified
|
|
145
|
+
# type.
|
|
146
|
+
#
|
|
147
|
+
# @yieldparam template_paths [Hash{Symbol => String}] :object contains
|
|
148
|
+
# the path on disk to the template file for the object, :spec contains
|
|
149
|
+
# the path on disk to the template file for the tests for the object
|
|
150
|
+
# (if it exists).
|
|
151
|
+
# @yieldparam config_hash [Hash{Object => Object}] the contents of the
|
|
152
|
+
# :global key in the config_defaults.yml file.
|
|
153
|
+
#
|
|
154
|
+
# @raise [PDK::CLI::FatalError] if no suitable template could be found.
|
|
155
|
+
#
|
|
156
|
+
# @api private
|
|
157
|
+
def with_templates
|
|
158
|
+
require 'pdk/logger'
|
|
159
|
+
require 'pdk/util/template_uri'
|
|
160
|
+
|
|
161
|
+
templates.each do |template|
|
|
162
|
+
if template[:uri].nil?
|
|
163
|
+
PDK.logger.debug(_('No %{dir_type} template found; trying next template directory.') % { dir_type: template[:type] })
|
|
164
|
+
next
|
|
165
|
+
end
|
|
166
|
+
|
|
167
|
+
PDK::Template.with(PDK::Util::TemplateURI.new(template[:uri]), context) do |template_dir|
|
|
168
|
+
if template_files.any? { |source_file, _| template_dir.has_single_item?(source_file) }
|
|
169
|
+
yield template_dir
|
|
170
|
+
# TODO: refactor to a search-and-execute form instead
|
|
171
|
+
return # work is done # rubocop:disable Lint/NonLocalExitFromIterator
|
|
172
|
+
elsif template[:allow_fallback]
|
|
173
|
+
PDK.logger.debug(_('Unable to find a %{type} template in %{url}; trying next template directory.') % { type: friendly_name, url: template[:uri] })
|
|
174
|
+
else
|
|
175
|
+
raise PDK::CLI::FatalError, _('Unable to find the %{type} template in %{url}.') % { type: friendly_name, url: template[:uri] }
|
|
176
|
+
end
|
|
177
|
+
end
|
|
178
|
+
end
|
|
179
|
+
rescue ArgumentError => e
|
|
180
|
+
raise PDK::CLI::ExitWithError, e
|
|
181
|
+
end
|
|
182
|
+
|
|
183
|
+
# Provides the possible template directory locations in the order in
|
|
184
|
+
# which they should be searched for a valid template.
|
|
185
|
+
#
|
|
186
|
+
# If a template-url has been specified on in the options hash (e.g. from
|
|
187
|
+
# a CLI parameter), then this template directory will be checked first
|
|
188
|
+
# and we do not fall back to the next possible template directory.
|
|
189
|
+
#
|
|
190
|
+
# If we have not been provided a specific template directory to use, we
|
|
191
|
+
# try the template specified in the module metadata (as set during
|
|
192
|
+
# PDK::Generate::Module) and fall back to the default template if
|
|
193
|
+
# necessary.
|
|
194
|
+
#
|
|
195
|
+
# @return [Array<Hash{Symbol => Object}>] an array of hashes. Each hash
|
|
196
|
+
# contains 3 keys: :type contains a String that describes the template
|
|
197
|
+
# directory, :url contains a String with the URL to the template
|
|
198
|
+
# directory, and :allow_fallback contains a Boolean that specifies if
|
|
199
|
+
# the lookup process should proceed to the next template directory if
|
|
200
|
+
# the template file is not in this template directory.
|
|
201
|
+
#
|
|
202
|
+
# @api private
|
|
203
|
+
def templates
|
|
204
|
+
require 'pdk/util/template_uri'
|
|
205
|
+
|
|
206
|
+
@templates ||= PDK::Util::TemplateURI.templates(@options)
|
|
207
|
+
end
|
|
208
|
+
|
|
209
|
+
# Retrieves the name of the module (without the forge username) from the
|
|
210
|
+
# module metadata.
|
|
211
|
+
#
|
|
212
|
+
# @return [String] The name of the module.
|
|
213
|
+
#
|
|
214
|
+
# @api private
|
|
215
|
+
def module_name
|
|
216
|
+
return nil unless context.is_a?(PDK::Context::Module)
|
|
217
|
+
|
|
218
|
+
require 'pdk/util'
|
|
219
|
+
@module_name ||= PDK::Util.module_metadata(context.root_path)['name'].rpartition('-').last
|
|
220
|
+
rescue ArgumentError => e
|
|
221
|
+
raise PDK::CLI::FatalError, e
|
|
222
|
+
end
|
|
223
|
+
|
|
224
|
+
private
|
|
225
|
+
|
|
226
|
+
# Transform an object name into a ruby class name
|
|
227
|
+
def class_name_from_object_name(object_name)
|
|
228
|
+
object_name.to_s.split('_').map(&:capitalize).join
|
|
229
|
+
end
|
|
230
|
+
end
|
|
231
|
+
end
|
|
232
|
+
end
|