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,295 +1,295 @@
|
|
|
1
|
-
require 'pdk'
|
|
2
|
-
|
|
3
|
-
module PDK
|
|
4
|
-
module Util
|
|
5
|
-
class TemplateURI
|
|
6
|
-
SCP_PATTERN = %r{\A(?!\w+://)(?:(?<user>.+?)@)?(?<host>[^:/]+):(?<path>.+)\z}
|
|
7
|
-
|
|
8
|
-
PACKAGED_TEMPLATE_KEYWORD = 'pdk-default'.freeze
|
|
9
|
-
DEPRECATED_TEMPLATE_URL = 'https://github.com/puppetlabs/pdk-module-template'.freeze
|
|
10
|
-
PDK_TEMPLATE_URL = 'https://github.com/puppetlabs/pdk-templates'.freeze
|
|
11
|
-
|
|
12
|
-
LEGACY_PACKAGED_TEMPLATE_PATHS = {
|
|
13
|
-
'windows' => 'file:///C:/Program Files/Puppet Labs/DevelopmentKit/share/cache/pdk-templates.git',
|
|
14
|
-
'macos' => 'file:///opt/puppetlabs/pdk/share/cache/pdk-templates.git',
|
|
15
|
-
'linux' => 'file:///opt/puppetlabs/pdk/share/cache/pdk-templates.git',
|
|
16
|
-
}.freeze
|
|
17
|
-
|
|
18
|
-
# XXX Previously
|
|
19
|
-
# - template_uri used to get the string form of the uri when generating the module and written to pdk answers and metadata
|
|
20
|
-
# - template_path or deuri_path used for humans to see and commands to run
|
|
21
|
-
# - uri_path used only internally by the template selection code; move out
|
|
22
|
-
# - template_ref used by git checkout
|
|
23
|
-
attr_reader :uri
|
|
24
|
-
|
|
25
|
-
# input/output formats:
|
|
26
|
-
#
|
|
27
|
-
# file:///c:/foo (git clone location)
|
|
28
|
-
# c:/foo (shell paths)
|
|
29
|
-
# file:///c:/foo#main (only for metadata)
|
|
30
|
-
# c:/foo#main (only for metadata)
|
|
31
|
-
#
|
|
32
|
-
# non output formats:
|
|
33
|
-
#
|
|
34
|
-
# /c:/foo (internal use only)
|
|
35
|
-
# /c:/foo#main (internal use only)
|
|
36
|
-
#
|
|
37
|
-
def initialize(opts_or_uri)
|
|
38
|
-
require 'addressable'
|
|
39
|
-
# If a uri string is passed, skip the valid uri finding code.
|
|
40
|
-
@uri = if opts_or_uri.is_a?(self.class)
|
|
41
|
-
opts_or_uri.uri
|
|
42
|
-
elsif opts_or_uri.is_a?(String)
|
|
43
|
-
begin
|
|
44
|
-
uri, ref = opts_or_uri.split('#', 2)
|
|
45
|
-
if PDK::Util::TemplateURI.packaged_template?(uri)
|
|
46
|
-
PDK::Util::TemplateURI.default_template_addressable_uri.tap { |default| default.fragment = ref unless ref.nil? || ref.empty? }
|
|
47
|
-
else
|
|
48
|
-
Addressable::URI.parse(opts_or_uri)
|
|
49
|
-
end
|
|
50
|
-
rescue Addressable::URI::InvalidURIError
|
|
51
|
-
raise PDK::CLI::FatalError, _('PDK::Util::TemplateURI attempted initialization with a non-uri string: {string}') % { string: opts_or_uri }
|
|
52
|
-
end
|
|
53
|
-
elsif opts_or_uri.is_a?(Addressable::URI)
|
|
54
|
-
opts_or_uri.dup
|
|
55
|
-
else
|
|
56
|
-
PDK::Util::TemplateURI.first_valid_uri(PDK::Util::TemplateURI.templates(opts_or_uri))
|
|
57
|
-
end
|
|
58
|
-
end
|
|
59
|
-
|
|
60
|
-
def ==(other)
|
|
61
|
-
@uri == other.uri
|
|
62
|
-
end
|
|
63
|
-
|
|
64
|
-
def bare_uri
|
|
65
|
-
PDK::Util::TemplateURI.bare_uri(@uri)
|
|
66
|
-
end
|
|
67
|
-
|
|
68
|
-
# This is the URI represented in a format suitable for writing to
|
|
69
|
-
# metadata.
|
|
70
|
-
#
|
|
71
|
-
# @returns String
|
|
72
|
-
def metadata_format
|
|
73
|
-
@metadata_format ||= if PDK::Util::TemplateURI.packaged_template?(bare_uri)
|
|
74
|
-
PDK::Util::TemplateURI.human_readable("pdk-default##{uri_fragment}")
|
|
75
|
-
else
|
|
76
|
-
PDK::Util::TemplateURI.human_readable(@uri.to_s)
|
|
77
|
-
end
|
|
78
|
-
end
|
|
79
|
-
alias to_s metadata_format
|
|
80
|
-
alias to_str metadata_format
|
|
81
|
-
|
|
82
|
-
# Returns the fragment of the URI, of the default template's ref if one does not exist
|
|
83
|
-
# @returns String
|
|
84
|
-
# @api private
|
|
85
|
-
def uri_fragment
|
|
86
|
-
@uri.fragment || self.class.default_template_ref(self)
|
|
87
|
-
end
|
|
88
|
-
|
|
89
|
-
def uri_fragment=(fragment)
|
|
90
|
-
@uri.fragment = fragment
|
|
91
|
-
end
|
|
92
|
-
|
|
93
|
-
def default?
|
|
94
|
-
bare_uri == PDK::Util::TemplateURI.bare_uri(PDK::Util::TemplateURI.default_template_addressable_uri)
|
|
95
|
-
end
|
|
96
|
-
|
|
97
|
-
def default_ref?
|
|
98
|
-
uri_fragment == self.class.default_template_ref(self)
|
|
99
|
-
end
|
|
100
|
-
|
|
101
|
-
def puppetlabs_template?
|
|
102
|
-
self.class.packaged_template?(bare_uri) || bare_uri == PDK_TEMPLATE_URL
|
|
103
|
-
end
|
|
104
|
-
|
|
105
|
-
# Class Methods
|
|
106
|
-
|
|
107
|
-
# Remove the fragment off of URI. Useful for removing the branch
|
|
108
|
-
# for Git based URIs
|
|
109
|
-
def self.bare_uri(uri)
|
|
110
|
-
require 'addressable'
|
|
111
|
-
|
|
112
|
-
if uri.is_a?(Addressable::URI) && uri.fragment
|
|
113
|
-
human_readable(uri.to_s.chomp('#' + uri.fragment))
|
|
114
|
-
else
|
|
115
|
-
human_readable(uri.to_s)
|
|
116
|
-
end
|
|
117
|
-
end
|
|
118
|
-
|
|
119
|
-
# This is the path of the URI, suitable for accessing directly from the shell.
|
|
120
|
-
# @returns String
|
|
121
|
-
def shell_path
|
|
122
|
-
self.class.human_readable(@uri.path)
|
|
123
|
-
end
|
|
124
|
-
|
|
125
|
-
# @returns PDK::Util::TemplateURI
|
|
126
|
-
def self.default_template_uri
|
|
127
|
-
require 'pdk/util'
|
|
128
|
-
require 'addressable'
|
|
129
|
-
|
|
130
|
-
PDK::Util::TemplateURI.new(default_template_addressable_uri)
|
|
131
|
-
end
|
|
132
|
-
|
|
133
|
-
# @returns Addressable::URI
|
|
134
|
-
# @api private
|
|
135
|
-
def self.default_template_addressable_uri
|
|
136
|
-
require 'pdk/util'
|
|
137
|
-
require 'addressable'
|
|
138
|
-
|
|
139
|
-
if PDK::Util.package_install?
|
|
140
|
-
Addressable::URI.new(scheme: 'file', host: '', path: File.join(PDK::Util.package_cachedir, 'pdk-templates.git'))
|
|
141
|
-
else
|
|
142
|
-
Addressable::URI.parse(PDK_TEMPLATE_URL)
|
|
143
|
-
end
|
|
144
|
-
end
|
|
145
|
-
|
|
146
|
-
# `C:...` urls are not URI-safe. They should be of the form `/C:...` to
|
|
147
|
-
# be URI-safe. scp-like urls like `user@host:/path` are not URI-safe
|
|
148
|
-
# either and so are subsequently converted to ssh:// URIs.
|
|
149
|
-
#
|
|
150
|
-
# @returns String
|
|
151
|
-
def self.uri_safe(string)
|
|
152
|
-
url = (Gem.win_platform? && string =~ %r{^[a-zA-Z][\|:]}) ? "/#{string}" : string
|
|
153
|
-
parse_scp_url(url)
|
|
154
|
-
end
|
|
155
|
-
|
|
156
|
-
# If the passed value is a URI-safe windows path such as `/C:...` then it
|
|
157
|
-
# should be changed to a human-friendly `C:...` form. Otherwise the
|
|
158
|
-
# passed value is left alone.
|
|
159
|
-
#
|
|
160
|
-
# @returns String
|
|
161
|
-
def self.human_readable(string)
|
|
162
|
-
(Gem.win_platform? && string =~ %r{^\/[a-zA-Z][\|:]}) ? string[1..-1] : string
|
|
163
|
-
end
|
|
164
|
-
|
|
165
|
-
def self.parse_scp_url(url)
|
|
166
|
-
require 'pathname'
|
|
167
|
-
require 'addressable'
|
|
168
|
-
|
|
169
|
-
# Valid URIs to avoid catching:
|
|
170
|
-
# - absolute local paths
|
|
171
|
-
# - have :'s in paths when preceeded by a slash
|
|
172
|
-
# - have only digits following the : and preceeding a / or end-of-string that is 0-65535
|
|
173
|
-
# The last item is ambiguous in the case of scp/git paths vs. URI port
|
|
174
|
-
# numbers, but can be made unambiguous by making the form to
|
|
175
|
-
# ssh://git@github.com/1234/repo.git or
|
|
176
|
-
# ssh://git@github.com:1234/user/repo.git
|
|
177
|
-
scp_url = url.match(SCP_PATTERN)
|
|
178
|
-
return url unless Pathname.new(url).relative? && scp_url
|
|
179
|
-
|
|
180
|
-
uri = Addressable::URI.new(scheme: 'ssh', user: scp_url[:user], host: scp_url[:host], path: scp_url[:path])
|
|
181
|
-
PDK.logger.warn _('%{scp_uri} appears to be an SCP style URL; it will be converted to an RFC compliant URI: %{rfc_uri}') % {
|
|
182
|
-
scp_uri: url,
|
|
183
|
-
rfc_uri: uri.to_s,
|
|
184
|
-
}
|
|
185
|
-
|
|
186
|
-
uri.to_s
|
|
187
|
-
end
|
|
188
|
-
|
|
189
|
-
# @return [Array<Hash{Symbol => Object}>] an array of hashes. Each hash
|
|
190
|
-
# contains 3 keys: :type contains a String that describes the template
|
|
191
|
-
# directory, :url contains a String with the URL to the template
|
|
192
|
-
# directory, and :allow_fallback contains a Boolean that specifies if
|
|
193
|
-
# the lookup process should proceed to the next template directory if
|
|
194
|
-
# the template file is not in this template directory.
|
|
195
|
-
def self.templates(opts)
|
|
196
|
-
require 'pdk/answer_file'
|
|
197
|
-
require 'pdk/util'
|
|
198
|
-
require 'addressable'
|
|
199
|
-
|
|
200
|
-
explicit_url = opts.fetch(:'template-url', nil)
|
|
201
|
-
explicit_ref = opts.fetch(:'template-ref', nil)
|
|
202
|
-
|
|
203
|
-
# 1. Get the CLI, metadata (or answers if no metadata), and default URIs
|
|
204
|
-
# 2. Construct the hash
|
|
205
|
-
if explicit_url
|
|
206
|
-
explicit_uri = Addressable::URI.parse(uri_safe(explicit_url))
|
|
207
|
-
explicit_uri.fragment = explicit_ref || default_template_ref(new(explicit_uri))
|
|
208
|
-
else
|
|
209
|
-
explicit_uri = nil
|
|
210
|
-
end
|
|
211
|
-
metadata_uri = if PDK::Util.module_root && PDK::Util::Filesystem.file?(File.join(PDK::Util.module_root, 'metadata.json'))
|
|
212
|
-
if PDK::Util.module_metadata['template-url']
|
|
213
|
-
new(uri_safe(PDK::Util.module_metadata['template-url'])).uri
|
|
214
|
-
else
|
|
215
|
-
nil
|
|
216
|
-
end
|
|
217
|
-
else
|
|
218
|
-
nil
|
|
219
|
-
end
|
|
220
|
-
default_template_url = PDK.config.get_within_scopes('module_defaults.template-url')
|
|
221
|
-
answers_uri = if [PACKAGED_TEMPLATE_KEYWORD, DEPRECATED_TEMPLATE_URL].include?(default_template_url)
|
|
222
|
-
Addressable::URI.parse(default_template_uri)
|
|
223
|
-
elsif default_template_url
|
|
224
|
-
new(uri_safe(default_template_url)).uri
|
|
225
|
-
else
|
|
226
|
-
nil
|
|
227
|
-
end
|
|
228
|
-
default_uri = default_template_uri.uri
|
|
229
|
-
default_uri.fragment = default_template_ref(default_template_uri)
|
|
230
|
-
|
|
231
|
-
ary = []
|
|
232
|
-
ary << { type: _('--template-url'), uri: explicit_uri, allow_fallback: false } if explicit_url
|
|
233
|
-
ary << { type: _('metadata.json'), uri: metadata_uri, allow_fallback: true } if metadata_uri
|
|
234
|
-
ary << { type: _('PDK answers'), uri: answers_uri, allow_fallback: true } if answers_uri
|
|
235
|
-
ary << { type: _('default'), uri: default_uri, allow_fallback: false }
|
|
236
|
-
ary
|
|
237
|
-
end
|
|
238
|
-
|
|
239
|
-
# @returns String
|
|
240
|
-
def self.default_template_ref(uri = nil)
|
|
241
|
-
require 'pdk/util'
|
|
242
|
-
require 'pdk/version'
|
|
243
|
-
|
|
244
|
-
return 'main' if PDK::Util.development_mode?
|
|
245
|
-
return PDK::TEMPLATE_REF if uri.nil?
|
|
246
|
-
|
|
247
|
-
uri = new(uri) unless uri.is_a?(self)
|
|
248
|
-
uri.default? ? PDK::TEMPLATE_REF : 'main'
|
|
249
|
-
end
|
|
250
|
-
|
|
251
|
-
# @returns Addressable::URI
|
|
252
|
-
def self.first_valid_uri(templates_array)
|
|
253
|
-
# 1. Get the four sources of URIs
|
|
254
|
-
# 2. Pick the first non-nil URI
|
|
255
|
-
# 3. Error if the URI is not a valid git repo (missing directory or http 404)
|
|
256
|
-
# 4. Leave updating answers/metadata to other code
|
|
257
|
-
found_template = templates_array.find { |t| valid_template?(t) }
|
|
258
|
-
|
|
259
|
-
raise PDK::CLI::FatalError, _('Unable to find a valid module template to use.') if found_template.nil?
|
|
260
|
-
found_template[:uri]
|
|
261
|
-
end
|
|
262
|
-
|
|
263
|
-
def self.valid_template?(template, context = PDK.context)
|
|
264
|
-
require 'addressable'
|
|
265
|
-
|
|
266
|
-
return false if template.nil? || !template.is_a?(Hash)
|
|
267
|
-
return false if template[:uri].nil? || !template[:uri].is_a?(Addressable::URI)
|
|
268
|
-
|
|
269
|
-
return true if PDK::Util::Git.repo?(bare_uri(template[:uri]))
|
|
270
|
-
path = human_readable(template[:uri].path)
|
|
271
|
-
if PDK::Util::Filesystem.directory?(path)
|
|
272
|
-
# We know that it's not a git repository, but it's a valid path on disk
|
|
273
|
-
begin
|
|
274
|
-
renderer = PDK::Template::Renderer.instance(path, template[:uri], context)
|
|
275
|
-
return !renderer.nil?
|
|
276
|
-
rescue StandardError
|
|
277
|
-
nil
|
|
278
|
-
end
|
|
279
|
-
end
|
|
280
|
-
|
|
281
|
-
unless template[:allow_fallback]
|
|
282
|
-
raise PDK::CLI::FatalError, _('Unable to find a valid template at %{uri}') % {
|
|
283
|
-
uri: template[:uri].to_s,
|
|
284
|
-
}
|
|
285
|
-
end
|
|
286
|
-
|
|
287
|
-
false
|
|
288
|
-
end
|
|
289
|
-
|
|
290
|
-
def self.packaged_template?(path)
|
|
291
|
-
path == PACKAGED_TEMPLATE_KEYWORD || LEGACY_PACKAGED_TEMPLATE_PATHS.value?(path)
|
|
292
|
-
end
|
|
293
|
-
end
|
|
294
|
-
end
|
|
295
|
-
end
|
|
1
|
+
require 'pdk'
|
|
2
|
+
|
|
3
|
+
module PDK
|
|
4
|
+
module Util
|
|
5
|
+
class TemplateURI
|
|
6
|
+
SCP_PATTERN = %r{\A(?!\w+://)(?:(?<user>.+?)@)?(?<host>[^:/]+):(?<path>.+)\z}
|
|
7
|
+
|
|
8
|
+
PACKAGED_TEMPLATE_KEYWORD = 'pdk-default'.freeze
|
|
9
|
+
DEPRECATED_TEMPLATE_URL = 'https://github.com/puppetlabs/pdk-module-template'.freeze
|
|
10
|
+
PDK_TEMPLATE_URL = 'https://github.com/puppetlabs/pdk-templates'.freeze
|
|
11
|
+
|
|
12
|
+
LEGACY_PACKAGED_TEMPLATE_PATHS = {
|
|
13
|
+
'windows' => 'file:///C:/Program Files/Puppet Labs/DevelopmentKit/share/cache/pdk-templates.git',
|
|
14
|
+
'macos' => 'file:///opt/puppetlabs/pdk/share/cache/pdk-templates.git',
|
|
15
|
+
'linux' => 'file:///opt/puppetlabs/pdk/share/cache/pdk-templates.git',
|
|
16
|
+
}.freeze
|
|
17
|
+
|
|
18
|
+
# XXX Previously
|
|
19
|
+
# - template_uri used to get the string form of the uri when generating the module and written to pdk answers and metadata
|
|
20
|
+
# - template_path or deuri_path used for humans to see and commands to run
|
|
21
|
+
# - uri_path used only internally by the template selection code; move out
|
|
22
|
+
# - template_ref used by git checkout
|
|
23
|
+
attr_reader :uri
|
|
24
|
+
|
|
25
|
+
# input/output formats:
|
|
26
|
+
#
|
|
27
|
+
# file:///c:/foo (git clone location)
|
|
28
|
+
# c:/foo (shell paths)
|
|
29
|
+
# file:///c:/foo#main (only for metadata)
|
|
30
|
+
# c:/foo#main (only for metadata)
|
|
31
|
+
#
|
|
32
|
+
# non output formats:
|
|
33
|
+
#
|
|
34
|
+
# /c:/foo (internal use only)
|
|
35
|
+
# /c:/foo#main (internal use only)
|
|
36
|
+
#
|
|
37
|
+
def initialize(opts_or_uri)
|
|
38
|
+
require 'addressable'
|
|
39
|
+
# If a uri string is passed, skip the valid uri finding code.
|
|
40
|
+
@uri = if opts_or_uri.is_a?(self.class)
|
|
41
|
+
opts_or_uri.uri
|
|
42
|
+
elsif opts_or_uri.is_a?(String)
|
|
43
|
+
begin
|
|
44
|
+
uri, ref = opts_or_uri.split('#', 2)
|
|
45
|
+
if PDK::Util::TemplateURI.packaged_template?(uri)
|
|
46
|
+
PDK::Util::TemplateURI.default_template_addressable_uri.tap { |default| default.fragment = ref unless ref.nil? || ref.empty? }
|
|
47
|
+
else
|
|
48
|
+
Addressable::URI.parse(opts_or_uri)
|
|
49
|
+
end
|
|
50
|
+
rescue Addressable::URI::InvalidURIError
|
|
51
|
+
raise PDK::CLI::FatalError, _('PDK::Util::TemplateURI attempted initialization with a non-uri string: {string}') % { string: opts_or_uri }
|
|
52
|
+
end
|
|
53
|
+
elsif opts_or_uri.is_a?(Addressable::URI)
|
|
54
|
+
opts_or_uri.dup
|
|
55
|
+
else
|
|
56
|
+
PDK::Util::TemplateURI.first_valid_uri(PDK::Util::TemplateURI.templates(opts_or_uri))
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def ==(other)
|
|
61
|
+
@uri == other.uri
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
def bare_uri
|
|
65
|
+
PDK::Util::TemplateURI.bare_uri(@uri)
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
# This is the URI represented in a format suitable for writing to
|
|
69
|
+
# metadata.
|
|
70
|
+
#
|
|
71
|
+
# @returns String
|
|
72
|
+
def metadata_format
|
|
73
|
+
@metadata_format ||= if PDK::Util::TemplateURI.packaged_template?(bare_uri)
|
|
74
|
+
PDK::Util::TemplateURI.human_readable("pdk-default##{uri_fragment}")
|
|
75
|
+
else
|
|
76
|
+
PDK::Util::TemplateURI.human_readable(@uri.to_s)
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
alias to_s metadata_format
|
|
80
|
+
alias to_str metadata_format
|
|
81
|
+
|
|
82
|
+
# Returns the fragment of the URI, of the default template's ref if one does not exist
|
|
83
|
+
# @returns String
|
|
84
|
+
# @api private
|
|
85
|
+
def uri_fragment
|
|
86
|
+
@uri.fragment || self.class.default_template_ref(self)
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
def uri_fragment=(fragment)
|
|
90
|
+
@uri.fragment = fragment
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
def default?
|
|
94
|
+
bare_uri == PDK::Util::TemplateURI.bare_uri(PDK::Util::TemplateURI.default_template_addressable_uri)
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
def default_ref?
|
|
98
|
+
uri_fragment == self.class.default_template_ref(self)
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
def puppetlabs_template?
|
|
102
|
+
self.class.packaged_template?(bare_uri) || bare_uri == PDK_TEMPLATE_URL
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
# Class Methods
|
|
106
|
+
|
|
107
|
+
# Remove the fragment off of URI. Useful for removing the branch
|
|
108
|
+
# for Git based URIs
|
|
109
|
+
def self.bare_uri(uri)
|
|
110
|
+
require 'addressable'
|
|
111
|
+
|
|
112
|
+
if uri.is_a?(Addressable::URI) && uri.fragment
|
|
113
|
+
human_readable(uri.to_s.chomp('#' + uri.fragment))
|
|
114
|
+
else
|
|
115
|
+
human_readable(uri.to_s)
|
|
116
|
+
end
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
# This is the path of the URI, suitable for accessing directly from the shell.
|
|
120
|
+
# @returns String
|
|
121
|
+
def shell_path
|
|
122
|
+
self.class.human_readable(@uri.path)
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
# @returns PDK::Util::TemplateURI
|
|
126
|
+
def self.default_template_uri
|
|
127
|
+
require 'pdk/util'
|
|
128
|
+
require 'addressable'
|
|
129
|
+
|
|
130
|
+
PDK::Util::TemplateURI.new(default_template_addressable_uri)
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
# @returns Addressable::URI
|
|
134
|
+
# @api private
|
|
135
|
+
def self.default_template_addressable_uri
|
|
136
|
+
require 'pdk/util'
|
|
137
|
+
require 'addressable'
|
|
138
|
+
|
|
139
|
+
if PDK::Util.package_install?
|
|
140
|
+
Addressable::URI.new(scheme: 'file', host: '', path: File.join(PDK::Util.package_cachedir, 'pdk-templates.git'))
|
|
141
|
+
else
|
|
142
|
+
Addressable::URI.parse(PDK_TEMPLATE_URL)
|
|
143
|
+
end
|
|
144
|
+
end
|
|
145
|
+
|
|
146
|
+
# `C:...` urls are not URI-safe. They should be of the form `/C:...` to
|
|
147
|
+
# be URI-safe. scp-like urls like `user@host:/path` are not URI-safe
|
|
148
|
+
# either and so are subsequently converted to ssh:// URIs.
|
|
149
|
+
#
|
|
150
|
+
# @returns String
|
|
151
|
+
def self.uri_safe(string)
|
|
152
|
+
url = (Gem.win_platform? && string =~ %r{^[a-zA-Z][\|:]}) ? "/#{string}" : string
|
|
153
|
+
parse_scp_url(url)
|
|
154
|
+
end
|
|
155
|
+
|
|
156
|
+
# If the passed value is a URI-safe windows path such as `/C:...` then it
|
|
157
|
+
# should be changed to a human-friendly `C:...` form. Otherwise the
|
|
158
|
+
# passed value is left alone.
|
|
159
|
+
#
|
|
160
|
+
# @returns String
|
|
161
|
+
def self.human_readable(string)
|
|
162
|
+
(Gem.win_platform? && string =~ %r{^\/[a-zA-Z][\|:]}) ? string[1..-1] : string
|
|
163
|
+
end
|
|
164
|
+
|
|
165
|
+
def self.parse_scp_url(url)
|
|
166
|
+
require 'pathname'
|
|
167
|
+
require 'addressable'
|
|
168
|
+
|
|
169
|
+
# Valid URIs to avoid catching:
|
|
170
|
+
# - absolute local paths
|
|
171
|
+
# - have :'s in paths when preceeded by a slash
|
|
172
|
+
# - have only digits following the : and preceeding a / or end-of-string that is 0-65535
|
|
173
|
+
# The last item is ambiguous in the case of scp/git paths vs. URI port
|
|
174
|
+
# numbers, but can be made unambiguous by making the form to
|
|
175
|
+
# ssh://git@github.com/1234/repo.git or
|
|
176
|
+
# ssh://git@github.com:1234/user/repo.git
|
|
177
|
+
scp_url = url.match(SCP_PATTERN)
|
|
178
|
+
return url unless Pathname.new(url).relative? && scp_url
|
|
179
|
+
|
|
180
|
+
uri = Addressable::URI.new(scheme: 'ssh', user: scp_url[:user], host: scp_url[:host], path: scp_url[:path])
|
|
181
|
+
PDK.logger.warn _('%{scp_uri} appears to be an SCP style URL; it will be converted to an RFC compliant URI: %{rfc_uri}') % {
|
|
182
|
+
scp_uri: url,
|
|
183
|
+
rfc_uri: uri.to_s,
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
uri.to_s
|
|
187
|
+
end
|
|
188
|
+
|
|
189
|
+
# @return [Array<Hash{Symbol => Object}>] an array of hashes. Each hash
|
|
190
|
+
# contains 3 keys: :type contains a String that describes the template
|
|
191
|
+
# directory, :url contains a String with the URL to the template
|
|
192
|
+
# directory, and :allow_fallback contains a Boolean that specifies if
|
|
193
|
+
# the lookup process should proceed to the next template directory if
|
|
194
|
+
# the template file is not in this template directory.
|
|
195
|
+
def self.templates(opts)
|
|
196
|
+
require 'pdk/answer_file'
|
|
197
|
+
require 'pdk/util'
|
|
198
|
+
require 'addressable'
|
|
199
|
+
|
|
200
|
+
explicit_url = opts.fetch(:'template-url', nil)
|
|
201
|
+
explicit_ref = opts.fetch(:'template-ref', nil)
|
|
202
|
+
|
|
203
|
+
# 1. Get the CLI, metadata (or answers if no metadata), and default URIs
|
|
204
|
+
# 2. Construct the hash
|
|
205
|
+
if explicit_url
|
|
206
|
+
explicit_uri = Addressable::URI.parse(uri_safe(explicit_url))
|
|
207
|
+
explicit_uri.fragment = explicit_ref || default_template_ref(new(explicit_uri))
|
|
208
|
+
else
|
|
209
|
+
explicit_uri = nil
|
|
210
|
+
end
|
|
211
|
+
metadata_uri = if PDK::Util.module_root && PDK::Util::Filesystem.file?(File.join(PDK::Util.module_root, 'metadata.json'))
|
|
212
|
+
if PDK::Util.module_metadata['template-url']
|
|
213
|
+
new(uri_safe(PDK::Util.module_metadata['template-url'])).uri
|
|
214
|
+
else
|
|
215
|
+
nil
|
|
216
|
+
end
|
|
217
|
+
else
|
|
218
|
+
nil
|
|
219
|
+
end
|
|
220
|
+
default_template_url = PDK.config.get_within_scopes('module_defaults.template-url')
|
|
221
|
+
answers_uri = if [PACKAGED_TEMPLATE_KEYWORD, DEPRECATED_TEMPLATE_URL].include?(default_template_url)
|
|
222
|
+
Addressable::URI.parse(default_template_uri)
|
|
223
|
+
elsif default_template_url
|
|
224
|
+
new(uri_safe(default_template_url)).uri
|
|
225
|
+
else
|
|
226
|
+
nil
|
|
227
|
+
end
|
|
228
|
+
default_uri = default_template_uri.uri
|
|
229
|
+
default_uri.fragment = default_template_ref(default_template_uri)
|
|
230
|
+
|
|
231
|
+
ary = []
|
|
232
|
+
ary << { type: _('--template-url'), uri: explicit_uri, allow_fallback: false } if explicit_url
|
|
233
|
+
ary << { type: _('metadata.json'), uri: metadata_uri, allow_fallback: true } if metadata_uri
|
|
234
|
+
ary << { type: _('PDK answers'), uri: answers_uri, allow_fallback: true } if answers_uri
|
|
235
|
+
ary << { type: _('default'), uri: default_uri, allow_fallback: false }
|
|
236
|
+
ary
|
|
237
|
+
end
|
|
238
|
+
|
|
239
|
+
# @returns String
|
|
240
|
+
def self.default_template_ref(uri = nil)
|
|
241
|
+
require 'pdk/util'
|
|
242
|
+
require 'pdk/version'
|
|
243
|
+
|
|
244
|
+
return 'main' if PDK::Util.development_mode?
|
|
245
|
+
return PDK::TEMPLATE_REF if uri.nil?
|
|
246
|
+
|
|
247
|
+
uri = new(uri) unless uri.is_a?(self)
|
|
248
|
+
uri.default? ? PDK::TEMPLATE_REF : 'main'
|
|
249
|
+
end
|
|
250
|
+
|
|
251
|
+
# @returns Addressable::URI
|
|
252
|
+
def self.first_valid_uri(templates_array)
|
|
253
|
+
# 1. Get the four sources of URIs
|
|
254
|
+
# 2. Pick the first non-nil URI
|
|
255
|
+
# 3. Error if the URI is not a valid git repo (missing directory or http 404)
|
|
256
|
+
# 4. Leave updating answers/metadata to other code
|
|
257
|
+
found_template = templates_array.find { |t| valid_template?(t) }
|
|
258
|
+
|
|
259
|
+
raise PDK::CLI::FatalError, _('Unable to find a valid module template to use.') if found_template.nil?
|
|
260
|
+
found_template[:uri]
|
|
261
|
+
end
|
|
262
|
+
|
|
263
|
+
def self.valid_template?(template, context = PDK.context)
|
|
264
|
+
require 'addressable'
|
|
265
|
+
|
|
266
|
+
return false if template.nil? || !template.is_a?(Hash)
|
|
267
|
+
return false if template[:uri].nil? || !template[:uri].is_a?(Addressable::URI)
|
|
268
|
+
|
|
269
|
+
return true if PDK::Util::Git.repo?(bare_uri(template[:uri]))
|
|
270
|
+
path = human_readable(template[:uri].path)
|
|
271
|
+
if PDK::Util::Filesystem.directory?(path)
|
|
272
|
+
# We know that it's not a git repository, but it's a valid path on disk
|
|
273
|
+
begin
|
|
274
|
+
renderer = PDK::Template::Renderer.instance(path, template[:uri], context)
|
|
275
|
+
return !renderer.nil?
|
|
276
|
+
rescue StandardError
|
|
277
|
+
nil
|
|
278
|
+
end
|
|
279
|
+
end
|
|
280
|
+
|
|
281
|
+
unless template[:allow_fallback]
|
|
282
|
+
raise PDK::CLI::FatalError, _('Unable to find a valid template at %{uri}') % {
|
|
283
|
+
uri: template[:uri].to_s,
|
|
284
|
+
}
|
|
285
|
+
end
|
|
286
|
+
|
|
287
|
+
false
|
|
288
|
+
end
|
|
289
|
+
|
|
290
|
+
def self.packaged_template?(path)
|
|
291
|
+
path == PACKAGED_TEMPLATE_KEYWORD || LEGACY_PACKAGED_TEMPLATE_PATHS.value?(path)
|
|
292
|
+
end
|
|
293
|
+
end
|
|
294
|
+
end
|
|
295
|
+
end
|