pdk 1.9.1 → 1.10.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +25 -0
- data/lib/pdk/cli.rb +5 -1
- data/lib/pdk/cli/build.rb +6 -2
- data/lib/pdk/cli/convert.rb +3 -0
- data/lib/pdk/cli/module/generate.rb +3 -0
- data/lib/pdk/cli/new/class.rb +0 -2
- data/lib/pdk/cli/new/defined_type.rb +0 -2
- data/lib/pdk/cli/new/module.rb +3 -0
- data/lib/pdk/cli/new/provider.rb +0 -2
- data/lib/pdk/cli/new/task.rb +0 -1
- data/lib/pdk/cli/update.rb +2 -0
- data/lib/pdk/cli/util.rb +10 -0
- data/lib/pdk/cli/validate.rb +1 -1
- data/lib/pdk/generate/module.rb +11 -9
- data/lib/pdk/generate/puppet_object.rb +5 -9
- data/lib/pdk/module/convert.rb +3 -3
- data/lib/pdk/module/metadata.rb +2 -2
- data/lib/pdk/module/templatedir.rb +54 -29
- data/lib/pdk/module/update.rb +22 -14
- data/lib/pdk/util.rb +1 -57
- data/lib/pdk/util/filesystem.rb +7 -1
- data/lib/pdk/util/git.rb +46 -1
- data/lib/pdk/util/template_uri.rb +231 -0
- data/lib/pdk/util/version.rb +1 -2
- data/lib/pdk/version.rb +1 -1
- data/locales/pdk.pot +174 -106
- metadata +12 -5
data/lib/pdk/module/update.rb
CHANGED
@@ -6,6 +6,8 @@ module PDK
|
|
6
6
|
GIT_DESCRIBE_PATTERN = %r{\A(?<base>.+?)-(?<additional_commits>\d+)-g(?<sha>.+)\Z}
|
7
7
|
|
8
8
|
def run
|
9
|
+
template_uri.git_ref = new_template_version
|
10
|
+
|
9
11
|
stage_changes!
|
10
12
|
|
11
13
|
if current_version == new_version
|
@@ -50,8 +52,8 @@ module PDK
|
|
50
52
|
raise PDK::CLI::ExitWithError, e.message
|
51
53
|
end
|
52
54
|
|
53
|
-
def
|
54
|
-
@
|
55
|
+
def template_uri
|
56
|
+
@template_uri ||= PDK::Util::TemplateURI.new(module_metadata.data['template-url'])
|
55
57
|
end
|
56
58
|
|
57
59
|
def current_version
|
@@ -62,6 +64,16 @@ module PDK
|
|
62
64
|
@new_version ||= fetch_remote_version(new_template_version)
|
63
65
|
end
|
64
66
|
|
67
|
+
def new_template_version
|
68
|
+
return options[:'template-ref'] if options[:'template-ref']
|
69
|
+
|
70
|
+
if template_uri.default? && template_uri.ref_is_tag? && PDK::Util.package_install?
|
71
|
+
PDK::Util::TemplateURI.default_template_ref
|
72
|
+
else
|
73
|
+
template_uri.git_ref
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
65
77
|
private
|
66
78
|
|
67
79
|
def current_template_version
|
@@ -73,27 +85,23 @@ module PDK
|
|
73
85
|
|
74
86
|
return data if data.nil?
|
75
87
|
|
76
|
-
if data[:base]
|
77
|
-
"#{data[:base].gsub(%r{^heads
|
88
|
+
if data[:base] =~ %r{^(?:heads|remotes)/}
|
89
|
+
"#{data[:base].gsub(%r{^(heads/|remotes/\w+?/)}, '')}@#{data[:sha]}"
|
78
90
|
else
|
79
91
|
data[:base]
|
80
92
|
end
|
81
93
|
end
|
82
94
|
|
83
|
-
def
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
def fetch_remote_version(version)
|
88
|
-
return version unless version.include?('/')
|
95
|
+
def fetch_remote_version(template_ref)
|
96
|
+
return template_ref unless current_template_version.is_a?(String)
|
97
|
+
return template_ref if template_ref == PDK::TEMPLATE_REF
|
89
98
|
|
90
|
-
branch = version.partition('/').last
|
91
99
|
sha_length = GIT_DESCRIBE_PATTERN.match(current_template_version)[:sha].length - 1
|
92
|
-
"#{
|
100
|
+
"#{template_ref}@#{PDK::Util::Git.ls_remote(template_uri.git_remote, template_ref)[0..sha_length]}"
|
93
101
|
end
|
94
102
|
|
95
103
|
def update_message
|
96
|
-
format_string = if
|
104
|
+
format_string = if template_uri.default?
|
97
105
|
_('Updating %{module_name} using the default template, from %{current_version} to %{new_version}')
|
98
106
|
else
|
99
107
|
_('Updating %{module_name} using the template at %{template_url}, from %{current_version} to %{new_version}')
|
@@ -101,7 +109,7 @@ module PDK
|
|
101
109
|
|
102
110
|
format_string % {
|
103
111
|
module_name: module_metadata.data['name'],
|
104
|
-
template_url:
|
112
|
+
template_url: template_uri.git_remote,
|
105
113
|
current_version: current_version,
|
106
114
|
new_version: new_version,
|
107
115
|
}
|
data/lib/pdk/util.rb
CHANGED
@@ -5,6 +5,7 @@ require 'pdk/util/version'
|
|
5
5
|
require 'pdk/util/windows'
|
6
6
|
require 'pdk/util/vendored_file'
|
7
7
|
require 'pdk/util/filesystem'
|
8
|
+
require 'pdk/util/template_uri'
|
8
9
|
|
9
10
|
module PDK
|
10
11
|
module Util
|
@@ -197,63 +198,6 @@ module PDK
|
|
197
198
|
end
|
198
199
|
module_function :targets_relative_to_pwd
|
199
200
|
|
200
|
-
def default_template_url
|
201
|
-
answer_file_url = PDK.answers['template-url']
|
202
|
-
|
203
|
-
return puppetlabs_template_url if answer_file_url.nil?
|
204
|
-
|
205
|
-
# Ignore answer file template-url if the value is the old or new default.
|
206
|
-
return puppetlabs_template_url if answer_file_url == 'https://github.com/puppetlabs/pdk-module-template'
|
207
|
-
return puppetlabs_template_url if answer_file_url == puppetlabs_template_url
|
208
|
-
|
209
|
-
if File.directory?(answer_file_url)
|
210
|
-
# Instantiating a new TemplateDir object pointing to the directory
|
211
|
-
# will cause the directory contents to be validated, raising
|
212
|
-
# ArgumentError if it does not appear to be a valid template.
|
213
|
-
PDK::Module::TemplateDir.new(answer_file_url) {}
|
214
|
-
return answer_file_url
|
215
|
-
end
|
216
|
-
|
217
|
-
raise ArgumentError unless PDK::Util::Git.repo?(answer_file_url)
|
218
|
-
|
219
|
-
answer_file_url
|
220
|
-
rescue ArgumentError
|
221
|
-
PDK.logger.warn(
|
222
|
-
_("Unable to access the previously used template '%{template}', using the default template instead.") % {
|
223
|
-
template: answer_file_url,
|
224
|
-
},
|
225
|
-
)
|
226
|
-
PDK.answers.update!('template-url' => nil)
|
227
|
-
return puppetlabs_template_url
|
228
|
-
end
|
229
|
-
module_function :default_template_url
|
230
|
-
|
231
|
-
def puppetlabs_template_url
|
232
|
-
if package_install?
|
233
|
-
'file://' + File.join(package_cachedir, 'pdk-templates.git')
|
234
|
-
else
|
235
|
-
'https://github.com/puppetlabs/pdk-templates'
|
236
|
-
end
|
237
|
-
end
|
238
|
-
module_function :puppetlabs_template_url
|
239
|
-
|
240
|
-
def default_template_ref
|
241
|
-
# TODO: This should respect a --template-ref option if we add that
|
242
|
-
return 'origin/master' if default_template_url != puppetlabs_template_url
|
243
|
-
|
244
|
-
puppetlabs_template_ref
|
245
|
-
end
|
246
|
-
module_function :default_template_ref
|
247
|
-
|
248
|
-
def puppetlabs_template_ref
|
249
|
-
if PDK::Util.development_mode?
|
250
|
-
'origin/master'
|
251
|
-
else
|
252
|
-
PDK::TEMPLATE_REF
|
253
|
-
end
|
254
|
-
end
|
255
|
-
module_function :puppetlabs_template_ref
|
256
|
-
|
257
201
|
# TO-DO: Refactor replacement of lib/pdk/module/build.rb:metadata to use this function instead
|
258
202
|
def module_metadata
|
259
203
|
PDK::Module::Metadata.from_file(File.join(module_root, 'metadata.json')).data
|
data/lib/pdk/util/filesystem.rb
CHANGED
@@ -4,7 +4,13 @@ module PDK
|
|
4
4
|
def write_file(path, content)
|
5
5
|
raise ArgumentError unless path.is_a?(String) || path.respond_to?(:to_path)
|
6
6
|
|
7
|
-
|
7
|
+
# Harmonize newlines across platforms.
|
8
|
+
content = content.encode(universal_newline: true)
|
9
|
+
|
10
|
+
# Make sure all written files have a trailing newline.
|
11
|
+
content += "\n" unless content[-1] == "\n"
|
12
|
+
|
13
|
+
File.open(path, 'wb') { |f| f.write(content) }
|
8
14
|
end
|
9
15
|
module_function :write_file
|
10
16
|
end
|
data/lib/pdk/util/git.rb
CHANGED
@@ -1,5 +1,21 @@
|
|
1
1
|
module PDK
|
2
2
|
module Util
|
3
|
+
class GitError < StandardError
|
4
|
+
attr_reader :stdout
|
5
|
+
attr_reader :stderr
|
6
|
+
attr_reader :exit_code
|
7
|
+
attr_reader :args
|
8
|
+
|
9
|
+
def initialze(args, result)
|
10
|
+
@args = args
|
11
|
+
@stdout = result[:stdout]
|
12
|
+
@stderr = result[:stderr]
|
13
|
+
@exit_code = result[:exit_code]
|
14
|
+
|
15
|
+
super(_('Git command failed: git %{args}' % { args: args.join(' ') }))
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
3
19
|
module Git
|
4
20
|
def self.git_bindir
|
5
21
|
@git_dir ||= File.join('private', 'git', Gem.win_platform? ? 'cmd' : 'bin')
|
@@ -55,7 +71,27 @@ module PDK
|
|
55
71
|
git('ls-remote', '--exit-code', maybe_repo)[:exit_code].zero?
|
56
72
|
end
|
57
73
|
|
74
|
+
def self.work_tree?(path)
|
75
|
+
return false unless File.directory?(path)
|
76
|
+
|
77
|
+
Dir.chdir(path) do
|
78
|
+
rev_parse = git('rev-parse', '--is-inside-work-tree')
|
79
|
+
rev_parse[:exit_code].zero? && rev_parse[:stdout].strip == 'true'
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
def self.work_dir_clean?(repo)
|
84
|
+
raise PDK::CLI::ExitWithError, _('Unable to locate git work dir "%{workdir}') % { workdir: repo } unless File.directory?(repo)
|
85
|
+
raise PDK::CLI::ExitWithError, _('Unable to locate git dir "%{gitdir}') % { gitdir: repo } unless File.directory?(File.join(repo, '.git'))
|
86
|
+
|
87
|
+
git('--work-tree', repo, '--git-dir', File.join(repo, '.git'), 'status', '--untracked-files=no', '--porcelain', repo)[:stdout].empty?
|
88
|
+
end
|
89
|
+
|
58
90
|
def self.ls_remote(repo, ref)
|
91
|
+
if File.directory?(repo)
|
92
|
+
repo = 'file://' + repo
|
93
|
+
end
|
94
|
+
|
59
95
|
output = git('ls-remote', '--refs', repo, ref)
|
60
96
|
|
61
97
|
unless output[:exit_code].zero?
|
@@ -67,7 +103,16 @@ module PDK
|
|
67
103
|
end
|
68
104
|
|
69
105
|
matching_refs = output[:stdout].split("\n").map { |r| r.split("\t") }
|
70
|
-
matching_refs.find { |_sha, remote_ref| remote_ref == ref }
|
106
|
+
matching_ref = matching_refs.find { |_sha, remote_ref| remote_ref == "refs/tags/#{ref}" || remote_ref == "refs/remotes/origin/#{ref}" || remote_ref == "refs/heads/#{ref}" }
|
107
|
+
raise PDK::CLI::ExitWithError, _('Unable to find a branch or tag named "%{ref}" in %{repo}') % { ref: ref, repo: repo } if matching_ref.nil?
|
108
|
+
matching_ref.first
|
109
|
+
end
|
110
|
+
|
111
|
+
def self.describe(path, ref = nil)
|
112
|
+
args = ['--git-dir', path, 'describe', '--all', '--long', '--always', ref].compact
|
113
|
+
result = git(*args)
|
114
|
+
raise PDK::Util::GitError, args, result unless result[:exit_code].zero?
|
115
|
+
result[:stdout].strip
|
71
116
|
end
|
72
117
|
end
|
73
118
|
end
|
@@ -0,0 +1,231 @@
|
|
1
|
+
require 'pdk/util'
|
2
|
+
|
3
|
+
module PDK
|
4
|
+
module Util
|
5
|
+
class TemplateURI
|
6
|
+
SCP_PATTERN = %r{\A(?!\w+://)(?:(?<user>.+?)@)?(?<host>[^:/]+):(?<path>.+)\z}
|
7
|
+
|
8
|
+
# XXX Previously
|
9
|
+
# - template_uri used to get the string form of the uri when generating the module and written to pdk answers and metadata
|
10
|
+
# - template_path or deuri_path used for humans to see and commands to run
|
11
|
+
# - uri_path used only internally by the template selection code; move out
|
12
|
+
# - template_ref used by git checkout
|
13
|
+
attr_reader :uri
|
14
|
+
|
15
|
+
# input/output formats:
|
16
|
+
#
|
17
|
+
# file:///c:/foo (git clone location)
|
18
|
+
# c:/foo (shell paths)
|
19
|
+
# file:///c:/foo#master (only for metadata)
|
20
|
+
# c:/foo#master (only for metadata)
|
21
|
+
#
|
22
|
+
# non output formats:
|
23
|
+
#
|
24
|
+
# /c:/foo (internal use only)
|
25
|
+
# /c:/foo#master (internal use only)
|
26
|
+
#
|
27
|
+
def initialize(opts_or_uri)
|
28
|
+
# If a uri string is passed, skip the valid uri finding code.
|
29
|
+
@uri = if opts_or_uri.is_a?(String) || opts_or_uri.is_a?(self.class)
|
30
|
+
begin
|
31
|
+
Addressable::URI.parse(opts_or_uri)
|
32
|
+
rescue Addressable::URI::InvalidURIError
|
33
|
+
raise PDK::CLI::FatalError, _('PDK::Util::TemplateURI attempted initialization with a non-uri string: {string}') % { string: opts_or_uri }
|
34
|
+
end
|
35
|
+
elsif opts_or_uri.is_a?(Addressable::URI)
|
36
|
+
opts_or_uri.dup
|
37
|
+
else
|
38
|
+
self.class.first_valid_uri(self.class.templates(opts_or_uri))
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def ==(other)
|
43
|
+
@uri == other.uri
|
44
|
+
end
|
45
|
+
|
46
|
+
# This is the URI represented in a format suitable for writing to
|
47
|
+
# metadata.
|
48
|
+
#
|
49
|
+
# @returns String
|
50
|
+
def metadata_format
|
51
|
+
self.class.human_readable(@uri.to_s)
|
52
|
+
end
|
53
|
+
alias to_s metadata_format
|
54
|
+
alias to_str metadata_format
|
55
|
+
|
56
|
+
# This is the url without a fragment, suitable for git clones.
|
57
|
+
#
|
58
|
+
# @returns String
|
59
|
+
def git_remote
|
60
|
+
self.class.git_remote(@uri)
|
61
|
+
end
|
62
|
+
|
63
|
+
def self.git_remote(uri)
|
64
|
+
if uri.is_a?(Addressable::URI) && uri.fragment
|
65
|
+
human_readable(uri.to_s.chomp('#' + uri.fragment))
|
66
|
+
else
|
67
|
+
human_readable(uri.to_s)
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
# This is the path of the URI, suitable for accessing directly from the shell.
|
72
|
+
# @returns String
|
73
|
+
def shell_path
|
74
|
+
self.class.human_readable(@uri.path)
|
75
|
+
end
|
76
|
+
|
77
|
+
# @returns String
|
78
|
+
def git_ref
|
79
|
+
if @uri.fragment
|
80
|
+
@uri.fragment
|
81
|
+
else
|
82
|
+
self.class.default_template_ref
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
def git_ref=(ref)
|
87
|
+
@uri.fragment = ref
|
88
|
+
end
|
89
|
+
|
90
|
+
# @returns PDK::Util::TemplateURI
|
91
|
+
def self.default_template_uri
|
92
|
+
if PDK::Util.package_install?
|
93
|
+
PDK::Util::TemplateURI.new(Addressable::URI.new(scheme: 'file', host: '', path: File.join(PDK::Util.package_cachedir, 'pdk-templates.git')))
|
94
|
+
else
|
95
|
+
PDK::Util::TemplateURI.new('https://github.com/puppetlabs/pdk-templates')
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
def default?
|
100
|
+
git_remote == self.class.default_template_uri.git_remote
|
101
|
+
end
|
102
|
+
|
103
|
+
def ref_is_tag?
|
104
|
+
PDK::Util::Git.git('ls-remote', '--tags', '--exit-code', git_remote, git_ref)[:exit_code].zero?
|
105
|
+
end
|
106
|
+
|
107
|
+
# `C:...` urls are not URI-safe. They should be of the form `/C:...` to
|
108
|
+
# be URI-safe. scp-like urls like `user@host:/path` are not URI-safe
|
109
|
+
# either but are not handled here. Should they be?
|
110
|
+
#
|
111
|
+
# @returns String
|
112
|
+
def self.uri_safe(string)
|
113
|
+
(Gem.win_platform? && string =~ %r{^[a-zA-Z][\|:]}) ? "/#{string}" : string
|
114
|
+
end
|
115
|
+
|
116
|
+
# If the passed value is a URI-safe windows path such as `/C:...` then it
|
117
|
+
# should be changed to a human-friendly `C:...` form. Otherwise the
|
118
|
+
# passed value is left alone.
|
119
|
+
#
|
120
|
+
# @returns String
|
121
|
+
def self.human_readable(string)
|
122
|
+
(Gem.win_platform? && string =~ %r{^\/[a-zA-Z][\|:]}) ? string[1..-1] : string
|
123
|
+
end
|
124
|
+
|
125
|
+
# @return [Array<Hash{Symbol => Object}>] an array of hashes. Each hash
|
126
|
+
# contains 3 keys: :type contains a String that describes the template
|
127
|
+
# directory, :url contains a String with the URL to the template
|
128
|
+
# directory, and :allow_fallback contains a Boolean that specifies if
|
129
|
+
# the lookup process should proceed to the next template directory if
|
130
|
+
# the template file is not in this template directory.
|
131
|
+
#
|
132
|
+
def self.templates(opts)
|
133
|
+
explicit_url = opts.fetch(:'template-url', nil)
|
134
|
+
explicit_ref = opts.fetch(:'template-ref', nil)
|
135
|
+
|
136
|
+
# 1. Get the CLI, metadata (or answers if no metadata), and default URIs
|
137
|
+
# 2. Construct the hash
|
138
|
+
if explicit_url
|
139
|
+
# Valid URIs to avoid catching:
|
140
|
+
# - absolute local paths
|
141
|
+
# - have :'s in paths when preceeded by a slash
|
142
|
+
# - have only digits following the : and preceeding a / or end-of-string that is 0-65535
|
143
|
+
# The last item is ambiguous in the case of scp/git paths vs. URI port
|
144
|
+
# numbers, but can be made unambiguous by making the form to
|
145
|
+
# ssh://git@github.com/1234/repo.git or
|
146
|
+
# ssh://git@github.com:1234/user/repo.git
|
147
|
+
scp_url = explicit_url.match(SCP_PATTERN)
|
148
|
+
if Pathname.new(uri_safe(explicit_url)).relative? && scp_url
|
149
|
+
explicit_uri = Addressable::URI.new(scheme: 'ssh', user: scp_url[:user], host: scp_url[:host], path: scp_url[:path])
|
150
|
+
PDK.logger.warn _('%{scp_uri} appears to be an SCP style URL; it will be converted to an RFC compliant URI: %{rfc_uri}') % {
|
151
|
+
scp_uri: explicit_url,
|
152
|
+
rfc_uri: explicit_uri.to_s,
|
153
|
+
}
|
154
|
+
end
|
155
|
+
explicit_uri ||= Addressable::URI.parse(uri_safe(explicit_url))
|
156
|
+
explicit_uri.fragment = explicit_ref || default_template_ref
|
157
|
+
else
|
158
|
+
explicit_uri = nil
|
159
|
+
end
|
160
|
+
metadata_uri = if PDK::Util.module_root && File.file?(File.join(PDK::Util.module_root, 'metadata.json'))
|
161
|
+
Addressable::URI.parse(uri_safe(PDK::Util.module_metadata['template-url']))
|
162
|
+
else
|
163
|
+
nil
|
164
|
+
end
|
165
|
+
answers_uri = if PDK.answers['template-url'] == 'https://github.com/puppetlabs/pdk-module-template'
|
166
|
+
# use the new github template-url if it is still the old one.
|
167
|
+
Addressable::URI.parse(default_template_uri)
|
168
|
+
elsif PDK.answers['template-url']
|
169
|
+
Addressable::URI.parse(uri_safe(PDK.answers['template-url']))
|
170
|
+
else
|
171
|
+
nil
|
172
|
+
end
|
173
|
+
default_uri = Addressable::URI.parse(default_template_uri)
|
174
|
+
default_uri.fragment = default_template_ref
|
175
|
+
|
176
|
+
ary = []
|
177
|
+
ary << { type: _('--template-url'), uri: explicit_uri, allow_fallback: false } if explicit_url
|
178
|
+
ary << { type: _('metadata.json'), uri: metadata_uri, allow_fallback: true } if metadata_uri
|
179
|
+
ary << { type: _('PDK answers'), uri: answers_uri, allow_fallback: true } if answers_uri
|
180
|
+
ary << { type: _('default'), uri: default_uri, allow_fallback: false }
|
181
|
+
ary
|
182
|
+
end
|
183
|
+
|
184
|
+
# @returns String
|
185
|
+
def self.default_template_ref
|
186
|
+
if PDK::Util.development_mode?
|
187
|
+
'master'
|
188
|
+
else
|
189
|
+
PDK::TEMPLATE_REF
|
190
|
+
end
|
191
|
+
end
|
192
|
+
|
193
|
+
# @returns Addressable::URI
|
194
|
+
def self.first_valid_uri(templates_array)
|
195
|
+
# 1. Get the four sources of URIs
|
196
|
+
# 2. Pick the first non-nil URI
|
197
|
+
# 3. Error if the URI is not a valid git repo (missing directory or http 404)
|
198
|
+
# 4. Leave updating answers/metadata to other code
|
199
|
+
found_template = templates_array.find { |t| valid_template?(t) }
|
200
|
+
|
201
|
+
raise PDK::CLI::FatalError, _('Unable to find a valid module template to use.') if found_template.nil?
|
202
|
+
found_template[:uri]
|
203
|
+
end
|
204
|
+
|
205
|
+
def self.valid_template?(template)
|
206
|
+
return false if template.nil? || !template.is_a?(Hash)
|
207
|
+
return false if template[:uri].nil? || !template[:uri].is_a?(Addressable::URI)
|
208
|
+
|
209
|
+
return true if PDK::Util::Git.repo?(git_remote(template[:uri]))
|
210
|
+
|
211
|
+
path = human_readable(template[:uri].path)
|
212
|
+
if File.directory?(path)
|
213
|
+
begin
|
214
|
+
PDK::Module::TemplateDir.new(path) {}
|
215
|
+
return true
|
216
|
+
rescue ArgumentError
|
217
|
+
nil
|
218
|
+
end
|
219
|
+
end
|
220
|
+
|
221
|
+
unless template[:allow_fallback]
|
222
|
+
raise PDK::CLI::FatalError, _('Unable to find a valid template at %{uri}') % {
|
223
|
+
uri: template[:uri].to_s,
|
224
|
+
}
|
225
|
+
end
|
226
|
+
|
227
|
+
false
|
228
|
+
end
|
229
|
+
end
|
230
|
+
end
|
231
|
+
end
|