app_archetype 1.2.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.doxie.json +25 -0
- data/.github/workflows/build.yml +25 -0
- data/.gitignore +22 -0
- data/.rubocop.yml +35 -0
- data/.ruby-version +1 -0
- data/CONTRIBUTING.md +51 -0
- data/Gemfile +3 -0
- data/Gemfile.lock +172 -0
- data/LICENSE +21 -0
- data/README.md +138 -0
- data/Rakefile +19 -0
- data/app_archetype.gemspec +39 -0
- data/bin/archetype +20 -0
- data/lib/app_archetype.rb +14 -0
- data/lib/app_archetype/cli.rb +204 -0
- data/lib/app_archetype/cli/presenters.rb +106 -0
- data/lib/app_archetype/cli/prompts.rb +152 -0
- data/lib/app_archetype/generators.rb +95 -0
- data/lib/app_archetype/logger.rb +69 -0
- data/lib/app_archetype/renderer.rb +116 -0
- data/lib/app_archetype/template.rb +12 -0
- data/lib/app_archetype/template/helpers.rb +216 -0
- data/lib/app_archetype/template/manifest.rb +193 -0
- data/lib/app_archetype/template/plan.rb +172 -0
- data/lib/app_archetype/template/source.rb +39 -0
- data/lib/app_archetype/template/variable.rb +237 -0
- data/lib/app_archetype/template/variable_manager.rb +75 -0
- data/lib/app_archetype/template_manager.rb +113 -0
- data/lib/app_archetype/version.rb +6 -0
- data/lib/core_ext/string.rb +67 -0
- data/spec/app_archetype/cli/presenters_spec.rb +99 -0
- data/spec/app_archetype/cli/prompts_spec.rb +292 -0
- data/spec/app_archetype/cli_spec.rb +132 -0
- data/spec/app_archetype/generators_spec.rb +119 -0
- data/spec/app_archetype/logger_spec.rb +86 -0
- data/spec/app_archetype/renderer_spec.rb +291 -0
- data/spec/app_archetype/template/helpers_spec.rb +251 -0
- data/spec/app_archetype/template/manifest_spec.rb +245 -0
- data/spec/app_archetype/template/plan_spec.rb +191 -0
- data/spec/app_archetype/template/source_spec.rb +60 -0
- data/spec/app_archetype/template/variable_manager_spec.rb +103 -0
- data/spec/app_archetype/template/variable_spec.rb +245 -0
- data/spec/app_archetype/template_manager_spec.rb +221 -0
- data/spec/core_ext/string_spec.rb +143 -0
- data/spec/spec_helper.rb +29 -0
- metadata +370 -0
data/Rakefile
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
require 'private_gem/tasks'
|
2
|
+
require 'bundler/gem_tasks'
|
3
|
+
require 'bump/tasks'
|
4
|
+
require 'rspec/core/rake_task'
|
5
|
+
require 'rubocop/rake_task'
|
6
|
+
require 'rubycritic/rake_task'
|
7
|
+
require 'yard'
|
8
|
+
|
9
|
+
RSpec::Core::RakeTask.new(:spec)
|
10
|
+
RuboCop::RakeTask.new
|
11
|
+
|
12
|
+
RubyCritic::RakeTask.new do |task|
|
13
|
+
task.paths = FileList['lib/**/*.rb'] - FileList['spec/**/*_spec.rb']
|
14
|
+
task.options = '--no-browser --path ./target/reports/critique'
|
15
|
+
end
|
16
|
+
|
17
|
+
YARD::Rake::YardocTask.new
|
18
|
+
|
19
|
+
task default: %i[spec rubocop rubycritic yard]
|
@@ -0,0 +1,39 @@
|
|
1
|
+
lib = File.expand_path('lib', __dir__)
|
2
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
3
|
+
require 'app_archetype/version'
|
4
|
+
|
5
|
+
Gem::Specification.new do |spec|
|
6
|
+
spec.name = 'app_archetype'
|
7
|
+
spec.version = AppArchetype::VERSION
|
8
|
+
spec.authors = ['Andrew Bigger']
|
9
|
+
spec.email = ['andrew.bigger@gmail.com']
|
10
|
+
spec.summary = 'Code project template renderer'
|
11
|
+
spec.homepage = 'https://github.com/andrewbigger/app_archetype'
|
12
|
+
spec.license = 'MIT'
|
13
|
+
|
14
|
+
spec.files = `git ls-files -z`.split("\x0")
|
15
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
16
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
17
|
+
spec.require_paths = ['lib']
|
18
|
+
|
19
|
+
spec.add_dependency 'cli-format', '~> 0.2'
|
20
|
+
spec.add_dependency 'highline', '~> 2.0'
|
21
|
+
spec.add_dependency 'json', '~> 2.3'
|
22
|
+
spec.add_dependency 'jsonnet', '~> 0.3.0'
|
23
|
+
spec.add_dependency 'json-schema', '~> 2.8'
|
24
|
+
spec.add_dependency 'logger', '~> 1.4.2'
|
25
|
+
spec.add_dependency 'os', '~> 1.1'
|
26
|
+
spec.add_dependency 'ostruct', '~> 0.3'
|
27
|
+
spec.add_dependency 'ruby-handlebars', '~> 0.4'
|
28
|
+
spec.add_dependency 'thor', '~> 1.0'
|
29
|
+
|
30
|
+
spec.add_development_dependency 'bump', '~> 0.9'
|
31
|
+
spec.add_development_dependency 'private_gem', '~> 1.1'
|
32
|
+
spec.add_development_dependency 'pry', '~> 0.13'
|
33
|
+
spec.add_development_dependency 'rake', '~> 13.0'
|
34
|
+
spec.add_development_dependency 'rspec', '~> 3.9'
|
35
|
+
spec.add_development_dependency 'rubocop', '~> 0.92'
|
36
|
+
spec.add_development_dependency 'rubycritic', '~> 4.5'
|
37
|
+
spec.add_development_dependency 'simplecov', '~> 0.19'
|
38
|
+
spec.add_development_dependency 'yard', '~> 0.9'
|
39
|
+
end
|
data/bin/archetype
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
lib_path = File.expand_path('../lib', __dir__)
|
4
|
+
$LOAD_PATH.unshift(lib_path) unless $LOAD_PATH.include?(lib_path)
|
5
|
+
|
6
|
+
require 'pry'
|
7
|
+
require 'app_archetype/cli'
|
8
|
+
|
9
|
+
Signal.trap('INT') do
|
10
|
+
warn("\n#{caller.join("\n")}: interrupted")
|
11
|
+
exit(1)
|
12
|
+
end
|
13
|
+
|
14
|
+
begin
|
15
|
+
AppArchetype::CLI.start
|
16
|
+
rescue StandardError => e
|
17
|
+
puts "ERROR: #{e.message}"
|
18
|
+
puts e.backtrace.join("\n")
|
19
|
+
exit 1
|
20
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
require 'core_ext/string'
|
2
|
+
|
3
|
+
require 'app_archetype/logger'
|
4
|
+
require 'app_archetype/template'
|
5
|
+
|
6
|
+
require 'app_archetype/template_manager'
|
7
|
+
require 'app_archetype/renderer'
|
8
|
+
require 'app_archetype/generators'
|
9
|
+
|
10
|
+
require 'app_archetype/version'
|
11
|
+
|
12
|
+
# AppArchetype is the namespace for app_archetype
|
13
|
+
module AppArchetype
|
14
|
+
end
|
@@ -0,0 +1,204 @@
|
|
1
|
+
require 'logger'
|
2
|
+
require 'thor'
|
3
|
+
require 'highline'
|
4
|
+
|
5
|
+
require 'app_archetype'
|
6
|
+
require 'app_archetype/cli/presenters'
|
7
|
+
require 'app_archetype/cli/prompts'
|
8
|
+
|
9
|
+
module AppArchetype
|
10
|
+
# Command line interface helpers and actions
|
11
|
+
class CLI < Thor
|
12
|
+
package_name 'Archetype'
|
13
|
+
|
14
|
+
class <<self
|
15
|
+
##
|
16
|
+
# Retrieves template dir from environment and raises error
|
17
|
+
# when TEMPLATE_DIR environment variable is not set.
|
18
|
+
#
|
19
|
+
# @return [String]
|
20
|
+
#
|
21
|
+
def template_dir
|
22
|
+
@template_dir = ENV['ARCHETYPE_TEMPLATE_DIR']
|
23
|
+
|
24
|
+
unless @template_dir
|
25
|
+
raise 'ARCHETYPE_TEMPLATE_DIR environment variable not set'
|
26
|
+
end
|
27
|
+
|
28
|
+
return @template_dir if File.exist?(@template_dir)
|
29
|
+
|
30
|
+
raise "ARCHETYPE_TEMPLATE_DIR #{@template_dir} does not exist"
|
31
|
+
end
|
32
|
+
|
33
|
+
##
|
34
|
+
# Editor retrieves the chosen editor command to open text files
|
35
|
+
# and raises error when ARCHETYPE_EDITOR is not set.
|
36
|
+
#
|
37
|
+
# If we detect that the which command fails then we warn the user that
|
38
|
+
# something appears awry
|
39
|
+
#
|
40
|
+
# @return [String]
|
41
|
+
#
|
42
|
+
def editor
|
43
|
+
@editor = ENV['ARCHETYPE_EDITOR']
|
44
|
+
raise 'ARCHETYPE_EDITOR environment variable not set' unless @editor
|
45
|
+
|
46
|
+
`which #{@editor}`
|
47
|
+
if $?.exitstatus != 0
|
48
|
+
CLI.print_warning(
|
49
|
+
"WARN: Configured editor #{@editor} is not installed correctly "\
|
50
|
+
'please check your configuration'
|
51
|
+
)
|
52
|
+
end
|
53
|
+
|
54
|
+
@editor
|
55
|
+
end
|
56
|
+
|
57
|
+
##
|
58
|
+
# Template manager creates and loads a template manager
|
59
|
+
#
|
60
|
+
# @return [AppArchetype::TemplateManager]
|
61
|
+
#
|
62
|
+
def manager
|
63
|
+
@manager ||= AppArchetype::TemplateManager.new(template_dir)
|
64
|
+
@manager.load
|
65
|
+
|
66
|
+
@manager
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
include AppArchetype::Logger
|
71
|
+
|
72
|
+
def self.exit_on_failure?
|
73
|
+
true
|
74
|
+
end
|
75
|
+
|
76
|
+
desc 'version', 'Prints archetype gem version'
|
77
|
+
def version
|
78
|
+
print_message(AppArchetype::VERSION)
|
79
|
+
end
|
80
|
+
map %w[--version -v] => :version
|
81
|
+
|
82
|
+
desc 'list', 'Lists known templates in ARCHETYPE_TEMPLATE_DIR'
|
83
|
+
def list
|
84
|
+
print_message(
|
85
|
+
Presenters.manifest_list(
|
86
|
+
CLI.manager.manifests
|
87
|
+
)
|
88
|
+
)
|
89
|
+
end
|
90
|
+
|
91
|
+
desc 'path', 'Prints configured ARCHETYPE_TEMPLATE_DIR'
|
92
|
+
def path
|
93
|
+
print_message(
|
94
|
+
CLI.template_dir
|
95
|
+
)
|
96
|
+
end
|
97
|
+
|
98
|
+
desc 'open', 'Opens template manifest'
|
99
|
+
def open(name)
|
100
|
+
editor = CLI.editor
|
101
|
+
manifest = CLI.manager.find_by_name(name)
|
102
|
+
|
103
|
+
pid = Process.spawn("#{editor} #{manifest.path}")
|
104
|
+
Process.waitpid(pid)
|
105
|
+
end
|
106
|
+
|
107
|
+
desc 'new', 'Creates a template in ARCHETYPE_TEMPLATE_DIR'
|
108
|
+
def new(rel)
|
109
|
+
raise 'template rel not provided' unless rel
|
110
|
+
|
111
|
+
dest = File.join(CLI.template_dir, rel)
|
112
|
+
FileUtils.mkdir_p(dest)
|
113
|
+
|
114
|
+
name = File.basename(rel)
|
115
|
+
AppArchetype::Generators.render_empty_template(name, dest)
|
116
|
+
|
117
|
+
print_message("Template `#{name}` created at #{dest}")
|
118
|
+
end
|
119
|
+
|
120
|
+
desc 'delete', 'Deletes a template in ARCHETYPE_TEMPLATE_DIR'
|
121
|
+
def delete(name)
|
122
|
+
manifest = CLI.manager.find_by_name(name)
|
123
|
+
raise 'Cannot find template' unless manifest
|
124
|
+
|
125
|
+
proceed = Prompts.delete_template(manifest)
|
126
|
+
|
127
|
+
return unless proceed
|
128
|
+
|
129
|
+
FileUtils.rm_rf(manifest.parent_path)
|
130
|
+
print_message("Template `#{manifest.name}` has been removed")
|
131
|
+
end
|
132
|
+
|
133
|
+
desc 'validate', 'Runs a schema validation on given template'
|
134
|
+
def validate(name)
|
135
|
+
manifest = CLI.manager.find_by_name(name)
|
136
|
+
raise 'Cannot find template' unless manifest
|
137
|
+
|
138
|
+
result = manifest.validate
|
139
|
+
|
140
|
+
print_message("VALIDATION RESULTS FOR `#{name}`")
|
141
|
+
if result.any?
|
142
|
+
print_message(
|
143
|
+
Presenters.validation_result(result)
|
144
|
+
)
|
145
|
+
|
146
|
+
raise "Manifest `#{name}` is not valid"
|
147
|
+
end
|
148
|
+
|
149
|
+
print_message("Manifest `#{name}` is valid") if result.empty?
|
150
|
+
end
|
151
|
+
|
152
|
+
desc 'variables', 'Prints template variables'
|
153
|
+
def variables(search_term)
|
154
|
+
result = CLI.manager.find_by_name(search_term)
|
155
|
+
return print_message("Manifest `#{search_term}` not found") unless result
|
156
|
+
|
157
|
+
print_message("VARIABLES FOR `#{search_term}`")
|
158
|
+
print_message(
|
159
|
+
Presenters.variable_list(result.variables.all)
|
160
|
+
)
|
161
|
+
end
|
162
|
+
|
163
|
+
desc 'find', 'Finds a template in collection by name'
|
164
|
+
def find(search_term)
|
165
|
+
result = CLI.manager.find_by_name(search_term)
|
166
|
+
return print_message("Manifest `#{search_term}` not found") unless result
|
167
|
+
|
168
|
+
print_message("SEARCH RESULTS FOR `#{search_term}`")
|
169
|
+
print_message(
|
170
|
+
Presenters.manifest_list([result])
|
171
|
+
)
|
172
|
+
end
|
173
|
+
|
174
|
+
desc 'render', 'Renders project template'
|
175
|
+
method_option(
|
176
|
+
:overwrite,
|
177
|
+
type: :boolean,
|
178
|
+
default: false,
|
179
|
+
desc: 'Option to overwrite any existing files'
|
180
|
+
)
|
181
|
+
def render(manifest_name)
|
182
|
+
manifest = CLI.manager.find_by_name(manifest_name)
|
183
|
+
|
184
|
+
raise "Unable to find manifest `#{manifest_name}`" unless manifest
|
185
|
+
|
186
|
+
template = manifest.template
|
187
|
+
template.load
|
188
|
+
|
189
|
+
manifest.variables.all.each do |var|
|
190
|
+
value = Prompts.variable_prompt_for(var)
|
191
|
+
var.set!(value)
|
192
|
+
end
|
193
|
+
|
194
|
+
plan = AppArchetype::Template::Plan.new(
|
195
|
+
template,
|
196
|
+
manifest.variables,
|
197
|
+
destination_path: FileUtils.pwd,
|
198
|
+
overwrite: options.overwrite
|
199
|
+
)
|
200
|
+
plan.devise
|
201
|
+
plan.execute
|
202
|
+
end
|
203
|
+
end
|
204
|
+
end
|
@@ -0,0 +1,106 @@
|
|
1
|
+
require 'cli-format'
|
2
|
+
|
3
|
+
module AppArchetype
|
4
|
+
class CLI < Thor
|
5
|
+
# CLI output presenters
|
6
|
+
module Presenters
|
7
|
+
##
|
8
|
+
# Output table header
|
9
|
+
#
|
10
|
+
RESULT_HEADER = %w[NAME VERSION].freeze
|
11
|
+
|
12
|
+
##
|
13
|
+
# Variable table header
|
14
|
+
#
|
15
|
+
VARIABLE_HEADER = %w[NAME DESCRIPTION DEFAULT].freeze
|
16
|
+
|
17
|
+
##
|
18
|
+
# Validation result table header
|
19
|
+
#
|
20
|
+
VALIDATION_HEADER = %w[ERROR].freeze
|
21
|
+
|
22
|
+
class <<self
|
23
|
+
##
|
24
|
+
# Creates a presenter for given data
|
25
|
+
#
|
26
|
+
# Accepts header row data and has configurable format.
|
27
|
+
#
|
28
|
+
# Header must be array of string
|
29
|
+
#
|
30
|
+
# Data is array of arrays where the inner array is a row.
|
31
|
+
#
|
32
|
+
# Format by default is a table, although can be 'csv'
|
33
|
+
# or 'json'.
|
34
|
+
#
|
35
|
+
# @param header [Array]
|
36
|
+
# @param data [Array]
|
37
|
+
# @param format [String]
|
38
|
+
#
|
39
|
+
# @return [CliFormat::Presenter]
|
40
|
+
#
|
41
|
+
def table(header: [], data: [], format: 'table')
|
42
|
+
has_header = header.any?
|
43
|
+
opts = { header: has_header, format: format }
|
44
|
+
|
45
|
+
presenter = CliFormat::Presenter.new(opts)
|
46
|
+
presenter.header = header if has_header
|
47
|
+
|
48
|
+
data.each { |row| presenter.rows << row }
|
49
|
+
|
50
|
+
presenter
|
51
|
+
end
|
52
|
+
|
53
|
+
##
|
54
|
+
# Builds a table of manifest information
|
55
|
+
#
|
56
|
+
# @param [Array] manifests
|
57
|
+
#
|
58
|
+
def manifest_list(manifests)
|
59
|
+
table(
|
60
|
+
header: RESULT_HEADER,
|
61
|
+
data: manifests.map do |manifest|
|
62
|
+
[
|
63
|
+
manifest.name,
|
64
|
+
manifest.version
|
65
|
+
]
|
66
|
+
end
|
67
|
+
).show
|
68
|
+
end
|
69
|
+
|
70
|
+
##
|
71
|
+
# Builds a table of variable information
|
72
|
+
#
|
73
|
+
# @param [Array] variables
|
74
|
+
#
|
75
|
+
def variable_list(variables)
|
76
|
+
table(
|
77
|
+
header: VARIABLE_HEADER,
|
78
|
+
data: variables.map do |variable|
|
79
|
+
[
|
80
|
+
variable.name,
|
81
|
+
variable.description,
|
82
|
+
variable.default
|
83
|
+
]
|
84
|
+
end
|
85
|
+
).show
|
86
|
+
end
|
87
|
+
|
88
|
+
##
|
89
|
+
# Builds a table for manifest validation results
|
90
|
+
#
|
91
|
+
# @param [Array] results
|
92
|
+
#
|
93
|
+
def validation_result(results)
|
94
|
+
table(
|
95
|
+
header: VALIDATION_HEADER,
|
96
|
+
data: results.map do |result|
|
97
|
+
[
|
98
|
+
result
|
99
|
+
]
|
100
|
+
end
|
101
|
+
).show
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
@@ -0,0 +1,152 @@
|
|
1
|
+
require 'highline'
|
2
|
+
|
3
|
+
module AppArchetype
|
4
|
+
class CLI < Thor
|
5
|
+
# CLI output presenters
|
6
|
+
module Prompts
|
7
|
+
##
|
8
|
+
# Variable prompt question. Asked when evaluating template
|
9
|
+
# variables
|
10
|
+
#
|
11
|
+
# @param [AppArchetype::Template::Variable] variable
|
12
|
+
#
|
13
|
+
# @return [Proc]
|
14
|
+
#
|
15
|
+
VAR_PROMPT_MESSAGE = lambda do |variable|
|
16
|
+
"\nEnter value for `#{variable.name}` variable\n\n"\
|
17
|
+
"DESCRIPTION: #{variable.description}\n"\
|
18
|
+
"TYPE: #{variable.type}\n"\
|
19
|
+
"DEFAULT: #{variable.default}"
|
20
|
+
end
|
21
|
+
|
22
|
+
class <<self
|
23
|
+
##
|
24
|
+
# Prompt returns a TTY prompt object for asking the user
|
25
|
+
# questions.
|
26
|
+
#
|
27
|
+
# @return [HighLine]
|
28
|
+
def prompt
|
29
|
+
HighLine.new
|
30
|
+
end
|
31
|
+
|
32
|
+
##
|
33
|
+
# A yes/no prompt for asking the user a yes or no question.
|
34
|
+
#
|
35
|
+
# @return [Boolean]
|
36
|
+
#
|
37
|
+
def yes?(message)
|
38
|
+
prompt.ask("#{message} [Y/n]", String) { |input| input.strip == 'Y' }
|
39
|
+
end
|
40
|
+
|
41
|
+
##
|
42
|
+
# Prompt for requesting user input.
|
43
|
+
#
|
44
|
+
# A default can be provided in the event the user does not
|
45
|
+
# provide an answer.
|
46
|
+
#
|
47
|
+
# Validator also performs type conversion by default it is
|
48
|
+
# a string
|
49
|
+
#
|
50
|
+
# @param message [String]
|
51
|
+
# @param default [Object]
|
52
|
+
# @param validator [Object|Lambda]
|
53
|
+
#
|
54
|
+
# @return [Object]
|
55
|
+
#
|
56
|
+
def ask(message, validator: String, default: nil)
|
57
|
+
resp = prompt.ask(message, validator)
|
58
|
+
return default if !default.nil? && resp.to_s.empty?
|
59
|
+
|
60
|
+
resp
|
61
|
+
end
|
62
|
+
|
63
|
+
##
|
64
|
+
# Y/N prompt to ensure user is sure they wish to delete
|
65
|
+
# the selected template
|
66
|
+
#
|
67
|
+
# @param [AppArchetype::Template::Manifest] manifest
|
68
|
+
#
|
69
|
+
# @return [Boolean]
|
70
|
+
def delete_template(manifest)
|
71
|
+
yes?(
|
72
|
+
"Are you sure you want to delete `#{manifest.name}`?"
|
73
|
+
)
|
74
|
+
end
|
75
|
+
|
76
|
+
##
|
77
|
+
# Returns a variable prompt based on the type of variable
|
78
|
+
# required. Once prompt has been executed, the response is
|
79
|
+
# returned to the caller.
|
80
|
+
#
|
81
|
+
# When the value is set in the manifest, the set value is
|
82
|
+
# returned without a prompt.
|
83
|
+
#
|
84
|
+
# For boolean and integer variables, the relevant prompt
|
85
|
+
# function is called.
|
86
|
+
#
|
87
|
+
# By default the string variable prompt will be used.
|
88
|
+
#
|
89
|
+
# @param [AppArchetype::Template::Variable] var
|
90
|
+
#
|
91
|
+
# @return [Object]
|
92
|
+
#
|
93
|
+
def variable_prompt_for(var)
|
94
|
+
return var.value if var.value?
|
95
|
+
return boolean_variable_prompt(var) if var.type == 'boolean'
|
96
|
+
return integer_variable_prompt(var) if var.type == 'integer'
|
97
|
+
|
98
|
+
string_variable_prompt(var)
|
99
|
+
end
|
100
|
+
|
101
|
+
##
|
102
|
+
# Prompt for boolean variable. This quizzes the user as to
|
103
|
+
# whether they want the variable set or not. The response
|
104
|
+
# is returned to the caller.
|
105
|
+
#
|
106
|
+
# @param [AppArchetype::Template::Variable] variable
|
107
|
+
#
|
108
|
+
# @return [Boolean]
|
109
|
+
#
|
110
|
+
def boolean_variable_prompt(variable)
|
111
|
+
yes?(
|
112
|
+
VAR_PROMPT_MESSAGE.call(variable)
|
113
|
+
)
|
114
|
+
end
|
115
|
+
|
116
|
+
##
|
117
|
+
# Prompt for integer. This quizzes the user for their
|
118
|
+
# choice and then attempts to convert it to an integer.
|
119
|
+
#
|
120
|
+
# In the event a non integer value is entered, a
|
121
|
+
# RuntimeError is thrown.
|
122
|
+
#
|
123
|
+
# @param [AppArchetype::Template::Variable] variable
|
124
|
+
#
|
125
|
+
# @return [Integer]
|
126
|
+
#
|
127
|
+
def integer_variable_prompt(variable)
|
128
|
+
ask(
|
129
|
+
VAR_PROMPT_MESSAGE.call(variable),
|
130
|
+
default: variable.default,
|
131
|
+
validator: Integer
|
132
|
+
)
|
133
|
+
end
|
134
|
+
|
135
|
+
##
|
136
|
+
# Prompt for a string. Asks user for input and returns
|
137
|
+
# it.
|
138
|
+
#
|
139
|
+
# @param [AppArchetype::Template::Variable] variable
|
140
|
+
#
|
141
|
+
# @return [String]
|
142
|
+
#
|
143
|
+
def string_variable_prompt(variable)
|
144
|
+
ask(
|
145
|
+
VAR_PROMPT_MESSAGE.call(variable),
|
146
|
+
default: variable.default
|
147
|
+
)
|
148
|
+
end
|
149
|
+
end
|
150
|
+
end
|
151
|
+
end
|
152
|
+
end
|