pdk 1.17.0 → 2.1.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 +148 -11
- data/README.md +1 -1
- data/lib/pdk.rb +1 -1
- data/lib/pdk/cli.rb +7 -1
- data/lib/pdk/cli/convert.rb +7 -9
- data/lib/pdk/cli/env.rb +52 -0
- data/lib/pdk/cli/exec/command.rb +11 -1
- data/lib/pdk/cli/new.rb +2 -0
- data/lib/pdk/cli/new/class.rb +2 -1
- data/lib/pdk/cli/new/defined_type.rb +2 -1
- data/lib/pdk/cli/new/fact.rb +29 -0
- data/lib/pdk/cli/new/function.rb +29 -0
- data/lib/pdk/cli/new/provider.rb +2 -1
- data/lib/pdk/cli/new/task.rb +2 -1
- data/lib/pdk/cli/new/test.rb +2 -1
- data/lib/pdk/cli/new/transport.rb +2 -1
- data/lib/pdk/cli/release.rb +1 -1
- data/lib/pdk/cli/release/publish.rb +11 -1
- data/lib/pdk/cli/remove.rb +20 -0
- data/lib/pdk/cli/remove/config.rb +80 -0
- data/lib/pdk/cli/set.rb +20 -0
- data/lib/pdk/cli/set/config.rb +119 -0
- data/lib/pdk/cli/update.rb +6 -8
- data/lib/pdk/cli/util.rb +1 -0
- data/lib/pdk/cli/util/option_validator.rb +6 -0
- data/lib/pdk/cli/util/update_manager_printer.rb +82 -0
- data/lib/pdk/config.rb +96 -13
- data/lib/pdk/context.rb +8 -5
- data/lib/pdk/generate/defined_type.rb +25 -32
- data/lib/pdk/generate/fact.rb +25 -0
- data/lib/pdk/generate/function.rb +48 -0
- data/lib/pdk/generate/module.rb +11 -10
- data/lib/pdk/generate/provider.rb +15 -64
- data/lib/pdk/generate/puppet_class.rb +25 -31
- data/lib/pdk/generate/puppet_object.rb +83 -187
- data/lib/pdk/generate/task.rb +28 -46
- data/lib/pdk/generate/transport.rb +20 -74
- data/lib/pdk/module.rb +1 -1
- data/lib/pdk/module/convert.rb +43 -23
- data/lib/pdk/module/metadata.rb +6 -2
- data/lib/pdk/module/release.rb +8 -2
- data/lib/pdk/module/update.rb +7 -11
- data/lib/pdk/module/update_manager.rb +7 -0
- data/lib/pdk/report.rb +3 -3
- data/lib/pdk/report/event.rb +8 -2
- data/lib/pdk/template.rb +59 -0
- data/lib/pdk/template/fetcher.rb +98 -0
- data/lib/pdk/template/fetcher/git.rb +85 -0
- data/lib/pdk/template/fetcher/local.rb +28 -0
- data/lib/pdk/template/renderer.rb +96 -0
- data/lib/pdk/template/renderer/v1.rb +25 -0
- data/lib/pdk/template/renderer/v1/legacy_template_dir.rb +116 -0
- data/lib/pdk/template/renderer/v1/renderer.rb +132 -0
- data/lib/pdk/template/renderer/v1/template_file.rb +102 -0
- data/lib/pdk/template/template_dir.rb +67 -0
- data/lib/pdk/tests/unit.rb +8 -1
- data/lib/pdk/util.rb +4 -35
- data/lib/pdk/util/bundler.rb +1 -1
- data/lib/pdk/util/changelog_generator.rb +20 -3
- data/lib/pdk/util/json_finder.rb +85 -0
- data/lib/pdk/util/puppet_strings.rb +3 -3
- data/lib/pdk/util/puppet_version.rb +2 -2
- data/lib/pdk/util/ruby_version.rb +5 -1
- data/lib/pdk/util/template_uri.rb +9 -11
- data/lib/pdk/util/vendored_file.rb +1 -2
- data/lib/pdk/validate.rb +17 -10
- data/lib/pdk/validate/control_repo/control_repo_validator_group.rb +23 -0
- data/lib/pdk/validate/control_repo/environment_conf_validator.rb +98 -0
- data/lib/pdk/validate/invokable_validator.rb +8 -4
- data/lib/pdk/validate/tasks/tasks_metadata_lint_validator.rb +1 -1
- data/lib/pdk/validate/validator.rb +7 -0
- data/lib/pdk/validate/validator_group.rb +1 -0
- data/lib/pdk/validate/yaml/yaml_syntax_validator.rb +2 -2
- data/lib/pdk/version.rb +1 -1
- data/locales/pdk.pot +356 -228
- metadata +65 -28
- data/lib/pdk/module/template_dir.rb +0 -115
- data/lib/pdk/module/template_dir/base.rb +0 -268
- data/lib/pdk/module/template_dir/git.rb +0 -91
- data/lib/pdk/module/template_dir/local.rb +0 -21
- data/lib/pdk/template_file.rb +0 -96
@@ -3,47 +3,40 @@ require 'pdk'
|
|
3
3
|
module PDK
|
4
4
|
module Generate
|
5
5
|
class DefinedType < PuppetObject
|
6
|
-
OBJECT_TYPE = :defined_type
|
7
6
|
PUPPET_STRINGS_TYPE = 'defined_types'.freeze
|
8
7
|
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
# provided to the defined type and defined type spec templates during
|
13
|
-
# rendering.
|
14
|
-
def template_data
|
15
|
-
data = { name: object_name }
|
8
|
+
def initialize(*_args)
|
9
|
+
super
|
10
|
+
object_name_parts = @object_name.split('::')
|
16
11
|
|
17
|
-
|
12
|
+
@object_name = if object_name_parts.first == module_name
|
13
|
+
object_name
|
14
|
+
else
|
15
|
+
[module_name, object_name].join('::')
|
16
|
+
end
|
18
17
|
end
|
19
18
|
|
20
|
-
|
21
|
-
|
22
|
-
#
|
23
|
-
# @return [String] the path where the new defined type will be written.
|
24
|
-
def target_object_path
|
25
|
-
@target_pp_path ||= begin
|
26
|
-
define_name_parts = object_name.split('::')[1..-1]
|
27
|
-
define_name_parts << 'init' if define_name_parts.empty?
|
28
|
-
|
29
|
-
"#{File.join(module_dir, 'manifests', *define_name_parts)}.pp"
|
30
|
-
end
|
19
|
+
def friendly_name
|
20
|
+
'Defined Type'.freeze
|
31
21
|
end
|
32
22
|
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
23
|
+
def template_files
|
24
|
+
# Calculate the defined type tests name
|
25
|
+
define_name_parts = object_name.split('::')
|
26
|
+
# drop the module name if the object name contains multiple parts
|
27
|
+
define_name_parts.delete_at(0) if define_name_parts.length > 1
|
28
|
+
files = { 'defined_type_spec.erb' => File.join('spec', 'defines', *define_name_parts) + '_spec.rb' }
|
29
|
+
return files if spec_only?
|
30
|
+
|
31
|
+
define_name_parts = object_name.split('::')[1..-1]
|
32
|
+
define_name_parts << 'init' if define_name_parts.empty?
|
33
|
+
files['defined_type.erb'] = File.join('manifests', *define_name_parts) + '.pp'
|
41
34
|
|
42
|
-
|
43
|
-
|
35
|
+
files
|
36
|
+
end
|
44
37
|
|
45
|
-
|
46
|
-
|
38
|
+
def template_data
|
39
|
+
{ name: object_name }
|
47
40
|
end
|
48
41
|
end
|
49
42
|
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'pdk'
|
2
|
+
|
3
|
+
module PDK
|
4
|
+
module Generate
|
5
|
+
class Fact < PuppetObject
|
6
|
+
def friendly_name
|
7
|
+
'Custom Fact'.freeze
|
8
|
+
end
|
9
|
+
|
10
|
+
def template_files
|
11
|
+
files = {
|
12
|
+
'fact_spec.erb' => File.join('spec', 'unit', 'facter', object_name) + '_spec.rb',
|
13
|
+
}
|
14
|
+
return files if spec_only?
|
15
|
+
files.merge(
|
16
|
+
'fact.erb' => File.join('lib', 'facter', object_name) + '.rb',
|
17
|
+
)
|
18
|
+
end
|
19
|
+
|
20
|
+
def template_data
|
21
|
+
{ name: object_name }
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
require 'pdk'
|
2
|
+
|
3
|
+
module PDK
|
4
|
+
module Generate
|
5
|
+
class Function < PuppetObject
|
6
|
+
def initialize(*_args)
|
7
|
+
super
|
8
|
+
object_name_parts = @object_name.split('::')
|
9
|
+
|
10
|
+
@object_name = if object_name_parts.first == module_name
|
11
|
+
object_name
|
12
|
+
else
|
13
|
+
[module_name, object_name].join('::')
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def friendly_name
|
18
|
+
'Function'.freeze
|
19
|
+
end
|
20
|
+
|
21
|
+
def template_files
|
22
|
+
# Calculate the function tests name
|
23
|
+
func_name_parts = object_name.split('::')
|
24
|
+
# Drop the module name if the object name contains multiple parts
|
25
|
+
func_name_parts.delete_at(0) if func_name_parts.length > 1
|
26
|
+
files = {
|
27
|
+
File.join('functions', 'function_spec.erb') => File.join('spec', 'functions', *func_name_parts) + '_spec.rb',
|
28
|
+
}
|
29
|
+
return files if spec_only?
|
30
|
+
func_name_parts = object_name.split('::')[1..-1]
|
31
|
+
template_file = File.join('functions', "#{options[:type]}_function.erb")
|
32
|
+
|
33
|
+
files[template_file] = if options[:type].eql?('v4')
|
34
|
+
File.join('lib', 'puppet', 'functions', module_name, *func_name_parts) + '.rb'
|
35
|
+
else
|
36
|
+
File.join('functions', *func_name_parts) + '.pp'
|
37
|
+
end
|
38
|
+
files
|
39
|
+
end
|
40
|
+
|
41
|
+
def template_data
|
42
|
+
func_name = object_name.split('::').last
|
43
|
+
namespace = object_name.split('::')[0...-1].join('::')
|
44
|
+
{ name: object_name, func_name: func_name, namespace: namespace }
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
data/lib/pdk/generate/module.rb
CHANGED
@@ -58,17 +58,18 @@ module PDK
|
|
58
58
|
end
|
59
59
|
|
60
60
|
begin
|
61
|
-
PDK::
|
62
|
-
|
63
|
-
|
64
|
-
|
61
|
+
context = PDK::Context::None.new(temp_target_dir)
|
62
|
+
PDK::Template.with(template_uri, context) do |template_dir|
|
63
|
+
template_dir.render_new_module(metadata.data['name'], metadata.data) do |relative_file_path, file_content, file_status|
|
64
|
+
next if [:delete, :unmanage].include?(file_status)
|
65
|
+
file = Pathname.new(temp_target_dir) + relative_file_path
|
65
66
|
file.dirname.mkpath
|
66
67
|
PDK::Util::Filesystem.write_file(file, file_content)
|
67
68
|
end
|
68
69
|
|
69
70
|
# Add information about the template used to generate the module to the
|
70
71
|
# metadata (for a future update command).
|
71
|
-
metadata.update!(
|
72
|
+
metadata.update!(template_dir.metadata)
|
72
73
|
|
73
74
|
metadata.write!(File.join(temp_target_dir, 'metadata.json'))
|
74
75
|
end
|
@@ -82,11 +83,11 @@ module PDK
|
|
82
83
|
# If the user specifies our default template url via the command
|
83
84
|
# line, remove the saved template-url answer so that the template_uri
|
84
85
|
# resolution can find new default URLs in the future.
|
85
|
-
PDK.config.user
|
86
|
+
PDK.config.set(%w[user module_defaults template-url], nil) if opts.key?(:'template-url')
|
86
87
|
else
|
87
88
|
# Save the template-url answers if the module was generated using a
|
88
89
|
# template/reference other than ours.
|
89
|
-
PDK.config.user
|
90
|
+
PDK.config.set(%w[user module_defaults template-url], template_uri.metadata_format)
|
90
91
|
end
|
91
92
|
|
92
93
|
begin
|
@@ -342,9 +343,9 @@ module PDK
|
|
342
343
|
end
|
343
344
|
|
344
345
|
require 'pdk/answer_file'
|
345
|
-
PDK.config.user
|
346
|
-
PDK.config.user
|
347
|
-
PDK.config.user
|
346
|
+
PDK.config.set(%w[user module_defaults forge_username], opts[:username]) unless opts[:username].nil?
|
347
|
+
PDK.config.set(%w[user module_defaults author], answers['author']) unless answers['author'].nil?
|
348
|
+
PDK.config.set(%w[user module_defaults license], answers['license']) unless answers['license'].nil?
|
348
349
|
end
|
349
350
|
end
|
350
351
|
end
|
@@ -3,74 +3,25 @@ require 'pdk'
|
|
3
3
|
module PDK
|
4
4
|
module Generate
|
5
5
|
class Provider < PuppetObject
|
6
|
-
|
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://puppet.com/docs/puppet/latest/create_types_and_providers_resource_api.html.') % { 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 provider will be written.
|
56
|
-
def target_object_path
|
57
|
-
@target_object_path ||= File.join(module_dir, 'lib', 'puppet', 'provider', object_name, object_name) + '.rb'
|
6
|
+
def friendly_name
|
7
|
+
'Resource API Provider'.freeze
|
58
8
|
end
|
59
9
|
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
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
|
+
)
|
69
20
|
end
|
70
21
|
|
71
|
-
|
72
|
-
|
73
|
-
|
22
|
+
def template_data
|
23
|
+
{ name: object_name,
|
24
|
+
provider_class: class_name_from_object_name(object_name) }
|
74
25
|
end
|
75
26
|
end
|
76
27
|
end
|
@@ -3,46 +3,40 @@ require 'pdk'
|
|
3
3
|
module PDK
|
4
4
|
module Generate
|
5
5
|
class PuppetClass < PuppetObject
|
6
|
-
OBJECT_TYPE = :class
|
7
6
|
PUPPET_STRINGS_TYPE = 'puppet_classes'.freeze
|
8
7
|
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
# provided to the class and class spec templates during rendering.
|
13
|
-
def template_data
|
14
|
-
data = { name: object_name }
|
8
|
+
def initialize(*_args)
|
9
|
+
super
|
10
|
+
object_name_parts = @object_name.split('::')
|
15
11
|
|
16
|
-
|
12
|
+
@object_name = if object_name_parts.first == module_name
|
13
|
+
object_name
|
14
|
+
else
|
15
|
+
[module_name, object_name].join('::')
|
16
|
+
end
|
17
17
|
end
|
18
18
|
|
19
|
-
|
20
|
-
|
21
|
-
#
|
22
|
-
# @return [String] the path where the new class will be written.
|
23
|
-
def target_object_path
|
24
|
-
@target_pp_path ||= begin
|
25
|
-
class_name_parts = object_name.split('::')[1..-1]
|
26
|
-
class_name_parts << 'init' if class_name_parts.empty?
|
27
|
-
|
28
|
-
"#{File.join(module_dir, 'manifests', *class_name_parts)}.pp"
|
29
|
-
end
|
19
|
+
def friendly_name
|
20
|
+
'Puppet Class'.freeze
|
30
21
|
end
|
31
22
|
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
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'
|
40
34
|
|
41
|
-
|
42
|
-
|
35
|
+
files
|
36
|
+
end
|
43
37
|
|
44
|
-
|
45
|
-
|
38
|
+
def template_data
|
39
|
+
{ name: object_name }
|
46
40
|
end
|
47
41
|
end
|
48
42
|
end
|
@@ -3,7 +3,7 @@ require 'pdk'
|
|
3
3
|
module PDK
|
4
4
|
module Generate
|
5
5
|
class PuppetObject
|
6
|
-
attr_reader :
|
6
|
+
attr_reader :context
|
7
7
|
attr_reader :object_name
|
8
8
|
attr_reader :options
|
9
9
|
|
@@ -20,228 +20,124 @@ module PDK
|
|
20
20
|
# will contain the object.
|
21
21
|
# @param object_name [String] The name of the object.
|
22
22
|
# @param options [Hash{Symbol => Object}]
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
@module_dir = module_dir
|
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
|
27
26
|
@options = options
|
28
27
|
@object_name = object_name
|
29
|
-
|
30
|
-
if [:class, :defined_type].include?(object_type) # rubocop:disable Style/GuardClause
|
31
|
-
object_name_parts = object_name.split('::')
|
32
|
-
|
33
|
-
@object_name = if object_name_parts.first == module_name
|
34
|
-
object_name
|
35
|
-
else
|
36
|
-
[module_name, object_name].join('::')
|
37
|
-
end
|
38
|
-
end
|
39
28
|
end
|
40
29
|
|
30
|
+
# Whether the generator should only return test (spec) files
|
31
|
+
# @return [Boolean]
|
41
32
|
def spec_only?
|
42
33
|
@options[:spec_only]
|
43
34
|
end
|
44
35
|
|
45
|
-
#
|
46
|
-
#
|
47
|
-
#
|
48
|
-
def
|
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
|
49
40
|
raise NotImplementedError
|
50
41
|
end
|
51
42
|
|
52
|
-
#
|
53
|
-
# of this method should return a String
|
54
|
-
#
|
55
|
-
|
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
|
56
49
|
raise NotImplementedError
|
57
50
|
end
|
58
51
|
|
59
|
-
#
|
60
|
-
#
|
61
|
-
#
|
62
|
-
|
63
|
-
def target_type_path
|
64
|
-
nil
|
65
|
-
end
|
66
|
-
|
67
|
-
# @abstract Subclass and implement {#target_spec_path}. Implementations
|
68
|
-
# of this method should return a String containing the destination path
|
69
|
-
# of the tests for the object being generated.
|
70
|
-
def target_spec_path
|
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
|
71
56
|
raise NotImplementedError
|
72
57
|
end
|
73
58
|
|
74
|
-
#
|
75
|
-
# of this method should return a String containing the destination path
|
76
|
-
# of the tests for the object being generated.
|
77
|
-
def target_type_spec_path
|
78
|
-
nil
|
79
|
-
end
|
80
|
-
|
81
|
-
# @abstract Subclass and implement {#target_device_path}. Implementations
|
82
|
-
# of this method should return a String containing the destination path
|
83
|
-
# of the device class being generated.
|
84
|
-
def target_device_path
|
85
|
-
nil
|
86
|
-
end
|
87
|
-
|
88
|
-
# Retrieves the type of the object being generated, e.g. :class,
|
89
|
-
# :defined_type, etc. This is specified in the subclass' OBJECT_TYPE
|
90
|
-
# constant.
|
59
|
+
# Raises an error if any pre-conditions are not met
|
91
60
|
#
|
92
|
-
# @return [
|
93
|
-
#
|
94
|
-
|
95
|
-
|
96
|
-
self.class::OBJECT_TYPE
|
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)
|
97
65
|
end
|
98
66
|
|
99
|
-
#
|
100
|
-
# the JSON output of puppet-strings.
|
67
|
+
# Check the preconditions of this template group, behaving as a predicate rather than raising an exception.
|
101
68
|
#
|
102
|
-
# @return [
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
self::PUPPET_STRINGS_TYPE
|
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
|
110
75
|
end
|
111
76
|
|
112
|
-
#
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
]
|
118
|
-
|
119
|
-
unless spec_only?
|
120
|
-
targets += [
|
121
|
-
target_object_path,
|
122
|
-
target_type_path,
|
123
|
-
target_device_path,
|
124
|
-
]
|
125
|
-
end
|
126
|
-
|
127
|
-
targets.compact
|
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
|
128
82
|
end
|
129
83
|
|
130
|
-
#
|
131
|
-
#
|
132
|
-
#
|
133
|
-
# @raise [PDK::CLI::ExitWithError] if the target files already exist.
|
84
|
+
# Stages and then executes the changes for the templates to be rendereed.
|
85
|
+
# This is the main entry point for the class.
|
134
86
|
#
|
87
|
+
# @see #stage_changes
|
88
|
+
# @return [PDK::Module::UpdateManager] The update manager which implemented the changes
|
135
89
|
# @api public
|
136
|
-
def
|
137
|
-
|
138
|
-
|
139
|
-
targets.each do |target_file|
|
140
|
-
next unless PDK::Util::Filesystem.exist?(target_file)
|
141
|
-
|
142
|
-
raise PDK::CLI::ExitWithError, _("Unable to generate %{object_type}; '%{file}' already exists.") % {
|
143
|
-
file: target_file,
|
144
|
-
object_type: spec_only? ? 'unit test' : object_type,
|
145
|
-
}
|
146
|
-
end
|
147
|
-
end
|
148
|
-
|
149
|
-
# Check the preconditions of this template group, behaving as a
|
150
|
-
# predicate rather than raising an exception.
|
151
|
-
#
|
152
|
-
# @return [Boolean] true if the generator is safe to run, otherwise
|
153
|
-
# false.
|
154
|
-
def can_run?
|
155
|
-
check_preconditions
|
156
|
-
true
|
157
|
-
rescue PDK::CLI::ExitWithError
|
158
|
-
false
|
90
|
+
def run(update_manager = update_manager_instance)
|
91
|
+
stage_changes(update_manager).sync_changes!
|
92
|
+
update_manager
|
159
93
|
end
|
160
94
|
|
161
95
|
# Check that the templates can be rendered. Find an appropriate template
|
162
|
-
# and
|
96
|
+
# and stages the target files from the template. This is the main entry
|
163
97
|
# point for the class.
|
164
98
|
#
|
165
99
|
# @raise [PDK::CLI::ExitWithError] if the target files already exist.
|
166
100
|
# @raise [PDK::CLI::FatalError] (see #render_file)
|
167
|
-
#
|
101
|
+
# @return [PDK::Module::UpdateManager] The update manager with the staged changes
|
168
102
|
# @api public
|
169
|
-
def
|
103
|
+
def stage_changes(update_manager)
|
170
104
|
check_preconditions
|
171
105
|
|
172
|
-
with_templates do |
|
173
|
-
|
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?
|
174
110
|
|
175
|
-
|
176
|
-
|
177
|
-
render_file(target_device_path, template_path[:device], data) if template_path[:device]
|
178
|
-
render_file(target_spec_path, template_path[:spec], data) if template_path[:spec]
|
179
|
-
render_file(target_type_spec_path, template_path[:type_spec], data) if template_path[:type_spec]
|
111
|
+
stage_change(relative_dest_path, new_content, update_manager)
|
112
|
+
end
|
180
113
|
end
|
114
|
+
non_template_files.each { |relative_dest_path, content| stage_change(relative_dest_path, content, update_manager) }
|
115
|
+
|
116
|
+
update_manager
|
181
117
|
end
|
182
118
|
|
183
|
-
#
|
184
|
-
#
|
185
|
-
# @param dest_path [String] The path that the rendered file should be
|
186
|
-
# written to. Any necessary directories will be automatically created.
|
187
|
-
# @param template_path [String] The path on disk to the file containing
|
188
|
-
# the template.
|
189
|
-
# @param data [Hash{Object => Object}] The data to be provided to the
|
190
|
-
# template when rendering.
|
191
|
-
#
|
192
|
-
# @raise [PDK::CLI::FatalError] if the parent directories to `dest_path`
|
193
|
-
# do not exist and could not be created.
|
194
|
-
# @raise [PDK::CLI::FatalError] if the rendered file could not be written
|
195
|
-
# to `dest_path`.
|
196
|
-
#
|
119
|
+
# Stages a single file into the Update Manager.
|
197
120
|
# @return [void]
|
198
|
-
#
|
199
121
|
# @api private
|
200
|
-
def
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
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
|
+
}
|
205
129
|
end
|
130
|
+
update_manager.add_file(absolute_file_path, content)
|
206
131
|
end
|
207
132
|
|
208
|
-
#
|
209
|
-
#
|
210
|
-
# @param dest_path [String] The path that the rendered file should be
|
211
|
-
# written to. Any necessary directories will be automatically created.
|
212
|
-
# @param &block [String] The content to be written
|
213
|
-
#
|
214
|
-
# @raise [PDK::CLI::FatalError] if the parent directories to `dest_path`
|
215
|
-
# do not exist and could not be created.
|
216
|
-
# @raise [PDK::CLI::FatalError] if the rendered file could not be written
|
217
|
-
# to `dest_path`.
|
218
|
-
#
|
219
|
-
# @return [void]
|
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
|
220
135
|
#
|
221
136
|
# @api private
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
PDK.logger.info(_("Creating '%{file}' from template.") % { file: dest_path })
|
227
|
-
|
228
|
-
file_content = yield
|
229
|
-
|
230
|
-
begin
|
231
|
-
PDK::Util::Filesystem.mkdir_p(File.dirname(dest_path))
|
232
|
-
rescue SystemCallError => e
|
233
|
-
raise PDK::CLI::FatalError, _("Unable to create directory '%{path}': %{message}") % {
|
234
|
-
path: File.dirname(dest_path),
|
235
|
-
message: e.message,
|
236
|
-
}
|
237
|
-
end
|
238
|
-
|
239
|
-
PDK::Util::Filesystem.write_file(dest_path, file_content)
|
240
|
-
rescue SystemCallError => e
|
241
|
-
raise PDK::CLI::FatalError, _("Unable to write to file '%{path}': %{message}") % {
|
242
|
-
path: dest_path,
|
243
|
-
message: e.message,
|
244
|
-
}
|
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
|
+
{}
|
245
141
|
end
|
246
142
|
|
247
143
|
# Search the possible template directories in order of preference to find
|
@@ -268,18 +164,15 @@ module PDK
|
|
268
164
|
next
|
269
165
|
end
|
270
166
|
|
271
|
-
PDK::
|
272
|
-
|
273
|
-
|
274
|
-
if template_paths
|
275
|
-
config_hash = template_dir.object_config
|
276
|
-
yield template_paths, config_hash
|
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
|
277
170
|
# TODO: refactor to a search-and-execute form instead
|
278
171
|
return # work is done # rubocop:disable Lint/NonLocalExitFromIterator
|
279
172
|
elsif template[:allow_fallback]
|
280
|
-
PDK.logger.debug(_('Unable to find a %{type} template in %{url}; trying next template directory.') % { type:
|
173
|
+
PDK.logger.debug(_('Unable to find a %{type} template in %{url}; trying next template directory.') % { type: friendly_name, url: template[:uri] })
|
281
174
|
else
|
282
|
-
raise PDK::CLI::FatalError, _('Unable to find the %{type} template in %{url}.') % { type:
|
175
|
+
raise PDK::CLI::FatalError, _('Unable to find the %{type} template in %{url}.') % { type: friendly_name, url: template[:uri] }
|
283
176
|
end
|
284
177
|
end
|
285
178
|
end
|
@@ -320,15 +213,18 @@ module PDK
|
|
320
213
|
#
|
321
214
|
# @api private
|
322
215
|
def module_name
|
323
|
-
|
216
|
+
return nil unless context.is_a?(PDK::Context::Module)
|
324
217
|
|
325
|
-
|
218
|
+
require 'pdk/util'
|
219
|
+
@module_name ||= PDK::Util.module_metadata(context.root_path)['name'].rpartition('-').last
|
326
220
|
rescue ArgumentError => e
|
327
221
|
raise PDK::CLI::FatalError, e
|
328
222
|
end
|
329
223
|
|
330
|
-
|
331
|
-
|
224
|
+
private
|
225
|
+
|
226
|
+
# Transform an object name into a ruby class name
|
227
|
+
def class_name_from_object_name(object_name)
|
332
228
|
object_name.to_s.split('_').map(&:capitalize).join
|
333
229
|
end
|
334
230
|
end
|