pdk 1.0.1 → 1.1.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 +26 -0
- data/README.md +11 -0
- data/lib/pdk/answer_file.rb +1 -1
- data/lib/pdk/cli.rb +16 -6
- data/lib/pdk/cli/bundle.rb +5 -3
- data/lib/pdk/cli/errors.rb +10 -1
- data/lib/pdk/cli/exec.rb +9 -4
- data/lib/pdk/cli/module.rb +14 -0
- data/lib/pdk/cli/module/generate.rb +40 -0
- data/lib/pdk/cli/new.rb +2 -1
- data/lib/pdk/cli/new/class.rb +1 -1
- data/lib/pdk/cli/new/defined_type.rb +27 -0
- data/lib/pdk/cli/new/module.rb +1 -11
- data/lib/pdk/cli/util.rb +3 -3
- data/lib/pdk/cli/util/command_redirector.rb +26 -0
- data/lib/pdk/cli/util/interview.rb +17 -6
- data/lib/pdk/cli/util/option_normalizer.rb +3 -3
- data/lib/pdk/cli/validate.rb +9 -9
- data/lib/pdk/generate.rb +1 -0
- data/lib/pdk/generators/defined_type.rb +49 -0
- data/lib/pdk/generators/module.rb +113 -23
- data/lib/pdk/generators/puppet_class.rb +2 -2
- data/lib/pdk/generators/puppet_object.rb +3 -3
- data/lib/pdk/module/metadata.rb +7 -7
- data/lib/pdk/module/templatedir.rb +3 -3
- data/lib/pdk/report/event.rb +43 -12
- data/lib/pdk/tests/unit.rb +51 -17
- data/lib/pdk/util.rb +3 -3
- data/lib/pdk/util/bundler.rb +5 -5
- data/lib/pdk/util/version.rb +5 -2
- data/lib/pdk/util/windows.rb +6 -0
- data/lib/pdk/validators/base_validator.rb +1 -1
- data/lib/pdk/validators/metadata/metadata_json_lint.rb +2 -2
- data/lib/pdk/validators/metadata/metadata_syntax.rb +2 -2
- data/lib/pdk/validators/puppet/puppet_lint.rb +1 -1
- data/lib/pdk/validators/puppet/puppet_syntax.rb +1 -1
- data/lib/pdk/validators/ruby/rubocop.rb +1 -1
- data/lib/pdk/version.rb +1 -1
- data/lib/puppet/util/windows/api_types.rb +9 -5
- data/locales/pdk.pot +314 -180
- metadata +16 -10
@@ -29,7 +29,7 @@ module PDK
|
|
29
29
|
begin
|
30
30
|
OptionValidator.enum(format, PDK::Report.formats)
|
31
31
|
rescue ArgumentError
|
32
|
-
raise PDK::CLI::
|
32
|
+
raise PDK::CLI::ExitWithError, _("'%{name}' is not a valid report format (%{valid})") % {
|
33
33
|
name: format,
|
34
34
|
valid: PDK::Report.formats.join(', '),
|
35
35
|
}
|
@@ -53,13 +53,13 @@ module PDK
|
|
53
53
|
param_type = 'String' if param_type.nil?
|
54
54
|
|
55
55
|
unless PDK::CLI::Util::OptionValidator.valid_param_name?(param_name)
|
56
|
-
raise PDK::CLI::
|
56
|
+
raise PDK::CLI::ExitWithError, _("'%{name}' is not a valid parameter name") % {
|
57
57
|
name: param_name,
|
58
58
|
}
|
59
59
|
end
|
60
60
|
|
61
61
|
unless PDK::CLI::Util::OptionValidator.valid_data_type?(param_type)
|
62
|
-
raise PDK::CLI::
|
62
|
+
raise PDK::CLI::ExitWithError, _("'%{type}' is not a valid data type") % {
|
63
63
|
type: param_type,
|
64
64
|
}
|
65
65
|
end
|
data/lib/pdk/cli/validate.rb
CHANGED
@@ -6,16 +6,16 @@ module PDK::CLI
|
|
6
6
|
usage _('validate [validators] [options] [targets]')
|
7
7
|
summary _('Run static analysis tests.')
|
8
8
|
description _(
|
9
|
-
"Run metadata,
|
10
|
-
'[validators] is an optional comma
|
11
|
-
"If not specified, all validators
|
12
|
-
'[targets] is an optional space
|
13
|
-
'If not specified,
|
9
|
+
"Run metadata, Puppet, or Ruby validation.\n\n" \
|
10
|
+
'[validators] is an optional comma-separated list of validators to use. ' \
|
11
|
+
"If not specified, all validators are used.\n\n" \
|
12
|
+
'[targets] is an optional space-separated list of files or directories to be validated. ' \
|
13
|
+
'If not specified, validators are run against all applicable files in the module.',
|
14
14
|
)
|
15
15
|
|
16
|
-
flag nil, :list, _('
|
17
|
-
flag :a, 'auto-correct', _('
|
18
|
-
flag nil, :parallel, _('
|
16
|
+
flag nil, :list, _('List all available validators.')
|
17
|
+
flag :a, 'auto-correct', _('Automatically correct problems where possible.')
|
18
|
+
flag nil, :parallel, _('Run validations in parallel.')
|
19
19
|
|
20
20
|
run do |opts, args, _cmd|
|
21
21
|
if args == ['help']
|
@@ -44,7 +44,7 @@ module PDK::CLI
|
|
44
44
|
|
45
45
|
invalid = vals.reject { |v| validator_names.include?(v) }
|
46
46
|
invalid.each do |v|
|
47
|
-
PDK.logger.warn(_("Unknown validator '%{v}'. Available validators: %{validators}") % { v: v, validators: validator_names.join(', ') })
|
47
|
+
PDK.logger.warn(_("Unknown validator '%{v}'. Available validators: %{validators}.") % { v: v, validators: validator_names.join(', ') })
|
48
48
|
end
|
49
49
|
else
|
50
50
|
# This is a single item. Check if it's a known validator, or otherwise treat it as a target.
|
data/lib/pdk/generate.rb
CHANGED
@@ -0,0 +1,49 @@
|
|
1
|
+
require 'pdk/generators/puppet_object'
|
2
|
+
|
3
|
+
module PDK
|
4
|
+
module Generate
|
5
|
+
class DefinedType < PuppetObject
|
6
|
+
OBJECT_TYPE = :defined_type
|
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 = { name: object_name }
|
15
|
+
|
16
|
+
data
|
17
|
+
end
|
18
|
+
|
19
|
+
# Calculates the path to the .pp file that the new defined type will be
|
20
|
+
# written to.
|
21
|
+
#
|
22
|
+
# @return [String] the path where the new defined type will be written.
|
23
|
+
def target_object_path
|
24
|
+
@target_pp_path ||= begin
|
25
|
+
define_name_parts = object_name.split('::')[1..-1]
|
26
|
+
define_name_parts << 'init' if define_name_parts.empty?
|
27
|
+
|
28
|
+
"#{File.join(module_dir, 'manifests', *define_name_parts)}.pp"
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
# Calculates the path to the file where the tests for the new defined
|
33
|
+
# type will be written.
|
34
|
+
#
|
35
|
+
# @return [String] the path where the tests for the new defined type
|
36
|
+
# will be written.
|
37
|
+
def target_spec_path
|
38
|
+
@target_spec_path ||= begin
|
39
|
+
define_name_parts = object_name.split('::')
|
40
|
+
|
41
|
+
# drop the module name if the object name contains multiple parts
|
42
|
+
define_name_parts.delete_at(0) if define_name_parts.length > 1
|
43
|
+
|
44
|
+
"#{File.join(module_dir, 'spec', 'defines', *define_name_parts)}_spec.rb"
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -9,6 +9,7 @@ require 'pdk/module/metadata'
|
|
9
9
|
require 'pdk/module/templatedir'
|
10
10
|
require 'pdk/cli/exec'
|
11
11
|
require 'pdk/cli/util/interview'
|
12
|
+
require 'pdk/cli/util/option_validator'
|
12
13
|
require 'pdk/util'
|
13
14
|
require 'pdk/util/version'
|
14
15
|
|
@@ -18,20 +19,37 @@ module PDK
|
|
18
19
|
def self.default_template_url
|
19
20
|
if !PDK.answers['template-url'].nil?
|
20
21
|
PDK.answers['template-url']
|
21
|
-
|
22
|
+
else
|
23
|
+
puppetlabs_template_url
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def self.puppetlabs_template_url
|
28
|
+
if PDK::Util.package_install?
|
22
29
|
'file://' + File.join(PDK::Util.package_cachedir, 'pdk-module-template.git')
|
23
30
|
else
|
24
31
|
'https://github.com/puppetlabs/pdk-module-template'
|
25
32
|
end
|
26
33
|
end
|
27
34
|
|
28
|
-
def self.
|
35
|
+
def self.validate_options(opts)
|
36
|
+
unless PDK::CLI::Util::OptionValidator.valid_module_name?(opts[:name])
|
37
|
+
error_msg = _(
|
38
|
+
"'%{module_name}' is not a valid module name.\n" \
|
39
|
+
'Module names must begin with a lowercase letter and can only include lowercase letters, digits, and underscores.',
|
40
|
+
) % { module_name: opts[:name] }
|
41
|
+
raise PDK::CLI::ExitWithError, error_msg
|
42
|
+
end
|
43
|
+
|
29
44
|
target_dir = File.expand_path(opts[:target_dir])
|
30
45
|
|
31
|
-
if File.exist?(target_dir)
|
32
|
-
|
33
|
-
|
46
|
+
raise PDK::CLI::ExitWithError, _("The destination directory '%{dir}' already exists") % { dir: target_dir } if File.exist?(target_dir)
|
47
|
+
end
|
48
|
+
|
49
|
+
def self.invoke(opts = {})
|
50
|
+
validate_options(opts)
|
34
51
|
|
52
|
+
target_dir = File.expand_path(opts[:target_dir])
|
35
53
|
parent_dir = File.dirname(target_dir)
|
36
54
|
|
37
55
|
begin
|
@@ -68,10 +86,21 @@ module PDK
|
|
68
86
|
end
|
69
87
|
end
|
70
88
|
|
71
|
-
|
89
|
+
if template_url == puppetlabs_template_url
|
90
|
+
# If the user specifies our template via the command line, remove the
|
91
|
+
# saved template-url answer.
|
92
|
+
PDK.answers.update!('template-url' => nil) if opts.key?(:'template-url')
|
93
|
+
else
|
94
|
+
# Save the template-url answer if the module was generated using
|
95
|
+
# a template other than ours.
|
96
|
+
PDK.answers.update!('template-url' => template_url)
|
97
|
+
end
|
72
98
|
|
73
99
|
begin
|
74
|
-
FileUtils.mv(temp_target_dir, target_dir)
|
100
|
+
if FileUtils.mv(temp_target_dir, target_dir)
|
101
|
+
PDK.logger.info(_('Module \'%{name}\' generated at path \'%{path}\'.') % { name: opts[:name], path: target_dir })
|
102
|
+
PDK.logger.info(_('In your module directory, add classes with the \'pdk new class\' command.'))
|
103
|
+
end
|
75
104
|
rescue Errno::EACCES => e
|
76
105
|
raise PDK::CLI::FatalError, _("Failed to move '%{source}' to '%{target}': %{message}") % {
|
77
106
|
source: temp_target_dir,
|
@@ -87,7 +116,7 @@ module PDK
|
|
87
116
|
login_clean = 'username' if login_clean.empty?
|
88
117
|
|
89
118
|
if login_clean != login
|
90
|
-
PDK.logger.warn _('Your username is not a valid Forge username
|
119
|
+
PDK.logger.warn _('Your username is not a valid Forge username. Proceeding with the username %{username}. You can fix this later in metadata.json.') % {
|
91
120
|
username: login_clean,
|
92
121
|
}
|
93
122
|
end
|
@@ -101,9 +130,7 @@ module PDK
|
|
101
130
|
defaults = {
|
102
131
|
'name' => "#{username}-#{opts[:name]}",
|
103
132
|
'version' => '0.1.0',
|
104
|
-
'dependencies' => [
|
105
|
-
{ 'name' => 'puppetlabs-stdlib', 'version_requirement' => '>= 4.13.1 < 5.0.0' },
|
106
|
-
],
|
133
|
+
'dependencies' => [],
|
107
134
|
'requirements' => [
|
108
135
|
{ 'name' => 'puppet', 'version_requirement' => '>= 4.7.0 < 6.0.0' },
|
109
136
|
],
|
@@ -160,7 +187,7 @@ module PDK
|
|
160
187
|
{
|
161
188
|
name: 'author',
|
162
189
|
question: _('Who wrote this module?'),
|
163
|
-
help: _('This
|
190
|
+
help: _('This is used to credit the module\'s author.'),
|
164
191
|
required: true,
|
165
192
|
default: metadata.data['author'],
|
166
193
|
},
|
@@ -171,30 +198,87 @@ module PDK
|
|
171
198
|
required: true,
|
172
199
|
default: metadata.data['license'],
|
173
200
|
},
|
201
|
+
{
|
202
|
+
name: 'operatingsystem_support',
|
203
|
+
question: _('What operating systems does this module support?'),
|
204
|
+
help: _('Use the up and down keys to move between the choices, space to select and enter to continue.'),
|
205
|
+
required: true,
|
206
|
+
choices: {
|
207
|
+
'RedHat based Linux' => [
|
208
|
+
{
|
209
|
+
'operatingsystem' => 'CentOS',
|
210
|
+
'operatingsystemrelease' => ['7'],
|
211
|
+
},
|
212
|
+
{
|
213
|
+
'operatingsystem' => 'OracleLinux',
|
214
|
+
'operatingsystemrelease' => ['7'],
|
215
|
+
},
|
216
|
+
{
|
217
|
+
'operatingsystem' => 'RedHat',
|
218
|
+
'operatingsystemrelease' => ['7'],
|
219
|
+
},
|
220
|
+
{
|
221
|
+
'operatingsystem' => 'Scientific',
|
222
|
+
'operatingsystemrelease' => ['7'],
|
223
|
+
},
|
224
|
+
],
|
225
|
+
'Debian based Linux' => [
|
226
|
+
{
|
227
|
+
'operatingsystem' => 'Debian',
|
228
|
+
'operatingsystemrelease' => ['8'],
|
229
|
+
},
|
230
|
+
{
|
231
|
+
'operatingsystem' => 'Ubuntu',
|
232
|
+
'operatingsystemrelease' => ['16.04'],
|
233
|
+
},
|
234
|
+
],
|
235
|
+
'Fedora' => {
|
236
|
+
'operatingsystem' => 'Fedora',
|
237
|
+
'operatingsystemrelease' => ['25'],
|
238
|
+
},
|
239
|
+
'OSX' => {
|
240
|
+
'operatingsystem' => 'Darwin',
|
241
|
+
'operatingsystemrelease' => ['16'],
|
242
|
+
},
|
243
|
+
'SLES' => {
|
244
|
+
'operatingsystem' => 'SLES',
|
245
|
+
'operatingsystemrelease' => ['12'],
|
246
|
+
},
|
247
|
+
'Solaris' => {
|
248
|
+
'operatingsystem' => 'Solaris',
|
249
|
+
'operatingsystemrelease' => ['11'],
|
250
|
+
},
|
251
|
+
'Windows' => {
|
252
|
+
'operatingsystem' => 'windows',
|
253
|
+
'operatingsystemrelease' => ['2008 R2', '2012 R2', '10'],
|
254
|
+
},
|
255
|
+
},
|
256
|
+
default: [1, 2, 7],
|
257
|
+
},
|
174
258
|
{
|
175
259
|
name: 'summary',
|
176
|
-
question: _('
|
177
|
-
help: _('This
|
260
|
+
question: _('Summarize the purpose of this module in a single sentence.'),
|
261
|
+
help: _('This helps other Puppet users understand what the module does.'),
|
178
262
|
required: true,
|
179
263
|
default: metadata.data['summary'],
|
180
264
|
},
|
181
265
|
{
|
182
266
|
name: 'source',
|
183
267
|
question: _('If there is a source code repository for this module, enter the URL here.'),
|
184
|
-
help: _('Skip this if
|
268
|
+
help: _('Skip this if no repository exists yet. You can update this later in the metadata.json.'),
|
185
269
|
required: true,
|
186
270
|
default: metadata.data['source'],
|
187
271
|
},
|
188
272
|
{
|
189
273
|
name: 'project_page',
|
190
274
|
question: _('If there is a URL where others can learn more about this module, enter it here.'),
|
191
|
-
help: _('Optional.
|
275
|
+
help: _('Optional. You can update this later in the metadata.json.'),
|
192
276
|
default: metadata.data['project_page'],
|
193
277
|
},
|
194
278
|
{
|
195
279
|
name: 'issues_url',
|
196
280
|
question: _('If there is a public issue tracker for this module, enter its URL here.'),
|
197
|
-
help: _('Optional.
|
281
|
+
help: _('Optional. You can update this later in the metadata.json.'),
|
198
282
|
default: metadata.data['issues_url'],
|
199
283
|
},
|
200
284
|
]
|
@@ -208,23 +292,24 @@ module PDK
|
|
208
292
|
interview.add_questions(questions)
|
209
293
|
|
210
294
|
puts _(
|
211
|
-
"\nWe need to create a metadata.json file for this module, so we\'re going to ask you %{count}
|
295
|
+
"\nWe need to create a metadata.json file for this module, so we\'re going to ask you %{count} " \
|
212
296
|
"questions.\n" \
|
213
|
-
'If the question is not applicable to this module,
|
214
|
-
'
|
297
|
+
'If the question is not applicable to this module, accept the default option ' \
|
298
|
+
'shown after each question. You can modify any answers at any time by manually updating ' \
|
215
299
|
"the metadata.json file.\n\n",
|
216
300
|
) % { count: interview.num_questions }
|
217
301
|
|
218
302
|
answers = interview.run
|
219
303
|
|
220
304
|
if answers.nil?
|
221
|
-
PDK.logger.info _('Interview cancelled
|
305
|
+
PDK.logger.info _('Interview cancelled; not generating the module.')
|
222
306
|
exit 0
|
223
307
|
end
|
224
308
|
|
225
309
|
forge_username = answers['name']
|
226
310
|
answers['name'] = "#{answers['name']}-#{opts[:name]}"
|
227
311
|
answers['license'] = opts[:license] if opts.key?(:license)
|
312
|
+
answers['operatingsystem_support'].flatten!
|
228
313
|
metadata.update!(answers)
|
229
314
|
|
230
315
|
puts '-' * 40
|
@@ -234,8 +319,13 @@ module PDK
|
|
234
319
|
puts '-' * 40
|
235
320
|
puts
|
236
321
|
|
237
|
-
|
238
|
-
|
322
|
+
begin
|
323
|
+
continue = prompt.yes?(_('About to generate this module; continue?')) do |q|
|
324
|
+
q.validate(proc { |value| [true, false].include?(value) || value =~ %r{\A(?:yes|y|no|n)\Z}i }, _('Answer "Y" to continue or "n" to cancel.'))
|
325
|
+
end
|
326
|
+
rescue TTY::Prompt::Reader::InputInterrupt
|
327
|
+
PDK.logger.info _('Interview cancelled; not generating the module.')
|
328
|
+
exit 0
|
239
329
|
end
|
240
330
|
|
241
331
|
unless continue
|
@@ -28,8 +28,8 @@ module PDK
|
|
28
28
|
end
|
29
29
|
end
|
30
30
|
|
31
|
-
# Calculates the path to the file
|
32
|
-
# be written
|
31
|
+
# Calculates the path to the file where the tests for the new class will
|
32
|
+
# be written.
|
33
33
|
#
|
34
34
|
# @return [String] the path where the tests for the new class will be
|
35
35
|
# written.
|
@@ -78,14 +78,14 @@ module PDK
|
|
78
78
|
# and create the target files from the template. This is the main entry
|
79
79
|
# point for the class.
|
80
80
|
#
|
81
|
-
# @raise [PDK::CLI::
|
81
|
+
# @raise [PDK::CLI::ExitWithError] if the target files already exist.
|
82
82
|
# @raise [PDK::CLI::FatalError] (see #render_file)
|
83
83
|
#
|
84
84
|
# @api public
|
85
85
|
def run
|
86
86
|
[target_object_path, target_spec_path].each do |target_file|
|
87
87
|
if File.exist?(target_file)
|
88
|
-
raise PDK::CLI::
|
88
|
+
raise PDK::CLI::ExitWithError, _("Unable to generate %{object_type}; '%{file}' already exists.") % { file: target_file, object_type: object_type }
|
89
89
|
end
|
90
90
|
end
|
91
91
|
|
@@ -165,7 +165,7 @@ module PDK
|
|
165
165
|
# TODO: refactor to a search-and-execute form instead
|
166
166
|
return # work is done # rubocop:disable Lint/NonLocalExitFromIterator
|
167
167
|
elsif template[:allow_fallback]
|
168
|
-
PDK.logger.debug(_('Unable to find a %{type} template in %{url}
|
168
|
+
PDK.logger.debug(_('Unable to find a %{type} template in %{url}; trying next template directory.') % { type: object_type, url: template[:url] })
|
169
169
|
else
|
170
170
|
raise PDK::CLI::FatalError, _('Unable to find the %{type} template in %{url}.') % { type: object_type, url: template[:url] }
|
171
171
|
end
|
data/lib/pdk/module/metadata.rb
CHANGED
@@ -44,11 +44,11 @@ module PDK
|
|
44
44
|
|
45
45
|
def self.from_file(metadata_json_path)
|
46
46
|
unless File.file?(metadata_json_path)
|
47
|
-
raise ArgumentError, _("'%{file}' does not exist or is not a file") % { file: metadata_json_path }
|
47
|
+
raise ArgumentError, _("'%{file}' does not exist or is not a file.") % { file: metadata_json_path }
|
48
48
|
end
|
49
49
|
|
50
50
|
unless File.readable?(metadata_json_path)
|
51
|
-
raise ArgumentError, _("Unable to open '%{file}' for reading") % { file: metadata_json_path }
|
51
|
+
raise ArgumentError, _("Unable to open '%{file}' for reading.") % { file: metadata_json_path }
|
52
52
|
end
|
53
53
|
|
54
54
|
begin
|
@@ -90,16 +90,16 @@ module PDK
|
|
90
90
|
|
91
91
|
err = case modname
|
92
92
|
when nil, '', :namespace_missing
|
93
|
-
'
|
93
|
+
_('Field must be a dash-separated user name and module name.')
|
94
94
|
when %r{[^a-z0-9_]}i
|
95
|
-
'
|
95
|
+
_('Module name must contain only alphanumeric or underscore characters.')
|
96
96
|
when %r{^[^a-z]}i
|
97
|
-
'
|
97
|
+
_('Module name must begin with a letter.')
|
98
98
|
else
|
99
|
-
'
|
99
|
+
_('Namespace must contain only alphanumeric characters.')
|
100
100
|
end
|
101
101
|
|
102
|
-
raise ArgumentError, "Invalid 'name' field in metadata.json:
|
102
|
+
raise ArgumentError, _("Invalid 'name' field in metadata.json: %{err}") % { err: err }
|
103
103
|
end
|
104
104
|
end
|
105
105
|
end
|
@@ -52,7 +52,7 @@ module PDK
|
|
52
52
|
unless clone_result[:exit_code].zero?
|
53
53
|
PDK.logger.error clone_result[:stdout]
|
54
54
|
PDK.logger.error clone_result[:stderr]
|
55
|
-
raise PDK::CLI::FatalError, _("Unable to clone git repository '%{repo}' to '%{dest}'") % { repo: path_or_url, dest: temp_dir }
|
55
|
+
raise PDK::CLI::FatalError, _("Unable to clone git repository '%{repo}' to '%{dest}'.") % { repo: path_or_url, dest: temp_dir }
|
56
56
|
end
|
57
57
|
|
58
58
|
@path = PDK::Util.canonical_path(temp_dir)
|
@@ -178,11 +178,11 @@ module PDK
|
|
178
178
|
# @api private
|
179
179
|
def validate_module_template!
|
180
180
|
unless File.directory?(@path)
|
181
|
-
raise ArgumentError, _("The specified template '%{path}' is not a directory") % { path: @path }
|
181
|
+
raise ArgumentError, _("The specified template '%{path}' is not a directory.") % { path: @path }
|
182
182
|
end
|
183
183
|
|
184
184
|
unless File.directory?(@moduleroot_dir) # rubocop:disable Style/GuardClause
|
185
|
-
raise ArgumentError, _("The template at '%{path}' does not contain a 'moduleroot/' directory") % { path: @path }
|
185
|
+
raise ArgumentError, _("The template at '%{path}' does not contain a 'moduleroot/' directory.") % { path: @path }
|
186
186
|
end
|
187
187
|
end
|
188
188
|
|